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