1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
20 import abstract_compiler
23 private var toolcontext
: ToolContext
24 private var model
: Model
25 private var modelbuilder
: ModelBuilder
26 private var mainmodule
: MModule
27 private var class_hierarchy
: POSet[MClass]
28 private var arguments
: Array[String]
29 private var output_dir
: nullable String
30 private var dot_dir
: nullable String
31 private var share_dir
: nullable String
32 private var source
: nullable String
34 private var opt_dir
= new OptionString("Directory where doc is generated", "-d", "--dir")
35 private var opt_source
= new OptionString("What link for source (%f for filename, %l for first line, %L for last line)", "--source")
36 private var opt_sharedir
= new OptionString("Directory containing the nitdoc files", "--sharedir")
37 private var opt_nodot
= new OptionBool("Do not generate graphes with graphiviz", "--no-dot")
39 init(toolcontext
: ToolContext) do
40 # We need a model to collect stufs
41 self.toolcontext
= toolcontext
42 self.arguments
= toolcontext
.option_context
.rest
43 toolcontext
.option_context
.options
.clear
44 toolcontext
.option_context
.add_option
(opt_dir
)
45 toolcontext
.option_context
.add_option
(opt_source
)
46 toolcontext
.option_context
.add_option
(opt_sharedir
)
47 toolcontext
.option_context
.add_option
(opt_nodot
)
48 toolcontext
.process_options
51 if arguments
.length
< 1 then
52 toolcontext
.option_context
.usage
57 modelbuilder
= new ModelBuilder(model
, toolcontext
)
59 # Here we load an process std modules
60 var mmodules
= modelbuilder
.parse_and_build
([arguments
.first
])
61 if mmodules
.is_empty
then return
62 modelbuilder
.full_propdef_semantic_analysis
63 assert mmodules
.length
== 1
64 self.mainmodule
= mmodules
.first
65 self.class_hierarchy
= mainmodule
.flatten_mclass_hierarchy
68 private fun process_options
do
69 if not opt_dir
.value
is null then
70 output_dir
= opt_dir
.value
74 if not opt_sharedir
.value
is null then
75 share_dir
= opt_sharedir
.value
77 var dir
= "NIT_DIR".environ
79 dir
= "{sys.program_name.dirname}/../share/nitdoc"
81 dir
= "{dir}/share/nitdoc"
84 if share_dir
is null then
85 print
"Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
88 dir
= "{share_dir.to_s}/scripts/js-facilities.js"
89 if share_dir
is null then
90 print
"Error: Invalid nitdoc share files. Check --sharedir or envvar NIT_DIR"
94 if not opt_source
.value
is null then
97 source
= opt_source
.value
102 if arguments
.length
== 1 then
103 # Create destination dir if it's necessary
104 if not output_dir
.file_exists
then output_dir
.mkdir
105 sys
.system
("cp -r {share_dir.to_s}/* {output_dir.to_s}/")
107 if not opt_nodot
.value
then self.dot_dir
= output_dir
.to_s
117 var overviewpage
= new NitdocOverview(modelbuilder
, dot_dir
)
118 overviewpage
.save
("{output_dir.to_s}/index.html")
122 var fullindex
= new NitdocFullindex(self)
123 fullindex
.save
("{output_dir.to_s}/full-index.html")
127 for mmodule
in model
.mmodules
do
128 var modulepage
= new NitdocModule(mmodule
, modelbuilder
, dot_dir
)
129 modulepage
.save
("{output_dir.to_s}/{mmodule.url}")
134 for mclass
in modelbuilder
.model
.mclasses
do
135 var classpage
= new NitdocClass(mclass
, self, dot_dir
, source
)
136 classpage
.save
("{output_dir.to_s}/{mclass.url}")
140 # Generate QuickSearch file
141 fun quicksearch_list
do
142 var file
= new OFStream.open
("{output_dir.to_s}/quicksearch-list.js")
143 var content
= new Buffer
144 content
.append
("var entries = \{ ")
145 for prop
in model
.mproperties
do
146 if not prop
isa MMethod then continue
147 content
.append
("\"{prop.name}\
": [")
148 for propdef
in prop
.mpropdefs
do
149 content
.append
("\{txt: \"{propdef.mproperty.full_name}\", url
:\
"{propdef.url}\" \
}")
150 if not propdef is prop.mpropdefs.last then content.append(", ")
156 for mclass in model.mclasses do
157 content.append("\
"{mclass.name}\": [")
158 for mclassdef in mclass.mclassdefs do
159 content.append("\
{txt: \"{mclassdef.mclass.full_name}\
", url:\"{mclass.url}\
" \}")
160 if not mclassdef
is mclass
.mclassdefs
.last
then content
.append
(", ")
163 if not mclass
is model
.mclasses
.last
then content
.append
(", ")
166 content
.append
(" \};")
167 file
.write
(content
.to_s
)
174 abstract class NitdocPage
176 var dot_dir
: nullable String
177 var source
: nullable String
181 fun append
(str
: String) do html
.append
(str
)
182 var html
= new Buffer
185 append
("<meta charset='utf-8'/>")
186 append
("<script type='text/javascript' src='scripts/jquery-1.7.1.min.js'></script>")
187 append
("<script type='text/javascript' src='quicksearch-list.js'></script>")
188 append
("<script type='text/javascript' src='scripts/js-facilities.js'></script>")
189 append
("<link rel='stylesheet' href='styles/main.css' type='text/css' media='screen'/>")
196 append
("<nav class='main'>")
199 append
("<li id='liGitHub'>")
200 append
("<a class='btn' id='logGitHub'>")
201 append
("<img id='imgGitHub' src='resources/icons/github-icon.png' alt='GitHub'/>")
203 append
("<div class='popover bottom'>")
204 append
("<div class='arrow'> </div>")
205 append
("<div class='githubTitle'>")
206 append
("<h3>Github Sign In</h3>")
209 append
("<label id='lbloginGit'>Username</label>")
210 append
("<input id='loginGit' name='login' type='text'/>")
211 append
("<label id='logginMessage'>Hello ")
212 append
("<a id='githubAccount'><strong id='nickName'></strong></a>")
216 append
("<label id='lbpasswordGit'>Password</label>")
217 append
("<input id='passwordGit' name='password' type='password'/>")
218 append
("<div id='listBranches'>")
219 append
("<label id='lbBranches'>Branch</label>")
220 append
("<select class='dropdown' id='dropBranches' name='dropBranches' tabindex='1'></select>")
224 append
("<label id='lbrepositoryGit'>Repository</label>")
225 append
("<input id='repositoryGit' name='repository' type='text'/>")
228 append
("<label id='lbbranchGit'>Branch</label>")
229 append
("<input id='branchGit' name='branch' type='text'/>")
232 append
("<a id='signIn'>Sign In</a>")
241 fun content
is abstract
244 append
("<footer>Nit standard library. Version jenkins-component=stdlib-19.</footer>")
247 # Generate a clickable graphviz image using a dot content
248 fun generate_dot
(dot
: String, name
: String, alt
: String) do
249 var output_dir
= dot_dir
250 if output_dir
== null then return
251 var file
= new OFStream.open
("{output_dir}/{name}.dot")
254 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 ; \}")
255 append
("<article class='graph'>")
256 append
("<img src='{name}.png' usemap='#{name}' style='margin:auto' alt='{alt}'/>")
258 var fmap
= new IFStream.open
("{output_dir}/{name}.map")
259 append
(fmap
.read_all
)
263 # Add a (source) link for a given location
264 fun show_source
(l
: Location): String
266 if source
== null then
267 return "({l.file.filename.simplify_path})"
269 # THIS IS JUST UGLY ! (but there is no replace yet)
270 var x
= source
.split_with
("%f")
271 source
= x
.join
(l
.file
.filename
.simplify_path
)
272 x
= source
.split_with
("%l")
273 source
= x
.join
(l
.line_start
.to_s
)
274 x
= source
.split_with
("%L")
275 source
= x
.join
(l
.line_end
.to_s
)
276 return " (<a href=\"{source.to_s}\
">show code</a>)"
280 # Render the page as a html string
281 fun render
: String do
282 append
("<!DOCTYPE html>")
288 append
("<div class='page'>")
296 # Save html page in the specified file
297 fun save
(file
: String) do
298 var out
= new OFStream.open
(file
)
307 private var mbuilder
: ModelBuilder
308 private var mmodules
= new Array[MModule]
310 init(mbuilder
: ModelBuilder, dot_dir
: nullable String) do
311 self.mbuilder
= mbuilder
312 self.dot_dir
= dot_dir
314 var mmodules
= new HashSet[MModule]
315 for mmodule
in mbuilder
.model
.mmodules
do
316 var owner
= mmodule
.public_owner
317 if owner
!= null then
320 mmodules
.add
(mmodule
)
324 var sorter
= new ComparableSorter[MModule]
325 self.mmodules
.add_all
(mmodules
)
326 sorter
.sort
(self.mmodules
)
331 append
("<title>Overview | Nit Standard Library</title>")
335 append
("<li class='current'>Overview</li>")
336 append
("<li><a href='full-index.html'>Full Index</a></li>")
340 append
("<div class='content fullpage'>")
341 append
("<h1>Nit Standard Library</h1>")
342 append
("<article class='overview'><p>Documentation for the standard library of Nit<br />Version jenkins-component=stdlib-19<br />Date: TODAY</p></article>")
343 append
("<article class='overview'>")
345 append
("<h2>Modules</h2>")
347 for mmodule
in mmodules
do
348 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
349 append
("<li>{mmodule.link(mbuilder)} {amodule.short_comment}</li>")
358 fun process_generate_dot
do
360 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")
361 for mmodule
in mmodules
do
362 op
.append
("\"{mmodule.name}\
"[URL=\"{mmodule.url}\
"];\n")
363 for imported
in mmodule
.in_importation
.direct_greaters
do
364 if imported
.direct_owner
== null then
365 op
.append
("\"{mmodule.name}\
"->\"{imported.name}\
";\n")
370 generate_dot
(op
.to_s
, "dep", "Modules hierarchy")
374 # The full index page
375 class NitdocFullindex
378 private var nitdoc
: Nitdoc
380 init(nitdoc
: Nitdoc) do
387 append
("<title>Full Index | Nit Standard Library</title>")
391 append
("<li><a href='index.html'>Overview</a></li>")
392 append
("<li class='current'>Full Index</li>")
396 append
("<div class='content fullpage'>")
397 append
("<h1>Full Index</h1>")
404 # Add to content modules column
406 var sorter
= new ComparableSorter[MModule]
407 var sorted
= new Array[MModule]
408 for mmodule
in nitdoc
.modelbuilder
.model
.mmodule_importation_hierarchy
do
412 append
("<article class='modules filterable'>")
413 append
("<h2>Modules</h2>")
415 for mmodule
in sorted
do
416 append
("<li>{mmodule.link(nitdoc.modelbuilder)}</li>")
422 # Add to content classes modules
423 fun classes_column
do
424 var sorted
= nitdoc
.modelbuilder
.model
.mclasses
425 var sorter
= new ComparableSorter[MClass]
427 append
("<article class='modules filterable'>")
428 append
("<h2>Classes</h2>")
430 for mclass
in sorted
do
431 append
("<li>{mclass.link(nitdoc.modelbuilder)}</li>")
437 # Insert the properties column of fullindex page
438 fun properties_column
do
439 var sorted
= nitdoc
.modelbuilder
.model
.mproperties
440 var sorter
= new ComparableSorter[MProperty]
442 append
("<article class='modules filterable'>")
443 append
("<h2>Properties</h2>")
445 for mproperty
in sorted
do
446 if mproperty
isa MAttribute then continue
447 append
("<li>{mproperty.intro.link(nitdoc.modelbuilder)} ({mproperty.intro.mclassdef.mclass.link(nitdoc.modelbuilder)})</li>")
459 private var mmodule
: MModule
460 private var mbuilder
: ModelBuilder
462 init(mmodule
: MModule, mbuilder
: ModelBuilder, dot_dir
: nullable String) do
463 self.mmodule
= mmodule
464 self.mbuilder
= mbuilder
465 self.dot_dir
= dot_dir
470 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
471 append
("<title>{mmodule.name} module | {amodule.short_comment}</title>")
475 append
("<li><a href='index.html'>Overview</a></li>")
476 append
("<li class='current'>{mmodule.name}</li>")
477 append
("<li><a href='full-index.html'>Full Index</a></li>")
482 append
("<div class='content'>")
483 append
("<h1>{mmodule.name}</h1>")
484 append
("<div class='subtitle'>{mmodule.html_signature(mbuilder)}</div>")
485 append
(mmodule
.html_full_comment
(mbuilder
))
492 fun process_generate_dot
do
493 var name
= "dep_{mmodule.name}"
495 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")
496 for m
in mmodule
.in_importation
.poset
do
497 var public_owner
= m
.public_owner
498 if public_owner
== null then
501 op
.append
("\"{m.name}\
"[shape=box,margin=0.03];\n")
503 op
.append
("\"{m.name}\
"[URL=\"{m.url}\
"];\n")
506 for imported
in m
.in_importation
.direct_greaters
do
507 if imported
.public_owner
== null then
508 op
.append
("\"{public_owner.name}\
"->\"{imported.name}\
";\n")
513 generate_dot
(op
.to_s
, name
, "Dependency graph for module {mmodule.name}")
517 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
518 append
("<div class='menu'>")
520 append
("<h3>Module Hierarchy</h3>")
521 var dependencies
= new Array[MModule]
522 for dep
in mmodule
.in_importation
.greaters
do
523 if dep
== mmodule
or dep
.public_owner
!= null then continue
524 dependencies
.add
(dep
)
526 if dependencies
.length
> 0 then
527 append
("<h4>All dependencies</h4>")
528 display_module_list
(dependencies
)
530 var clients
= new Array[MModule]
531 for dep
in mmodule
.in_importation
.smallers
do
532 if dep
== mmodule
or dep
.public_owner
!= null then continue
535 if clients
.length
> 0 then
536 append
("<h4>All clients</h4>")
537 display_module_list
(clients
)
540 if mmodule
.in_nesting
.direct_greaters
.length
> 0 then
542 append
("<h3>Nested Modules</h3>")
543 display_module_list
(mmodule
.in_nesting
.direct_greaters
.to_a
)
549 private fun display_module_list
(list
: Array[MModule]) do
551 var sorter
= new ComparableSorter[MModule]
553 for m
in list
do append
("<li>{m.link(mbuilder)}</li>")
557 # display the class column
559 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
560 var intro_mclasses
= mmodule
.intro_mclasses
561 var redef_mclasses
= mmodule
.redef_mclasses
562 var all_mclasses
= new HashSet[MClass]
563 for m
in mmodule
.in_nesting
.greaters
do
564 all_mclasses
.add_all
(m
.intro_mclasses
)
565 all_mclasses
.add_all
(m
.redef_mclasses
)
567 all_mclasses
.add_all
(intro_mclasses
)
568 all_mclasses
.add_all
(redef_mclasses
)
570 var sorted
= new Array[MClass]
571 sorted
.add_all
(all_mclasses
)
572 var sorter
= new ComparableSorter[MClass]
574 append
("<div class='module'>")
575 append
("<article class='classes filterable'>")
576 append
("<h2>Classes</h2>")
579 if redef_mclasses
.has
(c
) and c
.intro_mmodule
.public_owner
!= mmodule
then
580 append
("<li class='redef'>")
581 append
("<span title='refined in this module'>R </span>")
583 append
("<li class='intro'>")
584 append
("<span title='introduced in this module'>I </span>")
586 append
(c
.link
(mbuilder
))
594 # display the property column
597 var amodule
= mbuilder
.mmodule2nmodule
[mmodule
]
598 var mpropdefs
= new HashSet[MPropDef]
599 for m
in mmodule
.in_nesting
.greaters
do
600 for c
in m
.mclassdefs
do mpropdefs
.add_all
(c
.mpropdefs
)
602 for c
in mmodule
.mclassdefs
do mpropdefs
.add_all
(c
.mpropdefs
)
603 var sorted
= mpropdefs
.to_a
604 var sorter
= new ComparableSorter[MPropDef]
606 # display properties in one column
607 append
("<article class='properties filterable'>")
608 append
("<h2>Properties</h2>")
610 for mprop
in sorted
do
611 if mprop
isa MAttributeDef then continue
612 if mprop
.mproperty
.visibility
<= none_visibility
then continue
613 append
(mprop
.html_list_item
(mbuilder
))
624 private var mclass
: MClass
625 private var mbuilder
: ModelBuilder
626 private var nitdoc
: Nitdoc
627 private var vtypes
= new HashSet[MVirtualTypeDef]
628 private var consts
= new HashSet[MMethodDef]
629 private var meths
= new HashSet[MMethodDef]
630 private var inherited
= new HashSet[MPropDef]
632 init(mclass
: MClass, nitdoc
: Nitdoc, dot_dir
: nullable String, source
: nullable String) do
634 self.mbuilder
= nitdoc
.modelbuilder
636 self.dot_dir
= dot_dir
639 for mclassdef
in mclass
.mclassdefs
do
640 for mpropdef
in mclassdef
.mpropdefs
do
641 if mpropdef
.mproperty
.visibility
<= none_visibility
then continue
642 if mpropdef
isa MVirtualTypeDef then vtypes
.add
(mpropdef
)
643 if mpropdef
isa MMethodDef then
644 if mpropdef
.mproperty
.is_init
then
652 # get inherited properties
653 for mprop
in mclass
.inherited_mproperties
do
654 var mpropdef
= mprop
.intro
655 if mprop
.visibility
<= none_visibility
then continue
656 if mpropdef
isa MVirtualTypeDef then vtypes
.add
(mpropdef
)
657 if mpropdef
isa MMethodDef then
658 if mpropdef
.mproperty
.is_init
then
664 inherited
.add
(mpropdef
)
670 var nclass
= mbuilder
.mclassdef2nclassdef
[mclass
.intro
]
671 if nclass
isa AStdClassdef then
672 append
("<title>{mclass.name} class | {nclass.short_comment}</title>")
674 append
("<title>{mclass.name} class</title>")
679 append
("<li><a href='index.html'>Overview</a></li>")
680 var public_owner
= mclass
.public_owner
681 if public_owner
is null then
682 append
("<li>{mclass.intro_mmodule.link(mbuilder)}</li>")
684 append
("<li>{public_owner.link(mbuilder)}</li>")
686 append
("<li class='current'>{mclass.name}</li>")
687 append
("<li><a href='full-index.html'>Full Index</a></li>")
691 append
("<div class='menu'>")
695 append
("<div class='content'>")
700 fun properties_column
do
701 var sorter
= new ComparableSorter[MPropDef]
702 append
("<nav class='properties filterable'>")
703 append
("<h3>Properties</h3>")
705 if vtypes
.length
> 0 then
706 var vts
= new Array[MVirtualTypeDef]
709 append
("<h4>Virtual Types</h4>")
712 append
(mprop
.html_sidebar_item
(self))
717 if consts
.length
> 0 then
718 var cts
= new Array[MMethodDef]
721 append
("<h4>Constructors</h4>")
724 append
(mprop
.html_sidebar_item
(self))
729 if meths
.length
> 0 then
730 var mts
= new Array[MMethodDef]
733 append
("<h4>Methods</h4>")
736 if mprop
.mproperty
.intro_mclassdef
.mclass
.name
== "Object" then continue
737 append
(mprop
.html_sidebar_item
(self))
744 fun inheritance_column
do
745 var sorted
= new Array[MClass]
746 var sorterp
= new ComparableSorter[MClass]
748 append
("<h3>Inheritance</h3>")
749 if mclass
.ancestors
.length
> 1 then
750 sorted
= mclass
.ancestors
.to_a
752 append
("<h4>Superclasses</h4>")
755 if sup
== mclass
then continue
756 append
("<li>{sup.link(mbuilder)}</li>")
761 if mclass
.descendants
.length
<= 1 then
762 append
("<h4>No Known Subclasses</h4>")
763 else if mclass
.descendants
.length
<= 100 then
764 sorted
= mclass
.descendants
.to_a
766 append
("<h4>Subclasses</h4>")
769 if sub
== mclass
then continue
770 append
("<li>{sub.link(mbuilder)}</li>")
773 else if mclass
.children
.length
<= 100 then
774 sorted
= mclass
.children
.to_a
776 append
("<h4>Direct Subclasses Only</h4>")
779 if sub
== mclass
then continue
780 append
("<li>{sub.link(mbuilder)}</li>")
784 append
("<h4>Too much Subclasses to list</h4>")
791 append
("<h1>{mclass.html_signature}</h1>")
792 append
("<div class='subtitle info'>{mclass.html_full_signature(mbuilder)}")
796 var nclass
= mbuilder
.mclassdef2nclassdef
[mclass
.intro
]
797 append
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
798 append
("<section class='description'>")
799 if nclass
isa AStdClassdef and not nclass
.comment
.is_empty
then append
("<pre class=\"text_label\
" title=\"122\
" name=\"\
" tag=\"{mclass.mclassdefs.first.location.to_s}\
" type=\"2\
">{nclass.comment}</pre><textarea id=\"fileContent\
" class=\"edit\
" cols=\"76\
" rows=\"1\
" style=\"display
: none
;\
"></textarea><a id=\"cancelBtn\
" style=\"display
: none
;\
">Cancel</a><a id=\"commitBtn\
" style=\"display
: none
;\
">Commit</a><pre id=\"preSave\
" class=\"text_label\
" type=\"2\
"></pre>")
803 var concern2meths
= new ArrayMap[MModule, Array[MMethodDef]]
804 var sorted_meths
= new Array[MMethodDef]
805 var sorted
= new Array[MModule]
806 sorted_meths
.add_all
(meths
)
807 nitdoc
.mainmodule
.linearize_mpropdefs
(sorted_meths
)
809 if inherited
.has
(meth
) then continue
810 var mmodule
= meth
.mclassdef
.mmodule
811 if not concern2meths
.has_key
(mmodule
) then
813 concern2meths
[mmodule
] = new Array[MMethodDef]
815 concern2meths
[mmodule
].add
(meth
)
817 var sections
= new ArrayMap[MModule, Array[MModule]]
818 for mmodule
in concern2meths
.keys
do
819 var owner
= mmodule
.public_owner
820 if owner
== null then owner
= mmodule
821 if not sections
.has_key
(owner
) then sections
[owner
] = new Array[MModule]
822 if owner
!= mmodule
then sections
[owner
].add
(mmodule
)
824 append
("<section class='concerns'>")
825 append
("<h2 class='section-header'>Concerns</h2>")
827 for owner
, mmodules
in sections
do
828 var nowner
= mbuilder
.mmodule2nmodule
[owner
]
830 if nowner
.short_comment
.is_empty
then
831 append
("<a href=\"#{owner.anchor}\">{owner.name}</a>")
833 append
("<a href=\"#{owner.anchor}\">{owner.name}</a>: {nowner.short_comment}")
835 if not mmodules
.is_empty
then
837 for mmodule
in mmodules
do
838 var nmodule
= mbuilder
.mmodule2nmodule
[mmodule
]
839 if nmodule
.short_comment
.is_empty
then
840 append
("<li><a href=\"#{mmodule.anchor}\">{mmodule.name}</a></li>")
842 append
("<li><a href=\"#{mmodule.anchor}\">{mmodule.name}</a>: {nmodule.short_comment}</li>")
852 var prop_sorter
= new ComparableSorter[MPropDef]
853 var sorterprop
= new ComparableSorter[MProperty]
854 var sorterc
= new ComparableSorter[MClass]
855 var lmmodule
= new List[MModule]
856 # virtual and formal types
857 var local_vtypes
= new Array[MVirtualTypeDef]
858 for vt
in vtypes
do if not inherited
.has
(vt
) then local_vtypes
.add
(vt
)
859 if local_vtypes
.length
> 0 or mclass
.arity
> 0 then
860 append
("<section class='types'>")
861 append
("<h2>Formal and Virtual Types</h2>")
863 if mclass
.arity
> 0 and nclass
isa AStdClassdef then
864 for ft
, bound
in mclass
.parameter_types
do
865 append
("<article id='{ft}'>")
866 append
("<h3 class='signature'>{ft}: {bound.link(mbuilder)}</h3>")
867 append
("<div class=\"info\
">formal generic type</div>")
872 prop_sorter
.sort
(local_vtypes
)
873 for prop
in local_vtypes
do append
(prop
.html_full_desc
(self))
877 var local_consts
= new Array[MMethodDef]
878 for const
in consts
do if not inherited
.has
(const
) then local_consts
.add
(const
)
879 prop_sorter
.sort
(local_consts
)
880 if local_consts
.length
> 0 then
881 append
("<section class='constructors'>")
882 append
("<h2 class='section-header'>Constructors</h2>")
883 for prop
in local_consts
do append
(prop
.html_full_desc
(self))
887 if not concern2meths
.is_empty
then
888 append
("<section class='methods'>")
889 append
("<h2 class='section-header'>Methods</h2>")
890 for owner
, mmodules
in sections
do
891 append
("<a id=\"{owner.anchor}\
"></a>")
892 if owner
!= mclass
.intro_mmodule
and owner
!= mclass
.public_owner
then
893 var nowner
= mbuilder
.mmodule2nmodule
[owner
]
894 append
("<h3 class=\"concern-toplevel\
">Methods refined in {owner.link(mbuilder)}</h3>")
895 if nowner
.short_comment
.is_empty
then
896 append
("<p class=\"concern-doc\
">{owner.name}</p>")
898 append
("<p class=\"concern-doc\
">{owner.name}: {nowner.short_comment}</p>")
901 if concern2meths
.has_key
(owner
) then
902 var mmethods
= concern2meths
[owner
]
903 prop_sorter
.sort
(mmethods
)
904 for prop
in mmethods
do append
(prop
.html_full_desc
(self))
906 for mmodule
in mmodules
do
907 append
("<a id=\"{mmodule.anchor}\
"></a>")
908 var nmodule
= mbuilder
.mmodule2nmodule
[mmodule
]
909 if mmodule
!= mclass
.intro_mmodule
and mmodule
!= mclass
.public_owner
then
910 if nmodule
.short_comment
.is_empty
then
911 append
("<p class=\"concern-doc\
">{mmodule.name}</p>")
913 append
("<p class=\"concern-doc\
">{mmodule.name}: {nmodule.short_comment}</p>")
916 var mmethods
= concern2meths
[mmodule
]
917 prop_sorter
.sort
(mmethods
)
918 for prop
in mmethods
do append
(prop
.html_full_desc
(self))
922 # inherited properties
923 if inherited
.length
> 0 then
924 var sorted_inherited
= new Array[MPropDef]
925 sorted_inherited
.add_all
(inherited
)
926 nitdoc
.mainmodule
.linearize_mpropdefs
(sorted_inherited
)
927 var classes
= new ArrayMap[MClass, Array[MPropDef]]
928 for mmethod
in sorted_inherited
.reversed
do
929 var mclass
= mmethod
.mclassdef
.mclass
930 if not classes
.has_key
(mclass
) then classes
[mclass
] = new Array[MPropDef]
931 classes
[mclass
].add
(mmethod
)
933 append
("<h3>Inherited Properties</h3>")
934 for c
, mmethods
in classes
do
935 prop_sorter
.sort
(mmethods
)
936 append
("<p>Defined in {c.link(mbuilder)}: ")
937 for i
in [0..mmethods
.length
[ do
938 var mmethod
= mmethods
[i
]
939 append
(mmethod
.link
(mbuilder
))
940 if i
<= mmethods
.length
- 1 then append
(", ")
948 fun process_generate_dot
do
949 var pe
= nitdoc
.class_hierarchy
[mclass
]
950 var cla
= new HashSet[MClass]
951 var sm
= new HashSet[MClass]
952 var sm2
= new HashSet[MClass]
954 while cla
.length
+ sm
.length
< 10 and sm
.length
> 0 do
958 sm2
.add_all
(pe
.poset
[x
].direct_smallers
)
964 cla
.add_all
(pe
.greaters
)
967 var name
= "dep_{mclass.name}"
968 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")
971 op
.append
("\"{c.name}\
"[shape=box,margin=0.03];\n")
973 op
.append
("\"{c.name}\
"[URL=\"{c.url}\
"];\n")
975 for c2
in pe
.poset
[c
].direct_greaters
do
976 if not cla
.has
(c2
) then continue
977 op
.append
("\"{c.name}\
"->\"{c2.name}\
";\n")
979 if not pe
.poset
[c
].direct_smallers
.is_empty
then
981 for c2
in pe
.poset
[c
].direct_smallers
do
982 if cla
.has
(c2
) then others
= false
985 op
.append
("\"{c.name}...\
"[label=\"\
"];\n")
986 op
.append
("\"{c.name}...\
"->\"{c.name}\
"[style=dotted];\n")
991 generate_dot
(op
.to_s
, name
, "Dependency graph for class {mclass.name}")
1001 redef type OTHER: MModule
1002 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1004 # Get the list of all methods in a module
1005 fun imported_methods
: Set[MMethod] do
1006 var methods
= new HashSet[MMethod]
1007 for mclass
in imported_mclasses
do
1008 for method
in mclass
.intro_methods
do
1015 # Get the list aof all refined methods in a module
1016 fun redef_methods
: Set[MMethod] do
1017 var methods
= new HashSet[MMethod]
1018 for mclass
in redef_mclasses
do
1019 for method
in mclass
.intro_methods
do
1026 # URL to nitdoc page
1028 var res
= new Buffer
1029 res
.append
("module_")
1030 var mowner
= public_owner
1031 if mowner
!= null then
1032 res
.append
("{public_owner.name}_")
1034 res
.append
("{self.name}.html")
1038 # html anchor id to the module in a nitdoc page
1039 fun anchor
: String do
1040 var res
= new Buffer
1042 var mowner
= public_owner
1043 if mowner
!= null then
1044 res
.append
("{public_owner.name}_")
1046 res
.append
(self.name
)
1050 # Return a link (html a tag) to the nitdoc module page
1051 fun link
(mbuilder
: ModelBuilder): String do
1052 return "<a href='{url}' title='{mbuilder.mmodule2nmodule[self].short_comment}'>{name}</a>"
1055 # Return the module signature decorated with html
1056 fun html_signature
(mbuilder
: ModelBuilder): String do
1057 return "<span>module {html_full_namespace(mbuilder)}</span>"
1060 # Return the module full namespace decorated with html
1061 fun html_full_namespace
(mbuilder
: ModelBuilder): String do
1062 var res
= new Buffer
1063 res
.append
("<span>")
1064 var mowner
= public_owner
1065 if mowner
!= null then
1066 res
.append
(public_owner
.html_namespace
(mbuilder
))
1069 res
.append
(self.link
(mbuilder
))
1070 res
.append
("</span>")
1074 # Return the module full namespace decorated with html
1075 fun html_namespace
(mbuilder
: ModelBuilder): String do
1076 var res
= new Buffer
1077 res
.append
("<span>")
1078 var mowner
= public_owner
1079 if mowner
!= null then
1080 res
.append
(public_owner
.html_namespace
(mbuilder
))
1082 res
.append
(self.link
(mbuilder
))
1084 res
.append
("</span>")
1088 # Return the full comment of the module decorated with html
1089 fun html_full_comment
(mbuilder
: ModelBuilder): String do
1090 var res
= new Buffer
1091 res
.append
("<div id='description'>")
1092 res
.append
("<pre class='text_label'>{mbuilder.mmodule2nmodule[self].comment}</pre>")
1093 res
.append
("<textarea class='edit' rows='1' cols='76' id='fileContent'></textarea>")
1094 res
.append
("<a id='cancelBtn'>Cancel</a>")
1095 res
.append
("<a id='commitBtn'>Commit</a>")
1096 res
.append
("<pre class='text_label' id='preSave' type='2'></pre>")
1097 res
.append
("</div>")
1104 redef type OTHER: MClass
1105 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1107 # Return the module signature decorated with html
1108 fun html_full_signature
(mbuilder
: ModelBuilder): String do
1109 var res
= new Buffer
1110 if visibility
<= none_visibility
then
1111 res
.append
("private ")
1112 else if visibility
== protected_visibility
then
1113 res
.append
("protected ")
1115 res
.append
("{kind} {html_namespace(mbuilder)}")
1119 # Add type parameters
1120 fun html_signature
: String do
1122 return "{name}[{intro.parameter_names.join(", ")}]"
1128 # Return a link (html a tag) to the nitdoc class page
1129 fun link
(mbuilder
: ModelBuilder): String do
1130 if mbuilder
.mclassdef2nclassdef
.has_key
(intro
) then
1131 var nclass
= mbuilder
.mclassdef2nclassdef
[intro
]
1132 if nclass
isa AStdClassdef then
1133 return "<a href='{url}' title=\"{nclass.short_comment}\
">{html_signature}</a>"
1135 return "<a href='{url}'>{html_signature}</a>"
1138 return "<a href='{url}'>{html_signature}</a>"
1142 # Return the class namespace decorated with html
1143 fun html_namespace
(mbuilder
: ModelBuilder): String do
1144 var res
= new Buffer
1145 res
.append
(intro_mmodule
.html_namespace
(mbuilder
))
1146 res
.append
("::<span>{self.link(mbuilder)}</span>")
1151 return "class_{public_owner}_{c_name}.html"
1154 # Escape name for html output
1155 redef fun name
do return super.html_escape
1158 redef class MProperty
1160 redef type OTHER: MProperty
1161 redef fun <(other
: OTHER): Bool do return self.name
< other
.name
1163 # Return the property namespace decorated with html
1164 fun html_namespace
(mbuilder
: ModelBuilder): String do
1165 return "{intro_mclassdef.mclass.html_namespace(mbuilder)}::<span>{intro.link(mbuilder)}</span>"
1168 # Return the property signature decorated with html
1169 fun html_signature
(mbuilder
: ModelBuilder): String do
1170 var nprop
= mbuilder
.mpropdef2npropdef
[intro
]
1171 return "{name}{nprop.html_signature(mbuilder)}"
1174 # Escape name for html output
1175 redef fun name
do return super.html_escape
1179 fun link
(mbuilder
: ModelBuilder): String is abstract
1182 redef class MClassType
1183 redef fun link
(mbuilder
) do return mclass
.link
(mbuilder
)
1186 redef class MNullableType
1187 redef fun link
(mbuilder
) do return "nullable {mtype.link(mbuilder)}"
1190 redef class MClassDef
1191 # Return the classdef namespace decorated with html
1192 fun html_namespace
(mbuilder
: ModelBuilder): String do
1193 var res
= new Buffer
1194 res
.append
(mmodule
.html_full_namespace
(mbuilder
))
1195 res
.append
("::<span>{self.mclass.link(mbuilder)}</span>")
1200 redef class MPropDef
1202 redef type OTHER: MPropDef
1203 redef fun <(other
: OTHER): Bool do return self.mproperty
.name
< other
.mproperty
.name
1205 fun url
: String do return "{mclassdef.mclass.url}#{anchor}"
1206 fun anchor
: String do return "PROP_{mclassdef.mclass.public_owner.name}_{c_name}"
1208 # Return a link (html a tag) to the nitdoc class page
1209 fun link
(mbuilder
: ModelBuilder): String do
1210 if mbuilder
.mpropdef2npropdef
.has_key
(self) then
1211 var nprop
= mbuilder
.mpropdef2npropdef
[self]
1212 return "<a href=\"{url}\
" title=\"{nprop.short_comment}\
">{mproperty.name}</a>"
1214 return "<a href=\"{url}\
">{mproperty.name}</a>"
1218 # Return a list item for the mpropdef
1219 fun html_list_item
(mbuilder
: ModelBuilder): String do
1220 var res
= new Buffer
1222 res
.append
("<li class='intro'>")
1223 res
.append
("<span title='introduction'>I</span> {link(mbuilder)} ({mclassdef.mclass.link(mbuilder)})")
1226 res
.append
("<li class='redef'>")
1227 res
.append
("<span title='redefinition'>R</span> {link(mbuilder)} ({mclassdef.mclass.link(mbuilder)})")
1233 # Return a list item for the mpropdef
1234 fun html_sidebar_item
(page
: NitdocClass): String do
1235 var res
= new Buffer
1236 if is_intro
and mclassdef
.mclass
== page
.mclass
then
1237 res
.append
("<li class='intro'>")
1238 res
.append
("<span title='Introduced'>I</span>")
1239 else if is_intro
and mclassdef
.mclass
!= page
.mclass
then
1240 res
.append
("<li class='inherit'>")
1241 res
.append
("<span title='Inherited'>H</span>")
1243 res
.append
("<li class='redef'>")
1244 res
.append
("<span title='Redefined'>R</span>")
1246 res
.append
(link
(page
.mbuilder
))
1251 fun html_full_desc
(page
: NitdocClass): String is abstract
1252 fun html_info
(page
: NitdocClass): String is abstract
1255 redef class MMethodDef
1256 redef fun html_full_desc
(page
) do
1257 if not page
.mbuilder
.mpropdef2npropdef
.has_key
(self) then
1260 var res
= new Buffer
1261 var mprop
= mproperty
1262 var nprop
= page
.mbuilder
.mpropdef2npropdef
[self]
1263 var classes
= new Array[String]
1264 var is_redef
= mprop
.intro_mclassdef
.mclass
!= page
.mclass
1266 if mprop
.is_init
then classes
.add
("init")
1267 if is_redef
then classes
.add
("redef")
1268 if mprop
.visibility
== none_visibility
then
1269 classes
.add
("private")
1270 else if mprop
.visibility
== protected_visibility
then
1271 classes
.add
("protected")
1273 classes
.add
("public")
1275 res
.append
("<article class='{classes.join(" ")}' id='{anchor}'>")
1276 res
.append
("<h3 class='signature'>{mprop.html_signature(page.mbuilder)}</h3>")
1277 res
.append
(html_info
(page
))
1278 res
.append
("<div class='description'>")
1279 if nprop
.comment
== "" then
1280 res
.append
("<a class=\"newComment\
" title=\"32\
" tag=\"\
">New Comment</a>")
1282 res
.append
("<pre class=\"text_label\
" title=\"\
" name=\"\
" tag=\"\
" type=\"1\
">{nprop.comment}</pre>")
1284 res
.append
("<textarea id=\"fileContent\
" class=\"edit\
" cols=\"76\
" rows=\"1\
" style=\"display
: none
;\
"></textarea><a id=\"cancelBtn\
" style=\"display
: none
;\
">Cancel</a><a id=\"commitBtn\
" style=\"display
: none
;\
">Commit</a><pre id=\"preSave\
" class=\"text_label\
" type=\"2\
"></pre>")
1287 page
.nitdoc
.mainmodule
.linearize_mpropdefs
(mprop
.mpropdefs
)
1288 var previous_defs
= new Array[MMethodDef]
1289 var next_defs
= new Array[MMethodDef]
1290 var self_passed
= false
1291 for def
in mprop
.mpropdefs
do
1296 if not self_passed
then
1297 if not page
.mclass
.ancestors
.has
(def
.mclassdef
.mclass
) then continue
1298 if def
.is_intro
then continue
1299 previous_defs
.add
(def
)
1301 if not page
.mclass
.descendants
.has
(def
.mclassdef
.mclass
) then continue
1305 res
.append
("defined by {mclassdef.mmodule.html_full_namespace(page.mbuilder)}")
1306 if not is_intro
then
1307 res
.append
(", introduced by {mprop.intro.mclassdef.mclass.link(page.mbuilder)}")
1309 if not previous_defs
.is_empty
then
1310 res
.append
(", inherited from ")
1311 for i
in [0..previous_defs
.length
[ do
1312 res
.append
(previous_defs
[i
].mclassdef
.mclass
.link
(page
.mbuilder
))
1313 if i
< previous_defs
.length
- 1 then res
.append
(", ")
1316 if not next_defs
.is_empty
then
1317 res
.append
(", redefined by ")
1318 for i
in [0..next_defs
.length
[ do
1319 res
.append
(next_defs
[i
].mclassdef
.mclass
.link
(page
.mbuilder
))
1320 if i
< next_defs
.length
- 1 then res
.append
(", ")
1324 res
.append
("</div>")
1325 res
.append
("</article>")
1329 redef fun html_info
(page
) do
1330 var res
= new Buffer
1331 res
.append
("<div class='info'>")
1332 if mproperty
.visibility
<= none_visibility
then
1333 res
.append
("private ")
1334 else if mproperty
.visibility
<= protected_visibility
then
1335 res
.append
("protected ")
1337 if mproperty
.intro_mclassdef
.mclass
!= page
.mclass
then res
.append
("redef ")
1338 res
.append
("fun {mproperty.html_namespace(page.mbuilder)}")
1339 res
.append
("</div>")
1340 res
.append
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
1345 redef class MVirtualTypeDef
1346 redef fun html_full_desc
(page
) do
1347 var res
= new Buffer
1348 var mprop
= mproperty
1349 var is_redef
= mprop
.intro_mclassdef
.mclass
!= page
.mclass
1350 var classes
= new Array[String]
1352 if is_redef
then classes
.add
("redef")
1353 if mprop
.visibility
== none_visibility
then
1354 classes
.add
("private")
1355 else if mprop
.visibility
== protected_visibility
then
1356 classes
.add
("protected")
1358 classes
.add
("public")
1360 res
.append
("<article class='{classes.join(" ")}' id='{anchor}'>")
1361 res
.append
("<h3 class='signature'>{mprop.name}: {bound.link(page.mbuilder)}</h3>")
1362 res
.append
(html_info
(page
))
1363 res
.append
("<div class='description'>")
1365 if page
.mbuilder
.mpropdef2npropdef
.has_key
(self) and page
.mbuilder
.mpropdef2npropdef
[self].comment
!= "" then
1366 var nprop
= page
.mbuilder
.mpropdef2npropdef
[self]
1367 res
.append
("<pre class=\"text_label\
" title=\"\
" name=\"\
" tag=\"\
" type=\"1\
">{nprop.comment}</pre>")
1369 res
.append
("<a class=\"newComment\
" title=\"32\
" tag=\"\
">New Comment</a>")
1371 res
.append
("<textarea id=\"fileContent\
" class=\"edit\
" cols=\"76\
" rows=\"1\
" style=\"display
: none
;\
"></textarea><a id=\"cancelBtn\
" style=\"display
: none
;\
">Cancel</a><a id=\"commitBtn\
" style=\"display
: none
;\
">Commit</a><pre id=\"preSave\
" class=\"text_label\
" type=\"2\
"></pre>")
1374 page
.nitdoc
.mainmodule
.linearize_mpropdefs
(mprop
.mpropdefs
)
1375 var previous_defs
= new Array[MVirtualTypeDef]
1376 var next_defs
= new Array[MVirtualTypeDef]
1377 var self_passed
= false
1378 for def
in mprop
.mpropdefs
do
1383 if not self_passed
then
1384 if not page
.mclass
.ancestors
.has
(def
.mclassdef
.mclass
) then continue
1385 if def
.is_intro
then continue
1386 previous_defs
.add
(def
)
1388 if not page
.mclass
.descendants
.has
(def
.mclassdef
.mclass
) then continue
1392 res
.append
("defined by {mclassdef.mmodule.html_full_namespace(page.mbuilder)}")
1393 if not is_intro
then
1394 res
.append
(", introduced by {mprop.intro.mclassdef.mclass.link(page.mbuilder)}")
1396 if not previous_defs
.is_empty
then
1397 res
.append
(", inherited from ")
1398 for i
in [0..previous_defs
.length
[ do
1399 res
.append
(previous_defs
[i
].mclassdef
.mclass
.link
(page
.mbuilder
))
1400 if i
< previous_defs
.length
- 1 then res
.append
(", ")
1403 if not next_defs
.is_empty
then
1404 res
.append
(", redefined by ")
1405 for i
in [0..next_defs
.length
[ do
1406 res
.append
(next_defs
[i
].mclassdef
.mclass
.link
(page
.mbuilder
))
1407 if i
< next_defs
.length
- 1 then res
.append
(", ")
1411 res
.append
("</div>")
1412 res
.append
("</article>")
1416 redef fun html_info
(page
) do
1417 var res
= new Buffer
1418 res
.append
("<div class='info'>")
1419 if mproperty
.intro_mclassdef
.mclass
!= page
.mclass
then res
.append
("redef ")
1420 res
.append
("type {mproperty.html_namespace(page.mbuilder)}")
1421 res
.append
("</div>")
1422 res
.append
("<div style=\"float
: right
;\
"><a id=\"lblDiffCommit\
"></a></div>")
1432 private fun comment
: String do
1433 var ret
= new Buffer
1434 if n_moduledecl
is null or n_moduledecl
.n_doc
is null then ret
1435 if n_moduledecl
.n_doc
is null then return ""
1436 for t
in n_moduledecl
.n_doc
.n_comment
do
1437 ret
.append
(t
.text
.substring_from
(1))
1439 return ret
.to_s
.html_escape
1442 private fun short_comment
: String do
1443 var ret
= new Buffer
1444 if n_moduledecl
!= null and n_moduledecl
.n_doc
!= null then
1445 ret
.append
(n_moduledecl
.n_doc
.n_comment
.first
.text
.substring_from
(2).replace
("\n", ""))
1447 return ret
.to_s
.html_escape
1451 redef class AStdClassdef
1452 private fun comment
: String do
1453 var ret
= new Buffer
1454 if n_doc
!= null then
1455 for t
in n_doc
.n_comment
do ret
.append
(t
.text
.substring_from
(1))
1457 return ret
.to_s
.html_escape
1460 private fun short_comment
: String do
1461 var ret
= new Buffer
1462 if n_doc
!= null then ret
.append
(n_doc
.n_comment
.first
.text
.substring_from
(2).replace
("\n", ""))
1463 return ret
.to_s
.html_escape
1467 redef class APropdef
1468 private fun short_comment
: String is abstract
1469 private fun html_signature
(mbuilder
: ModelBuilder): String is abstract
1470 private fun comment
: String is abstract
1473 redef class AAttrPropdef
1474 redef fun short_comment
do
1475 var ret
= new Buffer
1476 if n_doc
!= null then ret
.append
(n_doc
.n_comment
.first
.text
.substring_from
(2).replace
("\n", ""))
1477 return ret
.to_s
.html_escape
1480 redef private fun comment
: String do
1481 var ret
= new Buffer
1482 if n_doc
!= null then
1483 for t
in n_doc
.n_comment
do ret
.append
(t
.text
.substring_from
(1))
1485 return ret
.to_s
.html_escape
1488 redef fun html_signature
(mbuilder
) do
1490 if n_type
!= null and n_type
.to_html
!= "" then res
+= ": {n_type.to_html}"
1495 redef class AMethPropdef
1496 redef fun short_comment
do
1497 var ret
= new Buffer
1498 if n_doc
!= null then ret
.append
(n_doc
.n_comment
.first
.text
.substring_from
(2).replace
("\n", ""))
1499 return ret
.to_s
.html_escape
1502 redef private fun comment
: String do
1503 var ret
= new Buffer
1504 if n_doc
!= null then
1505 for t
in n_doc
.n_comment
do ret
.append
(t
.text
.substring_from
(1))
1507 return ret
.to_s
.html_escape
1510 redef fun html_signature
(mbuilder
) do
1511 if n_signature
!= null then return n_signature
.to_html
1516 redef class ATypePropdef
1517 redef fun short_comment
do
1518 var ret
= new Buffer
1519 if n_doc
!= null then ret
.append
(n_doc
.n_comment
.first
.text
.substring_from
(2).replace
("\n", ""))
1520 return ret
.to_s
.html_escape
1523 redef private fun comment
: String do
1524 var ret
= new Buffer
1525 if n_doc
!= null then
1526 for t
in n_doc
.n_comment
do ret
.append
(t
.text
.substring_from
(1))
1528 return ret
.to_s
.html_escape
1531 redef fun html_signature
(mbuilder
) do
1532 return mpropdef
.bound
.link
(mbuilder
)
1536 redef class ASignature
1537 fun to_html
: String do
1540 if not n_params
.is_empty
then
1541 ret
= "{ret}({n_params.join(", ")})"
1543 if n_type
!= null and n_type
.to_html
!= "" then ret
+= ": {n_type.to_html}"
1550 var ret
= "{n_id.text}"
1551 if n_type
!= null then
1552 ret
= "{ret}: {n_type.to_html}"
1553 if n_dotdotdot
!= null then ret
= "{ret}..."
1560 fun to_html
: String do
1561 var ret
= "<a href=\"{n_id.text}.html\
">{n_id.text}</a>"
1562 if n_kwnullable
!= null then ret
= "nullable {ret}"
1563 if not n_types
.is_empty
then ret
= "{ret}[{n_types.join(", ")}]"
1567 fun name
: String do return n_id
.text
.html_escape
1570 # Create a tool context to handle options and paths
1571 var toolcontext
= new ToolContext
1573 # Here we launch the nit index
1574 var nitdoc
= new Nitdoc(toolcontext
)