Skip to content

improving HTML to permit nesting #38889

@clarkevans

Description

@clarkevans

Is there anyway the following two lines could be added to base/docs/utils.jl for this upcoming 1.6?

print(io::IO, h::HTML) = print(io, h.content)
print(io::IO, h::HTML{<:Function}) = h.content(io)

This feature provides two benefits. First, it lets HTML objects nest arbitrarily deep (eliminating need for catdoc?). Second it lets the user use print(h) in addition to display("text/html", h). Following is a walk-though of usability before/after the change.

# HTML has 2 constructors, list all 4 permutations

julia> h1 = HTML(HTML("<tag/>"))
HTML{HTML{String}}(HTML{String}("<tag/>"))

julia> h2 = HTML("<div>", HTML("<span>text</span>"), "</div>")
HTML{Base.Docs.var"#9#10"{Tuple{String,HTML{String},String}}}(Base.Docs.var"#9#10"{Tuple{String,HTML{String},String}}(("<div>", HTML{String}("<span>text</span"), "</div>")))

julia> h3 = HTML(HTML("<span>", "text", "</span>"))
HTML{HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}}}(HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}}(Base.Docs.var"#9#10"{Tuple{String,String,String}}(("<span>", "text", "</span"))))

julia> h4 = HTML("<div>", HTML("<span>", "text", "</span>"), "</div>")
HTML{Base.Docs.var"#9#10"{Tuple{String,HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}},String}}}(Base.Docs.var"#9#10"{Tuple{String,HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}},String}}(("<div>", HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}}(Base.Docs.var"#9#10"{Tuple{String,String,String}}(("<span>", "text", "</span"))), "</div>")))

# Existing, unusuable display

julia> display("text/html", h1)
HTML{String}("<tag/>")

julia> display("text/html", h2)
HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}}(Base.Docs.var"#9#10"{Tuple{String,String,String}}(("<span>", "text", "</span>")))

julia> display("text/html", h3)
HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}}(Base.Docs.var"#9#10"{Tuple{String,String,String}}(("<span>", "text", "</span>")))

julia> display("text/html", h4)
<div>HTML{Base.Docs.var"#9#10"{Tuple{String,String,String}}}(Base.Docs.var"#9#10"{Tuple{String,String,String}}(("<span>", "text", "</span>")))</div>

# Apply the two new functions...

julia> Base.print(io::IO, h::HTML) = print(io, h.content)
julia> Base.print(io::IO, h::HTML{<:Function}) = h.content(io)

# Then we get usable, expected output via nesting

julia> display("text/html", h1)
<tag/>

julia> display("text/html", h2)
<div><span>text</span></div>

julia> display("text/html", h3)
<span>text</span>

julia> display("text/html", h4)
<div><span>text</span></div>

This comes out of work on HypertextLiteral.jl and I've had to create my own HTML like object that differs only since it has this additional 2 statements. I don't see any side effects and it provides excellent value that would be great to have in a LTS, since so much new work involves building web services in Julia.

Metadata

Metadata

Assignees

No one assigned

    Labels

    display and printingAesthetics and correctness of printed representations of objects.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions