Merge: src/model/model_index: model index uses BKTree
[nit.git] / src / doc / templates / html_commands.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 # Render commands results as HTML
16 module html_commands
17
18 import commands_catalog
19 import commands_docdown
20 import commands_graph
21 import commands_ini
22 import commands_main
23 import commands_parser
24 import commands_usage
25
26 import templates::html_model
27 intrude import markdown::wikilinks
28
29 redef class DocCommand
30
31 # Render results as a HTML string
32 fun to_html: Writable do return "<p class='text-danger'>Not yet implemented</p>"
33 end
34
35 redef class CmdMessage
36
37 # Render the message as a HTML string
38 fun to_html: Writable is abstract
39 end
40
41 redef class CmdError
42 redef fun to_html do return "<p class='text-danger'>Error: {to_s}</p>"
43 end
44
45 redef class CmdWarning
46 redef fun to_html do return "<p class='text-warning'>Warning: {to_s}</p>"
47 end
48
49 # Model commands
50
51 redef class CmdEntity
52 redef fun to_html do
53 var mentity = self.mentity
54 if mentity == null then return ""
55 return mentity.html_link.write_to_string
56 end
57 end
58
59 redef class CmdEntities
60 redef fun to_html do
61 var mentities = self.results
62 if mentities == null then return ""
63
64 var tpl = new Template
65 tpl.add "<ul>"
66 for mentity in mentities do
67 var mdoc = mentity.mdoc_or_fallback
68 tpl.add "<li>"
69 tpl.add mentity.html_link
70 if mdoc != null then
71 tpl.add " - "
72 tpl.add mdoc.html_synopsis
73 end
74 tpl.add "</li>"
75 end
76 tpl.add "</ul>"
77 return tpl.write_to_string
78 end
79 end
80
81 redef class CmdComment
82 redef fun to_html do
83 var mentity = self.mentity
84 if mentity == null then return ""
85
86 var mdoc = self.mdoc
87 var tpl = new Template
88 tpl.add "<h3>"
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
92 # end
93 if mdoc != null then
94 # if not opts.has_key("no-link") and not opts.has_key("no-synopsis") then
95 tpl.add " - "
96 # end
97 # if not opts.has_key("no-synopsis") then
98 tpl.add mdoc.html_synopsis
99 # end
100 end
101 tpl.add "</h3>"
102 if mdoc != null then
103 # if not opts.has_key("no-comment") then
104 tpl.add mdoc.html_comment
105 # end
106 end
107 return tpl.write_to_string
108 end
109
110 redef fun render_comment do
111 var mdoc = self.mdoc
112 if mdoc == null then return null
113
114 if format == "html" then
115 if full_doc then return mdoc.html_documentation
116 return mdoc.html_synopsis
117 end
118 return super
119 end
120 end
121
122 redef class CmdEntityLink
123 redef fun to_html do
124 var mentity = self.mentity
125 if mentity == null then return ""
126 return mentity.html_link(text, title).write_to_string
127 end
128 end
129
130 redef class CmdCode
131 redef fun to_html do
132 var node = self.node
133 if node == null then return ""
134
135 var code = render_code(node)
136 return "<pre>{code.write_to_string}</pre>"
137 end
138
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
144 return hl.html
145 end
146 return super
147 end
148 end
149
150 # Custom HtmlightVisitor for commands
151 #
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
156
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
161 end
162 end
163
164 redef class CmdAncestors
165 redef fun to_html do return super # FIXME lin
166 end
167
168 redef class CmdParents
169 redef fun to_html do return super # FIXME lin
170 end
171
172 redef class CmdChildren
173 redef fun to_html do return super # FIXME lin
174 end
175
176 redef class CmdDescendants
177 redef fun to_html do return super # FIXME lin
178 end
179
180 redef class CmdFeatures
181 redef fun to_html do return super # FIXME lin
182 end
183
184 redef class CmdLinearization
185 redef fun to_html do return super # FIXME lin
186 end
187
188 # Usage commands
189
190 redef class CmdNew
191 redef fun to_html do return super # FIXME lin
192 end
193
194 redef class CmdCall
195 redef fun to_html do return super # FIXME lin
196 end
197
198 redef class CmdReturn
199 redef fun to_html do return super # FIXME lin
200 end
201
202 redef class CmdParam
203 redef fun to_html do return super # FIXME lin
204 end
205
206 # Graph commands
207
208 redef class CmdGraph
209 redef fun to_html do
210 var output = render
211 if output == null then return ""
212 return output.write_to_string
213 end
214 end
215
216 # Ini commands
217
218 redef class CmdIniDescription
219 redef fun to_html do
220 var desc = self.desc
221 if desc == null then return ""
222
223 return "<p>{desc}</p>"
224 end
225 end
226
227 redef class CmdIniGitUrl
228 redef fun to_html do
229 var url = self.url
230 if url == null then return ""
231
232 return "<a href=\"{url}\">{url}</a>"
233 end
234 end
235
236 redef class CmdIniCloneCommand
237 redef fun to_html do
238 var command = self.command
239 if command == null then return ""
240
241 return "<pre>{command}</pre>"
242 end
243 end
244
245 redef class CmdIniIssuesUrl
246 redef fun to_html do
247 var url = self.url
248 if url == null then return ""
249
250 return "<a href=\"{url}\">{url}</a>"
251 end
252 end
253
254 redef class CmdIniMaintainer
255 redef fun to_html do
256 var name = self.maintainer
257 if name == null then return ""
258
259 return "<b>{name.html_escape}</b>"
260 end
261 end
262
263 redef class CmdIniContributors
264 redef fun to_html do
265 var names = self.contributors
266 if names == null or names.is_empty then return ""
267
268 var tpl = new Template
269 tpl.add "<ul>"
270 for name in names do
271 tpl.add "<li><b>{name.html_escape}</b></li>"
272 end
273 tpl.add "</ul>"
274 return tpl.write_to_string
275 end
276 end
277
278 redef class CmdIniLicense
279 redef fun to_html do
280 var license = self.license
281 if license == null then return ""
282
283 return "<a href=\"https://opensource.org/licenses/{license}\">{license}</a>"
284 end
285 end
286
287 redef class CmdEntityFile
288 redef fun to_html do
289 var file = self.file
290 if file == null then return ""
291
292 return "<a href=\"{file_url or else ""}\">{file.basename}</a>"
293 end
294 end
295
296 redef class CmdEntityFileContent
297 redef fun to_html do
298 var content = self.content
299 if content == null then return ""
300
301 return "<pre>{content}</pre>"
302 end
303 end
304
305 # Main commands
306
307 redef class CmdMains
308 redef fun to_html do return super # FIXME lin
309 end
310
311 redef class CmdMainCompile
312 redef fun to_html do
313 var command = self.command
314 if command == null then return ""
315
316 return "<pre>{command}</pre>"
317 end
318 end
319
320 redef class CmdManSynopsis
321 redef fun to_html do
322 var synopsis = self.synopsis
323 if synopsis == null then return ""
324
325 return "<pre>{synopsis}</pre>"
326 end
327 end
328
329 redef class CmdManOptions
330 redef fun to_html do
331 var options = self.options
332 if options == null or options.is_empty then return ""
333
334 var tpl = new Template
335 tpl.addn "<pre>"
336 tpl.addn "<table width='100%'>"
337 for opt, desc in options do
338 tpl.addn "<tr>"
339 tpl.addn "<th valign='top' width='30%'>{opt}</th>"
340 tpl.addn "<td width='70%'>{desc}</td>"
341 tpl.addn "</tr>"
342 end
343 tpl.addn "</table>"
344 tpl.addn "</pre>"
345
346 return tpl.write_to_string
347 end
348 end
349
350 redef class CmdTesting
351 redef fun to_html do
352 var command = self.command
353 if command == null then return ""
354
355 return "<pre>{command}</pre>"
356 end
357 end
358
359 # MDoc
360
361 # Custom Markdown processor able to process doc commands
362 class CmdDecorator
363 super NitdocDecorator
364
365 redef type PROCESSOR: CmdMarkdownProcessor
366
367 # Model used by wikilink commands to find entities
368 var model: Model
369
370 # Filter to apply if any
371 var filter: nullable ModelFilter
372
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
380 super
381 else
382 v.add "<code>"
383 v.emit_text mentity.html_link.write_to_string
384 v.add "</code>"
385 end
386 end
387
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
391
392 var mentities = model.mentities_by_name(text, filter)
393 if mentities.is_empty then
394 return null
395 else if mentities.length > 1 then
396 # TODO smart resolve conflicts
397 end
398 return mentities.first
399 end
400
401 redef fun add_wikilink(v, token) do
402 v.render_wikilink(token, model)
403 end
404 end
405
406 # Same as `InlineDecorator` but with wikilink commands handling
407 class CmdInlineDecorator
408 super InlineDecorator
409
410 redef type PROCESSOR: CmdMarkdownProcessor
411
412 # Model used by wikilink commands to find entities
413 var model: Model
414
415 redef fun add_wikilink(v, token) do
416 v.render_wikilink(token, model)
417 end
418 end
419
420 # Custom MarkdownEmitter for commands
421 class CmdMarkdownProcessor
422 super MarkdownProcessor
423
424 # Parser used to process doc commands
425 var parser: CommandParser
426
427 # Render a wikilink
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}"
433
434 var command = parser.parse(link.write_to_string)
435 var error = parser.error
436
437 if error isa CmdError then
438 emit_text error.to_html.write_to_string
439 return
440 end
441 if error isa CmdWarning then
442 emit_text error.to_html.write_to_string
443 end
444 add command.as(not null).to_html
445 end
446 end
447
448 redef class Text
449 # Read `self` between `nstart` and `nend` (excluded) and writte chars to `out`.
450 private fun read(out: FlatBuffer, nstart, nend: Int): Int do
451 var pos = nstart
452 while pos < length and pos < nend do
453 out.add self[pos]
454 pos += 1
455 end
456 if pos == length then return -1
457 return pos
458 end
459 end