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 # Handle markdown formatting in Nit comments.
20 private import parser_util
24 private var markdown_proc
: MarkdownProcessor is lazy
, writable do
25 return original_mentity
.as(not null).model
.nitdoc_md_processor
28 private var inline_proc
: MarkdownProcessor is lazy
, writable do
29 return original_mentity
.as(not null).model
.nitdoc_inline_processor
32 # Renders the synopsis as a HTML comment block.
33 var html_synopsis
: Writable is lazy
do
34 var res
= new Template
35 var syn
= inline_proc
.process
(content
.first
)
36 res
.add
"<span class=\"synopsys nitdoc\
">{syn}</span>"
40 # Renders the synopsis as a HTML comment block.
41 var md_synopsis
: Writable is lazy
do
42 if content
.is_empty
then return ""
46 # Renders the comment without the synopsis as a HTML comment block.
47 var html_comment
: Writable is lazy
do
48 var lines
= content
.to_a
49 if not lines
.is_empty
then lines
.shift
50 return lines_to_html
(lines
)
54 var md_comment
: Writable is lazy
do
55 if content
.is_empty
then return ""
56 var lines
= content
.to_a
58 return lines
.join
("\n")
61 # Renders the synopsis and the comment as a HTML comment block.
62 var html_documentation
: Writable is lazy
do return lines_to_html
(content
.to_a
)
64 # Renders the synopsis and the comment as a HTML comment block.
65 var md_documentation
: Writable is lazy
do return lines_to_md
(content
.to_a
)
67 # Renders markdown line as a HTML comment block.
68 private fun lines_to_html
(lines
: Array[String]): Writable do
69 var res
= new Template
70 var decorator
= markdown_proc
.decorator
.as(NitdocDecorator)
71 decorator
.current_mdoc
= self
72 res
.add
"<div class=\"nitdoc\
">"
73 # do not use DocUnit as synopsys
74 if not lines
.is_empty
then
75 if not lines
.first
.has_prefix
(" ") and
76 not lines
.first
.has_prefix
("\t") then
78 var syn
= inline_proc
.process
(lines
.shift
)
79 res
.add
"<h1 class=\"synopsys\
">{syn}</h1>"
82 # check for annotations
83 for i
in [0 .. lines
.length
[ do
85 if line
.to_upper
.has_prefix
("ENSURE") or line
.to_upper
.has_prefix
("REQUIRE") then
86 var html
= inline_proc
.process
(line
)
87 lines
[i
] = "<p class=\"contract\
">{html}</p>"
88 else if line
.to_upper
.has_prefix
("TODO") or line
.to_upper
.has_prefix
("FIXME") then
89 var html
= inline_proc
.process
(line
)
90 lines
[i
] = "<p class=\"todo\
">{html}</p>"
94 res
.add markdown_proc
.process
(lines
.join
("\n"))
96 decorator
.current_mdoc
= null
100 private fun lines_to_md
(lines
: Array[String]): Writable do
101 var res
= new Template
102 if not lines
.is_empty
then
103 var syn
= lines
.first
104 if not syn
.has_prefix
(" ") and not syn
.has_prefix
("\t") and
105 not syn
.trim
.has_prefix
("#") then
110 res
.add lines
.join
("\n")
115 # The specific markdown decorator used internally to process MDoc object.
117 # You should use the various methods of `MDoc` like `MDoc::html_documentation`
119 # The class is public so specific behavior can be plugged on it.
120 class NitdocDecorator
123 private var toolcontext
= new ToolContext
125 # The currently processed mdoc.
127 # Unfortunately, this seems to be the simpler way to get the currently processed `MDoc` object.
128 var current_mdoc
: nullable MDoc = null
130 redef fun add_code
(v
, block
) do
131 var meta
= block
.meta
or else "nit"
133 # Do not try to highlight non-nit code.
134 if meta
!= "nit" and meta
!= "nitish" then
135 v
.add
"<pre class=\"{meta}\
"><code>"
137 v
.add
"</code></pre>\n"
141 var code
= block
.raw_content
142 var ast
= toolcontext
.parse_something
(code
)
143 if ast
isa AError then
144 v
.add
"<pre class=\"{meta}\
"><code>"
146 v
.add
"</code></pre>\n"
149 v
.add
"<pre class=\"nitcode\
"><code>"
150 var hl
= new HtmlightVisitor
151 hl
.line_id_prefix
= ""
152 hl
.highlight_node
(ast
)
154 v
.add
"</code></pre>\n"
157 redef fun add_span_code
(v
, text
, from
, to
) do
159 var code
= code_from_text
(text
, from
, to
)
160 var ast
= toolcontext
.parse_something
(code
)
162 if ast
isa AError then
163 v
.add
"<code class=\"rawcode\
">"
164 append_code
(v
, text
, from
, to
)
166 v
.add
"<code class=\"nitcode\
">"
167 var hl
= new HtmlightVisitor
168 hl
.line_id_prefix
= ""
169 hl
.highlight_node
(ast
)
175 private fun code_from_text
(buffer
: Text, from
, to
: Int): String do
176 var out
= new FlatBuffer
177 for i
in [from
..to
[ do out
.add buffer
[i
]
178 return out
.write_to_string
182 # Decorator for span elements.
184 # Because inline comments can appear as span elements,
185 # InlineDecorator do not decorate things like paragraphs or headers.
186 private class InlineDecorator
187 super NitdocDecorator
189 redef fun add_paragraph
(v
, block
) do
193 redef fun add_headline
(v
, block
) do
195 var line
= block
.block
.first_line
196 if line
== null then return
198 var id
= strip_id
(txt
)
199 var lvl
= block
.depth
200 headlines
[id
] = new HeadLine(id
, txt
, lvl
)
205 redef fun add_code
(v
, block
) do
207 var ast
= toolcontext
.parse_something
(block
.block
.text
.to_s
)
208 if ast
isa AError then
214 v
.add
"<code class=\"nitcode\
">"
215 var hl
= new HtmlightVisitor
216 hl
.highlight_node
(ast
)
223 # Get a markdown processor for Nitdoc comments.
224 var nitdoc_md_processor
: MarkdownProcessor is lazy
, writable do
225 var proc
= new MarkdownProcessor
226 proc
.decorator
= new NitdocDecorator
230 # Get a markdown inline processor for Nitdoc comments.
232 # This processor is specificaly designed to inlinable doc elements like synopsys.
233 var nitdoc_inline_processor
: MarkdownProcessor is lazy
, writable do
234 var proc
= new MarkdownProcessor
235 proc
.decorator
= new InlineDecorator