Skip to content

Commit

Permalink
Fix PrettyPrinting corner case, add more tests (#1415)
Browse files Browse the repository at this point in the history
Add some examples from the OSCAR dev docs to make sure they match
reality.

Also fix a bug where in some situations the pretty printing feature
caused a trailing 0 to be printed (e.g. when ending printing with
a `Dedent()`), as in this example:

    julia> show(stdout, MIME"text/plain"(), F)
    Number field with defining polynomial x^2 + 3
      over rational field0

I tried to add a test case for this, but the issue only happens
with `stdout`, not with an `IOBuffer`
  • Loading branch information
fingolfin authored Sep 5, 2023
1 parent c95f17e commit 58c0b47
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/PrettyPrinting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1533,13 +1533,13 @@ unlock(io::IOCustom) = unlock(io.io)

Base.displaysize(io::IOCustom) = displaysize(io.io)

write(io::IO, ::Indent) = (_unwrap(io).indent_level += 1; 0)
write(io::IO, ::Indent) = (_unwrap(io).indent_level += 1; nothing)
print(io::IO, ::Indent) = write(io, Indent())
write(io::IO, ::Dedent) = (_unwrap(io).indent_level = max(0, io.indent_level - 1); 0)
write(io::IO, ::Dedent) = (_unwrap(io).indent_level = max(0, io.indent_level - 1); nothing)
print(io::IO, ::Dedent) = write(io, Dedent())
write(io::IO, ::Lowercase) = (_unwrap(io).lowercasefirst = true; 0)
write(io::IO, ::Lowercase) = (_unwrap(io).lowercasefirst = true; nothing)
print(io::IO, ::Lowercase) = write(io, Lowercase())
write(io::IO, ::LowercaseOff) = (_unwrap(io).lowercasefirst = false; 0)
write(io::IO, ::LowercaseOff) = (_unwrap(io).lowercasefirst = false; nothing)
print(io::IO, ::LowercaseOff) = write(io, LowercaseOff())

write_indent(io::IO) = write(_unwrap(io).io, io.indent_str^io.indent_level)
Expand Down
104 changes: 104 additions & 0 deletions test/PrettyPrinting-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,110 @@
@test AbstractAlgebra.obj_to_string_wrt_times(x + y) == "(x + y)"
end

# Test various examples from the Oscar manual
@testset "PrettyPrinting examples" begin

function detailed(x)
io = IOBuffer()
show(io, MIME"text/plain"(), x)
return String(take!(io))
end

function oneline(x)
io = IOBuffer()
print(io, x)
return String(take!(io))
end

function supercompact(x)
io = IOBuffer()
print(IOContext(io, :supercompact => true), x)
return String(take!(io))
end

#
#
#
struct NewRing
base_ring
end

base_ring(R::NewRing) = R.base_ring

function Base.show(io::IO, ::MIME"text/plain", R::NewRing)
println(io, "I am a new ring") # at least one new line is needed
println(io, "I print with newlines")
print(io, base_ring(R)) # the last print statement must not add a new line
end

function Base.show(io::IO, R::NewRing)
if get(io, :supercompact, false)
# no nested printing
print(io, "supercompact printing of newring ")
else
# nested printing allowed, preferably supercompact
print(io, "one line printing of newring with ")
print(IOContext(io, :supercompact => true), "supercompact ", base_ring(R))
end
end

R = NewRing(QQ)
@test detailed(R) ==
"""I am a new ring
I print with newlines
Rationals"""
@test oneline(R) == "one line printing of newring with supercompact Rationals"
@test supercompact(R) == "supercompact printing of newring "

#
#
#
struct A{T}
x::T
end

function Base.show(io::IO, a::A)
io = AbstractAlgebra.pretty(io)
println(io, "Something of type A")
print(io, AbstractAlgebra.Indent(), "over ", AbstractAlgebra.Lowercase(), a.x)
print(io, AbstractAlgebra.Dedent()) # don't forget to undo the indentation!
end

struct B
end

function Base.show(io::IO, b::B)
io = AbstractAlgebra.pretty(io)
print(io, AbstractAlgebra.LowercaseOff(), "Hilbert thing")
end

x = A(2)
y = """
Something of type A
over 2"""
@test detailed(x) == y
@test oneline(x) == y
@test supercompact(x) == y

x = A(A(2))
y = """
Something of type A
over something of type A
over 2"""
@test detailed(x) == y
@test oneline(x) == y
@test supercompact(x) == y

x = A(B())
y = """
Something of type A
over Hilbert thing"""
@test detailed(x) == y
@test oneline(x) == y
@test supercompact(x) == y

end

let
io = IOBuffer()
io = AbstractAlgebra.pretty(io, force_newlines = true)
Expand Down

0 comments on commit 58c0b47

Please sign in to comment.