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