4841f02f05634758ed6da6bf7617c4b45bb65c63
1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # Introduces templates that compose the documentation HTML rendering.
19 import html
::bootstrap
20 import doc_phases
::doc_structure
21 import doc_phases
::doc_hierarchies
22 import doc_phases
::doc_graphs
23 import doc_phases
::doc_intros_redefs
24 import doc_phases
::doc_lin
26 # Renders the page as HTML.
31 var html_url
: String is writable, noinit
33 # Directory where css, js and other assets can be found.
34 var shareurl
: String is writable, noinit
36 # Attributes of the body tag element.
37 var body_attrs
= new Array[TagAttribute]
39 # Top menu template if any.
40 var topmenu
: DocTopMenu is writable, noinit
42 # Sidebar template if any.
43 var sidebar
: nullable DocSideBar = null is writable
45 # Footer content if any.
46 var footer
: nullable Writable = null is writable
48 # JS scripts to append at the end of the body
49 var scripts
= new Array[TplScript]
51 # Renders the html `<head>`.
52 private fun render_head
do
53 var css
= (self.shareurl
/ "css").html_escape
54 var vendors
= (self.shareurl
/ "vendors").html_escape
56 addn
"<!DOCTYPE html>"
58 addn
" <meta charset='utf-8'/>"
59 addn
" <!--link rel='stylesheet' href='{css}/Nitdoc.UI.css' type='text/css'/-->"
60 addn
" <link rel='stylesheet' href='{vendors}/bootstrap/css/bootstrap.min.css'/>"
61 addn
" <link rel='stylesheet' href='{css}/nitdoc.bootstrap.css'/>"
62 addn
" <link rel='stylesheet' href='{css}/nitdoc.css'/>"
63 addn
" <link rel='stylesheet' href='{css}/Nitdoc.QuickSearch.css'/>"
64 addn
" <link rel='stylesheet' href='{css}/Nitdoc.ModalBox.css'/>"
65 addn
" <link rel='stylesheet' href='{css}/Nitdoc.GitHub.css'/>"
66 addn
" <title>{title.html_escape}</title>"
69 for attr
in body_attrs
do add attr
73 # Renders the footer and content.
74 private fun render_content
do
76 if footer
!= null then
77 addn
"<div class='well footer'>"
78 add footer
.as(not null)
84 private fun render_footer
do
85 var vendors
= (self.shareurl
/ "vendors").html_escape
86 var js
= (self.shareurl
/ "js").html_escape
88 addn
"<script src='{vendors}/jquery/jquery-1.11.1.min.js'></script>"
89 addn
"<script src='{vendors}/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
90 addn
"<script src='{vendors}/bootstrap/js/bootstrap.min.js'></script>"
91 addn
"<script data-main='{js}/nitdoc' src='{js}/lib/require.js'></script>"
92 for script
in scripts
do add script
95 $("[data-toggle='tooltip']").tooltip();
96 $("[data-toggle='popover']").popover();
103 # Render the whole page
104 redef fun rendering
do
106 addn
"<div class='container-fluid'>"
107 addn
" <div class='row'>"
110 addn
" <div class='row' id='content'>"
111 var sidebar
= self.sidebar
112 if sidebar
!= null then
113 addn
"<div class='col col-xs-3 col-lg-2'>"
116 addn
"<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
120 addn
"<div class='col col-xs-12'>"
129 # Render table of content for this page.
130 fun html_toc
: UnorderedList do
131 var lst
= new UnorderedList
132 lst
.css_classes
.add
"nav"
133 for child
in root
.children
do
134 child
.render_toc_item
(lst
)
140 # Top menu bar template.
142 # FIXME should be a Bootstrap component template
143 # At this moment, the topmenu structure stills to specific to Nitdoc to use the
148 # Brand link to display in first position of the top menu.
150 # This is where you want to put your logo.
151 var brand
: nullable Writable is noinit
, writable
155 # Depends on the current page, this allows to hilighted the current item.
157 # FIXME should be using Boostrap breadcrumbs component.
158 # This will still like this to avoid diff and be changed in further fixes
159 # when we will modify the output.
160 var active_item
: nullable ListItem is noinit
, writable
162 redef fun rendering
do
163 addn
"<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
164 addn
" <div class='container-fluid'>"
165 addn
" <div class='navbar-header'>"
166 add
" <button type='button' class='navbar-toggle' "
167 addn
" data-toggle='collapse' data-target='#topmenu-collapse'>"
168 addn
" <span class='sr-only'>Toggle menu</span>"
169 addn
" <span class='icon-bar'></span>"
170 addn
" <span class='icon-bar'></span>"
171 addn
" <span class='icon-bar'></span>"
173 if brand
!= null then
174 add
"<span class='navbar-brand'>"
175 add brand
.write_to_string
179 addn
" <div class='collapse navbar-collapse' id='topmenu-collapse'>"
180 addn
" <ul class='nav navbar-nav'>"
182 if item
== active_item
then item
.css_classes
.add
"active"
183 add item
.write_to_string
192 # Nitdoc sidebar template.
196 # Sidebar contains `DocSideBox`.
197 var boxes
= new Array[DocSideBox]
199 redef fun rendering
do
200 if boxes
.is_empty
then return
201 addn
"<div id='sidebar'>"
202 for box
in boxes
do add box
207 # Something that can be put in a DocSideBar.
211 # Box HTML id, used for Bootstrap collapsing feature.
213 # Use `html_title.to_cmangle` by default.
214 var id
: String is lazy
do return title
.write_to_string
.to_cmangle
216 # Title of the box to display.
219 # Content to display in the box.
220 var content
: Writable
222 # Is the box opened by default?
224 # Otherwise, the user will have to clic on the title to display the content.
227 var is_open
= true is writable
229 redef fun rendering
do
231 if is_open
then open
= "in"
232 addn
"<div class='panel'>"
233 addn
" <div class='panel-heading'>"
234 add
" <a data-toggle='collapse' data-parent='#sidebar'"
235 add
" data-target='#box_{id}' href='#'>"
239 addn
" <div id='box_{id}' class='summary panel-body collapse {open}'>"
246 redef class DocComposite
250 var html_id
: String is noinit
, writable
252 # Title to display if any.
254 # This title can be decorated with HTML.
255 var html_title
: nullable Writable is noinit
, writable
257 # Subtitle to display if any.
258 var html_subtitle
: nullable Writable is noinit
, writable
260 # Render the element title and subtitle.
261 private fun render_title
do
262 if html_title
!= null then
263 var header
= new Header(hlvl
, html_title
.write_to_string
)
264 header
.css_classes
.add
"signature"
265 if hlvl
== 2 then header
.css_classes
.add
"well well-sm"
268 if html_subtitle
!= null then
269 addn
"<div class='info subtitle'>"
270 addn html_subtitle
.write_to_string
275 # Render the element body.
276 private fun render_body
do
277 for child
in children
do addn child
.write_to_string
280 redef fun rendering
do
281 if is_hidden
then return
286 # Level <hX> for HTML heading.
287 private fun hlvl
: Int do
288 if parent
== null then return 0
289 return parent
.hlvl
+ 1
292 # Is `self` not displayed in the page.
294 # By default, empty elements are hidden.
295 fun is_hidden
: Bool do return is_empty
297 # A short, undecorated title that goes in the table of contents.
299 # By default, returns `html_title.to_s`, subclasses should redefine it.
300 var toc_title
: String is lazy
, writable do return html_title
.to_s
302 # Is `self` hidden in the table of content?
303 var is_toc_hidden
= false is writable
305 # Render this element in a table of contents.
306 private fun render_toc_item
(lst
: UnorderedList) do
307 if is_toc_hidden
then return
309 var content
= new Template
310 content
.add
new Link("#{html_id}", toc_title
)
312 if not children
.is_empty
then
313 var sublst
= new UnorderedList
314 sublst
.css_classes
.add
"nav"
315 for child
in children
do
316 child
.render_toc_item
(sublst
)
320 lst
.add_li
new ListItem(content
)
323 # ID used in HTML tab labels.
325 # We sanitize it for Boostrap JS panels that do not like ":" and "." in ids.
326 var html_tab_id
: String is lazy
do
327 var id
= html_id
.replace
(":", "")
328 id
= id
.replace
(".", "")
333 redef class DocSection
336 redef fun rendering
do
338 addn
"<a id=\"{html_id}\
"></a>"
341 addn
"<section{render_css_classes} id=\"{html_id}\
">"
348 redef class DocArticle
351 redef fun rendering
do
352 if is_hidden
then return
353 addn
"<article{render_css_classes} id=\"{html_id}\
">"
360 redef class TabbedGroup
361 redef fun render_body
do
362 var tabs
= new DocTabs("{html_id}.tabs", "")
363 for child
in children
do
364 if child
.is_hidden
then continue
365 tabs
.add_panel
new DocTabPanel(child
.html_tab_id
, child
.toc_title
, child
)
371 redef class PanelGroup
372 redef var html_id
is lazy
do return "group:{group_title.to_lower.to_snake_case}"
373 redef var html_title
= null
374 redef var toc_title
is lazy
do return group_title
375 redef var is_toc_hidden
= true
378 redef class HomeArticle
379 redef var html_id
= "article:home"
380 redef var html_title
= "Overview"
382 # HTML content to display on the home page.
384 # This attribute is set by the `doc_render` phase who knows the context.
385 var content
: nullable String is noinit
, writable
387 redef fun render_body
do
388 var content
= self.content
389 if content
!= null then add content
394 redef class IndexArticle
395 redef var html_id
= "article:index"
396 redef var html_title
= "Index"
397 redef fun is_empty
do
398 return mmodules
.is_empty
and mclasses
.is_empty
and mprops
.is_empty
401 redef fun render_body
do
402 addn
"<div class='container-fluid'>"
403 addn
" <div class='row'>"
404 render_list
("Modules", mmodules
)
405 render_list
("Classes", mclasses
)
406 render_list
("Properties", mprops
)
411 # Displays a list from the content of `mentities`.
412 private fun render_list
(title
: String, mentities
: Array[MEntity]) do
413 if mentities
.is_empty
then return
414 addn
"<div class='col-xs-4'>"
415 addn
new Header(3, title
)
416 var lst
= new UnorderedList
417 for mentity
in mentities
do
418 if mentity
isa MProperty then
419 var tpl
= new Template
420 tpl
.add mentity
.intro
.html_link
422 tpl
.add mentity
.intro
.mclassdef
.mclass
.html_link
424 lst
.add_li
new ListItem(tpl
)
426 lst
.add_li
new ListItem(mentity
.html_link
)
434 redef class ProjectsSection
435 redef var html_id
= "section:projects"
436 redef var html_title
= "Projects"
439 redef class MEntityComposite
440 redef var html_id
is lazy
do return mentity
.nitdoc_id
441 redef var html_title
is lazy
do return mentity
.nitdoc_name
444 redef class MEntitySection
445 redef var html_id
is lazy
do return "section:{mentity.nitdoc_name}"
446 redef var html_title
is lazy
do return mentity
.html_name
447 redef var html_subtitle
is lazy
do return mentity
.html_declaration
450 redef class ConcernSection
451 redef var html_id
is lazy
do return "concern:{mentity.nitdoc_id}"
452 redef var html_title
is lazy
do return "in {mentity.nitdoc_name}"
453 redef fun is_toc_hidden
do return is_empty
456 redef class ImportationListSection
457 redef var html_id
is lazy
do return "section:{mentity.nitdoc_id}.importation"
458 redef var html_title
is lazy
do return "Dependencies"
461 redef class InheritanceListSection
462 redef var html_id
is lazy
do return "section:{mentity.nitdoc_id}.inheritance"
463 redef var html_title
is lazy
do return "Inheritance"
466 redef class IntroArticle
467 redef var html_id
is lazy
do return "article:{mentity.nitdoc_id}.intro"
468 redef var html_title
= null
469 redef var is_hidden
= false
470 redef var is_toc_hidden
= true
472 # Link to source to display if any.
473 var html_source_link
: nullable Writable is noinit
, writable
475 redef fun render_body
do
476 var tabs
= new DocTabs("{html_id}.tabs", "")
477 var comment
= mentity
.html_comment
478 if comment
!= null then
479 tabs
.add_panel
new DocTabPanel("{html_tab_id}-comment", "Comment", comment
)
481 for child
in children
do
482 if child
.is_hidden
then continue
483 tabs
.add_panel
new DocTabPanel(child
.html_tab_id
, child
.toc_title
, child
)
485 var lnk
= html_source_link
487 tabs
.drop_list
.items
.add
new ListItem(lnk
)
493 redef class ConcernsArticle
494 redef var html_id
is lazy
do return "article:{mentity.nitdoc_id}.concerns"
495 redef var html_title
= "Concerns"
496 redef fun is_hidden
do return concerns
.is_empty
497 redef fun render_body
do add concerns
.html_list
500 redef class DefinitionListArticle
501 redef var html_id
is lazy
do return "article:{mentity.nitdoc_id}.definition-list"
503 redef var html_title
is lazy
do
504 var title
= new Template
505 title
.add mentity
.html_icon
506 title
.add mentity
.html_link
510 redef var html_subtitle
is lazy
do return mentity
.html_namespace
511 redef var toc_title
is lazy
do return mentity
.html_name
514 redef class DefinitionArticle
515 redef var html_id
is lazy
do return "article:{mentity.nitdoc_id}.definition"
516 redef var html_title
is lazy
do return mentity
.html_name
517 redef var html_subtitle
is lazy
do return mentity
.html_declaration
518 redef var is_hidden
= false
520 # Does `self` display only it's title and no body?
523 var is_no_body
: Bool = false is writable
525 # Does `self` display only the short content as definition?
528 var is_short_comment
: Bool = false is writable
530 # Link to source to display if any.
531 var html_source_link
: nullable Writable is noinit
, writable
533 redef fun render_body
do
534 var tabs
= new DocTabs("{html_id}.tabs", "")
535 if not is_no_body
then
537 if is_short_comment
then
538 comment
= mentity
.html_short_comment
540 comment
= mentity
.html_comment
542 if comment
!= null then
543 tabs
.add_panel
new DocTabPanel("{html_tab_id}-comment", "Comment", comment
)
546 for child
in children
do
547 if child
.is_hidden
then continue
548 tabs
.add_panel
new DocTabPanel(child
.html_tab_id
, child
.toc_title
, child
)
550 var lnk
= html_source_link
552 tabs
.drop_list
.items
.add
new ListItem(lnk
)
558 redef class HierarchyListArticle
559 redef var html_id
is lazy
do return "article:{list_title}_{mentity.nitdoc_id}.hierarchy"
560 redef var html_title
is lazy
do return list_title
561 redef fun is_empty
do return mentities
.is_empty
562 redef var is_toc_hidden
= true
564 redef fun render_body
do
565 var lst
= new UnorderedList
566 lst
.css_classes
.add
"list-unstyled list-definition"
567 for mentity
in mentities
do
568 lst
.add_li mentity
.html_list_item
574 redef class IntrosRedefsSection
575 redef var html_id
is lazy
do return "article:{mentity.nitdoc_id}.intros_redefs"
576 redef var toc_title
do return "Intros / Redefs"
577 redef var html_title
= null
578 redef var html_subtitle
= null
579 redef var is_toc_hidden
= true
582 redef class IntrosRedefsListArticle
583 redef var html_id
is lazy
do return "article:{list_title}_{mentity.nitdoc_id}.intros_redefs"
584 redef var html_title
is lazy
do return list_title
585 redef fun is_hidden
do return mentities
.is_empty
586 redef var is_toc_hidden
= true
588 redef fun render_body
do
589 var lst
= new UnorderedList
590 lst
.css_classes
.add
"list-unstyled list-labeled"
591 for mentity
in mentities
do
592 lst
.add_li mentity
.html_list_item
598 redef class DefinitionLinArticle
599 redef var html_id
is lazy
do return "article:{mentity.nitdoc_id}.lin"
600 redef var html_title
is lazy
do return "Linearization"
601 redef fun is_hidden
do return mentities
.is_empty
602 redef var is_toc_hidden
= true
604 redef fun render_body
do
605 var lst
= new UnorderedList
606 lst
.css_classes
.add
"list-unstyled list-labeled"
607 for mentity
in mentities
do
608 if not mentity
isa MPropDef then continue # TODO handle all mentities
609 var tpl
= new Template
610 tpl
.add mentity
.mclassdef
.html_namespace
611 var comment
= mentity
.mclassdef
.html_short_comment
612 if comment
!= null then
616 var li
= new ListItem(tpl
)
617 li
.css_classes
.add
"signature"
624 redef class GraphArticle
625 redef var html_id
is lazy
do return "article:{mentity.nitdoc_id}.graph"
626 redef var html_title
= null
627 redef var toc_title
do return "Graph"
628 redef var is_hidden
= false
629 redef var is_toc_hidden
= true
631 # HTML map used to display link.
633 # This attribute is set by the `doc_render` phase who knows the context.
634 var map
: String is noinit
, writable
636 redef fun render_body
do
637 addn
"<div class=\"text-center\
">"
638 addn
" <img src='{id}.png' usemap='#{id}' style='margin:auto'"
639 addn
" alt='{graph_title}'/>"