3882eb060e07c92d26ed1c93dcc7ab16947add02
[nit.git] / src / doc / html_templates / html_model.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 # HTML templates for Nit model MEntities.
16 module html_model
17
18 import doc_base
19 import doc_down
20 import html_components
21 import html::bootstrap
22 import ordered_tree
23
24 redef class Location
25 # Github url based on this location
26 fun github(gitdir: String): String do
27 var base_dir = getcwd.join_path(gitdir).simplify_path
28 var file_loc = getcwd.join_path(file.filename).simplify_path
29 var gith_loc = file_loc.substring(base_dir.length + 1, file_loc.length)
30 return "{gith_loc}:{line_start},{column_start}--{line_end},{column_end}"
31 end
32 end
33
34 redef class MEntity
35 # ID used as a HTML unique ID and in file names.
36 #
37 # **Must** match the following (POSIX ERE) regular expression:
38 #
39 # ~~~POSIX ERE
40 # ^[A-Za-z_][A-Za-z0-9._-]*$
41 # ~~~
42 #
43 # That way, the ID is always a valid URI component and a valid XML name.
44 fun nitdoc_id: String is abstract
45
46 # URL of this entity’s Nitdoc page.
47 fun nitdoc_url: String is abstract
48
49 # Returns the mentity name without short signature.
50 #
51 # * MProject: `foo`
52 # * MGroup: `foo`
53 # * MModule: `foo`
54 # * MClass: `Foo[E]`
55 # * MClassDef: `Foo[E]`
56 # * MProperty: `foo(e)`
57 # * MPropdef: `foo(e)`
58 var html_name: String is lazy do return name.html_escape
59
60 # Returns a Link to the mentity `html_url`.
61 #
62 # Example: `<a href="html_url" title="mdoc.short_comment">html_short_name</a>
63 var html_link: Link is lazy do
64 var tpl = new Link(nitdoc_url, html_name)
65 var mdoc = mdoc_or_fallback
66 if mdoc != null then
67 tpl.title = mdoc.short_comment
68 end
69 return tpl
70 end
71
72 # Returns a Link to the mentity `nitdoc_id`.
73 #
74 # Example: `<a href="#nitdoc_id" title="mdoc.short_comment">html_short_name</a>
75 fun html_link_to_anchor: Link do
76 var tpl = new Link("#{nitdoc_id}", html_name)
77 var mdoc = mdoc_or_fallback
78 if mdoc != null then
79 tpl.title = mdoc.short_comment
80 end
81 return tpl
82 end
83
84 # A template article that briefly describe the entity
85 fun tpl_short_article: TplArticle do
86 var tpl = tpl_article
87 var mdoc = mdoc_or_fallback
88 if mdoc != null then
89 tpl.content = mdoc.tpl_short_comment
90 end
91 return tpl
92 end
93
94 # A template article that describe the entity
95 fun tpl_article: TplArticle do
96 var tpl = new TplArticle.with_title(nitdoc_id, tpl_title)
97 tpl.title_classes.add "signature"
98 tpl.subtitle = tpl_namespace
99 tpl.summary_title = html_name
100 return tpl
101 end
102
103 # A template signature that contains modifiers and parameters
104 fun tpl_declaration: Template is abstract
105
106 # A template namespace
107 fun tpl_namespace: Template is abstract
108
109 # A template definition of the mentity
110 # include name, sysnopsys, comment and namespace
111 fun tpl_definition: TplDefinition is abstract
112
113 # A li element that can go in a list
114 fun tpl_list_item: TplListItem do
115 var lnk = new Template
116 lnk.add new TplLabel.with_classes(tpl_css_classes)
117 lnk.add html_link
118 var mdoc = mdoc_or_fallback
119 if mdoc != null then
120 lnk.add ": "
121 lnk.add mdoc.tpl_short_comment
122 end
123 return new TplListItem.with_content(lnk)
124 end
125
126 var tpl_css_classes = new Array[String]
127
128 # Box title for this mentity
129 fun tpl_title: Template do
130 var title = new Template
131 title.add tpl_icon
132 title.add tpl_namespace
133 return title
134 end
135
136 # Icon that will be displayed before the title
137 fun tpl_icon: TplIcon do
138 var icon = new TplIcon.with_icon("tag")
139 icon.css_classes.add_all(tpl_css_classes)
140 return icon
141 end
142 end
143
144 redef class MConcern
145 # Return a li element for `self` that can be displayed in a concern list
146 private fun tpl_concern_item: TplListItem do
147 var lnk = new Template
148 lnk.add html_link_to_anchor
149 var mdoc = mdoc_or_fallback
150 if mdoc != null then
151 lnk.add ": "
152 lnk.add mdoc.tpl_short_comment
153 end
154 return new TplListItem.with_content(lnk)
155 end
156 end
157
158 redef class MProject
159 redef var nitdoc_id = name.to_cmangle is lazy
160 redef fun nitdoc_url do return root.nitdoc_url
161
162 redef fun tpl_declaration do
163 var tpl = new Template
164 tpl.add "<span>project "
165 tpl.add html_link
166 tpl.add "</span>"
167 return tpl
168 end
169
170 redef fun tpl_namespace do return html_link
171
172 redef fun tpl_definition do
173 var tpl = new TplDefinition
174 var mdoc = mdoc_or_fallback
175 if mdoc != null then
176 tpl.comment = mdoc.tpl_comment
177 end
178 return tpl
179 end
180
181 redef fun tpl_css_classes do return ["public"]
182 end
183
184 redef class MGroup
185 redef var nitdoc_id is lazy do
186 if parent != null then
187 return "{parent.nitdoc_id}__{name.to_cmangle}"
188 end
189 return name.to_cmangle
190 end
191
192 redef fun nitdoc_url do return "group_{nitdoc_id}.html"
193
194 redef fun tpl_namespace do
195 var tpl = new Template
196 tpl.add mproject.tpl_namespace
197 if mproject.root != self then
198 tpl.add "::"
199 tpl.add html_link
200 end
201 return tpl
202 end
203
204 redef fun tpl_declaration do
205 var tpl = new Template
206 tpl.add "<span>group "
207 tpl.add html_link
208 tpl.add "</span>"
209 return tpl
210 end
211
212 redef fun tpl_definition do
213 var tpl = new TplDefinition
214 var mdoc = mdoc_or_fallback
215 if mdoc != null then
216 tpl.comment = mdoc.tpl_comment
217 end
218 return tpl
219 end
220 end
221
222 redef class MModule
223 redef var nitdoc_id is lazy do
224 if mgroup != null then
225 if mgroup.mmodules.length == 1 then
226 return "{mgroup.nitdoc_id}-"
227 else
228 return "{mgroup.nitdoc_id}__{name.to_cmangle}"
229 end
230 end
231 return name.to_cmangle
232 end
233
234 redef fun nitdoc_url do return "module_{nitdoc_id}.html"
235
236 redef fun tpl_declaration do
237 var tpl = new Template
238 tpl.add "<span>module "
239 tpl.add tpl_namespace
240 tpl.add "</span>"
241 return tpl
242 end
243
244 redef fun tpl_namespace do
245 var tpl = new Template
246 if mgroup != null then
247 tpl.add mgroup.tpl_namespace
248 tpl.add "::"
249 end
250 tpl.add html_link
251 return tpl
252 end
253
254 redef fun tpl_definition do
255 var tpl = new TplClassDefinition
256 var mdoc = mdoc_or_fallback
257 if mdoc != null then
258 tpl.comment = mdoc.tpl_comment
259 end
260 return tpl
261 end
262
263 redef fun tpl_css_classes do return ["public"]
264 end
265
266 redef class MClass
267 redef var nitdoc_id = "{intro_mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
268 redef fun nitdoc_url do return "class_{nitdoc_id}.html"
269 redef fun mdoc_or_fallback do return intro.mdoc
270
271 # Format: `Foo[E]`
272 redef var html_name is lazy do
273 var tpl = new Template
274 tpl.add name.html_escape
275 if arity > 0 then
276 tpl.add "["
277 var parameter_names = new Array[String]
278 for p in mparameters do
279 parameter_names.add(p.html_name)
280 end
281 tpl.add parameter_names.join(", ")
282 tpl.add "]"
283 end
284 return tpl.write_to_string
285 end
286
287 redef fun tpl_declaration do return intro.tpl_declaration
288 redef fun tpl_definition do return intro.tpl_definition
289
290 redef fun tpl_namespace do
291 var tpl = new Template
292 tpl.add intro_mmodule.mgroup.mproject.tpl_namespace
293 tpl.add "::<span>"
294 tpl.add html_link
295 tpl.add "</span>"
296 return tpl
297 end
298
299 redef fun tpl_title do
300 var title = new Template
301 title.add tpl_icon
302 title.add html_link
303 return title
304 end
305
306 redef fun tpl_icon do return intro.tpl_icon
307
308 fun tpl_signature: Template do
309 var tpl = new Template
310 if arity > 0 then
311 tpl.add "["
312 var parameter_names = new Array[String]
313 for p in mparameters do
314 parameter_names.add(p.html_name)
315 end
316 tpl.add parameter_names.join(", ")
317 tpl.add "]"
318 end
319 return tpl
320 end
321
322 redef fun tpl_css_classes do return intro.tpl_css_classes
323 end
324
325 redef class MClassDef
326 redef var nitdoc_id = "{mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
327 redef fun nitdoc_url do return "{mclass.nitdoc_url}#{nitdoc_id}"
328
329 redef fun mdoc_or_fallback do return mdoc or else mclass.mdoc_or_fallback
330
331 redef fun tpl_namespace do
332 var tpl = new Template
333 tpl.add mmodule.tpl_namespace
334 tpl.add "::<span>"
335 tpl.add mclass.html_link
336 tpl.add "</span>"
337 return tpl
338 end
339
340 redef fun tpl_article do
341 var tpl = new TplArticle(nitdoc_id)
342 tpl.summary_title = "in {mmodule.html_name}"
343 tpl.title = tpl_declaration
344 tpl.title_classes.add "signature"
345 var title = new Template
346 title.add "in "
347 title.add mmodule.tpl_namespace
348 tpl.subtitle = title
349 var mdoc = mdoc_or_fallback
350 if mdoc != null then
351 tpl.content = mdoc.tpl_comment
352 end
353 return tpl
354 end
355
356 redef fun tpl_title do
357 var title = new Template
358 title.add tpl_icon
359 title.add html_link
360 return title
361 end
362
363 redef fun tpl_declaration do
364 var tpl = new Template
365 tpl.add tpl_modifiers
366 tpl.add html_link
367 tpl.add tpl_signature
368 return tpl
369 end
370
371 fun tpl_signature: Template do
372 var tpl = new Template
373 var mparameters = mclass.mparameters
374 if not mparameters.is_empty then
375 tpl.add "["
376 for i in [0..mparameters.length[ do
377 tpl.add "{mparameters[i].html_name}: "
378 tpl.add bound_mtype.arguments[i].tpl_signature
379 if i < mparameters.length - 1 then tpl.add ", "
380 end
381 tpl.add "]"
382 end
383 return tpl
384 end
385
386 redef fun tpl_definition do
387 var tpl = new TplClassDefinition
388 var mdoc = mdoc_or_fallback
389 if mdoc != null then
390 tpl.comment = mdoc.tpl_comment
391 end
392 return tpl
393 end
394
395 redef fun tpl_css_classes do
396 var set = new HashSet[String]
397 if is_intro then set.add "intro"
398 for m in mclass.intro.modifiers do set.add m.to_cmangle
399 for m in modifiers do set.add m.to_cmangle
400 return set.to_a
401 end
402
403 fun tpl_modifiers: Template do
404 var tpl = new Template
405 for modifier in modifiers do
406 if modifier == "public" then continue
407 tpl.add "{modifier.html_escape} "
408 end
409 return tpl
410 end
411 end
412
413 redef class MProperty
414 redef var nitdoc_id = "{intro_mclassdef.mclass.nitdoc_id}__{name.to_cmangle}" is lazy
415 redef fun nitdoc_url do return "property_{nitdoc_id}.html"
416
417 redef fun mdoc_or_fallback do return intro.mdoc
418
419 redef fun tpl_namespace do
420 var tpl = new Template
421 tpl.add intro_mclassdef.mclass.tpl_namespace
422 tpl.add "::<span>"
423 tpl.add intro.html_link
424 tpl.add "</span>"
425 return tpl
426 end
427
428 redef fun tpl_declaration do return intro.tpl_declaration
429
430 fun tpl_signature: Template do return new Template
431
432 redef fun tpl_title do return intro.tpl_title
433
434 redef fun tpl_icon do return intro.tpl_icon
435
436 redef fun tpl_css_classes do return intro.tpl_css_classes
437 end
438
439 redef class MPropDef
440 redef var nitdoc_id = "{mclassdef.nitdoc_id}__{name.to_cmangle}" is lazy
441 redef fun nitdoc_url do return "{mproperty.nitdoc_url}#{nitdoc_id}"
442
443 redef fun mdoc_or_fallback do return mdoc or else mproperty.mdoc_or_fallback
444
445 redef fun tpl_namespace do
446 var tpl = new Template
447 tpl.add mclassdef.tpl_namespace
448 tpl.add "::"
449 tpl.add html_link
450 return tpl
451 end
452
453 redef fun tpl_article do
454 var tpl = new TplArticle(nitdoc_id)
455 tpl.summary_title = "in {mclassdef.html_name}"
456 var title = new Template
457 title.add "in "
458 title.add mclassdef.html_link
459 tpl.title = title
460 tpl.subtitle = tpl_declaration
461 var mdoc = mdoc_or_fallback
462 if mdoc != null then
463 tpl.content = mdoc.tpl_comment
464 end
465 return tpl
466 end
467
468 redef fun tpl_definition do
469 var tpl = new TplDefinition
470 var mdoc = mdoc_or_fallback
471 if mdoc != null then
472 tpl.comment = mdoc.tpl_comment
473 end
474 return tpl
475 end
476
477 redef fun tpl_declaration do
478 var tpl = new Template
479 tpl.add tpl_modifiers
480 tpl.add html_link
481 tpl.add tpl_signature
482 return tpl
483 end
484
485 redef fun tpl_css_classes do
486 var set = new HashSet[String]
487 if is_intro then set.add "intro"
488 for m in mproperty.intro.modifiers do set.add m.to_cmangle
489 for m in modifiers do set.add m.to_cmangle
490 return set.to_a
491 end
492
493 fun tpl_modifiers: Template do
494 var tpl = new Template
495 for modifier in modifiers do
496 if modifier == "public" then continue
497 tpl.add "{modifier.html_escape} "
498 end
499 return tpl
500 end
501
502 fun tpl_signature: Template do return new Template
503
504 redef fun tpl_list_item do
505 var lnk = new Template
506 lnk.add new TplLabel.with_classes(tpl_css_classes.to_a)
507 var atext = html_link.text
508 var ahref = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
509 var atitle = html_link.title
510 var anchor = new Link.with_title(ahref, atext, atitle)
511 lnk.add anchor
512 var mdoc = mdoc_or_fallback
513 if mdoc != null then
514 lnk.add ": "
515 lnk.add mdoc.tpl_short_comment
516 end
517 return new TplListItem.with_content(lnk)
518 end
519
520 fun tpl_inheritance_item: TplListItem do
521 var lnk = new Template
522 lnk.add new TplLabel.with_classes(tpl_css_classes.to_a)
523 lnk.add mclassdef.mmodule.tpl_namespace
524 lnk.add "::"
525 var atext = mclassdef.html_link.text
526 var ahref = "{mclassdef.mclass.nitdoc_url}#{mproperty.nitdoc_id}"
527 var atitle = mclassdef.html_link.title
528 var anchor = new Link.with_title(ahref, atext, atitle)
529 lnk.add anchor
530 var mdoc = mdoc_or_fallback
531 if mdoc != null then
532 lnk.add ": "
533 lnk.add mdoc.tpl_short_comment
534 end
535 var li = new TplListItem.with_content(lnk)
536 li.css_classes.add "signature"
537 return li
538 end
539 end
540
541 redef class MAttributeDef
542 redef fun tpl_signature do
543 var tpl = new Template
544 if static_mtype != null then
545 tpl.add ": "
546 tpl.add static_mtype.tpl_signature
547 end
548 return tpl
549 end
550 end
551
552 redef class MMethod
553 redef fun tpl_signature do
554 var tpl = new Template
555 var params = new Array[String]
556 for param in intro.msignature.mparameters do
557 params.add param.name.html_escape
558 end
559 if not params.is_empty then
560 tpl.add "("
561 tpl.add params.join(", ")
562 tpl.add ")"
563 end
564 return tpl
565 end
566 end
567
568 redef class MMethodDef
569 redef fun tpl_signature do return msignature.tpl_signature
570 end
571
572 redef class MVirtualTypeProp
573 redef fun html_link do return mvirtualtype.html_link
574 redef fun tpl_signature do return html_link
575 end
576
577 redef class MVirtualTypeDef
578 redef fun tpl_signature do
579 var tpl = new Template
580 if bound == null then return tpl
581 tpl.add ": "
582 tpl.add bound.tpl_signature
583 return tpl
584 end
585 end
586
587 redef class MType
588 fun tpl_signature: Template is abstract
589 end
590
591 redef class MClassType
592 redef fun html_link do return mclass.html_link
593 redef fun tpl_signature do return html_link
594 end
595
596 redef class MNullableType
597 redef fun tpl_signature do
598 var tpl = new Template
599 tpl.add "nullable "
600 tpl.add mtype.tpl_signature
601 return tpl
602 end
603 end
604
605 redef class MGenericType
606 redef fun tpl_signature do
607 var lnk = html_link
608 var tpl = new Template
609 tpl.add new Link.with_title(lnk.href, mclass.name.html_escape, lnk.title)
610 tpl.add "["
611 for i in [0..arguments.length[ do
612 tpl.add arguments[i].tpl_signature
613 if i < arguments.length - 1 then tpl.add ", "
614 end
615 tpl.add "]"
616 return tpl
617 end
618 end
619
620 redef class MParameterType
621 redef fun html_link do
622 return new Link.with_title("{mclass.nitdoc_url}#FT_{name.to_cmangle}", name, "formal type")
623 end
624 redef fun tpl_signature do return html_link
625 end
626
627 redef class MVirtualType
628 redef fun html_link do return mproperty.intro.html_link
629 redef fun tpl_signature do return html_link
630 end
631
632 redef class MSignature
633 redef fun tpl_signature do
634 var tpl = new Template
635 if not mparameters.is_empty then
636 tpl.add "("
637 for i in [0..mparameters.length[ do
638 tpl.add mparameters[i].tpl_signature
639 if i < mparameters.length - 1 then tpl.add ", "
640 end
641 tpl.add ")"
642 end
643 if return_mtype != null then
644 tpl.add ": "
645 tpl.add return_mtype.tpl_signature
646 end
647 return tpl
648 end
649 end
650
651 redef class MParameter
652 fun tpl_signature: Template do
653 var tpl = new Template
654 tpl.add "{name}: "
655 tpl.add mtype.tpl_signature
656 if is_vararg then tpl.add "..."
657 return tpl
658 end
659 end
660
661 redef class ConcernsTree
662
663 private var seen = new HashSet[MConcern]
664
665 redef fun add(p, e) do
666 if seen.has(e) then return
667 seen.add e
668 super(p, e)
669 end
670
671 fun to_tpl: TplList do
672 var lst = new TplList.with_classes(["list-unstyled", "list-definition"])
673 for r in roots do
674 var li = r.tpl_concern_item
675 lst.add_li li
676 build_list(r, li)
677 end
678 return lst
679 end
680
681 private fun build_list(e: MConcern, li: TplListItem) do
682 if not sub.has_key(e) then return
683 var subs = sub[e]
684 var lst = new TplList.with_classes(["list-unstyled", "list-definition"])
685 for e2 in subs do
686 if e2 isa MGroup and e2.is_root then
687 build_list(e2, li)
688 else
689 var sli = e2.tpl_concern_item
690 lst.add_li sli
691 build_list(e2, sli)
692 end
693 end
694 li.append lst
695 end
696 end
697
698
699 ################################################################################
700 # Additions to `model_ext`.
701
702 redef class MRawType
703 redef fun tpl_signature do
704 var tpl = new Template
705
706 for part in parts do
707 if part.target != null then
708 tpl.add part.target.as(not null).html_link
709 else
710 tpl.add part.text.html_escape
711 end
712 end
713 return tpl
714 end
715 end
716
717 redef class MInnerClass
718 redef fun nitdoc_url do return inner.nitdoc_url
719 redef fun tpl_signature do return inner.tpl_signature
720 end
721
722 redef class MInnerClassDef
723 redef fun nitdoc_url do return inner.nitdoc_url
724
725 redef fun html_link_to_anchor do return inner.html_link_to_anchor
726 redef fun html_link do return inner.html_link
727 redef fun tpl_signature do return inner.tpl_signature
728
729 redef fun tpl_definition do
730 var tpl = new TplClassDefinition
731 var mdoc = mdoc_or_fallback
732 if mdoc != null then
733 tpl.comment = mdoc.tpl_comment
734 end
735 return tpl
736 end
737 end