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