ni_nitdoc: Adding properties column in class page
[nit.git] / src / ni_nitdoc.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2008 Jean Privat <jean@pryen.org>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 module ni_nitdoc
18
19 import model_utils
20 import abstract_compiler
21 import html
22
23 class Nitdoc
24 private var toolcontext: ToolContext
25 private var model: Model
26 private var modelbuilder: ModelBuilder
27 private var mainmodule: MModule
28 private var arguments: Array[String]
29 private var destinationdir: nullable String
30 private var sharedir: nullable String
31
32 private var opt_dir = new OptionString("Directory where doc is generated", "-d", "--dir")
33 private var opt_source = new OptionString("What link for source (%f for filename, %l for first line, %L for last line)", "--source")
34 private var opt_sharedir = new OptionString("Directory containing the nitdoc files", "--sharedir")
35 private var opt_nodot = new OptionBool("Do not generate graphes with graphiviz", "--no-dot")
36
37 init(toolcontext: ToolContext) do
38 # We need a model to collect stufs
39 self.toolcontext = toolcontext
40 self.arguments = toolcontext.option_context.rest
41 toolcontext.option_context.add_option(opt_dir)
42 toolcontext.option_context.add_option(opt_source)
43 toolcontext.option_context.add_option(opt_sharedir)
44 toolcontext.option_context.add_option(opt_nodot)
45 process_options
46
47 if arguments.length < 1 then
48 toolcontext.option_context.usage
49 exit(1)
50 end
51
52 model = new Model
53 modelbuilder = new ModelBuilder(model, toolcontext)
54
55 # Here we load an process std modules
56 var mmodules = modelbuilder.parse_and_build([arguments.first])
57 if mmodules.is_empty then return
58 modelbuilder.full_propdef_semantic_analysis
59 assert mmodules.length == 1
60 self.mainmodule = mmodules.first
61 end
62
63 private fun process_options do
64 if not opt_dir.value is null then
65 destinationdir = opt_dir.value
66 else
67 destinationdir = "nitdoc_directory"
68 end
69 if not opt_sharedir.value is null then
70 sharedir = opt_sharedir.value
71 else
72 var dir = "NIT_DIR".environ
73 if dir.is_empty then
74 dir = "{sys.program_name.dirname}/../share/nitdoc"
75 else
76 dir = "{dir}/share/nitdoc"
77 end
78 sharedir = dir
79 if sharedir is null then
80 print "Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR"
81 abort
82 end
83 dir = "{sharedir.to_s}/scripts/js-facilities.js"
84 if sharedir is null then
85 print "Error: Invalid nitdoc share files. Check --sharedir or envvar NIT_DIR"
86 abort
87 end
88 end
89 end
90
91 fun start do
92 if arguments.length == 1 then
93 # Create destination dir if it's necessary
94 if not destinationdir.file_exists then destinationdir.mkdir
95 sys.system("cp -r {sharedir.to_s}/* {destinationdir.to_s}/")
96 overview
97 fullindex
98 modules
99 classes
100 end
101 end
102
103 fun overview do
104 var overviewpage = new NitdocOverview.with(modelbuilder.nmodules, self.opt_nodot.value, destinationdir.to_s)
105 overviewpage.save("{destinationdir.to_s}/index.html")
106 end
107
108 fun fullindex do
109 var fullindex = new NitdocFullindex.with(model.mmodules)
110 fullindex.save("{destinationdir.to_s}/full-index.html")
111 end
112
113 fun modules do
114 for mod in modelbuilder.nmodules do
115 var modulepage = new NitdocModules.with(mod)
116 modulepage.save("{destinationdir.to_s}/{mod.mmodule.name}.html")
117 end
118 end
119
120 fun classes do
121 for amodule in modelbuilder.nmodules do
122 for mclass, aclassdef in amodule.mclass2nclassdef do
123 var classpage = new NitdocMClasses.with(mclass, aclassdef)
124 classpage.save("{destinationdir.to_s}/{mclass.name}.html")
125 end
126 end
127 end
128
129 end
130
131 class NitdocOverview
132 super NitdocPage
133
134 var amodules: Array[AModule]
135
136 # Init with Array[AModule] to get all ifnormations about each MModule containt in a program
137 # opt_nodot to inform about the graph gen
138 # destination: to know where will be saved dot files
139 init with(modules: Array[AModule], opt_nodot: Bool, destination: String) do
140 self.amodules = modules
141 self.opt_nodot = opt_nodot
142 self.destinationdir = destination
143 end
144
145 redef fun head do
146 super
147 add("title").text("Overview | Nit Standard Library")
148 end
149
150 redef fun header do
151 open("header")
152 open("nav").add_class("main")
153 open("ul")
154 add("li").add_class("current").text("Overview")
155 open("li")
156 add_html("<a href=\"full-index.html\">Full Index</a>")
157 close("li")
158 open("li").attr("id", "liGitHub")
159 open("a").add_class("btn").attr("id", "logGitHub")
160 add("img").attr("id", "imgGitHub").attr("src", "resources/icons/github-icon.png")
161 close("a")
162 open("div").add_class("popover bottom")
163 add("div").add_class("arrow").text(" ")
164 open("div").add_class("githubTitle")
165 add("h3").text("Github Sign In")
166 close("div")
167 open("div")
168 add("label").attr("id", "lbloginGit").text("Username")
169 add("input").attr("id", "loginGit").attr("name", "login").attr("type", "text")
170 open("label").attr("id", "logginMessage").text("Hello ")
171 open("a").attr("id", "githubAccount")
172 add("strong").attr("id", "nickName").text(" ")
173 close("a")
174 close("label")
175 close("div")
176 open("div")
177 add("label").attr("id", "lbpasswordGit").text("Password")
178 add("input").attr("id", "passwordGit").attr("name", "password").attr("type", "password")
179 open("div").attr("id", "listBranches")
180 add("label").attr("id", "lbBranches").text("Branch")
181 add("select").add_class("dropdown").attr("id", "dropBranches").attr("name", "dropBranches").attr("tabindex", "1").text(" ")
182 close("div")
183 close("div")
184 open("div")
185 add("label").attr("id", "lbrepositoryGit").text("Repository")
186 add("input").attr("id", "repositoryGit").attr("name", "repository").attr("type", "text")
187 close("div")
188 open("div")
189 add("label").attr("id", "lbbranchGit").text("Branch")
190 add("input").attr("id", "branchGit").attr("name", "branch").attr("type", "text")
191 close("div")
192 open("div")
193 add("a").attr("id", "signIn").text("Sign In")
194 close("div")
195 close("div")
196 close("li")
197 close("ul")
198 close("nav")
199 close("header")
200 end
201
202 redef fun body do
203 super
204 open("div").add_class("page")
205 open("div").add_class("content fullpage")
206 add("h1").text("Nit Standard Library")
207 open("article").add_class("overview")
208 add_html("<p>Documentation for the standard library of Nit<br />Version jenkins-component=stdlib-19<br />Date: TODAY</p>")
209 close("article")
210 open("article").add_class("overview")
211 add("h2").text("Modules")
212 open("ul")
213 add_modules
214 close("ul")
215 process_generate_dot
216 close("article")
217 close("div")
218 close("div")
219 add("footer").text("Nit standard library. Version jenkins-component=stdlib-19.")
220 end
221
222 fun add_modules do
223 var ls = new List[nullable MModule]
224 for amodule in amodules do
225 var mmodule = amodule.mmodule.public_owner
226 if mmodule != null and not ls.has(mmodule) then
227 open("li")
228 add("a").attr("href", "{mmodule.name}.html").text("{mmodule.to_s} ")
229 add_html(amodule.comment)
230 close("li")
231 ls.add(mmodule)
232 end
233 end
234 end
235
236 fun process_generate_dot do
237 var op = new Buffer
238 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")
239 for amodule in amodules do
240 op.append("\"{amodule.mmodule.name}\"[URL=\"{amodule.mmodule.name}.html\"];\n")
241 for mmodule2 in amodule.mmodule.in_importation.direct_greaters do
242 op.append("\"{amodule.mmodule.name}\"->\"{mmodule2.name}\";\n")
243 end
244 end
245 op.append("\}\n")
246 generate_dot(op.to_s, "dep", "Modules hierarchy")
247 end
248
249 end
250
251 class NitdocFullindex
252 super NitdocPage
253
254 var mmodules: Array[MModule]
255
256 init with(mmodules: Array[MModule]) do
257 self.mmodules = mmodules
258 opt_nodot = false
259 destinationdir = ""
260 end
261
262 redef fun head do
263 super
264 add("title").text("Full Index | Nit Standard Library")
265 end
266
267 redef fun header do
268 open("header")
269 open("nav").add_class("main")
270 open("ul")
271 open("li")
272 add_html("<a href=\"index.html\">Overview</a>")
273 close("li")
274 add("li").add_class("current").text("Full Index")
275 open("li").attr("id", "liGitHub")
276 open("a").add_class("btn").attr("id", "logGitHub")
277 add("img").attr("id", "imgGitHub").attr("src", "resources/icons/github-icon.png")
278 close("a")
279 open("div").add_class("popover bottom")
280 add("div").add_class("arrow").text(" ")
281 open("div").add_class("githubTitle")
282 add("h3").text("Github Sign In")
283 close("div")
284 open("div")
285 add("label").attr("id", "lbloginGit").text("Username")
286 add("input").attr("id", "loginGit").attr("name", "login").attr("type", "text")
287 open("label").attr("id", "logginMessage").text("Hello ")
288 open("a").attr("id", "githubAccount")
289 add("strong").attr("id", "nickName").text(" ")
290 close("a")
291 close("label")
292 close("div")
293 open("div")
294 add("label").attr("id", "lbpasswordGit").text("Password")
295 add("input").attr("id", "passwordGit").attr("name", "password").attr("type", "password")
296 open("div").attr("id", "listBranches")
297 add("label").attr("id", "lbBranches").text("Branch")
298 add("select").add_class("dropdown").attr("id", "dropBranches").attr("name", "dropBranches").attr("tabindex", "1").text(" ")
299 close("div")
300 close("div")
301 open("div")
302 add("label").attr("id", "lbrepositoryGit").text("Repository")
303 add("input").attr("id", "repositoryGit").attr("name", "repository").attr("type", "text")
304 close("div")
305 open("div")
306 add("label").attr("id", "lbbranchGit").text("Branch")
307 add("input").attr("id", "branchGit").attr("name", "branch").attr("type", "text")
308 close("div")
309 open("div")
310 add("a").attr("id", "signIn").text("Sign In")
311 close("div")
312 close("div")
313 close("li")
314 close("ul")
315 close("nav")
316 close("header")
317 end
318
319 redef fun body do
320 super
321 open("div").add_class("page")
322 open("div").add_class("content fullpage")
323 add("h1").text("Full Index")
324 add_content
325 close("div")
326 close("div")
327 add("footer").text("Nit standard library. Version jenkins-component=stdlib-19.")
328 end
329
330 fun add_content do
331 module_column
332 classes_column
333 properties_column
334 end
335
336 # Add to content modules column
337 fun module_column do
338 var ls = new List[nullable MModule]
339 open("article").add_class("modules filterable")
340 add("h2").text("Modules")
341 open("ul")
342 for mmodule in mmodules do
343 if mmodule.public_owner != null and not ls.has(mmodule.public_owner) then
344 ls.add(mmodule.public_owner)
345 open("li")
346 add("a").attr("href", "{mmodule.public_owner.name}.html").text(mmodule.public_owner.name)
347 close("li")
348 end
349 end
350 close("ul")
351 close("article")
352 end
353
354 # Add to content classes modules
355 fun classes_column do
356 open("article").add_class("classes filterable")
357 add("h2").text("Classes")
358 open("ul")
359
360 for mclass in mmodules.first.imported_mclasses do
361 open("li")
362 add("a").attr("href", "{mclass.name}.html").text(mclass.name)
363 close("li")
364 end
365
366 close("ul")
367 close("article")
368 end
369
370 # Insert the properties column of fullindex page
371 fun properties_column do
372 open("article").add_class("properties filterable")
373 add("h2").text("Properties")
374 open("ul")
375
376 for method in mmodules.first.imported_methods do
377 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
378 open("li").add_class("intro")
379 add("span").attr("title", "introduction").text("I")
380 add_html("&nbsp;")
381 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
382 close("li")
383 end
384
385 for method in mmodules.first.redef_methods do
386 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
387 open("li").add_class("redef")
388 add("span").attr("title", "redefinition").text("R")
389 add_html("&nbsp;")
390 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
391 close("li")
392 end
393
394 close("ul")
395 close("article")
396 end
397
398 end
399
400 class NitdocModules
401 super NitdocPage
402
403 var amodule: AModule
404 var modulename: String
405 init with(amodule: AModule) do
406 self.amodule = amodule
407 self.modulename = self.amodule.mmodule.name
408 opt_nodot = false
409 destinationdir = ""
410 end
411
412 redef fun head do
413 super
414 add("title").text("{modulename} module | {amodule.short_comment}")
415 end
416
417 redef fun header do
418 open("header")
419 open("nav").add_class("main")
420 open("ul")
421 open("li")
422 add_html("<a href=\"index.html\">Overview</a>")
423 close("li")
424 add("li").add_class("current").text(modulename)
425 open("li")
426 add_html("<a href=\"full-index.html\" >Full Index</a>")
427 close("li")
428 open("li").attr("id", "liGitHub")
429 open("a").add_class("btn").attr("id", "logGitHub")
430 add("img").attr("id", "imgGitHub").attr("src", "resources/icons/github-icon.png")
431 close("a")
432 open("div").add_class("popover bottom")
433 add("div").add_class("arrow").text(" ")
434 open("div").add_class("githubTitle")
435 add("h3").text("Github Sign In")
436 close("div")
437 open("div")
438 add("label").attr("id", "lbloginGit").text("Username")
439 add("input").attr("id", "loginGit").attr("name", "login").attr("type", "text")
440 open("label").attr("id", "logginMessage").text("Hello ")
441 open("a").attr("id", "githubAccount")
442 add("strong").attr("id", "nickName").text(" ")
443 close("a")
444 close("label")
445 close("div")
446 open("div")
447 add("label").attr("id", "lbpasswordGit").text("Password")
448 add("input").attr("id", "passwordGit").attr("name", "password").attr("type", "password")
449 open("div").attr("id", "listBranches")
450 add("label").attr("id", "lbBranches").text("Branch")
451 add("select").add_class("dropdown").attr("id", "dropBranches").attr("name", "dropBranches").attr("tabindex", "1").text(" ")
452 close("div")
453 close("div")
454 open("div")
455 add("label").attr("id", "lbrepositoryGit").text("Repository")
456 add("input").attr("id", "repositoryGit").attr("name", "repository").attr("type", "text")
457 close("div")
458 open("div")
459 add("label").attr("id", "lbbranchGit").text("Branch")
460 add("input").attr("id", "branchGit").attr("name", "branch").attr("type", "text")
461 close("div")
462 open("div")
463 add("a").attr("id", "signIn").text("Sign In")
464 close("div")
465 close("div")
466 close("li")
467 close("ul")
468 close("nav")
469 close("header")
470 end
471
472 redef fun body do
473 super
474 open("div").add_class("page")
475 menu
476 add_content
477 close("div")
478 add("footer").text("Nit standard library. Version jenkins-component=stdlib-19.")
479 end
480
481 # Insert all tags in content part
482 fun add_content do
483 open("div").add_class("content")
484 add("h1").text(modulename)
485 add("div").add_class("subtitle").text("module {modulename}")
486 module_comment
487 classes
488 properties
489 close("div")
490 end
491
492 # Insert module comment in the content
493 fun module_comment do
494 var doc = amodule.comment
495 open("div").attr("id", "description")
496 add("pre").add_class("text_label").text(doc)
497 add("textarea").add_class("edit").attr("rows", "1").attr("cols", "76").attr("id", "fileContent").text(" ")
498 add("a").attr("id", "cancelBtn").text("Cancel")
499 add("a").attr("id", "commitBtn").text("Commit")
500 add("pre").add_class("text_label").attr("id", "preSave").attr("type", "2")
501 close("div")
502 end
503
504 fun menu do
505 var mmodule = amodule.mmodule
506 open("div").add_class("menu")
507 open("nav")
508 add("h3").text("Module Hierarchy").attr("style","cursor: pointer;")
509 if mmodule.in_importation.direct_greaters.length > 0 then
510 add_html("<h4>All dependencies</h4><ul>")
511 for m in mmodule.in_importation.direct_greaters do
512 if m == mmodule or mmodule == m.public_owner then continue
513 open("li")
514 add("a").attr("href", "{m.name}.html").text(m.name)
515 close("li")
516 end
517 add_html("</ul>")
518 end
519 if mmodule.in_importation.greaters.length > 0 then
520 add_html("<h4>All clients</h4><ul>")
521 for m in mmodule.in_importation.greaters do
522 if m == mmodule then continue
523 open("li")
524 add("a").attr("href", "{m.name}.html").text(m.name)
525 close("li")
526 end
527 add_html("</ul>")
528 end
529 close("nav")
530 if mmodule.in_nesting.direct_greaters.length > 0 then
531 open("nav")
532 add("h3").text("Nested Modules").attr("style","cursor: pointer;")
533 open("ul")
534 for m in mmodule.in_nesting.direct_greaters do
535 open("li")
536 add("a").attr("href", "{m.name}.html").text(m.name)
537 close("li")
538 end
539 close("ul")
540
541 close("nav")
542 end
543 close("div")
544 end
545
546 fun classes do
547 open("div").add_class("module")
548 open("article").add_class("classes filterable")
549 add("h2").text("Classes")
550 open("ul")
551 for c, state in amodule.mmodule.mclasses do
552 var name = c.name
553 if state == c_is_intro or state == c_is_imported then
554 open("li").add_class("intro")
555 add("span").attr("title", "introduced in this module").text("I ")
556 else
557 open("li").add_class("redef")
558 add("span").attr("title", "refined in this module").text("R ")
559 end
560 add("a").attr("href", "{name}.html").text(name)
561 close("li")
562 end
563 close("ul")
564 close("article")
565 close("div")
566 end
567
568 fun properties do
569 open("article").add_class("properties filterable")
570 add_html("<h2>Properties</h2>")
571 open("ul")
572 for method in amodule.mmodule.imported_methods do
573 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
574 open("li").add_class("intro")
575 add("span").attr("title", "introduction").text("I")
576 add_html("&nbsp;")
577 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
578 close("li")
579 end
580
581 for method in amodule.mmodule.redef_methods do
582 if method.visibility is none_visibility or method.visibility is intrude_visibility then continue
583 open("li").add_class("redef")
584 add("span").attr("title", "redefinition").text("R")
585 add_html("&nbsp;")
586 add("a").attr("href", "{method.local_class.name}.html").attr("title", "").text("{method.name} ({method.local_class.name})")
587 close("li")
588 end
589
590 close("ul")
591 close("article")
592 end
593
594 end
595
596 # Nit Standard Library
597 class NitdocMClasses
598 super NitdocPage
599
600 var mclass: MClass
601 var aclassdef: AClassdef
602 var stdclassdef: nullable AStdClassdef
603 var public_owner: nullable MModule
604
605 init with(mclass: MClass, aclassdef: AClassdef) do
606 self.mclass = mclass
607 self.aclassdef = aclassdef
608 if aclassdef isa AStdClassdef then self.stdclassdef = aclassdef
609 self.public_owner = mclass.intro_mmodule.public_owner
610 opt_nodot = false
611 destinationdir = ""
612 end
613
614 redef fun head do
615 super
616 add("title").text("{self.mclass.name} class | Nit Standard Library")
617 end
618
619 redef fun header do
620 open("header")
621 open("nav").add_class("main")
622 open("ul")
623 open("li")
624 add_html("<a href=\"index.html\">Overview</a>")
625 close("li")
626 open("li")
627 if public_owner is null then
628 add_html("<a href=\"{mclass.intro_mmodule.name}.html\">{mclass.intro_mmodule.name}</a>")
629 else
630 add_html("<a href=\"{public_owner.name}.html\">{public_owner.name}</a>")
631 end
632 close("li")
633 add("li").add_class("current").text(mclass.name)
634 open("li")
635 add_html("<a href=\"full-index.html\" >Full Index</a>")
636 close("li")
637 open("li").attr("id", "liGitHub")
638 open("a").add_class("btn").attr("id", "logGitHub")
639 add("img").attr("id", "imgGitHub").attr("src", "resources/icons/github-icon.png")
640 close("a")
641 open("div").add_class("popover bottom")
642 add("div").add_class("arrow").text(" ")
643 open("div").add_class("githubTitle")
644 add("h3").text("Github Sign In")
645 close("div")
646 open("div")
647 add("label").attr("id", "lbloginGit").text("Username")
648 add("input").attr("id", "loginGit").attr("name", "login").attr("type", "text")
649 open("label").attr("id", "logginMessage").text("Hello ")
650 open("a").attr("id", "githubAccount")
651 add("strong").attr("id", "nickName").text(" ")
652 close("a")
653 close("label")
654 close("div")
655 open("div")
656 add("label").attr("id", "lbpasswordGit").text("Password")
657 add("input").attr("id", "passwordGit").attr("name", "password").attr("type", "password")
658 open("div").attr("id", "listBranches")
659 add("label").attr("id", "lbBranches").text("Branch")
660 add("select").add_class("dropdown").attr("id", "dropBranches").attr("name", "dropBranches").attr("tabindex", "1").text(" ")
661 close("div")
662 close("div")
663 open("div")
664 add("label").attr("id", "lbrepositoryGit").text("Repository")
665 add("input").attr("id", "repositoryGit").attr("name", "repository").attr("type", "text")
666 close("div")
667 open("div")
668 add("label").attr("id", "lbbranchGit").text("Branch")
669 add("input").attr("id", "branchGit").attr("name", "branch").attr("type", "text")
670 close("div")
671 open("div")
672 add("a").attr("id", "signIn").text("Sign In")
673 close("div")
674 close("div")
675 close("li")
676 close("ul")
677 close("nav")
678 close("header")
679 end
680
681 redef fun body do
682 super
683 open("div").add_class("page")
684 add_content
685 close("div")
686 add("footer").text("Nit standard library. Version jenkins-component=stdlib-19.")
687 end
688
689 # Insert all tags in content part
690 fun add_content do
691 open("div").add_class("menu")
692 properties_column
693 close("div")
694 open("div").add_class("content")
695 close("div")
696 end
697
698 fun properties_column do
699 open("nav").add_class("properties filterable")
700 add("h3").text("Properties")
701
702 if mclass.virtual_types.length > 0 then
703 add("h4").text("Virtual Types")
704 open("ul")
705 for prop in mclass.virtual_types do
706 add_html("<li class=\"redef\"><span title=\"Redefined\">R</span><a href=\"{prop.link_anchor}\">{prop.name}</a></li>")
707 end
708 close("ul")
709 end
710 if mclass.constructors.length > 0 then
711 add("h4").text("Constructors")
712 open("ul")
713 for prop in mclass.constructors do
714 add_html("<li class=\"intro\"><span title=\"Introduced\">I</span><a href=\"{prop.link_anchor}\">{prop.name}</a></li>")
715 end
716 close("ul")
717 end
718 add("h4").text("Methods")
719 open("ul")
720 if mclass.intro_methods.length > 0 then
721 for prop in mclass.intro_methods do
722 if prop.visibility is public_visibility or prop.visibility is protected_visibility then add_html("<li class=\"intro\"><span title=\"Introduced\">I</span><a href=\"{prop.link_anchor}\">{prop.name}</a></li>")
723 end
724 end
725 if mclass.inherited_methods.length > 0 then
726 for prop in mclass.inherited_methods do
727 if prop.visibility is public_visibility or prop.visibility is protected_visibility then add_html("<li class=\"inherit\"><span title=\"Inherited\">H</span><a href=\"{prop.link_anchor}\">{prop.name}</a></li>")
728 end
729 end
730 if mclass.redef_methods.length > 0 then
731 for prop in mclass.redef_methods do
732 if prop.visibility is public_visibility or prop.visibility is protected_visibility then add_html("<li class=\"redef\"><span title=\"Refined\">R</span><a href=\"{prop.link_anchor}\">{prop.name}</a></li>")
733 end
734 end
735 close("ul")
736 close("nav")
737 end
738
739 end
740
741 class NitdocPage
742 super HTMLPage
743
744 var opt_nodot: Bool
745 var destinationdir : String
746
747 redef fun head do
748 add("meta").attr("charset", "utf-8")
749 add("script").attr("type", "text/javascript").attr("src", "scripts/jquery-1.7.1.min.js")
750 add("script").attr("type", "text/javascript").attr("src", "quicksearch-list.js")
751 add("script").attr("type", "text/javascript").attr("src", "scripts/js-facilities.js")
752 add("link").attr("rel", "stylesheet").attr("href", "styles/main.css").attr("type", "text/css").attr("media", "screen")
753 end
754
755 redef fun body do header
756 fun header do end
757
758 # Generate a clickable graphviz image using a dot content
759 fun generate_dot(dot: String, name: String, alt: String) do
760 if opt_nodot then return
761 var file = new OFStream.open("{self.destinationdir}/{name}.dot")
762 file.write(dot)
763 file.close
764 sys.system("\{ test -f {self.destinationdir}/{name}.png && test -f {self.destinationdir}/{name}.s.dot && diff {self.destinationdir}/{name}.dot {self.destinationdir}/{name}.s.dot >/dev/null 2>&1 ; \} || \{ cp {self.destinationdir}/{name}.dot {self.destinationdir}/{name}.s.dot && dot -Tpng -o{self.destinationdir}/{name}.png -Tcmapx -o{self.destinationdir}/{name}.map {self.destinationdir}/{name}.s.dot ; \}")
765 open("article").add_class("graph")
766 add("img").attr("src", "{name}.png").attr("usemap", "#{name}").attr("style", "margin:auto").attr("alt", "{alt}")
767 close("article")
768 var fmap = new IFStream.open("{self.destinationdir}/{name}.map")
769 add_html(fmap.read_all)
770 fmap.close
771 end
772
773 end
774
775 redef class AModule
776 private fun comment: String do
777 var ret = ""
778 if n_moduledecl is null or n_moduledecl.n_doc is null then ret
779 if n_moduledecl.n_doc is null then return ""
780 for t in n_moduledecl.n_doc.n_comment do
781 ret += "{t.text.replace("# ", "")}"
782 end
783 return ret
784 end
785
786 private fun short_comment: String do
787 var ret = ""
788 if n_moduledecl != null and n_moduledecl.n_doc != null then
789 var txt = n_moduledecl.n_doc.n_comment.first.text
790 txt = txt.replace("# ", "")
791 txt = txt.replace("\n", "")
792 ret += txt
793 end
794 return ret
795 end
796 end
797
798 redef class MModule
799
800 var amodule: nullable AModule
801
802 # Get the list of all methods in a module
803 fun imported_methods: Set[MMethod] do
804 var methods = new HashSet[MMethod]
805 for mclass in imported_mclasses do
806 for method in mclass.intro_methods do
807 methods.add(method)
808 end
809 end
810 return methods
811 end
812
813 # Get the list aof all refined methods in a module
814 fun redef_methods: Set[MMethod] do
815 var methods = new HashSet[MMethod]
816 for mclass in redef_mclasses do
817 for method in mclass.intro_methods do
818 methods.add(method)
819 end
820 end
821 return methods
822 end
823 end
824
825 redef class MProperty
826
827 var is_redef: Bool
828 var apropdef: nullable APropdef
829
830 redef init(intro_mclassdef: MClassDef, name: String, visibility: MVisibility)
831 do
832 super
833 is_redef = false
834 end
835
836 fun local_class: MClass do
837 var classdef = self.intro_mclassdef
838 return classdef.mclass
839 end
840
841 fun class_text: String do
842 return local_class.name
843 end
844
845 fun link_anchor: String do
846 return "{class_text}.html#{anchor}"
847 end
848
849 fun anchor: String do
850 return "PROP_{c_name}"
851 end
852
853 end
854
855 redef class MClass
856
857 # Associate all MMethods to each MModule concerns
858 fun all_methods: HashMap[MModule, Set[MMethod]] do
859 var hm = new HashMap[MModule, Set[MMethod]]
860 for mmodule, childs in concerns do
861 if not hm.has_key(mmodule) then hm[mmodule] = new HashSet[MMethod]
862 for prop in intro_methods do
863 if mmodule == prop.intro_mclassdef.mmodule then
864 prop.is_redef = false
865 hm[mmodule].add(prop)
866 end
867 end
868 for prop in redef_methods do
869 if mmodule == prop.intro_mclassdef.mmodule then
870 prop.is_redef = true
871 hm[mmodule].add(prop)
872 end
873 end
874
875 if childs != null then
876 for child in childs do
877 if not hm.has_key(child) then hm[child] = new HashSet[MMethod]
878 for prop in intro_methods do
879 if child == prop.intro_mclassdef.mmodule then
880 prop.is_redef = false
881 hm[child].add(prop)
882 end
883 end
884 for prop in redef_methods do
885 if child == prop.intro_mclassdef.mmodule then
886 prop.is_redef = true
887 hm[child].add(prop)
888 end
889 end
890 end
891 end
892 end
893 return hm
894 end
895
896 end
897
898 # Create a tool context to handle options and paths
899 var toolcontext = new ToolContext
900 toolcontext.process_options
901
902 # Here we launch the nit index
903 var nitdoc = new Nitdoc(toolcontext)
904 nitdoc.start