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 # Render commands results as HTML
18 import commands_catalog
19 import commands_docdown
23 import commands_parser
26 import templates
::html_model
27 intrude import markdown
::wikilinks
29 redef class DocCommand
31 # Render results as a HTML string
32 fun to_html
: Writable do return "<p class='text-danger'>Not yet implemented</p>"
35 redef class CmdMessage
37 # Render the message as a HTML string
38 fun to_html
: Writable is abstract
42 redef fun to_html
do return "<p class='text-danger'>Error: {to_s}</p>"
45 redef class CmdWarning
46 redef fun to_html
do return "<p class='text-warning'>Warning: {to_s}</p>"
53 var mentity
= self.mentity
54 if mentity
== null then return ""
55 return mentity
.html_link
.write_to_string
59 redef class CmdEntities
61 var mentities
= self.results
62 if mentities
== null then return ""
64 var tpl
= new Template
66 for mentity
in mentities
do
67 var mdoc
= mentity
.mdoc_or_fallback
69 tpl
.add mentity
.html_link
72 tpl
.add mdoc
.html_synopsis
77 return tpl
.write_to_string
81 redef class CmdComment
83 var mentity
= self.mentity
84 if mentity
== null then return ""
87 var tpl
= new Template
89 # FIXME comments left here until I figure out what to do about the presentation options
90 # if not opts.has_key("no-link") then
91 tpl
.add mentity
.html_link
94 # if not opts.has_key("no-link") and not opts.has_key("no-synopsis") then
97 # if not opts.has_key("no-synopsis") then
98 tpl
.add mdoc
.html_synopsis
103 # if not opts.has_key("no-comment") then
104 tpl
.add mdoc
.html_comment
107 return tpl
.write_to_string
110 redef fun render_comment
do
112 if mdoc
== null then return null
114 if format
== "html" then
115 if full_doc
then return mdoc
.html_documentation
116 return mdoc
.html_synopsis
122 redef class CmdEntityLink
124 var mentity
= self.mentity
125 if mentity
== null then return ""
126 return mentity
.html_link
(text
, title
).write_to_string
133 if node
== null then return ""
135 var code
= render_code
(node
)
136 return "<pre>{code.write_to_string}</pre>"
139 redef fun render_code
(node
) do
140 if format
== "html" then
141 var hl
= new CmdHtmlightVisitor
142 hl
.show_infobox
= false
143 hl
.highlight_node node
150 # Custom HtmlightVisitor for commands
152 # We create a new subclass so its behavior can be refined in clients without
153 # breaking the main implementation.
154 class CmdHtmlightVisitor
155 super HtmlightVisitor
157 redef fun hrefto
(mentity
) do
158 if mentity
isa MClassDef then return mentity
.mclass
.html_url
159 if mentity
isa MPropDef then return mentity
.mproperty
.html_url
160 return mentity
.html_url
164 redef class CmdAncestors
165 redef fun to_html
do return super # FIXME lin
168 redef class CmdParents
169 redef fun to_html
do return super # FIXME lin
172 redef class CmdChildren
173 redef fun to_html
do return super # FIXME lin
176 redef class CmdDescendants
177 redef fun to_html
do return super # FIXME lin
180 redef class CmdFeatures
181 redef fun to_html
do return super # FIXME lin
184 redef class CmdLinearization
185 redef fun to_html
do return super # FIXME lin
191 redef fun to_html
do return super # FIXME lin
195 redef fun to_html
do return super # FIXME lin
198 redef class CmdReturn
199 redef fun to_html
do return super # FIXME lin
203 redef fun to_html
do return super # FIXME lin
211 if output
== null then return ""
212 return output
.write_to_string
218 redef class CmdIniDescription
221 if desc
== null then return ""
223 return "<p>{desc}</p>"
227 redef class CmdIniGitUrl
230 if url
== null then return ""
232 return "<a href=\"{url}\
">{url}</a>"
236 redef class CmdIniCloneCommand
238 var command
= self.command
239 if command
== null then return ""
241 return "<pre>{command}</pre>"
245 redef class CmdIniIssuesUrl
248 if url
== null then return ""
250 return "<a href=\"{url}\
">{url}</a>"
254 redef class CmdIniMaintainer
256 var name
= self.maintainer
257 if name
== null then return ""
259 return "<b>{name.html_escape}</b>"
263 redef class CmdIniContributors
265 var names
= self.contributors
266 if names
== null or names
.is_empty
then return ""
268 var tpl
= new Template
271 tpl
.add
"<li><b>{name.html_escape}</b></li>"
274 return tpl
.write_to_string
278 redef class CmdIniLicense
280 var license
= self.license
281 if license
== null then return ""
283 return "<a href=\"https
://opensource
.org
/licenses
/{license}\
">{license}</a>"
287 redef class CmdEntityFile
290 if file
== null then return ""
292 return "<a href=\"{file_url or else ""}\
">{file.basename}</a>"
296 redef class CmdEntityFileContent
298 var content
= self.content
299 if content
== null then return ""
301 return "<pre>{content}</pre>"
308 redef fun to_html
do return super # FIXME lin
311 redef class CmdMainCompile
313 var command
= self.command
314 if command
== null then return ""
316 return "<pre>{command}</pre>"
320 redef class CmdManSynopsis
322 var synopsis
= self.synopsis
323 if synopsis
== null then return ""
325 return "<pre>{synopsis}</pre>"
329 redef class CmdManOptions
331 var options
= self.options
332 if options
== null or options
.is_empty
then return ""
334 var tpl
= new Template
336 tpl
.addn
"<table width='100%'>"
337 for opt
, desc
in options
do
339 tpl
.addn
"<th valign='top' width='30%'>{opt}</th>"
340 tpl
.addn
"<td width='70%'>{desc}</td>"
346 return tpl
.write_to_string
350 redef class CmdTesting
352 var command
= self.command
353 if command
== null then return ""
355 return "<pre>{command}</pre>"
361 # Custom Markdown processor able to process doc commands
363 super NitdocDecorator
365 redef type PROCESSOR: CmdMarkdownProcessor
367 # Model used by wikilink commands to find entities
370 # Filter to apply if any
371 var filter
: nullable ModelFilter
373 redef fun add_span_code
(v
, buffer
, from
, to
) do
374 var text
= new FlatBuffer
375 buffer
.read
(text
, from
, to
)
376 var name
= text
.write_to_string
377 name
= name
.replace
("nullable ", "")
378 var mentity
= try_find_mentity
(name
)
379 if mentity
== null then
383 v
.emit_text mentity
.html_link
.write_to_string
388 private fun try_find_mentity
(text
: String): nullable MEntity do
389 var mentity
= model
.mentity_by_full_name
(text
, filter
)
390 if mentity
!= null then return mentity
392 var mentities
= model
.mentities_by_name
(text
, filter
)
393 if mentities
.is_empty
then
395 else if mentities
.length
> 1 then
396 # TODO smart resolve conflicts
398 return mentities
.first
401 redef fun add_wikilink
(v
, token
) do
402 v
.render_wikilink
(token
, model
)
406 # Same as `InlineDecorator` but with wikilink commands handling
407 class CmdInlineDecorator
408 super InlineDecorator
410 redef type PROCESSOR: CmdMarkdownProcessor
412 # Model used by wikilink commands to find entities
415 redef fun add_wikilink
(v
, token
) do
416 v
.render_wikilink
(token
, model
)
420 # Custom MarkdownEmitter for commands
421 class CmdMarkdownProcessor
422 super MarkdownProcessor
424 # Parser used to process doc commands
425 var parser
: CommandParser
428 fun render_wikilink
(token
: TokenWikiLink, model
: Model) do
429 var link
= token
.link
430 if link
== null then return
431 var name
= token
.name
432 if name
!= null then link
= "{name} | {link}"
434 var command
= parser
.parse
(link
.write_to_string
)
435 var error
= parser
.error
437 if error
isa CmdError then
438 emit_text error
.to_html
.write_to_string
441 if error
isa CmdWarning then
442 emit_text error
.to_html
.write_to_string
444 add command
.as(not null).to_html
449 # Read `self` between `nstart` and `nend` (excluded) and writte chars to `out`.
450 private fun read
(out
: FlatBuffer, nstart
, nend
: Int): Int do
452 while pos
< length
and pos
< nend
do
456 if pos
== length
then return -1