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 # Documentation generator for the nit language.
16 # Generate API documentation in HTML format from nit source code.
20 import modelize_property
24 # The NitdocContext contains all the knowledge used for doc generation
27 private var toolcontext
= new ToolContext
28 private var mbuilder
: ModelBuilder
29 private var mainmodule
: MModule
30 private var output_dir
: String
31 private var min_visibility
: MVisibility
33 private var opt_dir
= new OptionString("output directory", "-d", "--dir")
34 private var opt_source
= new OptionString("link for source (%f for filename, %l for first line, %L for last line)", "--source")
35 private var opt_sharedir
= new OptionString("directory containing nitdoc assets", "--sharedir")
36 private var opt_shareurl
= new OptionString("use shareurl instead of copy shared files", "--shareurl")
37 private var opt_nodot
= new OptionBool("do not generate graphes with graphviz", "--no-dot")
38 private var opt_private
= new OptionBool("also generate private API", "--private")
40 private var opt_custom_title
= new OptionString("custom title for homepage", "--custom-title")
41 private var opt_custom_menu
= new OptionString("custom items added in top menu (each item must be enclosed in 'li' tags)", "--custom-menu-items")
42 private var opt_custom_intro
= new OptionString("custom intro text for homepage", "--custom-overview-text")
43 private var opt_custom_footer
= new OptionString("custom footer text", "--custom-footer-text")
45 private var opt_github_upstream
= new OptionString("Git branch where edited commits will be pulled into (ex: user:repo:branch)", "--github-upstream")
46 private var opt_github_base_sha1
= new OptionString("Git sha1 of base commit used to create pull request", "--github-base-sha1")
47 private var opt_github_gitdir
= new OptionString("Git working directory used to resolve path name (ex: /home/me/myproject/)", "--github-gitdir")
49 private var opt_piwik_tracker
= new OptionString("Piwik tracker URL (ex: nitlanguage.org/piwik/)", "--piwik-tracker")
50 private var opt_piwik_site_id
= new OptionString("Piwik site ID", "--piwik-site-id")
53 var opts
= toolcontext
.option_context
54 opts
.add_option
(opt_dir
, opt_source
, opt_sharedir
, opt_shareurl
, opt_nodot
, opt_private
)
55 opts
.add_option
(opt_custom_title
, opt_custom_footer
, opt_custom_intro
, opt_custom_menu
)
56 opts
.add_option
(opt_github_upstream
, opt_github_base_sha1
, opt_github_gitdir
)
57 opts
.add_option
(opt_piwik_tracker
, opt_piwik_site_id
)
59 var tpl
= new Template
60 tpl
.add
"Usage: nitdoc [OPTION]... <file.nit>...\n"
61 tpl
.add
"Generates HTML pages of API documentation from Nit source files."
62 toolcontext
.tooldescription
= tpl
.write_to_string
63 toolcontext
.process_options
(args
)
66 self.parse
(toolcontext
.option_context
.rest
)
69 private fun process_options
do
70 if opt_private
.value
then
71 min_visibility
= none_visibility
73 min_visibility
= protected_visibility
75 var gh_upstream
= opt_github_upstream
.value
76 var gh_base_sha
= opt_github_base_sha1
.value
77 var gh_gitdir
= opt_github_gitdir
.value
78 if not gh_upstream
== null or not gh_base_sha
== null or not gh_gitdir
== null then
79 if gh_upstream
== null or gh_base_sha
== null or gh_gitdir
== null then
80 print
"Error: Options {opt_github_upstream.names.first}, {opt_github_base_sha1.names.first} and {opt_github_gitdir.names.first} are required to enable the GitHub plugin"
86 private fun parse
(arguments
: Array[String]) do
88 mbuilder
= new ModelBuilder(model
, toolcontext
)
89 var mmodules
= mbuilder
.parse
(arguments
)
90 if mmodules
.is_empty
then return
92 if mmodules
.length
== 1 then
93 mainmodule
= mmodules
.first
95 mainmodule
= new MModule(model
, null, "<main>", new Location(null, 0, 0, 0, 0))
96 mainmodule
.set_imported_mmodules
(mmodules
)
100 private fun generate_nitdoc
do
109 private fun init_output_dir
do
110 # location output dir
111 var output_dir
= opt_dir
.value
112 if output_dir
== null then
115 self.output_dir
= output_dir
116 # create destination dir if it's necessary
117 if not output_dir
.file_exists
then output_dir
.mkdir
119 var sharedir
= opt_sharedir
.value
120 if sharedir
== null then
121 var dir
= toolcontext
.nit_dir
123 print
"Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
126 sharedir
= "{dir}/share/nitdoc"
127 if not sharedir
.file_exists
then
128 print
"Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
133 if opt_shareurl
.value
== null then
134 sys
.system
("cp -r {sharedir.to_s}/* {output_dir.to_s}/")
136 sys
.system
("cp -r {sharedir.to_s}/resources/ {output_dir.to_s}/resources/")
141 private fun overview
do
142 var overviewpage
= new NitdocOverview(self)
143 overviewpage
.render
.write_to_file
("{output_dir.to_s}/index.html")
146 private fun search
do
147 var searchpage
= new NitdocSearch(self)
148 searchpage
.render
.write_to_file
("{output_dir.to_s}/search.html")
151 private fun modules
do
152 for mmodule
in mbuilder
.model
.mmodules
do
153 if mmodule
.name
== "<main>" then continue
154 var modulepage
= new NitdocModule(mmodule
, self)
155 modulepage
.render
.write_to_file
("{output_dir.to_s}/{mmodule.nitdoc_url}")
159 private fun classes
do
160 for mclass
in mbuilder
.model
.mclasses
do
161 var classpage
= new NitdocClass(mclass
, self)
162 classpage
.render
.write_to_file
("{output_dir.to_s}/{mclass.nitdoc_url}")
166 private fun quicksearch_list
do
167 var quicksearch
= new QuickSearch(self)
168 quicksearch
.render
.write_to_file
("{output_dir.to_s}/quicksearch-list.js")
172 # Nitdoc QuickSearch list generator
174 # Create a JSON object containing links to:
178 # All entities are grouped by name to make the research easier.
181 private var mmodules
= new HashSet[MModule]
182 private var mclasses
= new HashSet[MClass]
183 private var mpropdefs
= new HashMap[String, Set[MPropDef]]
185 init(ctx
: NitdocContext) do
186 for mmodule
in ctx
.mbuilder
.model
.mmodules
do
187 if mmodule
.name
== "<main>" then continue
190 for mclass
in ctx
.mbuilder
.model
.mclasses
do
191 if mclass
.visibility
< ctx
.min_visibility
then continue
194 for mproperty
in ctx
.mbuilder
.model
.mproperties
do
195 if mproperty
.visibility
< ctx
.min_visibility
then continue
196 if mproperty
isa MAttribute then continue
197 if not mpropdefs
.has_key
(mproperty
.name
) then
198 mpropdefs
[mproperty
.name
] = new HashSet[MPropDef]
200 mpropdefs
[mproperty
.name
].add_all
(mproperty
.mpropdefs
)
204 fun render
: Template do
205 var tpl
= new Template
206 tpl
.add
"var nitdocQuickSearchRawList=\{ "
207 for mmodule
in mmodules
do
208 tpl
.add
"\"{mmodule.name}\
":["
209 tpl
.add
"\{txt:\"{mmodule.full_name}\",url
:\
"{mmodule.nitdoc_url}\"\
},"
212 for mclass in mclasses do
213 var full_name = mclass.intro.mmodule.full_name
214 tpl.add "\
"{mclass.name}\":["
215 tpl.add "\
{txt:\"{full_name}\
",url:\"{mclass.nitdoc_url}\
"\},"
218 for mproperty
, mprops
in mpropdefs
do
219 tpl
.add
"\"{mproperty}\
":["
220 for mpropdef
in mprops
do
221 var full_name
= mpropdef
.mclassdef
.mclass
.full_name
222 tpl
.add
"\{txt:\"{full_name}\",url
:\
"{mpropdef.nitdoc_url}\"\
},"
232 # Define page structure and properties
233 abstract class NitdocPage
235 private var ctx: NitdocContext
236 private var shareurl = "."
238 init(ctx: NitdocContext) do
240 if ctx.opt_shareurl.value != null then shareurl = ctx.opt_shareurl.value.as(not null)
243 # Render the page as a html template
244 fun render: Template do
245 var tpl = new TplNitdocPage
247 tpl.topmenu = tpl_topmenu
248 tpl.sidebar = tpl_sidebar
249 tpl.content = tpl_content
250 tpl.footer = tpl_footer
252 tpl.body_attrs.add(new TagAttribute("data-bootstrap-share
", shareurl))
253 if ctx.opt_github_upstream.value != null and ctx.opt_github_base_sha1.value != null then
254 tpl.body_attrs.add(new TagAttribute("data-github-upstream
", ctx.opt_github_upstream.value))
255 tpl.body_attrs.add(new TagAttribute("data-github-base-sha1
", ctx.opt_github_base_sha1.value))
257 var requirejs = new TplScript
258 requirejs.attrs.add(new TagAttribute("data-main
", "{shareurl}/js
/nitdoc
"))
259 requirejs.attrs.add(new TagAttribute("src
", "{shareurl}/js
/lib
/require
.js
"))
260 tpl.scripts.add requirejs
263 var tracker_url = ctx.opt_piwik_tracker.value
264 var site_id = ctx.opt_piwik_site_id.value
265 if tracker_url != null and site_id != null then
266 tpl.scripts.add new TplPiwikScript(tracker_url, site_id)
272 fun tpl_title: String do
273 if ctx.opt_custom_title.value != null then
274 return ctx.opt_custom_title.value.to_s
280 # Page <head> template
281 fun tpl_head: TplHead do return new TplHead(tpl_title, shareurl)
284 fun tpl_topmenu: TplTopMenu do
285 var topmenu = new TplTopMenu
286 var custom_elt = ctx.opt_custom_menu.value
287 if custom_elt != null then topmenu.add_raw(custom_elt)
291 # Page sidebar template
292 # return null if no sidebar for this page
293 fun tpl_sidebar: nullable TplSidebar do return null
295 # Page content template
296 fun tpl_content: Template is abstract
298 # Page footer template
299 # return null if no footer for this page
300 fun tpl_footer: nullable TplFooter do
301 if ctx.opt_custom_footer.value != null then
302 return new TplFooter(ctx.opt_custom_footer.value.to_s)
307 # Clickable graphviz image using dot format
308 # return null if no graph for this page
309 fun tpl_graph(dot: FlatBuffer, name: String, alt: String): nullable TplGraph do
310 if ctx.opt_nodot.value then return null
311 var output_dir = ctx.output_dir
312 var file = new OFStream.open("{output_dir}/{name}.dot
")
315 sys.system("\
{ test -f {output_dir}/{name}.png
&& test
-f
{output_dir}/{name}.s
.dot
&& diff
{output_dir}/{name}.dot
{output_dir}/{name}.s
.dot
>/dev
/null 2>&1 ; \
} || \
{ cp {output_dir}/{name}.dot
{output_dir}/{name}.s
.dot
&& dot
-Tpng -o
{output_dir}/{name}.png
-Tcmapx -o
{output_dir}/{name}.map
{output_dir}/{name}.s
.dot
; \
}")
316 var fmap = new IFStream.open("{output_dir}/{name}.map
")
317 var map = fmap.read_all
319 return new TplGraph(name, alt, map)
322 # A (source) link template for a given location
323 fun tpl_showsource(location: nullable Location): nullable String
325 if location == null then return null
326 var source = ctx.opt_source.value
327 if source == null then return "({location.file.filename.simplify_path})"
328 # THIS IS JUST UGLY ! (but there is no replace yet)
329 var x = source.split_with("%f
")
330 source = x.join(location.file.filename.simplify_path)
331 x = source.split_with("%l
")
332 source = x.join(location.line_start.to_s)
333 x = source.split_with("%L
")
334 source = x.join(location.line_end.to_s)
335 source = source.simplify_path
336 return " (<a target
='_blank' title
='Show source' href
=\
"{source.to_s}\">source
</a
>)"
339 # MClassDef description template
340 fun tpl_mclassdef_article(mclassdef: MClassDef): TplArticle do
341 var article = mclassdef.tpl_article
342 article.content = new Template
343 if not mclassdef.is_intro then
345 var intro = mclassdef.mclass.intro
346 var location = intro.location
347 var sourcelink = tpl_showsource(location)
348 var intro_def = intro.tpl_short_definition
349 intro_def.location = sourcelink
350 intro_def.github_area = tpl_github(intro.full_namespace, intro.mdoc, location)
351 article.content.add intro_def
353 # add mclassdef full description
354 var location = mclassdef.location
355 var sourcelink = tpl_showsource(location)
356 var prop_def = mclassdef.tpl_definition
357 prop_def.location = sourcelink
358 prop_def.github_area = tpl_github(mclassdef.full_namespace, mclassdef.mdoc, location)
359 article.content.add prop_def
363 # MPropDef description template
364 fun tpl_mpropdef_article(mpropdef: MPropDef): TplArticle do
365 var article = mpropdef.tpl_article
366 article.content = new Template
367 if not mpropdef.is_intro then
369 var intro = mpropdef.mproperty.intro
370 var location = intro.location
371 var sourcelink = tpl_showsource(location)
372 var intro_def = intro.tpl_short_definition
373 intro_def.location = sourcelink
374 intro_def.github_area = tpl_github(intro.full_namespace, intro.mdoc, location)
375 article.content.add intro_def
377 # add mpropdef description
378 var location = mpropdef.location
379 var sourcelink = tpl_showsource(location)
380 var prop_def = mpropdef.tpl_definition
381 prop_def.location = sourcelink
382 prop_def.github_area = tpl_github(mpropdef.full_namespace, mpropdef.mdoc, location)
383 article.content.add prop_def
387 # Github area (for Github comment edition plugin)
388 # return null if no github plugin for this page
389 fun tpl_github(namespace: String, mdoc: nullable MDoc, loc: nullable Location): nullable TplGithubArea do
390 if loc == null then return null
391 if ctx.opt_github_gitdir.value == null then return null
392 var gitdir = ctx.opt_github_gitdir.value.as(not null)
393 var location = loc.github(gitdir)
396 comment = mdoc.full_comment
400 return new TplGithubArea(comment, namespace, location)
405 # Display a list of modules contained in program
409 private var mmodules = new Array[MModule]
411 init(ctx: NitdocContext) do
414 var mmodules = new HashSet[MModule]
415 for mmodule in ctx.mbuilder.model.mmodule_importation_hierarchy do
416 if mmodule.name == "<main
>" then continue
417 var owner = mmodule.public_owner
418 if owner != null then
421 mmodules.add(mmodule)
425 var sorter = new MModuleNameSorter
426 self.mmodules.add_all(mmodules)
427 sorter.sort(self.mmodules)
430 redef fun tpl_title do return "Overview | {super}"
432 redef fun tpl_topmenu do
434 topmenu.add_elt("#", "Overview", true)
435 topmenu
.add_elt
("search.html", "Search", false)
439 redef fun tpl_content
do
440 var tpl
= new TplOverviewPage
442 if ctx
.opt_custom_title
.value
!= null then
443 tpl
.title
= ctx
.opt_custom_title
.value
.to_s
445 tpl
.title
= "Overview"
448 if ctx
.opt_custom_intro
.value
!= null then
449 tpl
.text
= ctx
.opt_custom_intro
.value
.to_s
452 for mmodule
in mmodules
do
453 if mmodule
.mdoc
!= null then
454 var mtpl
= new Template
455 mtpl
.add mmodule
.tpl_link
457 mtpl
.add mmodule
.mdoc
.short_comment
466 # Genrate dot and template for module hierarchy
467 fun tpl_dot
: nullable TplGraph do
468 # build poset with public owners
469 var poset
= new POSet[MModule]
470 for mmodule
in mmodules
do
471 poset
.add_node
(mmodule
)
472 for omodule
in mmodules
do
473 if mmodule
== omodule
then continue
474 if mmodule
.in_importation
< omodule
then
475 poset
.add_node
(omodule
)
476 poset
.add_edge
(mmodule
, omodule
)
481 var op
= new FlatBuffer
482 op
.append
("digraph dep \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
483 for mmodule
in poset
do
484 op
.append
("\"{mmodule.name}\
"[URL=\"{mmodule.nitdoc_url}\
"];\n")
485 for omodule
in poset
[mmodule
].direct_greaters
do
486 op
.append
("\"{mmodule.name}\
"->\"{omodule.name}\
";\n")
490 return tpl_graph
(op
, "dep", "Modules hierarchy")
495 # Display a list of modules, classes and properties
499 init(ctx
: NitdocContext) do super(ctx
)
501 redef fun tpl_title
do return "Search | {super}"
503 redef fun tpl_topmenu
do
505 topmenu
.add_elt
("index.html", "Overview", false)
506 topmenu
.add_elt
("#", "Search", true)
510 redef fun tpl_content
do
511 var tpl
= new TplSearchPage
515 for mmodule
in modules_list
do
516 tpl
.modules
.add mmodule
.tpl_link
519 for mclass
in classes_list
do
520 tpl
.classes
.add mclass
.tpl_link
523 for mproperty
in mprops_list
do
525 m
.add mproperty
.intro
.tpl_link
527 m
.add mproperty
.intro
.mclassdef
.mclass
.tpl_link
534 # Extract mmodule list to display (sorted by name)
535 private fun modules_list
: Array[MModule] do
536 var sorted
= new Array[MModule]
537 for mmodule
in ctx
.mbuilder
.model
.mmodule_importation_hierarchy
do
538 if mmodule
.name
== "<main>" then continue
541 var sorter
= new MModuleNameSorter
546 # Extract mclass list to display (sorted by name)
547 private fun classes_list
: Array[MClass] do
548 var sorted
= new Array[MClass]
549 for mclass
in ctx
.mbuilder
.model
.mclasses
do
550 if mclass
.visibility
< ctx
.min_visibility
then continue
553 var sorter
= new MClassNameSorter
558 # Extract mproperty list to display (sorted by name)
559 private fun mprops_list
: Array[MProperty] do
560 var sorted
= new Array[MProperty]
561 for mproperty
in ctx
.mbuilder
.model
.mproperties
do
562 if mproperty
.visibility
< ctx
.min_visibility
then continue
563 if mproperty
isa MAttribute then continue
566 var sorter
= new MPropertyNameSorter
573 # Display the list of introduced and redefined classes in module
577 private var mmodule
: MModule
578 private var intro_mclassdefs
: Set[MClassDef]
579 private var redef_mclassdefs
: Set[MClassDef]
580 private var sorted_intro_mclassdefs
: Array[MClassDef]
581 private var sorted_redef_mclassdefs
: Array[MClassDef]
583 init(mmodule
: MModule, ctx
: NitdocContext) do
584 self.mmodule
= mmodule
585 var sorter
= new MClassDefNameSorter
586 intro_mclassdefs
= in_nesting_intro_mclassdefs
(ctx
.min_visibility
)
587 sorted_intro_mclassdefs
= intro_mclassdefs
.to_a
588 sorter
.sort sorted_intro_mclassdefs
589 redef_mclassdefs
= in_nesting_redef_mclassdefs
(ctx
.min_visibility
)
590 sorted_redef_mclassdefs
= redef_mclassdefs
.to_a
591 sorter
.sort sorted_redef_mclassdefs
595 redef fun tpl_title
do
596 if mmodule
.mdoc
!= null then
597 return "{mmodule.nitdoc_name} module | {mmodule.mdoc.short_comment} | {super}"
599 return "{mmodule.nitdoc_name} module | {super}"
603 redef fun tpl_topmenu
do
605 topmenu
.add_elt
("index.html", "Overview", false)
606 topmenu
.add_elt
("#", "{mmodule.nitdoc_name}", true)
607 topmenu
.add_elt
("search.html", "Search", false)
611 redef fun tpl_sidebar
do
612 var sidebar
= new TplSidebar
613 tpl_sidebar_classes
(sidebar
)
614 tpl_sidebar_inheritance
(sidebar
)
618 # Classes to display on sidebar
619 fun tpl_sidebar_classes
(sidebar
: TplSidebar) do
620 var box
= new TplSidebarBox("Class Definitions")
621 var group
= new TplSidebarGroup("Introductions")
622 for mclassdef
in sorted_intro_mclassdefs
do
623 tpl_sidebar_item
(mclassdef
, group
)
626 group
= new TplSidebarGroup("Refinements")
627 for mclassdef
in sorted_redef_mclassdefs
do
628 if intro_mclassdefs
.has
(mclassdef
.mclass
.intro
) then continue
629 tpl_sidebar_item
(mclassdef
, group
)
632 sidebar
.boxes
.add box
635 # Module inheritance to display on sidebar
636 fun tpl_sidebar_inheritance
(sidebar
: TplSidebar) do
637 var box
= new TplSidebarBox("Module Hierarchy")
638 box
.elts
.add tpl_sidebar_group
("Nested Modules", mmodule
.in_nesting
.direct_greaters
.to_a
)
639 var dependencies
= new Array[MModule]
640 for dep
in mmodule
.in_importation
.greaters
do
642 dep
.direct_owner
== mmodule
or
643 dep
.public_owner
== mmodule
then continue
644 dependencies
.add
(dep
)
646 if dependencies
.length
> 0 then
647 box
.elts
.add tpl_sidebar_group
("All dependencies", dependencies
)
649 var clients
= new Array[MModule]
650 for dep
in mmodule
.in_importation
.smallers
do
651 if dep
.name
== "<main>" then continue
652 if dep
== mmodule
then continue
655 if clients
.length
> 0 then
656 box
.elts
.add tpl_sidebar_group
("All clients", clients
)
658 sidebar
.boxes
.add box
661 private fun tpl_sidebar_item
(mclassdef
: MClassDef, group
: TplSidebarGroup) do
662 if mclassdef
.is_intro
then
663 group
.add_bullet
("I", "Introduced", mclassdef
.tpl_link_anchor
, ["intro"])
665 group
.add_bullet
("R", "Redefined", mclassdef
.tpl_link_anchor
, ["redef"])
669 private fun tpl_sidebar_group
(name
: String, elts
: Array[MModule]): TplSidebarGroup do
670 var group
= new TplSidebarGroup(name
)
672 group
.add_elt
(elt
.tpl_link
, new Array[String])
677 redef fun tpl_content
do
678 var class_sorter
= new MClassNameSorter
679 var tpl
= new TplModulePage
680 tpl
.title
= mmodule
.nitdoc_name
681 tpl
.subtitle
= mmodule
.tpl_signature
682 tpl
.definition
= mmodule
.tpl_definition
683 var location
= mmodule
.location
684 tpl
.definition
.location
= tpl_showsource
(location
)
685 tpl
.definition
.github_area
= tpl_github
(mmodule
.full_namespace
, mmodule
.mdoc
, location
)
687 for mclassdef
in sorted_intro_mclassdefs
do tpl
.intros
.add tpl_mclassdef_article
(mclassdef
)
688 for mclassdef
in sorted_redef_mclassdefs
do
689 if intro_mclassdefs
.has
(mclassdef
.mclass
.intro
) then continue
690 tpl
.redefs
.add tpl_mclassdef_article
(mclassdef
)
695 # Genrate dot hierarchy for class inheritance
696 fun tpl_dot
: nullable TplGraph do
697 # build poset with public owners
698 var poset
= new POSet[MModule]
699 for mmodule
in self.mmodule
.in_importation
.poset
do
700 if mmodule
.name
== "<main>" then continue
701 #if mmodule.public_owner != null then continue
702 if not mmodule
.in_importation
< self.mmodule
and not self.mmodule
.in_importation
< mmodule
and mmodule
!= self.mmodule
then continue
703 poset
.add_node
(mmodule
)
704 for omodule
in mmodule
.in_importation
.poset
do
705 if mmodule
== omodule
then continue
706 if omodule
.name
== "<main>" then continue
707 if not omodule
.in_importation
< self.mmodule
and not self.mmodule
.in_importation
< omodule
then continue
708 if omodule
.in_importation
< mmodule
then
709 poset
.add_node
(omodule
)
710 poset
.add_edge
(omodule
, mmodule
)
712 if mmodule
.in_importation
< omodule
then
713 poset
.add_node
(omodule
)
714 poset
.add_edge
(mmodule
, omodule
)
716 #if omodule.public_owner != null then continue
717 #if mmodule.in_importation < omodule then
718 #poset.add_node(omodule)
719 #poset.add_edge(mmodule, omodule)
724 var op
= new FlatBuffer
725 var name
= "dep_{mmodule.name}"
726 op
.append
("digraph {name} \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
727 for mmodule
in poset
do
728 if mmodule
== self.mmodule
then
729 op
.append
("\"{mmodule.name}\
"[shape=box,margin=0.03];\n")
731 op
.append
("\"{mmodule.name}\
"[URL=\"{mmodule.nitdoc_url}\
"];\n")
733 for omodule
in poset
[mmodule
].direct_greaters
do
734 op
.append
("\"{mmodule.name}\
"->\"{omodule.name}\
";\n")
738 return tpl_graph
(op
, name
, "Dependency graph for module {mmodule.name}")
741 private fun in_nesting_intro_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
742 var res
= new HashSet[MClassDef]
743 for mmodule
in self.mmodule
.in_nesting
.greaters
do
744 res
.add_all mmodule
.intro_mclassdefs
(min_visibility
)
749 private fun in_nesting_redef_mclassdefs
(min_visibility
: MVisibility): Set[MClassDef] do
750 var res
= new HashSet[MClassDef]
751 for mmodule
in self.mmodule
.in_nesting
.greaters
do
752 res
.add_all mmodule
.redef_mclassdefs
(min_visibility
)
759 # Display a list properties defined or redefined for this class
763 private var mclass
: MClass
764 private var inherited_mpropdefs
: Set[MPropDef]
765 private var intro_mpropdefs
: Set[MPropDef]
766 private var redef_mpropdefs
: Set[MPropDef]
767 private var all_mpropdefs
: Set[MPropDef]
769 init(mclass
: MClass, ctx
: NitdocContext) do
772 intro_mpropdefs
= mclass_intro_mpropdefs
773 redef_mpropdefs
= mclass_redef_mpropdefs
774 inherited_mpropdefs
= in_nesting_inherited_mpropedefs
775 all_mpropdefs
= new HashSet[MPropDef]
776 all_mpropdefs
.add_all intro_mpropdefs
777 all_mpropdefs
.add_all redef_mpropdefs
778 all_mpropdefs
.add_all inherited_mpropdefs
781 private fun in_nesting_inherited_mpropedefs
: Set[MPropDef] do
782 var res
= new HashSet[MPropDef]
783 var local
= mclass
.local_mproperties
(ctx
.min_visibility
)
784 for mprop
in mclass
.inherited_mproperties
(ctx
.mainmodule
, ctx
.min_visibility
) do
785 if local
.has
(mprop
) then continue
786 if mprop
isa MMethod and mprop
.is_init
then continue
792 private fun mclass_intro_mpropdefs
: Set[MPropDef] do
793 var res
= new HashSet[MPropDef]
794 for mclassdef
in mclass
.mclassdefs
do
795 var owner
= mclassdef
.mmodule
.public_owner
796 if owner
== null then owner
= mclassdef
.mmodule
797 for mpropdef
in mclassdef
.mpropdefs
do
798 if not mpropdef
.is_intro
then continue
799 if owner
!= mclass
.public_owner
then continue
800 var mprop
= mpropdef
.mproperty
801 if mprop
isa MMethod and mprop
.is_init
and mclass
.is_abstract
then continue
802 if mprop
.visibility
< ctx
.min_visibility
then continue
809 private fun mclass_redef_mpropdefs
: Set[MPropDef] do
810 var res
= new HashSet[MPropDef]
811 for mclassdef
in mclass
.mclassdefs
do
812 if mclassdef
== mclass
.intro
then continue
813 var owner
= mclassdef
.mmodule
.public_owner
814 if owner
== null then owner
= mclassdef
.mmodule
815 for mpropdef
in mclassdef
.mpropdefs
do
816 if owner
== mclass
.public_owner
then continue
817 if mpropdef
.mproperty
.visibility
< ctx
.min_visibility
then continue
824 redef fun tpl_title
do
825 if mclass
.mdoc
!= null then
826 return "{mclass.nitdoc_name} class | {mclass.mdoc.short_comment} | {super}"
828 return "{mclass.nitdoc_name} class | {super}"
832 redef fun tpl_topmenu
do
835 if mclass
.public_owner
== null then
836 mmodule
= mclass
.intro_mmodule
838 mmodule
= mclass
.public_owner
.as(not null)
840 topmenu
.add_elt
("index.html", "Overview", false)
841 topmenu
.add_elt
("{mmodule.nitdoc_url}", "{mmodule.nitdoc_name}", false)
842 topmenu
.add_elt
("#", "{mclass.nitdoc_name}", true)
843 topmenu
.add_elt
("search.html", "Search", false)
847 redef fun tpl_sidebar
do
848 var sidebar
= new TplSidebar
849 tpl_sidebar_properties
(sidebar
)
850 tpl_sidebar_inheritance
(sidebar
)
854 # Property list to display in sidebar
855 fun tpl_sidebar_properties
(sidebar
: TplSidebar) do
856 var kind_map
= sort_by_kind
(all_mpropdefs
)
857 var sorter
= new MPropDefNameSorter
858 var box
= new TplSidebarBox("Properties")
860 var elts
= kind_map
["type"].to_a
862 var group
= new TplSidebarGroup("Virtual Types")
864 tpl_sidebar_item
(mprop
, group
)
868 elts
= kind_map
["init"].to_a
870 group
= new TplSidebarGroup("Constructors")
872 tpl_sidebar_item
(mprop
, group
)
876 elts
= kind_map
["fun"].to_a
878 group
= new TplSidebarGroup("Methods")
880 tpl_sidebar_item
(mprop
, group
)
883 sidebar
.boxes
.add box
886 # Class inheritance to display in sidebar
887 fun tpl_sidebar_inheritance
(sidebar
: TplSidebar) do
888 var sorted
= new Array[MClass]
889 var sorterp
= new MClassNameSorter
890 var box
= new TplSidebarBox("Inheritance")
891 var greaters
= mclass
.in_hierarchy
(ctx
.mainmodule
).greaters
.to_a
892 if greaters
.length
> 1 then
893 ctx
.mainmodule
.linearize_mclasses
(greaters
)
894 box
.elts
.add tpl_sidebar_group
("Superclasses", greaters
)
896 var smallers
= mclass
.in_hierarchy
(ctx
.mainmodule
).smallers
.to_a
897 var direct_smallers
= mclass
.in_hierarchy
(ctx
.mainmodule
).direct_smallers
.to_a
898 if smallers
.length
<= 1 then
899 box
.elts
.add
(new TplSidebarGroup("No Known Subclasses"))
900 else if smallers
.length
<= 100 then
901 ctx
.mainmodule
.linearize_mclasses
(smallers
)
902 box
.elts
.add tpl_sidebar_group
("Subclasses", smallers
)
903 else if direct_smallers
.length
<= 100 then
904 ctx
.mainmodule
.linearize_mclasses
(direct_smallers
)
905 box
.elts
.add tpl_sidebar_group
("Direct Subclasses Only", direct_smallers
)
907 box
.elts
.add
(new TplSidebarGroup("Too much Subclasses to list"))
909 sidebar
.boxes
.add box
912 private fun tpl_sidebar_item
(mprop
: MPropDef, group
: TplSidebarGroup) do
913 if mprop
.is_intro
and mprop
.mclassdef
.mclass
== mclass
then
914 group
.add_bullet
("I", "Introduced", mprop
.tpl_link
, ["intro"])
915 else if mprop
.is_intro
and mprop
.mclassdef
.mclass
!= mclass
then
916 group
.add_bullet
("H", "Inherited", mprop
.tpl_link
, ["inherit"])
918 group
.add_bullet
("R", "Redefined", mprop
.tpl_link
, ["redef"])
922 private fun tpl_sidebar_group
(name
: String, elts
: Array[MClass]): TplSidebarGroup do
923 var group
= new TplSidebarGroup(name
)
925 if elt
== mclass
then continue
926 group
.add_elt
(elt
.tpl_link
, new Array[String])
931 redef fun tpl_content
do
932 var intro
= mclass
.intro
933 var tpl
= new TplClassPage
934 tpl
.title
= "{mclass.nitdoc_name}{mclass.tpl_short_signature}"
935 tpl
.subtitle
= mclass
.tpl_namespace_with_signature
936 tpl
.definition
= intro
.tpl_definition
937 var location
= intro
.location
938 tpl
.definition
.location
= tpl_showsource
(location
)
939 tpl
.definition
.github_area
= tpl_github
(intro
.full_namespace
, intro
.mdoc
, location
)
943 var prop_sorter
= new MPropDefNameSorter
944 var kind_map
= sort_by_kind
(intro_mpropdefs
)
947 var elts
= kind_map
["type"].to_a
948 prop_sorter
.sort
(elts
)
949 for elt
in elts
do tpl
.types
.add tpl_mpropdef_article
(elt
)
952 elts
= kind_map
["init"].to_a
953 prop_sorter
.sort
(elts
)
954 for elt
in elts
do tpl
.inits
.add tpl_mpropdef_article
(elt
)
957 elts
= kind_map
["fun"].to_a
958 prop_sorter
.sort
(elts
)
959 for elt
in elts
do tpl
.methods
.add tpl_mpropdef_article
(elt
)
962 kind_map
= sort_by_kind
(redef_mpropdefs
)
963 var module_sorter
= new MModuleNameSorter
964 var module_map
= sort_by_mmodule
(kind_map
["fun"])
965 var owner_map
= sort_by_public_owner
(module_map
.keys
)
966 var owners
= owner_map
.keys
.to_a
967 module_sorter
.sort owners
969 var ctpl
= new TplConcernList
970 var mtpl
= new Template
971 for owner
in owners
do
973 var octpl
= new TplConcernListElt
974 octpl
.anchor
= "#{owner.nitdoc_anchor}"
975 octpl
.name
= owner
.nitdoc_name
976 if owner
.mdoc
!= null then
977 octpl
.comment
= owner
.mdoc
.short_comment
981 var otpl
= new TplTopConcern
982 otpl
.anchor
= owner
.nitdoc_anchor
983 otpl
.concern
= owner
.tpl_link
986 var mmodules
= owner_map
[owner
].to_a
987 module_sorter
.sort mmodules
988 var stpl
= new TplConcernList
989 for mmodule
in mmodules
do
991 if mmodule
!= owner
then
992 var mctpl
= new TplConcernListElt
993 mctpl
.anchor
= "#{mmodule.nitdoc_anchor}"
994 mctpl
.name
= mmodule
.nitdoc_name
995 if mmodule
.mdoc
!= null then
996 mctpl
.comment
= mmodule
.mdoc
.short_comment
1000 var cctpl
= new TplConcern
1001 cctpl
.anchor
= mmodule
.nitdoc_anchor
1002 cctpl
.concern
= mmodule
.tpl_link
1003 if mmodule
.mdoc
!= null then
1004 cctpl
.comment
= mmodule
.mdoc
.short_comment
1008 var mprops
= module_map
[mmodule
].to_a
1009 prop_sorter
.sort mprops
1010 for mprop
in mprops
do mtpl
.add tpl_mpropdef_article
(mprop
)
1014 if not owners
.is_empty
then
1017 tpl
.methods
.add mtpl
1021 private fun sort_by_kind
(mpropdefs
: Set[MPropDef]): Map[String, Set[MPropDef]] do
1022 var map
= new HashMap[String, Set[MPropDef]]
1023 map
["type"] = new HashSet[MPropDef]
1024 map
["init"] = new HashSet[MPropDef]
1025 map
["fun"] = new HashSet[MPropDef]
1026 for mpropdef
in mpropdefs
do
1027 if mpropdef
isa MVirtualTypeDef then
1028 map
["type"].add mpropdef
1029 else if mpropdef
isa MMethodDef then
1030 if mpropdef
.mproperty
.is_init
then
1031 map
["init"].add mpropdef
1033 map
["fun"].add mpropdef
1040 private fun sort_by_mmodule
(mpropdefs
: Collection[MPropDef]): Map[MModule, Set[MPropDef]] do
1041 var map
= new HashMap[MModule, Set[MPropDef]]
1042 for mpropdef
in mpropdefs
do
1043 var mmodule
= mpropdef
.mclassdef
.mmodule
1044 if not map
.has_key
(mmodule
) then map
[mmodule
] = new HashSet[MPropDef]
1045 map
[mmodule
].add mpropdef
1050 private fun sort_by_public_owner
(mmodules
: Collection[MModule]): Map[MModule, Set[MModule]] do
1051 var map
= new HashMap[MModule, Set[MModule]]
1052 for mmodule
in mmodules
do
1054 if mmodule
.public_owner
!= null then owner
= mmodule
.public_owner
.as(not null)
1055 if not map
.has_key
(owner
) then map
[owner
] = new HashSet[MModule]
1056 map
[owner
].add mmodule
1061 # Generate dot hierarchy for classes
1062 fun tpl_dot
: nullable TplGraph do
1063 var pe
= mclass
.in_hierarchy
(ctx
.mainmodule
)
1064 var cla
= new HashSet[MClass]
1065 var sm
= new HashSet[MClass]
1066 var sm2
= new HashSet[MClass]
1068 while cla
.length
+ sm
.length
< 10 and sm
.length
> 0 do
1072 sm2
.add_all
(pe
.poset
[x
].direct_smallers
)
1078 cla
.add_all
(pe
.greaters
)
1080 var op
= new FlatBuffer
1081 var name
= "dep_{mclass.name}"
1082 op
.append
("digraph {name} \{ rankdir=BT; node[shape=none,margin=0,width=0,height=0,fontsize=10]; edge[dir=none,color=gray]; ranksep=0.2; nodesep=0.1;\n")
1085 op
.append
("\"{c.name}\
"[shape=box,margin=0.03];\n")
1087 op
.append
("\"{c.name}\
"[URL=\"{c.nitdoc_url}\
"];\n")
1089 for c2
in pe
.poset
[c
].direct_greaters
do
1090 if not cla
.has
(c2
) then continue
1091 op
.append
("\"{c.name}\
"->\"{c2.name}\
";\n")
1093 if not pe
.poset
[c
].direct_smallers
.is_empty
then
1095 for c2
in pe
.poset
[c
].direct_smallers
do
1096 if cla
.has
(c2
) then others
= false
1099 op
.append
("\"{c.name}...\
"[label=\"\
"];\n")
1100 op
.append
("\"{c.name}...\
"->\"{c.name}\
"[style=dotted];\n")
1105 return tpl_graph
(op
, name
, "Dependency graph for class {mclass.name}")
1114 # Return the HTML escaped name of the module
1115 private fun nitdoc_name
: String do return name
.html_escape
1117 private fun full_namespace
: String do
1118 if public_owner
!= null then
1119 return "{public_owner.nitdoc_name}::{nitdoc_name}"
1124 # URL to nitdoc page
1125 # module_owner_name.html
1126 private fun nitdoc_url
: String do
1127 var res
= new FlatBuffer
1128 res
.append
("module_")
1129 var mowner
= public_owner
1130 if mowner
!= null then
1131 res
.append
("{public_owner.name}_")
1133 res
.append
("{self.name}.html")
1137 # html nitdoc_anchor id for the module in a nitdoc page
1139 private fun nitdoc_anchor
: String do
1140 var res
= new FlatBuffer
1142 var mowner
= public_owner
1143 if mowner
!= null then
1144 res
.append
("{public_owner.name}_")
1146 res
.append
(self.name
)
1150 # Return a link (html a tag) to the nitdoc module page
1151 private fun tpl_link
: TplLink do
1152 var tpl
= new TplLink
1153 tpl
.href
= nitdoc_url
1154 tpl
.text
= nitdoc_name
1155 if mdoc
!= null then
1156 tpl
.title
= mdoc
.short_comment
1161 # Return the module signature decorated with html
1162 private fun tpl_signature
: Template do
1163 var tpl
= new Template
1164 tpl
.add
"<span>module "
1165 tpl
.add tpl_full_namespace
1170 # Return the module full namespace decorated with html
1171 private fun tpl_full_namespace
: Template do
1172 var tpl
= new Template
1174 var mowner
= public_owner
1175 if mowner
!= null then
1176 tpl
.add public_owner
.tpl_namespace
1184 # Return the module full namespace decorated with html
1185 private fun tpl_namespace
: Template do
1186 var tpl
= new Template
1188 var mowner
= public_owner
1189 if mowner
!= null then
1190 tpl
.add public_owner
.tpl_namespace
1198 # Description with short comment
1199 private fun tpl_short_definition
: TplDefinition do
1200 var tpl
= new TplDefinition
1201 tpl
.namespace
= tpl_namespace
1202 if mdoc
!= null then
1203 tpl
.comment
= mdoc
.tpl_short_comment
1208 # Description with full comment
1209 private fun tpl_definition
: TplDefinition do
1210 var tpl
= new TplDefinition
1211 tpl
.namespace
= tpl_namespace
1212 if mdoc
!= null then
1213 tpl
.comment
= mdoc
.tpl_comment
1220 # Return the HTML escaped name of the module
1221 private fun nitdoc_name
: String do return name
.html_escape
1223 # URL to nitdoc page
1224 # class_owner_name.html
1225 private fun nitdoc_url
: String do
1226 return "class_{public_owner}_{name}.html"
1229 # html nitdoc_anchor id for the class in a nitdoc page
1231 private fun nitdoc_anchor
: String do
1232 return "CLASS_{public_owner.name}_{name}"
1235 # Return a link (with signature) to the nitdoc class page
1236 private fun tpl_link
: TplLink do
1237 var tpl
= new TplLink
1238 tpl
.href
= nitdoc_url
1239 tpl
.text
= "{nitdoc_name}{tpl_short_signature.write_to_string}"
1240 if intro
.mdoc
!= null then
1241 tpl
.title
= intro
.mdoc
.short_comment
1246 # Return a short link (without signature) to the nitdoc class page
1247 private fun tpl_short_link
: TplLink do
1248 var tpl
= new TplLink
1249 tpl
.href
= nitdoc_url
1250 tpl
.text
= nitdoc_name
1251 if intro
.mdoc
!= null then
1252 tpl
.title
= intro
.mdoc
.short_comment
1257 # Return a link (with signature) to the class nitdoc_anchor
1258 private fun tpl_link_anchor
: TplLink do
1259 var tpl
= new TplLink
1260 tpl
.href
= "#{nitdoc_anchor}"
1261 tpl
.text
= "{nitdoc_name}{tpl_short_signature.write_to_string}"
1262 if intro
.mdoc
!= null then
1263 tpl
.title
= intro
.mdoc
.short_comment
1268 # Return the generic signature of the class with bounds
1269 private fun tpl_signature
: Template do
1270 var tpl
= new Template
1273 for i
in [0..intro
.parameter_names
.length
[ do
1274 tpl
.add
"{intro.parameter_names[i]}: "
1275 tpl
.add intro
.bound_mtype
.arguments
[i
].tpl_link
1276 if i
< intro
.parameter_names
.length
- 1 then tpl
.add
", "
1283 # Return the generic signature of the class without bounds
1284 private fun tpl_short_signature
: String do
1286 return "[{intro.parameter_names.join(", ")}]"
1292 # Return the class namespace decorated with html
1293 private fun tpl_namespace
: Template do
1294 var tpl
= new Template
1295 tpl
.add intro_mmodule
.tpl_namespace
1297 tpl
.add tpl_short_link
1302 private fun tpl_namespace_with_signature
: Template do
1303 var tpl
= new Template
1304 tpl
.add intro
.tpl_modifiers
1305 tpl
.add intro
.mmodule
.tpl_namespace
1308 tpl
.add tpl_signature
1313 redef class MProperty
1314 # Escape name for html output
1315 private fun nitdoc_name
: String do return name
.html_escape
1317 # Return the property namespace decorated with html
1318 private fun tpl_namespace
: Template do
1319 var tpl
= new Template
1320 tpl
.add intro_mclassdef
.mclass
.tpl_namespace
1321 tpl
.add intro_mclassdef
.mclass
.tpl_short_signature
1323 tpl
.add intro
.tpl_link
1328 private fun tpl_signature
: Template is abstract
1332 redef fun tpl_signature
do return intro
.msignature
.tpl_signature
1335 redef class MVirtualTypeProp
1336 redef fun tpl_signature
do
1337 var tpl
= new Template
1339 tpl
.add intro
.bound
.tpl_link
1345 # Link to the type definition in the nitdoc page
1346 private fun tpl_link
: Template is abstract
1349 redef class MClassType
1350 redef fun tpl_link
do return mclass
.tpl_link
1353 redef class MNullableType
1354 redef fun tpl_link
do
1355 var tpl
= new Template
1357 tpl
.add mtype
.tpl_link
1362 redef class MGenericType
1363 redef fun tpl_link
: Template do
1364 var tpl
= new Template
1365 tpl
.add mclass
.tpl_short_link
1367 for i
in [0..arguments
.length
[ do
1368 tpl
.add arguments
[i
].tpl_link
1369 if i
< arguments
.length
- 1 then tpl
.add
", "
1376 redef class MParameterType
1377 redef fun tpl_link
do
1378 var name
= mclass
.intro
.parameter_names
[rank
]
1379 var tpl
= new TplLink
1380 tpl
.href
= "{mclass.nitdoc_url}#FT_{name}"
1382 tpl
.title
= "formal type"
1387 redef class MVirtualType
1388 redef fun tpl_link
do return mproperty
.intro
.tpl_link
1391 redef class MClassDef
1392 # Return the classdef namespace decorated with html
1393 private fun tpl_namespace
: Template do
1394 var tpl
= new Template
1395 tpl
.add mmodule
.tpl_namespace
1397 tpl
.add mclass
.tpl_link
1402 private fun full_namespace
: String do
1403 return "{mmodule.full_namespace}::{mclass.nitdoc_name}"
1406 private fun tpl_link_anchor
: TplLink do return mclass
.tpl_link_anchor
1408 private fun tpl_article
: TplArticle do
1409 var tpl
= new TplArticle
1410 tpl
.id
= mclass
.nitdoc_anchor
1411 tpl
.classes
.add_all
(tpl_css_classes
)
1412 tpl
.title
= new Template
1413 tpl
.title
.add mclass
.tpl_short_link
1414 tpl
.title
.add mclass
.tpl_signature
1415 tpl
.subtitle
= new Template
1416 tpl
.subtitle
.add tpl_modifiers
1417 tpl
.subtitle
.add tpl_namespace
1418 tpl
.content
= new Template
1419 tpl
.content
.add tpl_definition
1423 private fun tpl_css_classes
: Set[String] do
1424 var set
= new HashSet[String]
1425 set
.add_all mclass
.intro
.modifiers
1426 set
.add_all modifiers
1430 private fun tpl_modifiers
: Template do
1431 var tpl
= new Template
1432 for modifier
in modifiers
do
1433 if modifier
== "public" then continue
1434 tpl
.add
"{modifier} "
1439 private fun tpl_short_definition
: TplDefinition do
1440 var tpl
= new TplDefinition
1441 tpl
.namespace
= mmodule
.tpl_full_namespace
1442 if mdoc
!= null then
1443 tpl
.comment
= mdoc
.tpl_short_comment
1448 private fun tpl_definition
: TplDefinition do
1449 var tpl
= new TplDefinition
1450 tpl
.namespace
= mmodule
.tpl_full_namespace
1451 if mdoc
!= null then
1452 tpl
.comment
= mdoc
.tpl_comment
1458 redef class MPropDef
1459 # Return the full qualified name of the mpropdef
1460 # module::classdef::name
1461 private fun tpl_namespace
: Template do
1462 var tpl
= new Template
1463 tpl
.add mclassdef
.tpl_namespace
1465 tpl
.add mproperty
.name
1469 private fun full_namespace
: String do
1470 return "{mclassdef.full_namespace}::{mproperty.nitdoc_name}"
1473 # URL into the nitdoc page
1474 # class_owner_name.html#nitdoc_anchor
1475 private fun nitdoc_url
: String do
1476 return "{mclassdef.mclass.nitdoc_url}#{nitdoc_anchor}"
1479 # html nitdoc_anchor id for the property in a nitdoc class page
1480 # PROP_mclass_propertyname
1481 private fun nitdoc_anchor
: String do
1482 return "PROP_{mclassdef.mclass.public_owner.nitdoc_name}_{mproperty.name.replace(" ", "_")}"
1485 # Return a link to property into the nitdoc class page
1486 # <a href="nitdoc_url" title="short_comment">nitdoc_name</a>
1487 private fun tpl_link
: TplLink do
1488 var tpl
= new TplLink
1489 tpl
.href
= nitdoc_url
1490 tpl
.text
= mproperty
.nitdoc_name
1491 if mproperty
.intro
.mdoc
!= null then
1492 tpl
.title
= mproperty
.intro
.mdoc
.short_comment
1497 private fun tpl_article
: TplArticle do
1498 var tpl
= new TplArticle
1499 tpl
.id
= nitdoc_anchor
1500 tpl
.classes
.add_all
(tpl_css_classes
)
1501 tpl
.title
= new Template
1502 tpl
.title
.add mproperty
.nitdoc_name
1503 tpl
.title
.add mproperty
.tpl_signature
1504 tpl
.subtitle
= new Template
1505 tpl
.subtitle
.add tpl_modifiers
1506 tpl
.subtitle
.add tpl_namespace
1507 tpl
.content
= new Template
1508 tpl
.content
.add tpl_definition
1512 private fun tpl_css_classes
: Set[String] do
1513 var set
= new HashSet[String]
1514 set
.add_all mproperty
.intro
.modifiers
1515 set
.add_all modifiers
1519 private fun tpl_modifiers
: Template do
1520 var tpl
= new Template
1521 for modifier
in modifiers
do
1522 if modifier
== "public" then continue
1523 tpl
.add
"{modifier} "
1528 private fun tpl_short_definition
: TplDefinition do
1529 var tpl
= new TplDefinition
1530 tpl
.namespace
= mclassdef
.tpl_namespace
1531 if mdoc
!= null then
1532 tpl
.comment
= mdoc
.tpl_short_comment
1537 private fun tpl_definition
: TplDefinition do
1538 var tpl
= new TplDefinition
1539 tpl
.namespace
= mclassdef
.tpl_namespace
1540 if mdoc
!= null then
1541 tpl
.comment
= mdoc
.tpl_comment
1547 redef class MSignature
1548 private fun tpl_signature
: Template do
1549 var tpl
= new Template
1550 if not mparameters
.is_empty
then
1552 for i
in [0..mparameters
.length
[ do
1553 tpl
.add mparameters
[i
].tpl_link
1554 if i
< mparameters
.length
- 1 then tpl
.add
", "
1558 if return_mtype
!= null then
1560 tpl
.add return_mtype
.tpl_link
1566 redef class MParameter
1567 private fun tpl_link
: Template do
1568 var tpl
= new Template
1570 tpl
.add mtype
.tpl_link
1571 if is_vararg
then tpl
.add
"..."
1576 redef class Location
1577 fun github
(gitdir
: String): String do
1578 var base_dir
= getcwd
.join_path
(gitdir
).simplify_path
1579 var file_loc
= getcwd
.join_path
(file
.filename
).simplify_path
1580 var gith_loc
= file_loc
.substring
(base_dir
.length
+ 1, file_loc
.length
)
1581 return "{gith_loc}:{line_start},{column_start}--{line_end},{column_end}"
1586 private fun short_comment
: String do
1587 return content
.first
.html_escape
1590 private fun full_comment
: String do
1591 return content
.join
("\n").html_escape
1594 private fun tpl_short_comment
: TplShortComment do
1595 return new TplShortComment(short_markdown
)
1598 private fun tpl_comment
: TplComment do
1599 return new TplComment(full_markdown
)
1603 var nitdoc
= new NitdocContext
1604 nitdoc
.generate_nitdoc