module ni_nitdoc
import model_utils
+import modelize_property
# The NitdocContext contains all the knowledge used for doc generation
class NitdocContext
model = new Model
mbuilder = new ModelBuilder(model, toolcontext)
# Here we load an process all modules passed on the command line
- var mmodules = mbuilder.parse_and_build(arguments)
+ var mmodules = mbuilder.parse(arguments)
if mmodules.is_empty then return
+ mbuilder.run_phases
if mmodules.length == 1 then
mainmodule = mmodules.first
private fun quicksearch_list do
var file = new OFStream.open("{output_dir.to_s}/quicksearch-list.js")
- var content = new Buffer
- content.append("var entries = \{ ")
-
+ file.write("var entries = \{ ")
for mmodule in model.mmodules do
- content.append("\"{mmodule.name}\": [")
- content.append("\{txt: \"{mmodule.name}\", url:\"{mmodule.url}\" \},")
- content.append("],")
+ file.write("\"{mmodule.name}\": [")
+ file.write("\{txt: \"{mmodule.name}\", url:\"{mmodule.url}\" \},")
+ file.write("],")
end
for mclass in model.mclasses do
if mclass.visibility < min_visibility then continue
- content.append("\"{mclass.name}\": [")
- content.append("\{txt: \"{mclass.name}\", url:\"{mclass.url}\" \},")
- content.append("],")
+ file.write("\"{mclass.name}\": [")
+ file.write("\{txt: \"{mclass.name}\", url:\"{mclass.url}\" \},")
+ file.write("],")
end
var name2mprops = new HashMap[String, Set[MPropDef]]
for mproperty in model.mproperties do
name2mprops[mproperty.name].add_all(mproperty.mpropdefs)
end
for mproperty, mpropdefs in name2mprops do
- content.append("\"{mproperty}\": [")
+ file.write("\"{mproperty}\": [")
for mpropdef in mpropdefs do
- content.append("\{txt: \"{mpropdef.full_name}\", url:\"{mpropdef.url}\" \},")
+ file.write("\{txt: \"{mpropdef.full_name}\", url:\"{mpropdef.url}\" \},")
end
- content.append("],")
+ file.write("],")
end
-
- content.append(" \};")
- file.write(content.to_s)
+ file.write(" \};")
file.close
end
# Nitdoc base page
abstract class NitdocPage
- super Buffer
var dot_dir: nullable String
var source: nullable String
var ctx: NitdocContext
init(ctx: NitdocContext) do
- super
self.ctx = ctx
end
protected fun head do
append("<meta charset='utf-8'/>")
append("<script type='text/javascript' src='scripts/jquery-1.7.1.min.js'></script>")
+ append("<script type='text/javascript' src='scripts/ZeroClipboard.min.js'></script>")
append("<script type='text/javascript' src='quicksearch-list.js'></script>")
+ append("<script type='text/javascript' src='scripts/base64.js'></script>")
+ append("<script type='text/javascript' src='scripts/github.js'></script>")
append("<script type='text/javascript' src='scripts/js-facilities.js'></script>")
append("<link rel='stylesheet' href='styles/main.css' type='text/css' media='screen'/>")
var title = ""
append("<nav class='main'>")
append("<ul>")
menu
- append("<li id='liGitHub'>")
- append("<a class='btn' id='logGitHub'>")
- append("<img id='imgGitHub' src='resources/icons/github-icon.png' alt='GitHub'/>")
- append("</a>")
- append("<div class='popover bottom'>")
- append("<div class='arrow'> </div>")
- append("<div class='githubTitle'>")
- append("<h3>Github Sign In</h3>")
- append("</div>")
- append("<div>")
- append("<label id='lbloginGit'>Username</label>")
- append("<input id='loginGit' name='login' type='text'/>")
- append("<label id='logginMessage'>Hello ")
- append("<a id='githubAccount'><strong id='nickName'></strong></a>")
- append("</label>")
- append("</div>")
- append("<div>")
- append("<label id='lbpasswordGit'>Password</label>")
- append("<input id='passwordGit' name='password' type='password'/>")
- append("<div id='listBranches'>")
- append("<label id='lbBranches'>Branch</label>")
- append("<select class='dropdown' id='dropBranches' name='dropBranches' tabindex='1'></select>")
- append("</div>")
- append("</div>")
- append("<div>")
- append("<label id='lbrepositoryGit'>Repository</label>")
- append("<input id='repositoryGit' name='repository' type='text'/>")
- append("</div>")
- append("<div>")
- append("<label id='lbbranchGit'>Branch</label>")
- append("<input id='branchGit' name='branch' type='text'/>")
- append("</div>")
- append("<div>")
- append("<a id='signIn'>Sign In</a>")
- append("</div>")
- append("</div>")
- append("</li>")
append("</ul>")
append("</nav>")
append("</header>")
source = x.join(l.line_start.to_s)
x = source.split_with("%L")
source = x.join(l.line_end.to_s)
- return " (<a href=\"{source.to_s}\">source</a>)"
+ return " (<a target='_blank' title='Show source' href=\"{source.to_s}\">source</a>)"
end
end
# Render the page as a html string
- fun render: String do
+ protected fun render do
append("<!DOCTYPE html>")
append("<head>")
head
append("</div>")
footer
append("</body>")
- return to_s
end
+ # Append a string to the page
+ fun append(s: String) do out.write(s)
+
# Save html page in the specified file
fun save(file: String) do
- var out = new OFStream.open(file)
- out.write(render)
- out.close
+ self.out = new OFStream.open(file)
+ render
+ self.out.close
end
+ private var out: nullable OFStream
end
# The overview page
end
redef fun content do
- append("<div class='content fullpage'>")
+ var footed = ""
+ if ctx.opt_custom_footer_text.value != null then footed = "footed"
+ append("<div class='content fullpage {footed}'>")
var title = "Overview"
if ctx.opt_custom_title.value != null then
title = ctx.opt_custom_title.value.to_s
end
redef fun content do
- append("<div class='content fullpage'>")
+ var footed = ""
+ if ctx.opt_custom_footer_text.value != null then footed = "footed"
+ append("<div class='content fullpage {footed}'>")
append("<h1>Full Index</h1>")
module_column
classes_column
redef fun content do
sidebar
- append("<div class='content'>")
+ var footed = ""
+ if ctx.opt_custom_footer_text.value != null then footed = "footed"
+ append("<div class='content {footed}'>")
append("<h1>{mmodule.name}</h1>")
append("<div class='subtitle info'>")
mmodule.html_signature(self)
end
end
# get inherited properties
- for mprop in mclass.inherited_mproperties do
- var mpropdef = mprop.intro
- if mprop.visibility < ctx.min_visibility then continue
- if mpropdef isa MVirtualTypeDef then vtypes.add(mpropdef)
- if mpropdef isa MMethodDef then
- if mpropdef.mproperty.is_init then
- consts.add(mpropdef)
- else
- meths.add(mpropdef)
+ for pclass in mclass.in_hierarchy(ctx.mainmodule).greaters do
+ if pclass == mclass then continue
+ for pclassdef in pclass.mclassdefs do
+ for mprop in pclassdef.intro_mproperties do
+ var mpropdef = mprop.intro
+ if mprop.visibility < ctx.min_visibility then continue
+ if mpropdef isa MVirtualTypeDef then vtypes.add(mpropdef)
+ if mpropdef isa MMethodDef then
+ if mpropdef.mproperty.is_init then
+ consts.add(mpropdef)
+ else
+ meths.add(mpropdef)
+ end
+ end
+ inherited.add(mpropdef)
end
end
- inherited.add(mpropdef)
end
end
properties_column
inheritance_column
append("</div>")
- append("<div class='content'>")
+ var footed = ""
+ if ctx.opt_custom_footer_text.value != null then footed = "footed"
+ append("<div class='content {footed}'>")
class_doc
append("</div>")
end
append("</div>")
# comment
var nclass = ctx.mbuilder.mclassdef2nclassdef[mclass.intro]
- append("<div style=\"float: right;\"><a id=\"lblDiffCommit\"></a></div>")
append("<section class='description'>")
- if nclass isa AStdClassdef and not nclass.full_comment.is_empty then append("<pre class=\"text_label\" title=\"122\" name=\"\" tag=\"{mclass.mclassdefs.first.location.to_s}\" type=\"2\">{nclass.full_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>")
process_generate_dot
append("</section>")
# concerns
if mclass.arity > 0 and nclass isa AStdClassdef then
for ft, bound in mclass.parameter_types do
append("<article id='FT_{ft}'>")
- append("<h3 class='signature'>{ft}: ")
+ append("<h3 class='signature' data-untyped-signature='{ft.to_s}'><span>{ft}: ")
bound.html_link(self)
- append("</h3>")
+ append("</span></h3>")
append("<div class=\"info\">formal generic type</div>")
append("</article>")
end
redef class MModule
# URL to nitdoc page
fun url: String do
- var res = new Buffer
- res.append("module_")
- var mowner = public_owner
- if mowner != null then
- res.append("{public_owner.name}_")
+ if url_cache == null then
+ var res = new Buffer
+ res.append("module_")
+ var mowner = public_owner
+ if mowner != null then
+ res.append("{public_owner.name}_")
+ end
+ res.append("{self.name}.html")
+ url_cache = res.to_s
end
- res.append("{self.name}.html")
- return res.to_s
+ return url_cache.as(not null)
end
+ private var url_cache: nullable String
# html anchor id to the module in a nitdoc page
fun anchor: String do
- var res = new Buffer
- res.append("MOD_")
- var mowner = public_owner
- if mowner != null then
- res.append("{public_owner.name}_")
+ if anchor_cache == null then
+ var res = new Buffer
+ res.append("MOD_")
+ var mowner = public_owner
+ if mowner != null then
+ res.append("{public_owner.name}_")
+ end
+ res.append(self.name)
+ anchor_cache = res.to_s
end
- res.append(self.name)
- return res.to_s
+ return anchor_cache.as(not null)
end
+ private var anchor_cache: nullable String
# Return a link (html a tag) to the nitdoc module page
fun html_link(page: NitdocPage) do
- if page.ctx.mbuilder.mmodule2nmodule.has_key(self) then
- page.append("<a href='{url}' title='{page.ctx.mbuilder.mmodule2nmodule[self].short_comment}'>{name}</a>")
- else
- page.append("<a href='{url}'>{name}</a>")
+ if html_link_cache == null then
+ var res = new Buffer
+ if page.ctx.mbuilder.mmodule2nmodule.has_key(self) then
+ res.append("<a href='{url}' title='{page.ctx.mbuilder.mmodule2nmodule[self].short_comment}'>{name}</a>")
+ else
+ res.append("<a href='{url}'>{name}</a>")
+ end
+ html_link_cache = res.to_s
end
+ page.append(html_link_cache.as(not null))
end
+ private var html_link_cache: nullable String
# Return the module signature decorated with html
fun html_signature(page: NitdocPage) do
if page.ctx.mbuilder.mmodule2nmodule.has_key(self) then
page.append("<div id='description'>")
page.append("<pre class='text_label'>{page.ctx.mbuilder.mmodule2nmodule[self].full_comment}</pre>")
- page.append("<textarea class='edit' rows='1' cols='76' id='fileContent'></textarea>")
- page.append("<a id='cancelBtn'>Cancel</a>")
- page.append("<a id='commitBtn'>Commit</a>")
- page.append("<pre class='text_label' id='preSave' type='2'></pre>")
page.append("</div>")
end
end
# Return a link (html a tag) to the nitdoc class page
fun html_link(page: NitdocPage) do
- page.append("<a href='{url}'")
- if page.ctx.mbuilder.mclassdef2nclassdef.has_key(intro) then
- var nclass = page.ctx.mbuilder.mclassdef2nclassdef[intro]
- if nclass isa AStdClassdef then
- page.append(" title=\"{nclass.short_comment}\"")
+ if html_link_cache == null then
+ var res = new Buffer
+ res.append("<a href='{url}'")
+ if page.ctx.mbuilder.mclassdef2nclassdef.has_key(intro) then
+ var nclass = page.ctx.mbuilder.mclassdef2nclassdef[intro]
+ if nclass isa AStdClassdef then
+ res.append(" title=\"{nclass.short_comment}\"")
+ end
end
+ res.append(">{signature}</a>")
+ html_link_cache = res.to_s
end
- page.append(">{signature}</a>")
+ page.append(html_link_cache.as(not null))
end
+ private var html_link_cache: nullable String
# Return the class namespace decorated with html
fun html_namespace(page: NitdocPage) do
end
redef class MPropDef
- fun url: String do return "{mclassdef.mclass.url}#{anchor}"
- fun anchor: String do return "PROP_{mclassdef.mclass.public_owner.name}_{mproperty.name}"
+ fun url: String do
+ if url_cache == null then
+ url_cache = "{mclassdef.mclass.url}#{anchor}"
+ end
+ return url_cache.as(not null)
+ end
+ private var url_cache: nullable String
+
+ fun anchor: String do
+ if anchor_cache == null then
+ anchor_cache = "PROP_{mclassdef.mclass.public_owner.name}_{mproperty.name}"
+ end
+ return anchor_cache.as(not null)
+ end
+ private var anchor_cache: nullable String
# Return a link (html a tag) to the nitdoc class page
fun html_link(page: NitdocPage) do
- if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then
- var nprop = page.ctx.mbuilder.mpropdef2npropdef[self]
- page.append("<a href=\"{url}\" title=\"{nprop.short_comment}\">{mproperty.name}</a>")
- else
- page.append("<a href=\"{url}\">{mproperty.name}</a>")
+ if html_link_cache == null then
+ var res = new Buffer
+ if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then
+ var nprop = page.ctx.mbuilder.mpropdef2npropdef[self]
+ res.append("<a href=\"{url}\" title=\"{nprop.short_comment}\">{mproperty.name}</a>")
+ else
+ res.append("<a href=\"{url}\">{mproperty.name}</a>")
+ end
+ html_link_cache = res.to_s
end
+ page.append(html_link_cache.as(not null))
end
+ private var html_link_cache: nullable String
# Return a list item for the mpropdef
private fun html_list_item(page: NitdocPage) do
if not page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then return
var nprop = page.ctx.mbuilder.mpropdef2npropdef[self]
page.append("<div class='description'>")
- if not is_intro then
+ if not is_intro and page.ctx.mbuilder.mpropdef2npropdef.has_key(mproperty.intro) then
var intro_nprop = page.ctx.mbuilder.mpropdef2npropdef[mproperty.intro]
- page.append("<p>from ")
+ page.append("<p class='info'>from ")
mproperty.html_namespace(page)
page.append("</p>")
if intro_nprop.full_comment == "" then
- page.append("<a class=\"newComment\" title=\"32\" tag=\"\">New Comment</a>")
+ page.append("<span class=\"noComment\">No comment</span>")
else
- page.append("<pre class=\"text_label\" title=\"\" name=\"\" tag=\"\" type=\"1\">{intro_nprop.full_comment}</pre>")
+ page.append("<pre>{intro_nprop.full_comment}</pre>")
end
- page.append("<p>from ")
+ page.append("<p class='info'>from ")
mclassdef.html_namespace(page)
page.append("</p>")
end
if nprop.full_comment == "" then
- page.append("<a class=\"newComment\" title=\"32\" tag=\"\">New Comment</a>")
+ page.append("<span class=\"noComment\">No comment</span>")
else
- page.append("<pre class=\"text_label\" title=\"\" name=\"\" tag=\"\" type=\"1\">{nprop.full_comment}</pre>")
+ page.append("<pre>{nprop.full_comment}</pre>")
end
- page.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>")
html_inheritance(page)
page.append("</div>")
end
classes.add(mproperty.visibility.to_s)
page.append("<article class='{classes.join(" ")}' id='{anchor}'>")
if page.ctx.mbuilder.mpropdef2npropdef.has_key(self) then
- page.append("<h3 class='signature'>{mproperty.name}")
+ page.append("<h3 class='signature' data-untyped-signature='{mproperty.name}{msignature.untyped_signature(page)}'>")
+ page.append("<span>{mproperty.name}")
msignature.html_signature(page)
- page.append("</h3>")
+ page.append("</span></h3>")
else
- page.append("<h3 class='signature'>init")
+ page.append("<h3 class='signature' data-untyped-signature='init{msignature.untyped_signature(page)}'>")
+ page.append("<span>init")
msignature.html_signature(page)
- page.append("</h3>")
+ page.append("</span></h3>")
end
html_info(page)
html_comment(page)
end
mproperty.html_namespace(page)
page.append("</div>")
- page.append("<div style=\"float: right;\"><a id=\"lblDiffCommit\"></a></div>")
end
end
if is_redef then classes.add("redef")
classes.add(mproperty.visibility.to_s)
page.append("<article class='{classes.join(" ")}' id='{anchor}'>")
- page.append("<h3 class='signature'>{mproperty.name}: ")
+ page.append("<h3 class='signature' data-untyped-signature='{mproperty.name}'><span>{mproperty.name}: ")
bound.html_link(page)
- page.append("</h3>")
+ page.append("</span></h3>")
html_info(page)
html_comment(page)
page.append("</article>")
page.append("type ")
mproperty.html_namespace(page)
page.append("</div>")
- page.append("<div style=\"float: right;\"><a id=\"lblDiffCommit\"></a></div>")
end
end
return_mtype.html_link(page)
end
end
+
+ private fun untyped_signature(page: NitdocPage): String do
+ var res = new Buffer
+ if not mparameters.is_empty then
+ res.append("(")
+ for i in [0..mparameters.length[ do
+ res.append(mparameters[i].name)
+ if i < mparameters.length - 1 then res.append(", ")
+ end
+ res.append(")")
+ end
+ return res.to_s
+ end
end
redef class MParameter