• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / 1398

06 Jan 2026 07:49AM UTC coverage: 76.733% (+0.06%) from 76.678%
1398

push

buildkite

web-flow
Improve wording a bit in new inline LaTeX Markdown note (#60559)

The wording felt a bit clumsy.

62583 of 81559 relevant lines covered (76.73%)

23344049.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.65
/stdlib/Markdown/src/render/html.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
include("rich.jl")
4

5
# Utils
6

7
function withtag(f, io::IO, tag, attrs...)
1,545✔
8
    print(io, "<$tag")
1,560✔
9
    for (attr, value) in attrs
1,560✔
10
        print(io, " ")
375✔
11
        htmlesc(io, attr)
375✔
12
        print(io, "=\"")
375✔
13
        htmlesc(io, value)
375✔
14
        print(io, "\"")
375✔
15
    end
399✔
16
    f === nothing && return print(io, " />")
1,560✔
17

18
    print(io, ">")
1,545✔
19
    f()
1,605✔
20
    print(io, "</$tag>")
1,545✔
21
end
22

23
tag(io::IO, tag, attrs...) = withtag(nothing, io, tag, attrs...)
15✔
24

25
const _htmlescape_chars = Dict('<'=>"&lt;",   '>'=>"&gt;",
26
                               '"'=>"&quot;", '&'=>"&amp;",
27
                               # ' '=>"&nbsp;",
28
                               )
29
for ch in "'`!\$%()=+{}[]"
30
    _htmlescape_chars[ch] = "&#$(Int(ch));"
31
end
32

33
function htmlesc(io::IO, s::AbstractString)
2,217✔
34
    # s1 = replace(s, r"&(?!(\w+|\#\d+);)" => "&amp;")
35
    for ch in s
4,428✔
36
        print(io, get(_htmlescape_chars, ch, ch))
25,398✔
37
    end
24,312✔
38
end
39
function htmlesc(io::IO, s::Symbol)
40
    htmlesc(io, string(s))
228✔
41
end
42
function htmlesc(io::IO, xs::Union{AbstractString,Symbol}...)
×
43
    for s in xs
×
44
        htmlesc(io, s)
×
45
    end
×
46
end
47
function htmlesc(s::Union{AbstractString,Symbol})
×
48
    sprint(htmlesc, s)
×
49
end
50

51
# Block elements
52

53
function html(io::IO, content::Vector)
573✔
54
    for md in content
573✔
55
        html(io, md)
798✔
56
        println(io)
798✔
57
    end
798✔
58
end
59

60
html(io::IO, md::MD) = html(io, md.content)
471✔
61

62
function html(io::IO, header::Header{l}) where l
123✔
63
    withtag(io, "h$l") do
123✔
64
        htmlinline(io, header.text)
123✔
65
    end
66
end
67

68
function html(io::IO, code′::Code)
90✔
69
    if code′.language == "styled"
90✔
70
        code′ = Code("", String(styled(code′.code)))
×
71
    end
72
    code = code′
90✔
73
    withtag(io, :pre) do
90✔
74
        maybe_lang = !isempty(code.language) ? Any[:class=>"language-$(code.language)"] : []
117✔
75
        withtag(io, :code, maybe_lang...) do
90✔
76
            htmlesc(io, code.code)
90✔
77
            # TODO should print newline if this is longer than one line ?
78
        end
79
    end
80
end
81

82
function html(io::IO, md::Paragraph)
411✔
83
    withtag(io, :p) do
411✔
84
        htmlinline(io, md.content)
411✔
85
    end
86
end
87

88
function html(io::IO, md::BlockQuote)
9✔
89
    withtag(io, :blockquote) do
9✔
90
        println(io)
9✔
91
        html(io, md.content)
9✔
92
    end
93
end
94

95
function html(io::IO, f::Footnote)
12✔
96
    withtag(io, :div, :class => "footnote", :id => "footnote-$(f.id)") do
12✔
97
        withtag(io, :p, :class => "footnote-title") do
12✔
98
            print(io, f.id)
12✔
99
        end
100
        html(io, f.text)
12✔
101
    end
102
end
103

104
function html(io::IO, md::Admonition)
15✔
105
    withtag(io, :div, :class => "admonition $(md.category)") do
15✔
106
        withtag(io, :p, :class => "admonition-title") do
15✔
107
            print(io, md.title)
15✔
108
        end
109
        html(io, md.content)
15✔
110
    end
111
end
112

113
function html(io::IO, md::List)
39✔
114
    maybe_attr = md.ordered > 1 ? Any[:start => string(md.ordered)] : []
75✔
115
    withtag(io, isordered(md) ? :ol : :ul, maybe_attr...) do
39✔
116
        for item in md.items
39✔
117
            println(io)
66✔
118
            withtag(io, :li) do
132✔
119
                html(io, item)
66✔
120
            end
121
        end
66✔
122
        println(io)
39✔
123
    end
124
end
125

126
function html(io::IO, md::HorizontalRule)
3✔
127
    tag(io, :hr)
3✔
128
end
129

130
html(io::IO, x) = tohtml(io, x)
18✔
131

132
# Inline elements
133

134
function htmlinline(io::IO, content::Vector)
756✔
135
    for x in content
756✔
136
        htmlinline(io, x)
1,458✔
137
    end
1,458✔
138
end
139

140
function htmlinline(io::IO, code′::Code)
210✔
141
    if code′.language == "styled"
210✔
142
        code′ = Code("", String(styled(code′.code)))
×
143
    end
144
    code = code′
210✔
145
    withtag(io, :code) do
210✔
146
        htmlesc(io, code.code)
210✔
147
    end
148
end
149

150
function htmlinline(io::IO, md::Union{Symbol,AbstractString})
1,026✔
151
    htmlesc(io, md)
1,077✔
152
end
153

154
function htmlinline(io::IO, md::Bold)
45✔
155
    withtag(io, :strong) do
45✔
156
        htmlinline(io, md.text)
45✔
157
    end
158
end
159

160
function htmlinline(io::IO, md::Italic)
66✔
161
    withtag(io, :em) do
66✔
162
        htmlinline(io, md.text)
66✔
163
    end
164
end
165

166
function htmlinline(io::IO, md::Strikethrough)
18✔
167
    withtag(io, :s) do
18✔
168
        htmlinline(io, md.text)
18✔
169
    end
170
end
171

172
function htmlinline(io::IO, md::Image)
×
173
    tag(io, :img, :src=>md.url, :alt=>md.alt)
×
174
end
175

176

177
function htmlinline(io::IO, f::Footnote)
12✔
178
    withtag(io, :a, :href => "#footnote-$(f.id)", :class => "footnote") do
12✔
179
        print(io, "[", f.id, "]")
12✔
180
    end
181
end
182

183
function htmlinline(io::IO, link::Link)
66✔
184
    withtag(io, :a, :href=>link.url) do
66✔
185
        htmlinline(io, link.text)
66✔
186
    end
187
end
188

189
function htmlinline(io::IO, br::LineBreak)
12✔
190
    tag(io, :br)
12✔
191
end
192

193
htmlinline(io::IO, x) = tohtml(io, x)
72✔
194

195
# API
196

197
export html
198

199
"""
200
    html([io::IO], md)
201

202
Output the contents of the Markdown object `md` in HTML format, either
203
writing to an (optional) `io` stream or returning a string.
204

205
One can alternatively use `show(io, "text/html", md)` or `repr("text/html", md)`, which
206
differ in that they wrap the output in a `<div class="markdown"> ... </div>` element.
207

208
# Examples
209
```jldoctest
210
julia> html(md"hello _world_")
211
"<p>hello <em>world</em></p>\\n"
212
```
213
"""
214
html(md) = sprint(html, md)
258✔
215

216
function show(io::IO, ::MIME"text/html", md::MD)
3✔
217
    withtag(io, :div, :class=>"markdown") do
3✔
218
        html(io, md)
3✔
219
    end
220
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc