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 # Synopsis HTML escaped.
25 var synopsis
: String is lazy
do return content
.first
.html_escape
27 # Comment without synopsis HTML escaped
28 var comment
: String is lazy
do
29 var lines
= content
.to_a
30 if not lines
.is_empty
then lines
.shift
31 return lines
.join
("\n")
34 # Full comment HTML escaped.
35 var documentation
: String is lazy
do return content
.join
("\n")
37 private var markdown_proc
: MarkdownProcessor is lazy
, writable do
38 return original_mentity
.as(not null).model
.nitdoc_md_processor
41 private var inline_proc
: MarkdownProcessor is lazy
, writable do
42 return original_mentity
.as(not null).model
.nitdoc_inline_processor
45 # Renders the synopsis as a HTML comment block.
46 var html_synopsis
: Writable is lazy
do
47 var res
= new Template
48 var syn
= inline_proc
.process
(content
.first
)
49 res
.add
"<span class=\"synopsys nitdoc\
">{syn}</span>"
53 # Renders the synopsis as a HTML comment block.
54 var md_synopsis
: Writable is lazy
do
55 if content
.is_empty
then return ""
59 # Renders the comment without the synopsis as a HTML comment block.
60 var html_comment
: Writable is lazy
do
61 var lines
= content
.to_a
62 if not lines
.is_empty
then lines
.shift
63 return lines_to_html
(lines
)
67 var md_comment
: Writable is lazy
do
68 if content
.is_empty
then return ""
69 var lines
= content
.to_a
71 return lines
.join
("\n")
74 # Renders the synopsis and the comment as a HTML comment block.
75 var html_documentation
: Writable is lazy
do return lines_to_html
(content
.to_a
)
77 # Renders the synopsis and the comment as a HTML comment block.
78 var md_documentation
: Writable is lazy
do return lines_to_md
(content
.to_a
)
80 # Renders markdown line as a HTML comment block.
81 private fun lines_to_html
(lines
: Array[String]): Writable do
82 var res
= new Template
83 var decorator
= markdown_proc
.decorator
.as(NitdocDecorator)
84 decorator
.current_mdoc
= self
85 res
.add
"<div class=\"nitdoc\
">"
86 # do not use DocUnit as synopsys
87 if not lines
.is_empty
then
88 if not lines
.first
.has_prefix
(" ") and
89 not lines
.first
.has_prefix
("\t") then
91 var syn
= inline_proc
.process
(lines
.shift
)
92 res
.add
"<h1 class=\"synopsys\
">{syn}</h1>"
95 # check for annotations
96 for i
in [0 .. lines
.length
[ do
98 if line
.to_upper
.has_prefix
("ENSURE") or line
.to_upper
.has_prefix
("REQUIRE") then
99 var html
= inline_proc
.process
(line
)
100 lines
[i
] = "<p class=\"contract\
">{html}</p>"
101 else if line
.to_upper
.has_prefix
("TODO") or line
.to_upper
.has_prefix
("FIXME") then
102 var html
= inline_proc
.process
(line
)
103 lines
[i
] = "<p class=\"todo\
">{html}</p>"
107 res
.add markdown_proc
.process
(lines
.join
("\n"))
109 decorator
.current_mdoc
= null
113 private fun lines_to_md
(lines
: Array[String]): Writable do
114 var res
= new Template
115 if not lines
.is_empty
then
116 var syn
= lines
.first
117 if not syn
.has_prefix
(" ") and not syn
.has_prefix
("\t") and
118 not syn
.trim
.has_prefix
("#") then
123 res
.add lines
.join
("\n")
128 # The specific markdown decorator used internally to process MDoc object.
130 # You should use the various methods of `MDoc` like `MDoc::html_documentation`
132 # The class is public so specific behavior can be plugged on it.
133 class NitdocDecorator
136 private var toolcontext
= new ToolContext
138 # The currently processed mdoc.
140 # Unfortunately, this seems to be the simpler way to get the currently processed `MDoc` object.
141 var current_mdoc
: nullable MDoc = null
143 redef fun add_code
(v
, block
) do
144 var meta
= block
.meta
or else "nit"
146 # Do not try to highlight non-nit code.
147 if meta
!= "nit" and meta
!= "nitish" then
148 v
.add
"<pre class=\"{meta}\
"><code>"
150 v
.add
"</code></pre>\n"
154 var code
= block
.raw_content
155 var ast
= toolcontext
.parse_something
(code
)
156 if ast
isa AError then
157 v
.add
"<pre class=\"{meta}\
"><code>"
159 v
.add
"</code></pre>\n"
162 v
.add
"<pre class=\"nitcode\
"><code>"
163 var hl
= new HtmlightVisitor
164 hl
.line_id_prefix
= ""
165 hl
.highlight_node
(ast
)
167 v
.add
"</code></pre>\n"
170 redef fun add_span_code
(v
, text
, from
, to
) do
172 var code
= code_from_text
(text
, from
, to
)
173 var ast
= toolcontext
.parse_something
(code
)
175 if ast
isa AError then
176 v
.add
"<code class=\"rawcode\
">"
177 append_code
(v
, text
, from
, to
)
179 v
.add
"<code class=\"nitcode\
">"
180 var hl
= new HtmlightVisitor
181 hl
.line_id_prefix
= ""
182 hl
.highlight_node
(ast
)
188 private fun code_from_text
(buffer
: Text, from
, to
: Int): String do
189 var out
= new FlatBuffer
190 for i
in [from
..to
[ do out
.add buffer
[i
]
191 return out
.write_to_string
195 # Decorator for span elements.
197 # Because inline comments can appear as span elements,
198 # InlineDecorator do not decorate things like paragraphs or headers.
199 private class InlineDecorator
200 super NitdocDecorator
202 redef fun add_paragraph
(v
, block
) do
206 redef fun add_headline
(v
, block
) do
210 redef fun add_code
(v
, block
) do
212 var ast
= toolcontext
.parse_something
(block
.block
.text
.to_s
)
213 if ast
isa AError then
219 v
.add
"<code class=\"nitcode\
">"
220 var hl
= new HtmlightVisitor
221 hl
.highlight_node
(ast
)
228 # Get a markdown processor for Nitdoc comments.
229 var nitdoc_md_processor
: MarkdownProcessor is lazy
, writable do
230 var proc
= new MarkdownProcessor
231 proc
.decorator
= new NitdocDecorator
235 # Get a markdown inline processor for Nitdoc comments.
237 # This processor is specificaly designed to inlinable doc elements like synopsys.
238 var nitdoc_inline_processor
: MarkdownProcessor is lazy
, writable do
239 var proc
= new MarkdownProcessor
240 proc
.decorator
= new InlineDecorator