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 content
.join
("\n").html_escape
34 # Full comment HTML escaped.
35 var documentation
: String is lazy
do return content
.join
("\n").html_escape
37 private var markdown_proc
: MarkdownProcessor is lazy
do
38 return original_mentity
.model
.nitdoc_md_processor
41 private var inline_proc
: MarkdownProcessor is lazy
do
42 return original_mentity
.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>"
54 # Renders the comment without the synopsis as a HTML comment block.
55 var html_comment
: Writable is lazy
do
56 var lines
= content
.to_a
57 if not lines
.is_empty
then lines
.shift
58 return lines_to_html
(lines
)
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 markdown line as a HTML comment block.
65 private fun lines_to_html
(lines
: Array[String]): Writable do
66 var res
= new Template
67 res
.add
"<div class=\"nitdoc\
">"
68 # do not use DocUnit as synopsys
69 if not lines
.is_empty
then
70 if not lines
.first
.has_prefix
(" ") and
71 not lines
.first
.has_prefix
("\t") then
73 var syn
= inline_proc
.process
(lines
.shift
)
74 res
.add
"<p class=\"synopsys\
">{syn}</p>"
77 # check for annotations
78 for i
in [0 .. lines
.length
[ do
80 if line
.to_upper
.has_prefix
("ENSURE") or line
.to_upper
.has_prefix
("REQUIRE") then
81 var html
= inline_proc
.process
(line
)
82 lines
[i
] = "<p class=\"contract\
">{html}</p>"
83 else if line
.to_upper
.has_prefix
("TODO") or line
.to_upper
.has_prefix
("FIXME") then
84 var html
= inline_proc
.process
(line
)
85 lines
[i
] = "<p class=\"todo\
">{html}</p>"
89 res
.add markdown_proc
.process
(lines
.join
("\n"))
96 private class NitdocDecorator
99 var toolcontext
= new ToolContext
101 redef fun add_code
(v
, block
) do
103 if block
isa BlockFence and block
.meta
!= null then
104 meta
= block
.meta
.to_s
106 # Do not try to highlight non-nit code.
107 if meta
!= "nit" and meta
!= "nitish" then
108 v
.add
"<pre class=\"{meta}\
"><code>"
110 v
.add
"</code></pre>\n"
114 var code
= code_from_block
(block
)
115 var ast
= toolcontext
.parse_something
(code
)
116 if ast
isa AError then
117 v
.add
"<pre class=\"{meta}\
"><code>"
119 v
.add
"</code></pre>\n"
122 v
.add
"<pre class=\"nitcode\
"><code>"
123 var hl
= new HighlightVisitor
124 hl
.line_id_prefix
= ""
127 v
.add
"</code></pre>\n"
130 redef fun add_span_code
(v
, text
, from
, to
) do
132 var code
= code_from_text
(text
, from
, to
)
133 var ast
= toolcontext
.parse_something
(code
)
135 if ast
isa AError then
136 v
.add
"<code class=\"rawcode\
">"
137 append_code
(v
, text
, from
, to
)
139 v
.add
"<code class=\"nitcode\
">"
140 var hl
= new HighlightVisitor
141 hl
.line_id_prefix
= ""
148 fun code_from_text
(buffer
: Text, from
, to
: Int): String do
149 var out
= new FlatBuffer
150 for i
in [from
..to
[ do out
.add buffer
[i
]
151 return out
.write_to_string
154 fun code_from_block
(block
: BlockCode): String do
155 var infence
= block
isa BlockFence
156 var text
= new FlatBuffer
157 var line
= block
.block
.first_line
158 while line
!= null do
159 if not line
.is_empty
then
161 if not infence
and str
.has_prefix
(" ") then
162 text
.append str
.substring
(4, str
.length
- line
.trailing
)
170 return text
.write_to_string
174 # Decorator for span elements.
176 # Because inline comments can appear as span elements,
177 # InlineDecorator do not decorate things like paragraphs or headers.
178 private class InlineDecorator
179 super NitdocDecorator
181 redef fun add_paragraph
(v
, block
) do
185 redef fun add_headline
(v
, block
) do
189 redef fun add_code
(v
, block
) do
191 var ast
= toolcontext
.parse_something
(block
.block
.text
.to_s
)
192 if ast
isa AError then
198 v
.add
"<code class=\"nitcode\
">"
199 var hl
= new HighlightVisitor
207 # Get a markdown processor for Nitdoc comments.
208 var nitdoc_md_processor
: MarkdownProcessor is lazy
do
209 var proc
= new MarkdownProcessor
210 proc
.emitter
.decorator
= new NitdocDecorator
214 # Get a markdown inline processor for Nitdoc comments.
216 # This processor is specificaly designed to inlinable doc elements like synopsys.
217 var nitdoc_inline_processor
: MarkdownProcessor is lazy
do
218 var proc
= new MarkdownProcessor
219 proc
.emitter
.decorator
= new InlineDecorator