src/doc/api: add links to renderer code
[nit.git] / src / doc / html_templates / model_html.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 # Translate mentities to html blocks.
16 module model_html
17
18 import model
19 import doc::doc_down
20 import html::bootstrap
21
22 redef class MEntity
23
24 # Returns the MEntity name escaped for html.
25 #
26 # * MPackage: `foo`
27 # * MGroup: `foo`
28 # * MModule: `foo`
29 # * MClass: `Foo[E]`
30 # * MClassDef: `Foo[E]`
31 # * MProperty: `foo(e)`
32 # * MPropdef: `foo(e)`
33 var html_name: String is lazy do return name.html_escape
34
35 # Returns the MEntity full_name escaped for html.
36 var html_full_name: String is lazy do return full_name.html_escape
37
38 # Link to MEntity in the web server.
39 # TODO this should be parameterizable... but how?
40 fun html_link: Link do return new Link("/doc/{full_name}", html_name)
41
42 # Returns the list of keyword used in `self` declaration.
43 fun html_modifiers: Array[String] is abstract
44
45 # Returns the complete MEntity declaration decorated with HTML.
46 #
47 # * MPackage: `package foo`
48 # * MGroup: `group foo`
49 # * MModule: `module foo`
50 # * MClass: `private abstract class Foo[E: Object]`
51 # * MClassDef: `redef class Foo[E]`
52 # * MProperty: `private fun foo(e: Object): Int`
53 # * MPropdef: `redef fun foo(e)`
54 fun html_declaration: Template do
55 var tpl = new Template
56 tpl.add "<span>"
57 tpl.add html_modifiers.join(" ")
58 tpl.add " "
59 tpl.add html_link
60 tpl.add "</span>"
61 return tpl
62 end
63
64 # Returns `self` namespace decorated with HTML links.
65 #
66 # * MPackage: `mpackage`
67 # * MGroup: `mpackage(::group)`
68 # * MModule: `mgroup::mmodule`
69 # * MClass: `mpackage::mclass`
70 # * MClassDef: `mmodule::mclassdef`
71 # * MProperty: `mclass::mprop`
72 # * MPropdef: `mclassdef:mpropdef`
73 fun html_namespace: Template is abstract
74
75 # Returns the synopsis and the comment of this MEntity formatted as HTML.
76 var html_documentation: nullable Writable is lazy do
77 var mdoc = mdoc_or_fallback
78 if mdoc == null then return null
79 return mdoc.html_documentation
80 end
81
82 # Returns the synopsis of this MEntity formatted as HTML.
83 var html_synopsis: nullable Writable is lazy do
84 var mdoc = mdoc_or_fallback
85 if mdoc == null then return null
86 return mdoc.html_synopsis
87 end
88
89 # Returns the the comment without the synopsis formatted as HTML.
90 var html_comment: nullable Writable is lazy do
91 var mdoc = mdoc_or_fallback
92 if mdoc == null then return null
93 return mdoc.html_comment
94 end
95
96 # Icon that will be displayed before the title
97 fun html_icon: BSIcon do
98 var icon = new BSIcon("tag")
99 icon.css_classes.add_all(css_classes)
100 return icon
101 end
102
103 # CSS classes used to decorate `self`.
104 #
105 # Mainly used for icons.
106 var css_classes = new Array[String]
107 end
108
109 redef class MPackage
110 redef var html_modifiers = ["package"]
111 redef fun html_namespace do return html_link
112 redef var css_classes = ["public"]
113 end
114
115 redef class MGroup
116 redef var html_modifiers = ["group"]
117
118 # Depends if `self` is root or not.
119 #
120 # * If root `mpackage`.
121 # * Else `mpackage::self`.
122 redef fun html_namespace do
123 var tpl = new Template
124 tpl.add mpackage.html_namespace
125 if mpackage.root != self then
126 tpl.add "::"
127 tpl.add html_link
128 end
129 return tpl
130 end
131
132 redef var css_classes = ["public"]
133 end
134
135 redef class MModule
136
137 redef var html_modifiers = ["module"]
138
139 # Depends if `self` belongs to a MGroup.
140 #
141 # * If mgroup `mgroup::self`.
142 # * Else `self`.
143 redef fun html_namespace do
144 var mgroup = self.mgroup
145 var tpl = new Template
146 if mgroup != null then
147 tpl.add mgroup.html_namespace
148 tpl.add "::"
149 end
150 tpl.add html_link
151 return tpl
152 end
153
154 redef var css_classes = ["public"]
155 end
156
157 redef class MClass
158 # Format: `Foo[E]`
159 redef var html_name is lazy do
160 var tpl = new Template
161 tpl.add name.html_escape
162 if arity > 0 then
163 tpl.add "["
164 var parameter_names = new Array[String]
165 for p in mparameters do
166 parameter_names.add(p.html_name)
167 end
168 tpl.add parameter_names.join(", ")
169 tpl.add "]"
170 end
171 return tpl.write_to_string
172 end
173
174 redef fun html_modifiers do return intro.html_modifiers
175 redef fun html_declaration do return intro.html_declaration
176
177 # Returns `mpackage::self`.
178 redef fun html_namespace do
179 var mgroup = intro_mmodule.mgroup
180 var tpl = new Template
181 if mgroup != null then
182 tpl.add mgroup.mpackage.html_namespace
183 tpl.add "::"
184 end
185 tpl.add "<span>"
186 tpl.add html_link
187 tpl.add "</span>"
188 return tpl
189 end
190
191 # Returns `intro.html_short_signature`.
192 fun html_short_signature: Template do return intro.html_short_signature
193
194 # Returns `intro.html_signature`.
195 fun html_signature: Template do return intro.html_signature
196
197 redef fun html_icon do return intro.html_icon
198 redef fun css_classes do return intro.css_classes
199 end
200
201 redef class MClassDef
202 # Depends if `self` is an intro or not.
203 #
204 # * If intro contains the visibility and kind.
205 # * If redef contains the `redef` keyword and kind.
206 redef fun html_modifiers do
207 var res = new Array[String]
208 if not is_intro then
209 res.add "redef"
210 else
211 if mclass.visibility != public_visibility then
212 res.add mclass.visibility.to_s
213 end
214 end
215 res.add mclass.kind.to_s
216 return res
217 end
218
219 # Depends if `self` is an intro or not.
220 #
221 # For intro: `private abstract class Foo[E: Object]`
222 # For redef: `redef class Foo[E]`
223 redef fun html_declaration do
224 var tpl = new Template
225 tpl.add "<span>"
226 tpl.add html_modifiers.join(" ")
227 tpl.add " "
228 tpl.add html_link
229 if is_intro then
230 tpl.add html_signature
231 else
232 tpl.add html_short_signature
233 end
234 tpl.add "</span>"
235 return tpl
236 end
237
238 # Returns `mmodule::self`
239 redef fun html_namespace do
240 var tpl = new Template
241 tpl.add mmodule.html_namespace
242 tpl.add "::<span>"
243 tpl.add mclass.html_link
244 tpl.add "</span>"
245 return tpl
246 end
247
248 # Returns the MClassDef generic signature without static bounds.
249 fun html_short_signature: Template do
250 var tpl = new Template
251 var mparameters = mclass.mparameters
252 if not mparameters.is_empty then
253 tpl.add "["
254 for i in [0..mparameters.length[ do
255 tpl.add mparameters[i].html_name
256 if i < mparameters.length - 1 then tpl.add ", "
257 end
258 tpl.add "]"
259 end
260 return tpl
261 end
262
263 # Returns the MClassDef generic signature with static bounds.
264 fun html_signature: Template do
265 var tpl = new Template
266 var mparameters = mclass.mparameters
267 if not mparameters.is_empty then
268 tpl.add "["
269 for i in [0..mparameters.length[ do
270 tpl.add "{mparameters[i].html_name}: "
271 tpl.add bound_mtype.arguments[i].html_signature
272 if i < mparameters.length - 1 then tpl.add ", "
273 end
274 tpl.add "]"
275 end
276 return tpl
277 end
278
279 redef fun css_classes do
280 var set = new HashSet[String]
281 if is_intro then set.add "intro"
282 for m in mclass.intro.modifiers do set.add m.to_cmangle
283 for m in modifiers do set.add m.to_cmangle
284 return set.to_a
285 end
286
287
288 # List of all modifiers like redef, private etc.
289 var modifiers: Array[String] is lazy do
290 var res = new Array[String]
291 if not is_intro then
292 res.add "redef"
293 else
294 res.add mclass.visibility.to_s
295 end
296 res.add mclass.kind.to_s
297 return res
298 end
299 end
300
301 redef class MProperty
302 redef fun html_modifiers do return intro.html_modifiers
303 redef fun html_declaration do return intro.html_declaration
304
305 # Returns `mclass::self`.
306 redef fun html_namespace do
307 var tpl = new Template
308 tpl.add intro_mclassdef.mclass.html_namespace
309 tpl.add "::<span>"
310 tpl.add intro.html_link
311 tpl.add "</span>"
312 return tpl
313 end
314
315 # Returns `intro.html_short_signature`.
316 fun html_short_signature: Template do return intro.html_short_signature
317
318 # Returns `intro.html_signature`.
319 fun html_signature: Template do return intro.html_signature
320
321 redef fun css_classes do return intro.css_classes
322 end
323
324 redef class MPropDef
325 # Depends if `self` is an intro or not.
326 #
327 # * If intro contains the visibility and kind.
328 # * If redef contains the `redef` keyword and kind.
329 redef fun html_modifiers do
330 var res = new Array[String]
331 if not is_intro then
332 res.add "redef"
333 else
334 if mproperty.visibility != public_visibility then
335 res.add mproperty.visibility.to_s
336 end
337 end
338 return res
339 end
340
341 # Depends if `self` is an intro or not.
342 #
343 # For intro: `private fun foo(e: Object): Bar is abstract`
344 # For redef: `redef fun foo(e) is cached`
345 redef fun html_declaration do
346 var tpl = new Template
347 tpl.add "<span>"
348 tpl.add html_modifiers.join(" ")
349 tpl.add " "
350 if is_intro then
351 tpl.add html_link
352 tpl.add html_signature
353 else
354 tpl.add mproperty.intro.html_link
355 tpl.add html_short_signature
356 end
357 tpl.add "</span>"
358 return tpl
359 end
360
361 # Returns `mclassdef::self`
362 redef fun html_namespace do
363 var tpl = new Template
364 tpl.add mclassdef.html_namespace
365 tpl.add "::"
366 tpl.add html_link
367 return tpl
368 end
369
370 # Returns the MPropdDef signature without static types.
371 fun html_short_signature: Template is abstract
372
373 # Returns the MPropDef signature with static types.
374 fun html_signature: Template is abstract
375
376 redef fun css_classes do
377 var set = new HashSet[String]
378 if is_intro then set.add "intro"
379 for m in mproperty.intro.modifiers do set.add m.to_cmangle
380 for m in modifiers do set.add m.to_cmangle
381 return set.to_a
382 end
383
384 # List of all modifiers like redef, private, abstract, intern, fun etc.
385 var modifiers: Array[String] is lazy do
386 var res = new Array[String]
387 if not is_intro then
388 res.add "redef"
389 else
390 res.add mproperty.visibility.to_s
391 end
392 var mprop = self
393 if mprop isa MVirtualTypeDef then
394 res.add "type"
395 else if mprop isa MMethodDef then
396 if mprop.is_abstract then
397 res.add "abstract"
398 else if mprop.is_intern then
399 res.add "intern"
400 end
401 if mprop.mproperty.is_init then
402 res.add "init"
403 else
404 res.add "fun"
405 end
406 end
407 return res
408 end
409 end
410
411 redef class MAttributeDef
412
413 redef fun html_modifiers do
414 var res = super
415 res.add "var"
416 return res
417 end
418
419 redef fun html_short_signature do return new Template
420
421 redef fun html_signature do
422 var static_mtype = self.static_mtype
423 var tpl = new Template
424 if static_mtype != null then
425 tpl.add ": "
426 tpl.add static_mtype.html_signature
427 end
428 return tpl
429 end
430 end
431
432 redef class MMethodDef
433
434 # FIXME annotation should be handled in their own way
435 redef fun html_modifiers do
436 if mproperty.is_init then
437 var res = new Array[String]
438 if mproperty.visibility != public_visibility then
439 res.add mproperty.visibility.to_s
440 end
441 return res
442 end
443 var res = super
444 if is_abstract then
445 res.add "abstract"
446 else if is_intern then
447 res.add "intern"
448 end
449 res.add "fun"
450 return res
451 end
452
453 redef fun html_declaration do
454 if mproperty.is_init then
455 var tpl = new Template
456 tpl.add "<span>"
457 tpl.add html_modifiers.join(" ")
458 tpl.add " "
459 tpl.add html_link
460 tpl.add html_signature
461 tpl.add "</span>"
462 return tpl
463 end
464 return super
465 end
466
467 redef fun html_short_signature do
468 var new_msignature = self.new_msignature
469 if mproperty.is_root_init and new_msignature != null then
470 return new_msignature.html_short_signature
471 end
472 return msignature.as(not null).html_short_signature
473 end
474
475 redef fun html_signature do
476 var new_msignature = self.new_msignature
477 if mproperty.is_root_init and new_msignature != null then
478 return new_msignature.html_signature
479 end
480 return msignature.as(not null).html_signature
481 end
482 end
483
484 redef class MVirtualTypeProp
485 redef fun html_link do return mvirtualtype.html_link
486 end
487
488 redef class MVirtualTypeDef
489
490 redef fun html_modifiers do
491 var res = super
492 res.add "type"
493 return res
494 end
495
496 redef fun html_short_signature do return new Template
497
498 redef fun html_signature do
499 var bound = self.bound
500 var tpl = new Template
501 if bound == null then return tpl
502 tpl.add ": "
503 tpl.add bound.html_signature
504 return tpl
505 end
506 end
507
508 redef class MType
509 # Returns the signature of this type whithout bounds.
510 fun html_short_signature: Template is abstract
511
512 # Returns the signature of this type.
513 fun html_signature: Template is abstract
514 end
515
516 redef class MClassType
517 redef fun html_link do return mclass.html_link
518 redef fun html_short_signature do return html_link
519 redef fun html_signature do return html_link
520 end
521
522 redef class MNullableType
523 redef fun html_short_signature do
524 var tpl = new Template
525 tpl.add "nullable "
526 tpl.add mtype.html_short_signature
527 return tpl
528 end
529
530 redef fun html_signature do
531 var tpl = new Template
532 tpl.add "nullable "
533 tpl.add mtype.html_signature
534 return tpl
535 end
536 end
537
538 redef class MGenericType
539 redef fun html_short_signature do
540 var lnk = html_link
541 var tpl = new Template
542 tpl.add new Link(lnk.href, mclass.name.html_escape, lnk.title)
543 tpl.add "["
544 for i in [0..arguments.length[ do
545 tpl.add arguments[i].html_short_signature
546 if i < arguments.length - 1 then tpl.add ", "
547 end
548 tpl.add "]"
549 return tpl
550 end
551
552 redef fun html_signature do
553 var lnk = html_link
554 var tpl = new Template
555 tpl.add new Link(lnk.href, mclass.name.html_escape, lnk.title)
556 tpl.add "["
557 for i in [0..arguments.length[ do
558 tpl.add arguments[i].html_signature
559 if i < arguments.length - 1 then tpl.add ", "
560 end
561 tpl.add "]"
562 return tpl
563 end
564 end
565
566 redef class MParameterType
567 redef fun html_short_signature do return html_link
568 redef fun html_signature do return html_link
569 end
570
571 redef class MVirtualType
572 redef fun html_signature do return html_link
573 end
574
575 redef class MSignature
576 redef fun html_short_signature do
577 var tpl = new Template
578 if not mparameters.is_empty then
579 tpl.add "("
580 for i in [0..mparameters.length[ do
581 tpl.add mparameters[i].html_short_signature
582 if i < mparameters.length - 1 then tpl.add ", "
583 end
584 tpl.add ")"
585 end
586 return tpl
587 end
588
589 redef fun html_signature do
590 var tpl = new Template
591 if not mparameters.is_empty then
592 tpl.add "("
593 for i in [0..mparameters.length[ do
594 tpl.add mparameters[i].html_signature
595 if i < mparameters.length - 1 then tpl.add ", "
596 end
597 tpl.add ")"
598 end
599 var return_mtype = self.return_mtype
600 if return_mtype != null then
601 tpl.add ": "
602 tpl.add return_mtype.html_signature
603 end
604 return tpl
605 end
606 end
607
608 redef class MParameter
609
610 # Returns `self` name and ellipsys if any.
611 fun html_short_signature: Template do
612 var tpl = new Template
613 tpl.add name
614 if is_vararg then tpl.add "..."
615 return tpl
616 end
617
618 # Returns `self` name with it's static type and ellipsys if any.
619 fun html_signature: Template do
620 var tpl = new Template
621 tpl.add "{name}: "
622 tpl.add mtype.html_signature
623 if is_vararg then tpl.add "..."
624 return tpl
625 end
626 end
627
628 redef class MEntityTree
629 # Render `self` as a hierarchical UnorderedList.
630 fun html_list: UnorderedList do
631 var lst = new_unordered_list
632 for r in roots do
633 var li = new_mentity_item(r)
634 lst.add_li li
635 build_html_list(r, li)
636 end
637 return lst
638 end
639
640 # Build the html list recursively.
641 private fun build_html_list(e: MEntity, li: ListItem) do
642 if not sub.has_key(e) then return
643 var subs = sub[e]
644 var lst = new_unordered_list
645 for e2 in subs do
646 if e2 isa MGroup and e2.is_root then
647 build_html_list(e2, li)
648 else
649 var sli = new_mentity_item(e2)
650 lst.add_li sli
651 build_html_list(e2, sli)
652 end
653 end
654 var text = new Template
655 text.add li.text
656 if not lst.is_empty then text.add lst
657 li.text = text
658 end
659
660 # HTML unordered List used to compose the tree.
661 #
662 # Redefine this method to add custom CSS classes or other html attributes.
663 protected fun new_unordered_list: UnorderedList do return new UnorderedList
664
665 # Return a li element for `mconcern` that can be displayed in a concern list
666 protected fun new_mentity_item(mentity: MEntity): ListItem do
667 var tpl = new Template
668 tpl.add mentity.html_link
669 var comment = mentity.html_synopsis
670 if comment != null then
671 tpl.add ": "
672 tpl.add comment
673 end
674 return new ListItem(tpl)
675 end
676 end