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
25 # Renders the page as HTML.
30 var html_url
: String is writable, noinit
32 # Directory where css, js and other assets can be found.
33 var shareurl
: String is writable, noinit
35 # Attributes of the body tag element.
36 var body_attrs
= new Array[TagAttribute]
38 # Top menu template if any.
39 var topmenu
: DocTopMenu is writable, noinit
41 # Sidebar template if any.
42 var sidebar
: nullable DocSideBar = null is writable
44 # Footer content if any.
45 var footer
: nullable Writable = null is writable
47 # JS scripts to append at the end of the body
48 var scripts
= new Array[TplScript]
50 # Renders the html `<head>`.
51 private fun render_head
do
52 var css
= (self.shareurl
/ "css").html_escape
53 var vendors
= (self.shareurl
/ "vendors").html_escape
55 addn
"<!DOCTYPE html>"
57 addn
" <meta charset='utf-8'/>"
58 addn
" <!--link rel='stylesheet' href='{css}/Nitdoc.UI.css' type='text/css'/-->"
59 addn
" <link rel='stylesheet' href='{vendors}/bootstrap/css/bootstrap.min.css'/>"
60 addn
" <link rel='stylesheet' href='{css}/nitdoc.bootstrap.css'/>"
61 addn
" <link rel='stylesheet' href='{css}/nitdoc.css'/>"
62 addn
" <link rel='stylesheet' href='{css}/Nitdoc.QuickSearch.css'/>"
63 addn
" <link rel='stylesheet' href='{css}/Nitdoc.ModalBox.css'/>"
64 addn
" <link rel='stylesheet' href='{css}/Nitdoc.GitHub.css'/>"
65 addn
" <title>{title.html_escape}</title>"
68 for attr
in body_attrs
do add attr
72 # Renders the footer and content.
73 private fun render_content
do
75 if footer
!= null then
76 addn
"<div class='well footer'>"
77 add footer
.as(not null)
83 private fun render_footer
do
84 var vendors
= (self.shareurl
/ "vendors").html_escape
85 var js
= (self.shareurl
/ "js").html_escape
87 addn
"<script src='{vendors}/jquery/jquery-1.11.1.min.js'></script>"
88 addn
"<script src='{vendors}/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
89 addn
"<script src='{vendors}/bootstrap/js/bootstrap.min.js'></script>"
90 addn
"<script data-main='{js}/nitdoc' src='{js}/lib/require.js'></script>"
91 for script
in scripts
do add script
94 $("[data-toggle='tooltip']").tooltip();
95 $("[data-toggle='popover']").popover();
102 # Render the whole page
103 redef fun rendering
do
105 addn
"<div class='container-fluid'>"
106 addn
" <div class='row'>"
109 addn
" <div class='row' id='content'>"
110 var sidebar
= self.sidebar
111 if sidebar
!= null then
112 addn
"<div class='col col-xs-3 col-lg-2'>"
115 addn
"<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
119 addn
"<div class='col col-xs-12'>"
128 # Render table of content for this page.
129 fun html_toc
: UnorderedList do
130 var lst
= new UnorderedList
131 lst
.css_classes
.add
"nav"
132 for child
in root
.children
do
133 child
.render_toc_item
(lst
)
139 # Top menu bar template.
141 # FIXME should be a Bootstrap component template
142 # At this moment, the topmenu structure stills to specific to Nitdoc to use the
147 # Brand link to display in first position of the top menu.
149 # This is where you want to put your logo.
150 var brand
: nullable Writable is noinit
, writable
154 # Depends on the current page, this allows to hilighted the current item.
156 # FIXME should be using Boostrap breadcrumbs component.
157 # This will still like this to avoid diff and be changed in further fixes
158 # when we will modify the output.
159 var active_item
: nullable ListItem is noinit
, writable
161 redef fun rendering
do
162 addn
"<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
163 addn
" <div class='container-fluid'>"
164 addn
" <div class='navbar-header'>"
165 add
" <button type='button' class='navbar-toggle' "
166 addn
" data-toggle='collapse' data-target='#topmenu-collapse'>"
167 addn
" <span class='sr-only'>Toggle menu</span>"
168 addn
" <span class='icon-bar'></span>"
169 addn
" <span class='icon-bar'></span>"
170 addn
" <span class='icon-bar'></span>"
172 if brand
!= null then
173 add
"<span class='navbar-brand'>"
174 add brand
.write_to_string
178 addn
" <div class='collapse navbar-collapse' id='topmenu-collapse'>"
179 addn
" <ul class='nav navbar-nav'>"
181 if item
== active_item
then item
.css_classes
.add
"active"
182 add item
.write_to_string
191 # Nitdoc sidebar template.
195 # Sidebar contains `DocSideBox`.
196 var boxes
= new Array[DocSideBox]
198 redef fun rendering
do
199 if boxes
.is_empty
then return
200 addn
"<div id='sidebar'>"
201 for box
in boxes
do add box
206 # Something that can be put in a DocSideBar.
210 # Box HTML id, used for Bootstrap collapsing feature.
212 # Use `html_title.to_cmangle` by default.
213 var id
: String is lazy
do return title
.write_to_string
.to_cmangle
215 # Title of the box to display.
218 # Content to display in the box.
219 var content
: Writable
221 # Is the box opened by default?
223 # Otherwise, the user will have to clic on the title to display the content.
226 var is_open
= true is writable
228 redef fun rendering
do
230 if is_open
then open
= "in"
231 addn
"<div class='panel'>"
232 addn
" <div class='panel-heading'>"
233 add
" <a data-toggle='collapse' data-parent='#sidebar'"
234 add
" data-target='#box_{id}' href='#'>"
238 addn
" <div id='box_{id}' class='summary panel-body collapse {open}'>"
245 redef class DocComposite
249 var html_id
: String is noinit
, writable
251 # Title to display if any.
253 # This title can be decorated with HTML.
254 var html_title
: nullable Writable is noinit
, writable
256 # Subtitle to display if any.
257 var html_subtitle
: nullable Writable is noinit
, writable
259 # Render the element title and subtitle.
260 private fun render_title
do
261 if html_title
!= null then
262 var header
= new Header(hlvl
, html_title
.write_to_string
)
263 header
.css_classes
.add
"signature"
264 if hlvl
== 2 then header
.css_classes
.add
"well well-sm"
267 if html_subtitle
!= null then
268 addn
"<div class='info subtitle'>"
269 addn html_subtitle
.write_to_string
274 # Render the element body.
275 private fun render_body
do
276 for child
in children
do addn child
.write_to_string
279 redef fun rendering
do
280 if is_hidden
then return
285 # Level <hX> for HTML heading.
286 private fun hlvl
: Int do
287 if parent
== null then return 0
288 return parent
.hlvl
+ 1
291 # Is `self` not displayed in the page.
293 # By default, empty elements are hidden.
294 fun is_hidden
: Bool do return is_empty
296 # A short, undecorated title that goes in the table of contents.
298 # By default, returns `html_title.to_s`, subclasses should redefine it.
299 var toc_title
: String is lazy
, writable do return html_title
.to_s
301 # Is `self` hidden in the table of content?
302 var is_toc_hidden
= false is writable
304 # Render this element in a table of contents.
305 private fun render_toc_item
(lst
: UnorderedList) do
306 if is_toc_hidden
then return
308 var content
= new Template
309 content
.add
new Link("#{html_id}", toc_title
)
311 if not children
.is_empty
then
312 var sublst
= new UnorderedList
313 sublst
.css_classes
.add
"nav"
314 for child
in children
do
315 child
.render_toc_item
(sublst
)
319 lst
.add_li
new ListItem(content
)
323 redef class DocSection
326 redef fun rendering
do
328 addn
"<a id=\"{html_id}\
"></a>"
331 addn
"<section{render_css_classes} id=\"{html_id}\
">"
338 redef class DocArticle
341 redef fun rendering
do
342 if is_hidden
then return
343 addn
"<article{render_css_classes} id=\"{html_id}\
">"
350 redef class HomeArticle
351 redef var html_id
= "intro"
352 redef var html_title
= "Overview"
354 # HTML content to display on the home page.
356 # This attribute is set by the `doc_render` phase who knows the context.
357 var content
: nullable String is noinit
, writable
359 redef fun render_body
do
360 var content
= self.content
361 if content
!= null then add content
366 redef class IndexArticle
367 redef var html_id
= "index"
368 redef var html_title
= "Index"
369 redef fun is_empty
do
370 return mmodules
.is_empty
and mclasses
.is_empty
and mprops
.is_empty
373 redef fun render_body
do
374 addn
"<div class='container-fluid'>"
375 addn
" <div class='row'>"
376 render_list
("Modules", mmodules
)
377 render_list
("Classes", mclasses
)
378 render_list
("Properties", mprops
)
383 # Displays a list from the content of `mentities`.
384 private fun render_list
(title
: String, mentities
: Array[MEntity]) do
385 if mentities
.is_empty
then return
386 addn
"<div class='col-xs-4'>"
387 addn
new Header(3, title
)
388 var lst
= new UnorderedList
389 for mentity
in mentities
do
390 if mentity
isa MProperty then
391 var tpl
= new Template
392 tpl
.add mentity
.intro
.html_link
394 tpl
.add mentity
.intro
.mclassdef
.mclass
.html_link
396 lst
.add_li
new ListItem(tpl
)
398 lst
.add_li
new ListItem(mentity
.html_link
)
406 redef class ProjectsSection
407 redef var html_id
= "projects"
408 redef var html_title
= "Projects"
411 redef class MEntityComposite
412 redef var html_id
is lazy
do return mentity
.nitdoc_id
413 redef var html_title
is lazy
do return mentity
.nitdoc_name
416 redef class MEntitySection
417 redef var html_id
is lazy
do return "section_{mentity.nitdoc_name}"
418 redef var html_title
is lazy
do return mentity
.html_name
419 redef var html_subtitle
is lazy
do return mentity
.html_declaration
422 redef class ConcernSection
423 redef var html_id
is lazy
do return "section_concerns_{mentity.nitdoc_id}"
424 redef var html_title
is lazy
do return "in {mentity.nitdoc_name}"
425 redef fun is_toc_hidden
do return is_empty
428 redef class ImportationListSection
429 redef var html_id
is lazy
do return "section_dependancies_{mentity.nitdoc_id}"
430 redef var html_title
is lazy
do return "Dependencies"
433 redef class InheritanceListSection
434 redef var html_id
is lazy
do return "section_inheritance_{mentity.nitdoc_id}"
435 redef var html_title
is lazy
do return "Inheritance"
438 redef class IntroArticle
439 redef var html_id
is lazy
do return "article_intro_{mentity.nitdoc_id}"
440 redef var html_title
= null
441 redef var is_hidden
= false
442 redef var is_toc_hidden
= true
444 redef fun render_body
do
445 var comment
= mentity
.html_comment
446 if comment
!= null then addn comment
451 redef class ConcernsArticle
452 redef var html_id
is lazy
do return "article_concerns_{mentity.nitdoc_id}"
453 redef var html_title
= "Concerns"
454 redef fun is_hidden
do return concerns
.is_empty
455 redef fun render_body
do add concerns
.html_list
458 redef class DefinitionArticle
459 redef var html_id
is lazy
do return "article_definition_{mentity.nitdoc_id}"
460 redef var html_title
is lazy
do return mentity
.html_name
461 redef var html_subtitle
is lazy
do return mentity
.html_declaration
462 redef var is_hidden
= false
464 # Does `self` display only it's title and no body?
467 var is_no_body
: Bool = false is writable
469 # Does `self` display only the short content as definition?
472 var is_short_comment
: Bool = false is writable
474 redef fun render_body
do
475 if not is_no_body
then
477 if is_short_comment
then
478 comment
= mentity
.html_short_comment
480 comment
= mentity
.html_comment
482 if comment
!= null then addn comment
488 redef class HierarchyListArticle
489 redef var html_id
is lazy
do return "article_hierarchy_{list_title}_{mentity.nitdoc_id}"
490 redef var html_title
is lazy
do return list_title
491 redef fun is_empty
do return mentities
.is_empty
492 redef fun is_toc_hidden
do return mentities
.is_empty
494 redef fun render_body
do
495 var lst
= new UnorderedList
496 lst
.css_classes
.add
"list-unstyled list-definition"
497 for mentity
in mentities
do
498 lst
.add_li mentity
.html_list_item
504 redef class IntrosRedefsListArticle
505 redef var html_id
is lazy
do return "article_intros_redefs_{mentity.nitdoc_id}"
506 redef var html_title
is lazy
do return list_title
507 redef fun is_hidden
do return mentities
.is_empty
508 redef var is_toc_hidden
= true
510 redef fun render_body
do
511 var lst
= new UnorderedList
512 lst
.css_classes
.add
"list-unstyled list-labeled"
513 for mentity
in mentities
do
514 lst
.add_li mentity
.html_list_item
520 redef class GraphArticle
521 redef var html_id
is lazy
do return "article_graph_{mentity.nitdoc_id}"
522 redef var html_title
= null
523 redef var toc_title
do return "Graph"
524 redef var is_hidden
= false
525 redef var is_toc_hidden
= true
527 # HTML map used to display link.
529 # This attribute is set by the `doc_render` phase who knows the context.
530 var map
: String is noinit
, writable
532 redef fun render_body
do
533 addn
"<div class=\"text-center\
">"
534 addn
" <img src='{id}.png' usemap='#{id}' style='margin:auto'"
535 addn
" alt='{graph_title}'/>"