1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Tool that produces highlighting for Nit programs
23 # The current highlight module
25 # It is used to know when to use anchored local links
26 var current_module
: MModule
28 # List of all highlighted modules
30 # It is used to have links that only targets highlighted entities
32 # Entities outside these modules will not be linked.
33 var mmodules
: Collection[MModule]
35 redef fun hrefto
(entity
) do return entity
.href
(self)
39 private fun href
(v
: NitlightVisitor): nullable String do return null
45 if self == v
.current_module
then return ""
46 if not v
.mmodules
.has
(self) then return null
47 return c_name
+ ".html"
54 # Because we only have code, just link to the introduction
62 var m
= mmodule
.href
(v
)
63 if m
== null then return null
71 # Because we only have code, just link to the introduction
79 var m
= mclassdef
.mmodule
.href
(v
)
80 if m
== null then return null
85 var toolcontext
= new ToolContext
87 # Try to colorize, even if programs are non valid
88 toolcontext
.keep_going
= true
90 var opt_fragment
= new OptionBool("Omit document header and footer", "-f", "--fragment")
91 var opt_line_id_prefix
= new OptionString("Prefix of the id of each line `<span>` element", "--line-id-prefix")
92 var opt_first_line
= new OptionInt("Start the source file at this line (default: 1)", 0, "--first-line")
93 var opt_last_line
= new OptionInt("End the source file at this line (default: to the end)", 0, "--last-line")
94 var opt_dir
= new OptionString("Output html files in a specific directory (required if more than one module)", "-d", "--dir")
95 var opt_full
= new OptionBool("Process also imported modules", "--full")
96 var opt_ast
= new OptionBool("Generate specific HTML elements for each Node of the AST", "--ast")
97 var opt_noinfobox
= new OptionBool("Disable the generation of infoboxes", "--no-infobox")
98 var opt_txt
= new OptionBool("Generate text with ANSI coloring escape sequences", "--txt")
99 toolcontext
.option_context
.add_option
(opt_fragment
, opt_line_id_prefix
, opt_first_line
, opt_last_line
, opt_dir
, opt_full
, opt_ast
, opt_txt
, opt_noinfobox
)
100 toolcontext
.tooldescription
= "Usage: nitlight [OPTION]... <file.nit>...\nGenerates HTML of highlited code from Nit source files."
101 toolcontext
.process_options
(args
)
103 var model
= new Model
104 var modelbuilder
= new ModelBuilder(model
, toolcontext
)
106 var args
= toolcontext
.option_context
.rest
108 var mmodules
= modelbuilder
.parse_full
(args
)
109 modelbuilder
.run_phases
111 if opt_full
.value
then mmodules
= modelbuilder
.parsed_modules
113 var dir
= opt_dir
.value
116 else if mmodules
.length
> 1 then
117 print
"More than one module to render, use option -d"
121 if opt_txt
.value
then
122 for mm
in mmodules
do
123 var v
= new AnsiHighlightVisitor
124 v
.include_loose_tokens
= true
125 v
.include_whole_lines
= true
127 if opt_first_line
.value
!= 0 then v
.first_line
= opt_first_line
.value
128 if opt_last_line
.value
!= 0 then v
.last_line
= opt_last_line
.value
129 var m
= modelbuilder
.mmodule2node
(mm
)
136 page
.write_to_file
("{dir}/{mm.c_name}.txt")
138 page
.write_to
(stdout
)
144 for mm
in mmodules
do
145 if dir
!= null then toolcontext
.info
("write {dir}/{mm.c_name}.html", 1)
147 var v
= new NitlightVisitor(mm
, mmodules
)
148 var prefix
= opt_line_id_prefix
.value
149 if prefix
!= null then
150 v
.line_id_prefix
= prefix
.trim
152 v
.include_loose_tokens
= true
153 v
.include_whole_lines
= true
155 if opt_first_line
.value
!= 0 then v
.first_line
= opt_first_line
.value
156 if opt_last_line
.value
!= 0 then v
.last_line
= opt_last_line
.value
157 if opt_ast
.value
then v
.with_ast
= true
158 if opt_noinfobox
.value
then v
.show_infobox
= false
160 var m
= modelbuilder
.mmodule2node
(mm
)
162 if not opt_fragment
.value
then
163 page
= new HTMLTag("html")
164 page
.add_raw_html
"""<head>
165 <meta charset="utf-8">
166 <title>file {{{m.location.file.filename}}}</title>"""
168 page
.add_raw_html
"""
169 <style type="text/css">
174 page
.add_raw_html
"""<link rel="stylesheet" type="text/css" href="style.css" />"""
176 page
.add_raw_html v
.head_content
177 page
.add_raw_html
"</head><body><pre class='nit_code'>"
180 if not opt_fragment
.value
then
182 page
.add_raw_html
"</pre>"
183 page
.add_raw_html v
.foot_content
184 page
.add_raw_html
"</body>"
190 page
.write_to_file
("{dir}/{mm.c_name}.html")
192 page
.write_to
(stdout
)
197 toolcontext
.info
("write {dir}/index.html", 1)
199 var page
= new HTMLTag("html")
200 page
.add_raw_html
"""<head>
201 <meta charset="utf-8">
204 for mm
in mmodules
do
205 var n
= new HTMLTag("li")
206 var n2
= new HTMLTag("a")
209 n2
.attr
("href", "{mm.c_name}.html")
210 n2
.text
(mm
.full_name
)
212 page
.add_raw_html
"</li></body>"
213 page
.write_to_file
("{dir}/index.html")
215 var v
= new HtmlightVisitor
216 toolcontext
.info
("write {dir}/style.css", 1)
217 var f
= new FileWriter.open
("{dir}/style.css")
218 f
.write v
.css_content