readable var _opt_dir: OptionString = new OptionString("Directory where doc is generated", "-d", "--dir")
readable var _opt_source: OptionString = new OptionString("What link for source (%f for filename, %l for first line, %L for last line)", "--source")
readable var _opt_public: OptionBool = new OptionBool("Generate only the public API", "--public")
+ readable var _opt_private: OptionBool = new OptionBool("Generate the private API", "--private")
+ readable var _opt_nodot: OptionBool = new OptionBool("Do not generate graphes with graphviz", "--no-dot")
fun public_only: Bool
do
return false
end
+ fun with_private: Bool
+ do
+ if self._opt_private.value == true then return true
+ return false
+ end
+
# The current processed filename
var filename: String
# `name' must also match the name of the graph in the dot content (eg. digraph NAME {...)
fun gen_dot(dot: String, name: String, alt: String)
do
+ if opt_nodot.value then return
var f = new OFStream.open("{self.dir}/{name}.dot")
f.write(dot)
f.close
super("nitdoc")
filename = "-unset-"
option_context.add_option(opt_public)
+ option_context.add_option(opt_private)
option_context.add_option(opt_dir)
option_context.add_option(opt_source)
+ option_context.add_option(opt_nodot)
end
redef fun process_options
super
var d = opt_dir.value
if d != null then dir = d
+
+ if not opt_nodot.value then
+ # Test if dot is runable
+ var res = sys.system("sh -c dot </dev/null >/dev/null 2>&1")
+ if res != 0 then
+ stderr.write "--no-dot implied since `dot' is not available. Try to install graphviz.\n"
+ opt_nodot.value = true
+ end
+ end
end
redef fun handle_property_conflict(lc, impls)
end
redef class String
+ # Replace all occurence of pattern ith string
+ fun replace(p: Pattern, string: String): String
+ do
+ return self.split_with(p).join(string)
+ end
+
+ # Escape the following characters < > & and " with their html counterpart
+ fun html_escape: String
+ do
+ var ret = self
+ if ret.has('&') then ret = ret.replace('&', "&")
+ if ret.has('<') then ret = ret.replace('<', "<")
+ if ret.has('>') then ret = ret.replace('>', ">")
+ if ret.has('"') then ret = ret.replace('"', """)
+ return ret
+ end
+
# Remove "/./", "//" and "bla/../"
fun simplify_path: String
do
end
if not keep then continue
clas.add(self[g])
+ lc.compute_super_classes
for gp in lc.global_properties do
if self.visibility_for(gp.intro.local_class.mmmodule) <= 1 then continue # private import or invisible import
var lp = lc[gp]
var lpi = self[gp.intro.local_class.global][gp]
if lps.has(lpi) then
- dctx.add("<li class='intro'><span title='introduction in an other module'>I</span> {lpi.html_open_link(dctx)}{lpi} ({lpi.local_class})</a></li>\n")
+ dctx.add("<li class='intro'><span title='introduction in an other module'>I</span> {lpi.html_open_link(dctx)}{lpi.html_name} ({lpi.local_class})</a></li>\n")
lps.remove(lpi)
else
- dctx.add("<li class='intro'><span title='introduction in this module'>I</span> {lpi}")
+ dctx.add("<li class='intro'><span title='introduction in this module'>I</span> {lpi.html_name}")
dctx.add(" ({lpi.local_class})</li>\n")
end
if lps.length >= 1 then
dctx.sort(lps)
for lp in lps do
- dctx.add("<li class='redef'><span title='redefinition'>R</span> {lp.html_open_link(dctx)}{lp} ({lp.local_class})</a></li>")
+ dctx.add("<li class='redef'><span title='redefinition'>R</span> {lp.html_open_link(dctx)}{lp.html_name} ({lp.local_class})</a></li>")
end
end
end
var lpi = self[gp.intro.local_class.global][gp]
lps.remove(lpi)
- dctx.add("<li class='intro'><span title='introduction'>I</span> {lpi.html_open_link(dctx)}{lpi} ({lpi.local_class})</a></li>\n")
+ dctx.add("<li class='intro'><span title='introduction'>I</span> {lpi.html_open_link(dctx)}{lpi.html_name} ({lpi.local_class})</a></li>\n")
if lps.length >= 1 then
dctx.sort(lps)
for lp in lps do
- dctx.add("<li class='redef'><span title='redefinition'>R</span> {lp.html_open_link(dctx)}{lp} ({lp.local_class})</a></li>\n")
+ dctx.add("<li class='redef'><span title='redefinition'>R</span> {lp.html_open_link(dctx)}{lp.html_name} ({lp.local_class})</a></li>\n")
end
end
end
fun html_open_link(dctx: DocContext): String
do
if not require_doc(dctx) then print "not required {self}"
- var title = "{name}{signature.to_s}"
+ var title = "{html_name}{signature.to_s}"
if short_doc != " " then
title += " #{short_doc}"
end
return "<a href=\"{local_class.html_name}.html#{html_anchor}\" title=\"{title}\">"
end
+ fun html_name: String
+ do
+ return self.name.to_s.html_escape
+ end
+
redef fun html_link(dctx)
do
if not require_doc(dctx) then print "not required {self}"
- var title = "{name}{signature.to_s}"
+ var title = "{html_name}{signature.to_s}"
if short_doc != " " then
title += " #{short_doc}"
end
- return "<a href=\"{local_class.html_name}.html#{html_anchor}\" title=\"{title}\">{self}</a>"
+ return "<a href=\"{local_class.html_name}.html#{html_anchor}\" title=\"{title}\">{html_name}</a>"
end
fun html_link_special(dctx: DocContext, lc: MMLocalClass): String
do
if not require_doc(dctx) then print "not required {self}"
- var title = "{name}{signature_for(lc.get_type)}"
+ var title = "{html_name}{signature_for(lc.get_type)}"
if short_doc != " " then
title += " #{short_doc}"
end
- return "<a href=\"{lc.html_name}.html#{html_anchor}\" title=\"{title}\">{self}</a>"
+ return "<a href=\"{lc.html_name}.html#{html_anchor}\" title=\"{title}\">{html_name}</a>"
end
# Kind of property (fun, attr, etc.)
return m == m.toplevel_owner
end
- # Return true if the global class must be documented according to the visibility configured
+ # Return true if the global property must be documented according to the visibility configured
fun require_doc(dctx: DocContext): Bool
do
- if global.visibility_level == 3 then return false # Private
+ if global.visibility_level == 3 and not dctx.with_private then return false # Private
if dctx.public_only then
var m = intro_module
if m != m.toplevel_owner then return false # Unexported
var is_redef = local_class.global != intro_class.global or local_class.mmmodule.toplevel_owner != intro_class.mmmodule.toplevel_owner
dctx.add("<article id=\"{html_anchor}\" class=\"{kind} {visibility} {if is_redef then "redef" else ""}\">\n")
- dctx.add("<h3 class=\"signature\">{name}{signature.to_html(dctx, true)}</h3>\n")
+ dctx.add("<h3 class=\"signature\">{html_name}{signature.to_html(dctx, true)}</h3>\n")
dctx.add("<div class=\"info\">\n")
#dctx.add("<p>LP: {self.mmmodule.html_link(dctx)}::{self.local_class.html_link(dctx)}::{self.html_link(dctx)}</p>")
if is_redef then
dctx.add("::{mmmodule[intro_class.global][global].html_link(dctx)}")
else
- dctx.add("::{name}")
+ dctx.add("::{html_name}")
end
dctx.add("</div>")
redef fun kind do return "type"
end
-redef class Symbol
- # Replace < and > with html entities
- redef fun to_s
- do
- var ret = super.to_s
-
- if(ret.has('<')) then
- var parts = ret.split_with("<")
- ret = ""
-
- for i in [0..parts.length[ do
- ret += parts[i]
-
- if(i < parts.length - 1) then
- ret += "<"
- end
- end
- end
-
- if(ret.has('>')) then
- var parts = ret.split_with(">")
- ret = ""
-
- for i in [0..parts.length[ do
- ret += parts[i]
-
- if(i < parts.length - 1) then
- ret += ">"
- end
- end
- end
-
- return ret
- end
-end
-
redef class MMSrcModule
redef fun short_doc
do
for c in n_comment do
res.append(c.text.substring_from(1))
end
- return res.to_s
+ return res.to_s.html_escape
end
# Oneliner transcription of the doc
fun short: String
do
- return n_comment.first.text.substring_from(1)
+ return n_comment.first.text.substring_from(1).html_escape
end
end
# Return true if the global class must be documented according to the visibility configured
fun require_doc(dctx: DocContext): Bool
do
- if global.visibility_level == 3 then return false # Private
+ if global.visibility_level == 3 and not dctx.with_private then return false # Private
if dctx.public_only then
var m = intro_module
if m != m.toplevel_owner then return false # Unexported