tests: Add test_astbuilder to the skip list of nitcg niti nitvm
[nit.git] / src / doc / static / static_cards.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 # Cards templates for the static documentation
16 module static_cards
17
18 import templates::html_commands
19
20 # A card that can be rendered to HTML
21 #
22 # Basically, these cards are templates with additionnal data and behavior.
23 abstract class StaticCard
24 super Template
25
26 # Card title
27 var title: String is writable
28
29 # Card id
30 var id: String is writable
31 end
32
33 # A list of cards
34 class CardList
35 super StaticCard
36
37 # Cards contained in this list
38 var cards = new Array[StaticCard] is writable
39
40 redef fun rendering do
41 addn "<div id='{id}' class='card-list'>"
42 for card in cards do
43 addn card
44 end
45 addn "</div>"
46 end
47 end
48
49 # Doc elements
50
51 # A card that display custom text data
52 class CardText
53 super StaticCard
54 autoinit(content)
55
56 # Custom content from options
57 var content: nullable String is writable
58
59 redef var id = "home"
60 redef var title = "Home"
61
62 redef fun rendering do
63 var content = self.content
64 if content == null then return
65 addn "<div>"
66 addn content
67 addn "</div>"
68 addn "<hr/>"
69 end
70 end
71
72 # A heading section
73 #
74 # It displays an heading at a specific level from 1 to 6.
75 class CardSection
76 super StaticCard
77 autoinit(level, title, subtitle)
78
79 # Section heading level
80 var level: Int is writable
81
82 # Section subtitle
83 var subtitle: nullable String is writable
84
85 redef var id = title.to_cmangle is lazy
86
87 redef fun rendering do
88 addn "<h{level} id='{id}'>{title}</h{level}>"
89 end
90 end
91
92 # A page header
93 class CardPageHeader
94 super CardSection
95 autoinit(title, subtitle)
96
97 redef var level = 2
98
99 redef fun rendering do
100 addn "<div class='page-header'>"
101 super
102 var subtitle = self.subtitle
103 if subtitle != null then
104 addn "<p class='text-muted'>"
105 addn subtitle
106 addn "</p>"
107 end
108 addn "</div>"
109 end
110 end
111
112 # A card that displays a summary of a list of cards
113 class CardSummary
114 super CardList
115 autoinit(no_title)
116
117 redef var id = "summary"
118 redef var title = "Summary"
119
120 # Show the summary title
121 var no_title: Bool = false is optional, writable
122
123 redef fun rendering do
124 if not no_title then
125 addn "<h4>Summary</h4>"
126 end
127 addn "<div class='summary'>"
128 addn " <ul class='list-unstyled'>"
129 var sections = new Array[CardSection]
130 for card in cards do
131 if card isa CardSection then
132 while sections.not_empty and sections.last.level >= card.level do
133 sections.pop
134 end
135 sections.add card
136 end
137 var level = if sections.is_empty then 1 else sections.last.level
138 if not card isa CardSection then level += 1
139 addn "<li><a href='#{card.id}'><h{level}>{card.title}</h{level}></a></li>"
140 end
141 addn " </ul>"
142 addn "</div>"
143 end
144 end
145
146 # A card that displays the summary of a Markdown document
147 class CardMdSummary
148 super CardMDoc
149 autoinit(md_processor, headlines)
150
151 # Markdown processor used to extract and render the content
152 var md_processor: MarkdownProcessor is writable
153
154 # Headlines found in the document
155 var headlines: ArrayMap[String, HeadLine] is writable
156
157 redef var id = "summary"
158 redef var title = "Summary"
159
160 redef fun rendering do
161 addn "<h4>Summary</h4>"
162 addn "<div class='summary'>"
163 addn " <ul class='list-unstyled'>"
164 for id, headline in headlines do
165 var level = headline.level
166 var title = md_processor.process(headline.title)
167 addn "<li><a href='#{id}'><h{level}>{title}</h{level}></a></li>"
168 end
169 addn " </ul>"
170 addn "</div>"
171 end
172 end
173
174 # MEntity related cards
175
176 # A card about a mentity
177 #
178 # It displays the documentation about the model entity.
179 class CardMEntity
180 super StaticCard
181 autoinit(mentity, full_doc)
182
183 # MEntity displayed in this card
184 var mentity: MEntity is writable
185
186 # Render the mentity full documentation?
187 var full_doc = false is optional, writable
188
189 redef var id = mentity.html_id is lazy
190 redef var title = mentity.html_name is lazy
191
192 redef fun rendering do
193 addn """
194 <div id='{{{id}}}' class='card'>
195 <div class='card-left text-center'>
196 {{{mentity.html_icon.write_to_string}}}
197 </div>
198 <div class='card-body'>
199 <h5 class='card-heading'>
200 {{{mentity.html_declaration.write_to_string}}}
201 </h5>
202 <p><small>{{{mentity.html_namespace.write_to_string}}}</small></p>"""
203 var mdoc = mentity.mdoc_or_fallback
204 if mdoc != null then
205 if full_doc then
206 addn mdoc.html_documentation
207 else
208 addn mdoc.html_synopsis
209 end
210 end
211 addn """
212 </div>
213 </div>"""
214 end
215 end
216
217 # A card that displays the content of a MDoc
218 class CardMDoc
219 super CardMEntity
220 autoinit(mentity, mdoc, full_doc)
221
222 # MDoc to display in this card
223 var mdoc: nullable MDoc is writable
224
225 redef fun rendering do
226 var mdoc = self.mdoc
227 if mdoc == null then return
228 addn "<div id='{id}' class='card'>"
229 addn " <div class='card-body nitdoc'>"
230 addn mdoc.html_documentation
231 addn " </div>"
232 addn "</div>"
233 end
234 end
235
236 # A card about the inheritance of a MEntity
237 class CardInheritance
238 super CardMEntity
239
240 # Ancestors list
241 var ancestors: nullable Array[MEntity] is writable
242
243 # Parents list
244 var parents: nullable Array[MEntity] is writable
245
246 # Children list
247 var children: nullable Array[MEntity] is writable
248
249 # Descendants list
250 var descendants: nullable Array[MEntity] is writable
251
252 redef var id = "inh_{super}" is lazy
253 redef var title = "Inheritance" is lazy
254
255 redef fun rendering do
256 var ancestors = self.ancestors
257 var descendants = self.descendants
258 if ancestors == null and parents == null and
259 children == null and descendants == null then return
260
261 addn "<div id='{id}' class='card'>"
262 addn " <div class='card-body'>"
263 if ancestors != null and ancestors.length <= 10 then
264 render_list("Ancestors", ancestors)
265 else
266 render_list("Parents", parents)
267 end
268 if descendants != null and descendants.length <= 10 then
269 render_list("Descendants", descendants)
270 else
271 render_list("Children", children)
272 end
273 addn " </div>"
274 addn "</div>"
275 end
276
277 private fun render_list(title: String, mentities: nullable Array[MEntity]) do
278 if mentities == null or mentities.is_empty then return
279 addn "<h4 id='{id}'>{title}</h4>"
280 addn "<ul class='list-unstyled'>"
281 for mentity in mentities do
282 addn html_list_item(mentity)
283 end
284 addn "</ul>"
285 end
286
287 private fun html_list_item(mentity: MEntity): ListItem do
288 var tpl = new Template
289 tpl.add mentity.html_namespace
290 var comment = mentity.mdoc_or_fallback
291 if comment != null then
292 tpl.add ": "
293 tpl.add comment.html_synopsis
294 end
295 return new ListItem(tpl)
296 end
297 end
298
299 # A card about the linearization of a MEntity
300 class CardLinearizationList
301 super CardMEntity
302
303 # Linearization cards contained in this list
304 var cards = new Array[CardLinearizationDef] is writable
305
306 redef var id = "lin_{super}" is lazy
307 redef var title = "Linearization" is lazy
308
309 redef fun rendering do
310 if cards.is_empty then return
311
312 addn "<div id='{id}'>"
313 for card in cards do
314 addn card
315 if card == cards.last then break
316 addn "<h4 class='text-muted text-center'>"
317 addn " <span class='glyphicon glyphicon-chevron-up'></span>"
318 addn "</h4>"
319 end
320 addn "</div>"
321 end
322 end
323
324 # A card about a definition in a linearization list
325 class CardLinearizationDef
326 super CardCode
327
328 # Is this card displayed by default?
329 var is_active: Bool = false is optional, writable
330
331 # Link to external code repository
332 #
333 # Used if `node` is null
334 var url: nullable String = null is optional, writable
335
336 redef var id = "def_{super}" is lazy
337 redef var title = mentity.full_name is lazy
338
339 redef fun rendering do
340 var url = self.url
341
342 var cin = if is_active then "in" else ""
343 var active = if is_active then "active" else ""
344 addn """
345 <div class='card {{{active}}}' id='{{{id}}}'>
346 <div class='card-body'>
347 <h5>
348 {{{mentity.html_icon.write_to_string}}}
349 {{{mentity.html_namespace.write_to_string}}}"""
350 if node != null then
351 addn """
352 <div class='btn-bar'>
353 <button class='btn btn-link' data-toggle='collapse'
354 data-target='#{{{mentity.html_id}}}'>
355 <span class='glyphicon glyphicon-console' title='Show code' />
356 </button>
357 </div>"""
358 else if url != null then
359 addn """
360 <div class='btn-bar'>
361 <a class='btn btn-link' href='{{{url}}}'>
362 <span class='glyphicon glyphicon-console' title='Show code' />
363 </a>
364 </div>"""
365 var mdoc = mentity.mdoc
366 if mdoc != null then
367 addn "<br/><br/>"
368 addn mdoc.html_documentation
369 end
370 end
371 addn "</h5>"
372 if node != null then
373 addn """
374 <div id='{{{mentity.html_id}}}' class='collapse {{{cin}}}'>
375 <pre>"""
376 render_code
377 addn """</pre>
378 <span class='text-muted'>{{{mentity.location.to_s}}}</span>
379 </div>"""
380 end
381 addn """
382 </div>
383 </div>"""
384 end
385 end
386
387 # A card that displays the code of a MEntity
388 class CardCode
389 super CardMEntity
390 autoinit(mentity, node)
391
392 # AST node to display in this card
393 var node: nullable ANode is writable
394
395 redef var id = "code_{super}" is lazy
396 redef var title = "Code"
397
398 redef fun rendering do
399 addn "<div id='{id}' class='card'>"
400 addn " <div class='card-body'>"
401
402 if node != null then
403 addn "<pre>"
404 render_code
405 addn "</pre>"
406 end
407 addn "<span class='text-muted'>{mentity.location}</span>"
408
409 addn " </div>"
410 addn "</div>"
411 end
412
413 private fun render_code do
414 var node = self.node
415 if node == null then return
416 var hl = new HtmlightVisitor
417 hl.show_infobox = false
418 hl.highlight_node node
419 addn hl.html
420 end
421 end
422
423 # A card that displays a graph
424 class CardGraph
425 super CardMEntity
426 autoinit(mentity, graph)
427
428 # Graph to display in this card
429 var graph: InheritanceGraph is writable
430
431 redef var id = "graph_{super}" is lazy
432 redef var title = "Graph"
433
434 redef fun rendering do
435 addn "<div id='{id}' class='card'>"
436 addn " <div class='card-body'>"
437 addn " <div class='text-center'>"
438 addn graph.graph.to_svg
439 addn " </div>"
440 addn " </div>"
441 addn "</div>"
442 end
443 end
444
445 # Catalog related cards
446
447 # A card that displays Nit catalog related data
448 abstract class CardCatalog
449 super StaticCard
450 autoinit(catalog)
451
452 # Catalog used to extract the data
453 var catalog: Catalog is writable
454 end
455
456 # A card that displays statistics about a Nit catalog
457 class CardCatalogStats
458 super CardCatalog
459
460 redef var id = "catalog_stats"
461 redef var title = "Stats"
462
463 redef fun rendering do
464 addn "<div id='{id}' class='container-fluid'>"
465 for key, value in catalog.catalog_stats.to_map do
466 addn "<span class='text-muted small'>"
467 addn " <strong>{value}</strong>&nbsp;<span>{key}</span>&nbsp;"
468 addn "</span>"
469 end
470 addn "</div>"
471 addn "<hr/>"
472 end
473 end
474
475 # A card that displays a list of tags
476 class CardCatalogTags
477 super CardCatalog
478
479 redef var id = "catalog_tags"
480 redef var title = "Tags"
481
482 # Sorter to sort tags alphabetically
483 var tags_sorter = new CatalogTagsSorter is writable
484
485 redef fun rendering do
486 var tags = catalog.tag2proj.keys.to_a
487 if tags.is_empty then return
488 tags_sorter.sort(tags)
489
490 addn "<h2 id='{id}'>Tags</h2>"
491 addn "<div class='container-fluid'>"
492 for tag in tags do
493 addn "<div class='col-xs-6 col-sm-3 col-md-2'>"
494 addn " <span class='badge'>{catalog.tag2proj[tag].length}</span>"
495 addn " <a href='tag_{tag.to_cmangle}.html'>{tag}</a>"
496 addn "</div>"
497 end
498 addn "</div>"
499 addn "<hr/>"
500 end
501 end
502
503 # A card that displays a package from a Nit catalog
504 class CardCatalogPackage
505 super CardCatalog
506 super CardMEntity
507 autoinit(catalog, mentity)
508
509 redef var id = "package_{super}" is lazy
510
511 redef fun rendering do
512 var mpackage = self.mentity
513 if not mpackage isa MPackage then return
514
515 addn """
516 <div id='{{{id}}}' class='card'>
517 <div class='card-left text-center'>{{{mpackage.html_icon.write_to_string}}}</div>
518 <div class='card-body' style='width: 75%'>
519 <h5 class='card-heading'>
520 {{{mentity.html_declaration.write_to_string}}}
521 <small>&nbsp;"""
522 for tag in mpackage.metadata.tags do
523 add "<span>"
524 add "<a href='tag_{tag.to_cmangle}.html' class='text-muted'>{tag}</a>"
525 if tag != mpackage.metadata.tags.last then addn ", "
526 add "</span>"
527 end
528 addn """</small>
529 </h5>"""
530 var mdoc = mentity.mdoc_or_fallback
531 if mdoc != null then
532 if full_doc then
533 addn mdoc.html_documentation
534 else
535 addn mdoc.html_synopsis
536 end
537 end
538 addn " </div>"
539 addn " <div class='card-right' style='width: 25%'>"
540 for maintainer in mpackage.metadata.maintainers do
541 addn maintainer.to_html
542 end
543 addn " <br>"
544 var license = mpackage.metadata.license
545 if license != null then
546 addn """
547 <span class='text-muted'>
548 <a href='http://opensource.org/licenses/{{{license}}}' class='text-muted'>
549 {{{license}}}
550 </a>
551 </span>"""
552 end
553 addn " </div>"
554 addn "</div>"
555 end
556 end
557
558 # A card that displays the metadata about a package in the Nit catalog
559 class CardMetadata
560 super CardMEntity
561 autoinit(mentity, metadata, stats, deps, clients)
562
563 # Package metadata to display
564 var metadata: MPackageMetadata is writable
565
566 # Package stats
567 var stats: MPackageStats is writable
568
569 # Package dependencies
570 var deps: Array[MPackage] is writable
571
572 # Package clients
573 var clients: Array[MPackage] is writable
574
575 redef var id = "metadata_{super}" is lazy
576 redef var title = "Metadata"
577
578 redef fun rendering do
579 for maintainer in metadata.maintainers do
580 addn """
581 <p class='lead'>
582 {{{maintainer.to_html}}}
583 </p>"""
584 end
585 var license = metadata.license
586 if license != null then
587 addn """
588 <span class='text-muted'>
589 <a href='http://opensource.org/licenses/{{{license}}}'>{{{license}}}</a>
590 license
591 </span>"""
592 end
593
594 var homepage = metadata.homepage
595 var browse = metadata.browse
596 var issues = metadata.issues
597 if homepage != null or browse != null or issues != null then
598 addn """
599 <h4>Links</h4>
600 <ul class='list-unstyled'>"""
601 if homepage != null then addn "<li><a href='{homepage}'>Homepage</a></li>"
602 if browse != null then addn "<li><a href='{browse}'>Source Code</a></li>"
603 if issues != null then addn "<li><a href='{issues}'>Issues</a></li>"
604 addn "</ul>"
605 end
606
607 var git = metadata.git
608 var last_date = metadata.last_date
609 var first_date = metadata.first_date
610 if git != null then
611 addn """
612 <h4>Git</h4>
613 <ul class='list-unstyled'>
614 <li><a href='{{{git}}}'>{{{git}}}</a></li>
615 </ul>
616 <span class='text-muted'><b>{{{stats.commits}}}</b> commits</span>
617 <br>"""
618 if last_date != null then
619 addn """<b class=text-muted>Last:</b> {{{last_date}}}<br>"""
620 end
621 if first_date != null then
622 addn """<b class=text-muted>First:</b> {{{first_date}}}"""
623 end
624 end
625
626 addn """
627 <h4>Quality</h4>
628 <ul class='list-unstyled'>
629 <li>{{{stats.documentation_score}}}% documented</li>
630 </ul>"""
631
632 if metadata.tags.not_empty then
633 addn "<h4>Tags</h4>"
634 for tag in metadata.tags do
635 addn " <a href='tag_{tag.to_cmangle}.html'>{tag}</a>"
636 if tag != metadata.tags.last then add ", "
637 end
638 end
639
640 if deps.not_empty then
641 addn "<h4>Dependencies</h4>"
642 for dep in deps do
643 add dep.html_link
644 if dep != deps.last then add ", "
645 end
646 end
647
648 if clients.not_empty then
649 addn "<h4>Clients</h4>"
650 for client in clients do
651 add client.html_link
652 if client != clients.last then add ", "
653 end
654 end
655
656 if metadata.contributors.not_empty then
657 addn """
658 <h4>Contributors</h4>
659 <ul class='list-unstyled'>"""
660 for contrib in metadata.contributors do
661 addn """<li>{{{contrib.to_html}}}</li>"""
662 end
663 addn "</ul>"
664 end
665
666 addn """
667 <h4>Stats</h4>
668 <ul class='list-unstyled'>
669 <li>{{{stats.mmodules}}} modules</li>
670 <li>{{{stats.mclasses}}} classes</li>
671 <li>{{{stats.mmethods}}} methods</li>
672 <li>{{{stats.loc}}} loc</li>
673 </ul>"""
674 end
675 end