diff --git a/src/display.jl b/src/display.jl index 249ad93f..ebe88d66 100644 --- a/src/display.jl +++ b/src/display.jl @@ -44,10 +44,6 @@ function prefix(x::Unit) end end -function show(io::IO, x::Unit{N,D}) where {N,D} - show(io, FreeUnits{(x,), D, nothing}()) -end - abstract type BracketStyle end struct NoBrackets <: BracketStyle end @@ -89,7 +85,7 @@ brackets are not printed. """ function showval(io::IO, x::Number, brackets::Bool=true) brackets && print_opening_bracket(io, x) - show(io, x) + show(io, MIME"text/plain"(), x) brackets && print_closing_bracket(io, x) end @@ -107,20 +103,10 @@ has_unit_spacing(u) = true has_unit_spacing(u::Units{(Unit{:Degree, NoDims}(0, 1//1),), NoDims}) = false """ - show(io::IO, x::Quantity) + show(io::IO, mime::MIME"text/plain", x::Quantity) Show a unitful quantity by calling [`showval`](@ref) on the numeric value, appending a space, and then calling `show` on a units object `U()`. """ -function show(io::IO, x::Quantity) - if isunitless(unit(x)) - showval(io, x.val, false) - else - showval(io, x.val, true) - has_unit_spacing(unit(x)) && print(io, ' ') - show(io, unit(x)) - end -end - function show(io::IO, mime::MIME"text/plain", x::Quantity) if isunitless(unit(x)) showval(io, mime, x.val, false) @@ -131,30 +117,30 @@ function show(io::IO, mime::MIME"text/plain", x::Quantity) end end -function show(io::IO, r::Union{StepRange{T},StepRangeLen{T}}) where T<:Quantity +function show(io::IO, mime::MIME"text/plain", r::Union{StepRange{T},StepRangeLen{T}}) where T<:Quantity a,s,b = first(r), step(r), last(r) U = unit(a) print(io, '(') if ustrip(U, s) == 1 - show(io, ustrip(U, a):ustrip(U, b)) + show(io, mime, ustrip(U, a):ustrip(U, b)) else - show(io, ustrip(U, a):ustrip(U, s):ustrip(U, b)) + show(io, mime, ustrip(U, a):ustrip(U, s):ustrip(U, b)) end print(io, ')') has_unit_spacing(U) && print(io,' ') - show(io, U) + show(io, mime, U) end -function show(io::IO, x::typeof(NoDims)) +function show(io::IO, ::MIME"text/plain", x::typeof(NoDims)) print(io, "NoDims") end """ - show(io::IO, x::Unitlike) + show(io::IO, ::MIME"text/plain", x::Unitlike) Call [`Unitful.showrep`](@ref) on each object in the tuple that is the type variable of a [`Unitful.Units`](@ref) or [`Unitful.Dimensions`](@ref) object. """ -function show(io::IO, x::Unitlike) +function show(io::IO, ::MIME"text/plain", x::Unitlike) showoperators = get(io, :showoperators, false) first = "" sep = showoperators ? "*" : " " @@ -241,3 +227,12 @@ superscript(i::Integer) = map(repr(i)) do c c == '0' ? '\u2070' : error("unexpected character") end + +Base.print(io::IO, x::AbstractQuantity) = show(io, "text/plain", x) +Base.print(io::IO, x::Dimension) = show(io, "text/plain", x) +Base.print(io::IO, x::Unit) = show(io, "text/plain", x) +Base.print(io::IO, x::Union{StepRange{T},StepRangeLen{T}}) where T<:Quantity = show(io, "text/plain", x) +Base.print(io::IO, x::Unitlike) = show(io, "text/plain", x) +Base.print(io::IO, x::MixedUnits) = show(io, "text/plain", x) +Base.print(io::IO, x::LogScaled) = show(io, "text/plain", x) +Base.print(io::IO, x::IsRootPowerRatio) = show(io, "text/plain", x) diff --git a/src/logarithm.jl b/src/logarithm.jl index 58d76beb..a9d9daa4 100644 --- a/src/logarithm.jl +++ b/src/logarithm.jl @@ -84,11 +84,11 @@ tolog(L,x) = (1+isrootpower(L)) * prefactor(L()) * (logfn(L()))(x) fromlog(L,S,x) = unwrap(S) * expfn(L())( x / ((1+isrootpower(S))*prefactor(L())) ) fromlog(L,x) = expfn(L())( x / ((1+isrootpower(L))*prefactor(L())) ) -function Base.show(io::IO, x::MixedUnits{T,U}) where {T,U} +function Base.show(io::IO, mime::MIME"text/plain", x::MixedUnits{T,U}) where {T,U} print(io, abbr(x)) if x.units != NoUnits print(io, " ") - show(io, x.units) + show(io, mime, x.units) end end @@ -312,11 +312,11 @@ function Base.promote_rule(::Type{G}, ::Type{N}) where {L,S,T1, G<:Gain{L,S,T1}, end Base.promote_rule(A::Type{G}, B::Type{L}) where {G<:Gain, L2, L<:Level{L2}} = LogScaled{L2} -function Base.show(io::IO, x::Gain) +function Base.show(io::IO, mime::MIME"text/plain", x::Gain) print(io, x.val, " ", abbr(x)) nothing end -function Base.show(io::IO, x::Level) +function Base.show(io::IO, mime::MIME"text/plain", x::Level) print(io, ustrip(x), " ", abbr(x)) nothing end diff --git a/src/types.jl b/src/types.jl index 05b76f61..2d87469e 100644 --- a/src/types.jl +++ b/src/types.jl @@ -273,7 +273,7 @@ struct IsRootPowerRatio{S,T} val::T end IsRootPowerRatio{S}(x) where {S} = IsRootPowerRatio{S, typeof(x)}(x) -Base.show(io::IO, x::IsRootPowerRatio{S}) where {S} = +Base.show(io::IO, ::MIME"text/plain", x::IsRootPowerRatio{S}) where {S} = print(io, ifelse(S, "root-power ratio", "power ratio"), " with reference ", x.val) const PowerRatio{T} = IsRootPowerRatio{false,T} const RootPowerRatio{T} = IsRootPowerRatio{true,T} diff --git a/src/utils.jl b/src/utils.jl index 0f343342..28eba172 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -236,7 +236,7 @@ struct DimensionError <: Exception end Base.showerror(io::IO, e::DimensionError) = - print(io, "DimensionError: $(e.x) and $(e.y) are not dimensionally compatible."); + print(io, "DimensionError: ", e.x, " and ", e.y, " are not dimensionally compatible."); """ struct AffineError <: Exception @@ -246,4 +246,4 @@ struct AffineError <: Exception x end -Base.showerror(io::IO, e::AffineError) = print(io, "AffineError: $(e.x)") +Base.showerror(io::IO, e::AffineError) = print(io, "AffineError: ", e.x) diff --git a/test/runtests.jl b/test/runtests.jl index 3e96550c..b5f40287 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1291,21 +1291,21 @@ end withenv("UNITFUL_FANCY_EXPONENTS" => false) do @static if VERSION โ‰ฅ v"1.6.0-DEV.770" @test string(typeof(1.0m/s)) == - "Quantity{Float64, ๐‹ ๐“^-1, FreeUnits{(m, s^-1), ๐‹ ๐“^-1, nothing}}" + "Quantity{Float64, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), FreeUnits{(Unitful.Unit{:Meter, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}()}(0, 1//1), Unitful.Unit{:Second, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}()}(0, -1//1)), Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), nothing}}" @test string(typeof(m/s)) == - "FreeUnits{(m, s^-1), ๐‹ ๐“^-1, nothing}" + "FreeUnits{(Unitful.Unit{:Meter, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}()}(0, 1//1), Unitful.Unit{:Second, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}()}(0, -1//1)), Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), nothing}" else @test string(typeof(1.0m/s)) == - "Quantity{Float64,๐‹ ๐“^-1,FreeUnits{(m, s^-1),๐‹ ๐“^-1,nothing}}" + "Quantity{Float64, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), FreeUnits{(Unitful.Unit{:Meter, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}()}(0, 1//1), Unitful.Unit{:Second, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}()}(0, -1//1)), Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), nothing}}" @test string(typeof(m/s)) == - "FreeUnits{(m, s^-1),๐‹ ๐“^-1,nothing}" + "FreeUnits{(Unitful.Unit{:Meter, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}()}(0, 1//1), Unitful.Unit{:Second, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}()}(0, -1//1)), Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), nothing}" end @test string(dimension(1u"m/s")) == "๐‹ ๐“^-1" @test string(NoDims) == "NoDims" end @testset ":fancy_exponent IOContext property" begin - @test sprint(io -> show(IOContext(io, :fancy_exponent => true), u"m/s")) == "m sโปยน" - @test sprint(io -> show(IOContext(io, :fancy_exponent => false), u"m/s")) == "m s^-1" + @test sprint(print, u"m/s", context = :fancy_exponent => true) == "m sโปยน" + @test sprint(print, u"m/s", context = :fancy_exponent => false) == "m s^-1" end end @@ -1315,31 +1315,45 @@ Base.show(io::IO, ::MIME"text/plain", ::Foo) = print(io, "42.0") @testset "Show quantities" begin withenv("UNITFUL_FANCY_EXPONENTS" => false) do - @test repr(1.0 * u"m * s * kg^-1") == "1.0 m s kg^-1" + @test repr(1.0 * u"m * s * kg^-1") == "Quantity{Float64, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Mass}(-1//1), Unitful.Dimension{:Time}(1//1))}(), FreeUnits{(Unitful.Unit{:Gram, Unitful.Dimensions{(Unitful.Dimension{:Mass}(1//1),)}()}(3, -1//1), Unitful.Unit{:Meter, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}()}(0, 1//1), Unitful.Unit{:Second, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}()}(0, 1//1)), Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Mass}(-1//1), Unitful.Dimension{:Time}(1//1))}(), nothing}}(1.0)" @test repr("text/plain", 1.0 * u"m * s * kg^-1") == "1.0 m s kg^-1" - @test repr(Foo() * u"m * s * kg^-1") == "1 m s kg^-1" + @test repr(Foo() * u"m * s * kg^-1") == "Quantity{Foo, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Mass}(-1//1), Unitful.Dimension{:Time}(1//1))}(), FreeUnits{(Unitful.Unit{:Gram, Unitful.Dimensions{(Unitful.Dimension{:Mass}(1//1),)}()}(3, -1//1), Unitful.Unit{:Meter, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}()}(0, 1//1), Unitful.Unit{:Second, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}()}(0, 1//1)), Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Mass}(-1//1), Unitful.Dimension{:Time}(1//1))}(), nothing}}(1)" @test repr("text/plain", Foo() * u"m * s * kg^-1") == "42.0 m s kg^-1" # Complex quantities - @test repr((1+2im) * u"m/s") == "(1 + 2im) m s^-1" + @test repr((1+2im) * u"m/s") == "Quantity{Complex{Int64}, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), FreeUnits{(Unitful.Unit{:Meter, Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1),)}()}(0, 1//1), Unitful.Unit{:Second, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}()}(0, -1//1)), Unitful.Dimensions{(Unitful.Dimension{:Length}(1//1), Unitful.Dimension{:Time}(-1//1))}(), nothing}}(1 + 2im)" @test repr("text/plain", (1+2im) * u"m/s") == "(1 + 2im) m s^-1" # Angular degree printing #253 - @test sprint(show, 1.0ยฐ) == "1.0ยฐ" + @test sprint(show, 1.0ยฐ) == "Quantity{Float64, Unitful.Dimensions{()}(), FreeUnits{(Unitful.Unit{:Degree, Unitful.Dimensions{()}()}(0, 1//1),), Unitful.Dimensions{()}(), nothing}}(1.0)" @test repr("text/plain", 1.0ยฐ) == "1.0ยฐ" # Concise printing of ranges - @test repr((1:10)*u"kg/m^3") == "(1:10) kg m^-3" - @test repr((1.0:0.1:10.0)*u"kg/m^3") == "(1.0:0.1:10.0) kg m^-3" - @test repr((1:10)*ยฐ) == "(1:10)ยฐ" + @test repr("text/plain", (1:10)*u"kg/m^3") == "(1:10) kg m^-3" + @test repr("text/plain", (1.0:0.1:10.0)*u"kg/m^3") == "(1.0:0.1:10.0) kg m^-3" + @test repr("text/plain", (1:10)*ยฐ) == "(1:10)ยฐ" end withenv("UNITFUL_FANCY_EXPONENTS" => true) do - @test repr(1.0 * u"m * s * kg^(-1//2)") == "1.0 m s kgโปยนแŸยฒ" + @test repr("text/plain", 1.0 * u"m * s * kg^(-1//2)") == "1.0 m s kgโปยนแŸยฒ" end withenv("UNITFUL_FANCY_EXPONENTS" => nothing) do - @test repr(1.0 * u"m * s * kg^(-1//2)") == + @test repr("text/plain", 1.0 * u"m * s * kg^(-1//2)") == (Sys.isapple() ? "1.0 m s kgโปยนแŸยฒ" : "1.0 m s kg^-1/2") end + + @testset "roundtripping show" begin + u = u"m/s" + u2 = eval(Meta.parse(repr(u))) + @test u == u2 + + q = Quantity(5, u"m") + q2 = eval(Meta.parse(repr(q))) + @test q == q2 + + d = u"๐Œ*๐‹/๐“^2" + d2 = eval(Meta.parse(repr(d))) + @test d == d2 + end end @testset "DimensionError message" begin @@ -1673,7 +1687,7 @@ end @testset "> Display" begin withenv("UNITFUL_FANCY_EXPONENTS" => false) do - @test repr(3u"dB/Hz") == "[3 dB] Hz^-1" + @test repr(3u"dB/Hz") == "Quantity{Gain{LogInfo{:Decibel, 10, 10}, :?, Int64}, Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}(), FreeUnits{(Unitful.Unit{:Hertz, Unitful.Dimensions{(Unitful.Dimension{:Time}(-1//1),)}()}(0, -1//1),), Unitful.Dimensions{(Unitful.Dimension{:Time}(1//1),)}(), nothing}}(Gain{LogInfo{:Decibel, 10, 10}, :?, Int64}(3))" @test repr("text/plain", 3u"dB/Hz") == "[3 dB] Hz^-1" end @test Unitful.abbr(3u"dBm") == "dBm"