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

JuliaLang / julia / #37610

03 Sep 2023 03:55PM UTC coverage: 86.433% (-0.8%) from 87.218%
#37610

push

local

web-flow
Standardize the entry-point for Julia execution (#50974)

This is a bit of a straw-man proposal (though I think mergable if people
agree) to standardize the execution entrypoint for Julia scripts. I
think there's at least four different ways that people might run a
script:

- As `julia main.jl`
- As a PkgCompiler sysimage, then calling the main entry point
- As a PkgCompiler "app", with the magic `julia_main` function
- As a StaticCompiler product with an explicit entrypoint specified on
the API.

The main problem I have with all of these variants is that they're all
different and it's kind of a pain to move between them. Here I propose
that we standardize on `Main.main(ARGS)` as the entrypoint for all
scripts. Downstream from that proposal, this PR then makes the following
changes:

1. If a system image has an existing `Main.main`, that is the entry
point for `julia -Jsysimage.so`.
2. If not, and the sysimage has a REPL, we call REPL.main (we could
handle this by defaulting `Main.main` to a weak import of `REPL.main`,
but for the purpose of this PR, it's an explicit fallback. That said, I
do want to emhpasize the direction of moving the REPL to be "just
another app".
3. If the REPL code is called and passed a script file, the REPL
executes any newly defined Main.main after loading the script file. As a
result, `julia` behaves the same as if we had generated a new system
image after loading `main.jl` and then running julia with that system
image.

The further downstream implication of this is that I'd like to get rid
of the distinction between PkgCompiler apps and system images. An app is
simply a system image with a `Main.main` function defined (note that
currently PkgCompiler uses `julia_main` instead).

---------

Co-authored-by: Martijn Visser <mgvisser@gmail.com>

25 of 25 new or added lines in 2 files covered. (100.0%)

73492 of 85028 relevant lines covered (86.43%)

13617619.45 hits per line

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

60.61
/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...)
120✔
8
    print(io, "<$tag")
120✔
9
    for (attr, value) in attrs
120✔
10
        print(io, " ")
24✔
11
        htmlesc(io, attr)
24✔
12
        print(io, "=\"")
24✔
13
        htmlesc(io, value)
24✔
14
        print(io, "\"")
24✔
15
    end
24✔
16
    f === nothing && return print(io, " />")
120✔
17

18
    print(io, ">")
120✔
19
    f()
128✔
20
    print(io, "</$tag>")
120✔
21
end
22

23
tag(io::IO, tag, attrs...) = withtag(nothing, io, tag, attrs...)
×
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)
168✔
34
    # s1 = replace(s, r"&(?!(\w+|\#\d+);)" => "&amp;")
35
    for ch in s
336✔
36
        print(io, get(_htmlescape_chars, ch, ch))
3,292✔
37
    end
3,182✔
38
end
39
function htmlesc(io::IO, s::Symbol)
24✔
40
    htmlesc(io, string(s))
24✔
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)
32✔
54
    for md in content
32✔
55
        html(io, md)
58✔
56
        println(io)
58✔
57
    end
58✔
58
end
59

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

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

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

78
function html(io::IO, md::Paragraph)
14✔
79
    withtag(io, :p) do
14✔
80
        htmlinline(io, md.content)
14✔
81
    end
82
end
83

84
function html(io::IO, md::BlockQuote)
×
85
    withtag(io, :blockquote) do
×
86
        println(io)
×
87
        html(io, md.content)
×
88
    end
89
end
90

91
function html(io::IO, f::Footnote)
×
92
    withtag(io, :div, :class => "footnote", :id => "footnote-$(f.id)") do
×
93
        withtag(io, :p, :class => "footnote-title") do
×
94
            print(io, f.id)
×
95
        end
96
        html(io, f.text)
×
97
    end
98
end
99

100
function html(io::IO, md::Admonition)
2✔
101
    withtag(io, :div, :class => "admonition $(md.category)") do
2✔
102
        withtag(io, :p, :class => "admonition-title") do
2✔
103
            print(io, md.title)
2✔
104
        end
105
        html(io, md.content)
2✔
106
    end
107
end
108

109
function html(io::IO, md::List)
×
110
    maybe_attr = md.ordered > 1 ? Any[:start => string(md.ordered)] : []
×
111
    withtag(io, isordered(md) ? :ol : :ul, maybe_attr...) do
×
112
        for item in md.items
×
113
            println(io)
×
114
            withtag(io, :li) do
×
115
                html(io, item)
×
116
            end
117
        end
×
118
        println(io)
×
119
    end
120
end
121

122
function html(io::IO, md::HorizontalRule)
×
123
    tag(io, :hr)
×
124
end
125

126
html(io::IO, x) = tohtml(io, x)
×
127

128
# Inline elements
129

130
function htmlinline(io::IO, content::Vector)
48✔
131
    for x in content
52✔
132
        htmlinline(io, x)
124✔
133
    end
124✔
134
end
135

136
function htmlinline(io::IO, code::Code)
40✔
137
    withtag(io, :code) do
40✔
138
        htmlesc(io, code.code)
40✔
139
    end
140
end
141

142
function htmlinline(io::IO, md::Union{Symbol,AbstractString})
66✔
143
    htmlesc(io, md)
66✔
144
end
145

146
function htmlinline(io::IO, md::Bold)
2✔
147
    withtag(io, :strong) do
2✔
148
        htmlinline(io, md.text)
2✔
149
    end
150
end
151

152
function htmlinline(io::IO, md::Italic)
2✔
153
    withtag(io, :em) do
2✔
154
        htmlinline(io, md.text)
2✔
155
    end
156
end
157

158
function htmlinline(io::IO, md::Image)
×
159
    tag(io, :img, :src=>md.url, :alt=>md.alt)
×
160
end
161

162

163
function htmlinline(io::IO, f::Footnote)
×
164
    withtag(io, :a, :href => "#footnote-$(f.id)", :class => "footnote") do
×
165
        print(io, "[", f.id, "]")
×
166
    end
167
end
168

169
function htmlinline(io::IO, link::Link)
14✔
170
    withtag(io, :a, :href=>link.url) do
14✔
171
        htmlinline(io, link.text)
14✔
172
    end
173
end
174

175
function htmlinline(io::IO, br::LineBreak)
×
176
    tag(io, :br)
×
177
end
178

179
htmlinline(io::IO, x) = tohtml(io, x)
×
180

181
# API
182

183
export html
184

185
html(md) = sprint(html, md)
18✔
186

187
function show(io::IO, ::MIME"text/html", md::MD)
×
188
    withtag(io, :div, :class=>"markdown") do
×
189
        html(io, md)
×
190
    end
191
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