X-Git-Url: http://nitlanguage.org diff --git a/src/doc/doc_pages.nit b/src/doc/doc_pages.nit index 828458c..73ae262 100644 --- a/src/doc/doc_pages.nit +++ b/src/doc/doc_pages.nit @@ -15,10 +15,10 @@ # Nitdoc page generation module doc_pages +import toolcontext import doc_model -# The NitdocContext contains all the knowledge used for doc generation -class NitdocContext +redef class ToolContext private var opt_dir = new OptionString("output directory", "-d", "--dir") private var opt_source = new OptionString("link for source (%f for filename, %l for first line, %L for last line)", "--source") private var opt_sharedir = new OptionString("directory containing nitdoc assets", "--sharedir") @@ -38,14 +38,13 @@ class NitdocContext private var opt_piwik_tracker = new OptionString("Piwik tracker URL (ex: nitlanguage.org/piwik/)", "--piwik-tracker") private var opt_piwik_site_id = new OptionString("Piwik site ID", "--piwik-site-id") - private var toolcontext = new ToolContext - private var mbuilder: ModelBuilder - private var mainmodule: MModule private var output_dir: String private var min_visibility: MVisibility - init do - var opts = toolcontext.option_context + redef init do + super + + var opts = option_context opts.add_option(opt_dir, opt_source, opt_sharedir, opt_shareurl, opt_nodot, opt_private) opts.add_option(opt_custom_title, opt_custom_footer, opt_custom_intro, opt_custom_brand) opts.add_option(opt_github_upstream, opt_github_base_sha1, opt_github_gitdir) @@ -54,19 +53,25 @@ class NitdocContext var tpl = new Template tpl.add "Usage: nitdoc [OPTION]... ...\n" tpl.add "Generates HTML pages of API documentation from Nit source files." - toolcontext.tooldescription = tpl.write_to_string - toolcontext.process_options(args) - - self.process_options - self.parse(toolcontext.option_context.rest) + tooldescription = tpl.write_to_string end - private fun process_options do + redef fun process_options(args) do + super + + # output dir + var output_dir = opt_dir.value + if output_dir == null then + output_dir = "doc" + end + self.output_dir = output_dir + # min visibility if opt_private.value then min_visibility = none_visibility else min_visibility = protected_visibility end + # github urls var gh_upstream = opt_github_upstream.value var gh_base_sha = opt_github_base_sha1.value var gh_gitdir = opt_github_gitdir.value @@ -77,23 +82,21 @@ class NitdocContext end end end +end - private fun parse(arguments: Array[String]) do - var model = new Model - mbuilder = new ModelBuilder(model, toolcontext) - var mmodules = mbuilder.parse(arguments) - if mmodules.is_empty then return - mbuilder.run_phases - if mmodules.length == 1 then - mainmodule = mmodules.first - else - mainmodule = new MModule(model, null, "
", new Location(null, 0, 0, 0, 0)) - mainmodule.is_fictive = true - mainmodule.set_imported_mmodules(mmodules) - end +# The Nitdoc class explores the model and generate pages for each mentities found +class Nitdoc + var model: Model + var mainmodule: MModule + var ctx: ToolContext + + init(ctx: ToolContext, model: Model, mainmodule: MModule) do + self.ctx = ctx + self.model = model + self.mainmodule = mainmodule end - fun generate_nitdoc do + fun generate do init_output_dir overview search @@ -105,18 +108,13 @@ class NitdocContext end private fun init_output_dir do - # location output dir - var output_dir = opt_dir.value - if output_dir == null then - output_dir = "doc" - end - self.output_dir = output_dir # create destination dir if it's necessary + var output_dir = ctx.output_dir if not output_dir.file_exists then output_dir.mkdir # locate share dir - var sharedir = opt_sharedir.value + var sharedir = ctx.opt_sharedir.value if sharedir == null then - var dir = toolcontext.nit_dir + var dir = ctx.nit_dir if dir == null then print "Error: Cannot locate nitdoc share files. Uses --sharedir or envvar NIT_DIR" abort @@ -128,7 +126,7 @@ class NitdocContext end end # copy shared files - if opt_shareurl.value == null then + if ctx.opt_shareurl.value == null then sys.system("cp -r {sharedir.to_s}/* {output_dir.to_s}/") else sys.system("cp -r {sharedir.to_s}/resources/ {output_dir.to_s}/resources/") @@ -137,49 +135,51 @@ class NitdocContext end private fun overview do - var overviewpage = new NitdocOverview(self) - overviewpage.render.write_to_file("{output_dir.to_s}/index.html") + var page = new NitdocOverview(ctx, model, mainmodule) + page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}") end private fun search do - var searchpage = new NitdocSearch(self) - searchpage.render.write_to_file("{output_dir.to_s}/search.html") + var page = new NitdocSearch(ctx, model, mainmodule) + page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}") end private fun groups do - for mproject in mbuilder.model.mprojects do + for mproject in model.mprojects do for mgroup in mproject.mgroups.to_a do - var page = new NitdocGroup(mgroup, self) - page.render.write_to_file("{output_dir.to_s}/{mgroup.nitdoc_url}") + var page = new NitdocGroup(ctx, model, mainmodule, mgroup) + page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}") end end end private fun modules do - for mmodule in mbuilder.model.mmodules do - if mmodule.name == "
" then continue - var modulepage = new NitdocModule(mmodule, self) - modulepage.render.write_to_file("{output_dir.to_s}/{mmodule.nitdoc_url}") + for mmodule in model.mmodules do + if mmodule.is_fictive then continue + var page = new NitdocModule(ctx, model, mainmodule, mmodule) + page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}") end end private fun classes do - for mclass in mbuilder.model.mclasses do - var classpage = new NitdocClass(mclass, self) - classpage.render.write_to_file("{output_dir.to_s}/{mclass.nitdoc_url}") + for mclass in model.mclasses do + if mclass.visibility <= ctx.min_visibility then continue + var page = new NitdocClass(ctx, model, mainmodule, mclass) + page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}") end end private fun properties do - for mproperty in mbuilder.model.mproperties do - var page = new NitdocProperty(mproperty, self) - page.render.write_to_file("{output_dir.to_s}/{mproperty.nitdoc_url}") + for mproperty in model.mproperties do + if mproperty.visibility <= ctx.min_visibility then continue + var page = new NitdocProperty(ctx, model, mainmodule, mproperty) + page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}") end end private fun quicksearch_list do - var quicksearch = new QuickSearch(self) - quicksearch.render.write_to_file("{output_dir.to_s}/quicksearch-list.js") + var quicksearch = new QuickSearch(ctx, model) + quicksearch.render.write_to_file("{ctx.output_dir.to_s}/quicksearch-list.js") end end @@ -196,16 +196,16 @@ class QuickSearch private var mclasses = new HashSet[MClass] private var mpropdefs = new HashMap[String, Set[MPropDef]] - init(ctx: NitdocContext) do - for mmodule in ctx.mbuilder.model.mmodules do - if mmodule.name == "
" then continue + init(ctx: ToolContext, model: Model) do + for mmodule in model.mmodules do + if mmodule.is_fictive then continue mmodules.add mmodule end - for mclass in ctx.mbuilder.model.mclasses do + for mclass in model.mclasses do if mclass.visibility < ctx.min_visibility then continue mclasses.add mclass end - for mproperty in ctx.mbuilder.model.mproperties do + for mproperty in model.mproperties do if mproperty.visibility < ctx.min_visibility then continue if mproperty isa MAttribute then continue if not mpropdefs.has_key(mproperty.name) then @@ -233,7 +233,9 @@ class QuickSearch tpl.add "\"{mproperty}\":[" for mpropdef in mprops do var full_name = mpropdef.mclassdef.mclass.full_name - tpl.add "\{txt:\"{full_name}\",url:\"{mpropdef.nitdoc_url}\"\}," + var cls_url = mpropdef.mclassdef.mclass.nitdoc_url + var def_url = "{cls_url}#{mpropdef.mproperty.nitdoc_id}" + tpl.add "\{txt:\"{full_name}\",url:\"{def_url}\"\}," end tpl.add "]," end @@ -246,13 +248,15 @@ end # Define page structure and properties abstract class NitdocPage - private var ctx: NitdocContext + private var ctx: ToolContext private var model: Model + private var mainmodule: MModule private var name_sorter = new MEntityNameSorter - init(ctx: NitdocContext) do + init(ctx: ToolContext, model: Model, mainmodule: MModule) do self.ctx = ctx - self.model = ctx.mbuilder.model + self.model = model + self.mainmodule = mainmodule end # Render the page as a html template @@ -265,6 +269,7 @@ abstract class NitdocPage # build page var tpl = tpl_page tpl.title = tpl_title + tpl.url = page_url tpl.shareurl = shareurl tpl.topmenu = tpl_topmenu tpl_content @@ -281,6 +286,9 @@ abstract class NitdocPage return tpl end + # URL to this page. + fun page_url: String is abstract + # Build page template fun tpl_page: TplPage is abstract @@ -297,7 +305,7 @@ abstract class NitdocPage # Build top menu template fun tpl_topmenu: TplTopMenu do - var topmenu = new TplTopMenu + var topmenu = new TplTopMenu(page_url) var brand = ctx.opt_custom_brand.value if brand != null then var tpl = new Template @@ -306,6 +314,8 @@ abstract class NitdocPage tpl.add "" topmenu.brand = tpl end + topmenu.add_link new TplLink("index.html", "Overview") + topmenu.add_link new TplLink("search.html", "Index") return topmenu end @@ -326,10 +336,14 @@ abstract class NitdocPage fmap.close var article = new TplArticle("graph") - if title != null then article.title = title + var alt = "" + if title != null then + article.title = title + alt = "alt='{title}'" + end article.css_classes.add "text-center" var content = new Template - content.add "{title}" + content.add "" content.add map article.content = content return article @@ -340,7 +354,10 @@ abstract class NitdocPage do if location == null then return null var source = ctx.opt_source.value - if source == null then return "({location.file.filename.simplify_path})" + if source == null then + var url = location.file.filename.simplify_path + return "View Source" + end # THIS IS JUST UGLY ! (but there is no replace yet) var x = source.split_with("%f") source = x.join(location.file.filename.simplify_path) @@ -349,7 +366,7 @@ abstract class NitdocPage x = source.split_with("%L") source = x.join(location.line_end.to_s) source = source.simplify_path - return " (source)" + return "View Source" end # MProject description template @@ -378,26 +395,30 @@ abstract class NitdocPage article.content = mmodule.tpl_definition # mclassdefs list var intros = mmodule.intro_mclassdefs(ctx.min_visibility).to_a - ctx.mainmodule.linearize_mclassdefs(intros) - var intros_art = new TplArticle.with_title("{mmodule.nitdoc_id}_intros", "Introduces") - var intros_lst = new TplList.with_classes(["list-unstyled", "list-labeled"]) - for mclassdef in intros do - intros_lst.add_li new TplListItem.with_content(mclassdef.tpl_list_item) - end - if not intros_lst.is_empty then - intros_art.content = intros_lst - article.add_child intros_art + if not intros.is_empty then + mainmodule.linearize_mclassdefs(intros) + var intros_art = new TplArticle.with_title("{mmodule.nitdoc_id}_intros", "Introduces") + var intros_lst = new TplList.with_classes(["list-unstyled", "list-labeled"]) + for mclassdef in intros do + intros_lst.add_li mclassdef.tpl_list_item + end + if not intros_lst.is_empty then + intros_art.content = intros_lst + article.add_child intros_art + end end var redefs = mmodule.redef_mclassdefs(ctx.min_visibility).to_a - ctx.mainmodule.linearize_mclassdefs(redefs) - var redefs_art = new TplArticle.with_title("{mmodule.nitdoc_id}_redefs", "Redefines") - var redefs_lst = new TplList.with_classes(["list-unstyled", "list-labeled"]) - for mclassdef in redefs do - redefs_lst.add_li new TplListItem.with_content(mclassdef.tpl_list_item) - end - if not redefs_lst.is_empty then - redefs_art.content = redefs_lst - article.add_child redefs_art + if not redefs.is_empty then + mainmodule.linearize_mclassdefs(redefs) + var redefs_art = new TplArticle.with_title("{mmodule.nitdoc_id}_redefs", "Redefines") + var redefs_lst = new TplList.with_classes(["list-unstyled", "list-labeled"]) + for mclassdef in redefs do + redefs_lst.add_li mclassdef.tpl_list_item + end + if not redefs_lst.is_empty then + redefs_art.content = redefs_lst + article.add_child redefs_art + end end return article end @@ -411,7 +432,7 @@ abstract class NitdocPage intro_article.source_link = tpl_showsource(mclass.intro.location) article.add_child intro_article end - ctx.mainmodule.linearize_mclassdefs(mclassdefs) + mainmodule.linearize_mclassdefs(mclassdefs) for mclassdef in mclassdefs do # add mclassdef full description var redef_article = mclassdef.tpl_article @@ -421,7 +442,7 @@ abstract class NitdocPage var intros = new TplArticle.with_title("{mclassdef.nitdoc_id}_intros", "Introduces") var intros_lst = new TplList.with_classes(["list-unstyled", "list-labeled"]) for mpropdef in mclassdef.collect_intro_mpropdefs(ctx.min_visibility) do - intros_lst.add_li new TplListItem.with_content(mpropdef.tpl_list_item) + intros_lst.add_li mpropdef.tpl_list_item end if not intros_lst.is_empty then intros.content = intros_lst @@ -430,7 +451,7 @@ abstract class NitdocPage var redefs = new TplArticle.with_title("{mclassdef.nitdoc_id}_redefs", "Redefines") var redefs_lst = new TplList.with_classes(["list-unstyled", "list-labeled"]) for mpropdef in mclassdef.collect_redef_mpropdefs(ctx.min_visibility) do - redefs_lst.add_li new TplListItem.with_content(mpropdef.tpl_list_item) + redefs_lst.add_li mpropdef.tpl_list_item end if not redefs_lst.is_empty then redefs.content = redefs_lst @@ -449,28 +470,72 @@ abstract class NitdocPage end # MProp description template - fun tpl_mprop_article(mproperty: MProperty, mpropdefs: Array[MPropDef]): TplArticle do - var article = mproperty.tpl_article - if not mpropdefs.has(mproperty.intro) then - # add intro synopsys - var intro_article = mproperty.intro.tpl_short_article - intro_article.source_link = tpl_showsource(mproperty.intro.location) - article.add_child intro_article + # + # `main_mpropdef`: The most important mpropdef to display + # `local_mpropdefs`: List of other locally defined mpropdefs to display + # `lin`: full linearization from local_mpropdefs to intro (displayed in redef tree) + fun tpl_mprop_article(main_mpropdef: MPropDef, local_mpropdefs: Array[MPropDef], + lin: Array[MPropDef]): TplArticle do + var mprop = main_mpropdef.mproperty + var article = new TplArticle(mprop.nitdoc_id) + var title = new Template + title.add mprop.tpl_icon + title.add "" + if main_mpropdef.is_intro then + title.add mprop.tpl_link + title.add mprop.intro.tpl_signature + else + var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url + var def_url = "{cls_url}#{mprop.nitdoc_id}" + var lnk = new TplLink.with_title(def_url, mprop.name, "Go to introduction") + title.add "redef " + title.add lnk + end + article.title = title + article.title_classes.add "signature" + article.summary_title = "{mprop.nitdoc_name}" + article.subtitle = main_mpropdef.tpl_namespace + if main_mpropdef.mdoc != null then + article.content = main_mpropdef.mdoc.tpl_comment + end + var subarticle = new TplArticle("{main_mpropdef.nitdoc_id}_redefs") + # Add redef in same `MClass` + if local_mpropdefs.length > 1 then + for mpropdef in local_mpropdefs do + if mpropdef == main_mpropdef then continue + var redef_article = new TplArticle("{mpropdef.nitdoc_id}") + var redef_title = new Template + redef_title.add "also redef in " + redef_title.add mpropdef.tpl_namespace + redef_article.title = redef_title + redef_article.title_classes.add "signature info" + redef_article.css_classes.add "nospace" + var redef_content = new Template + if mpropdef.mdoc != null then + redef_content.add mpropdef.mdoc.tpl_comment + end + redef_article.content = redef_content + subarticle.add_child redef_article + end end - ctx.mainmodule.linearize_mpropdefs(mpropdefs) - for mpropdef in mpropdefs do - # add mpropdef description - var redef_article = mpropdef.tpl_article - redef_article.source_link = tpl_showsource(mpropdef.location) - article.add_child redef_article + # Add linearization + if lin.length > 1 then + var lin_article = new TplArticle("{main_mpropdef.nitdoc_id}_lin") + lin_article.title = "Inheritance" + var lst = new TplList.with_classes(["list-unstyled", "list-labeled"]) + for mpropdef in lin do + lst.add_li mpropdef.tpl_inheritance_item + end + lin_article.content = lst + subarticle.add_child lin_article end + article.add_child subarticle return article end # MProperty description template fun tpl_mpropdef_article(mpropdef: MPropDef): TplArticle do var article = mpropdef.tpl_article - if mpropdef.is_intro then article.content = null article.source_link = tpl_showsource(mpropdef.location) return article end @@ -481,8 +546,6 @@ end class NitdocOverview super NitdocPage - init(ctx: NitdocContext) do super(ctx) - private var page = new TplPage redef fun tpl_page do return page @@ -497,12 +560,7 @@ class NitdocOverview end end - redef fun tpl_topmenu do - var topmenu = super - topmenu.add_item(new TplLink("#", "Overview"), true) - topmenu.add_item(new TplLink("search.html", "Index"), false) - return topmenu - end + redef fun page_url do return "index.html" # intro text private fun tpl_intro: TplSection do @@ -540,19 +598,12 @@ end class NitdocSearch super NitdocPage - init(ctx: NitdocContext) do super(ctx) - private var page = new TplPage redef fun tpl_page do return page redef fun tpl_title do return "Index" - redef fun tpl_topmenu do - var topmenu = super - topmenu.add_item(new TplLink("index.html", "Overview"), false) - topmenu.add_item(new TplLink("#", "Index"), true) - return topmenu - end + redef fun page_url do return "search.html" redef fun tpl_content do var tpl = new TplSearchPage("search_all") @@ -583,8 +634,8 @@ class NitdocSearch # Extract mmodule list to display (sorted by name) private fun modules_list: Array[MModule] do var sorted = new Array[MModule] - for mmodule in ctx.mbuilder.model.mmodule_importation_hierarchy do - if mmodule.name == "
" then continue + for mmodule in model.mmodule_importation_hierarchy do + if mmodule.is_fictive then continue sorted.add mmodule end name_sorter.sort(sorted) @@ -594,7 +645,7 @@ class NitdocSearch # Extract mclass list to display (sorted by name) private fun classes_list: Array[MClass] do var sorted = new Array[MClass] - for mclass in ctx.mbuilder.model.mclasses do + for mclass in model.mclasses do if mclass.visibility < ctx.min_visibility then continue sorted.add mclass end @@ -605,7 +656,7 @@ class NitdocSearch # Extract mproperty list to display (sorted by name) private fun mprops_list: Array[MProperty] do var sorted = new Array[MProperty] - for mproperty in ctx.mbuilder.model.mproperties do + for mproperty in model.mproperties do if mproperty.visibility < ctx.min_visibility then continue if mproperty isa MAttribute then continue sorted.add mproperty @@ -626,10 +677,9 @@ class NitdocGroup private var intros: Set[MClass] private var redefs: Set[MClass] - init(mgroup: MGroup, ctx: NitdocContext) do + init(ctx: ToolContext, model: Model, mainmodule: MModule, mgroup: MGroup) do + super self.mgroup = mgroup - super(ctx) - self.concerns = model.concerns_tree(mgroup.collect_mmodules) self.concerns.sort_with(new MConcernRankSorter) self.intros = mgroup.in_nesting_intro_mclasses(ctx.min_visibility) @@ -647,19 +697,17 @@ class NitdocGroup private var sidebar = new TplSidebar redef fun tpl_sidebar do return sidebar - redef fun tpl_title do return "{mgroup.nitdoc_name}" + redef fun tpl_title do return mgroup.nitdoc_name + + redef fun page_url do return mgroup.nitdoc_url redef fun tpl_topmenu do var topmenu = super var mproject = mgroup.mproject - topmenu.add_item(new TplLink("index.html", "Overview"), false) - if mgroup.is_root then - topmenu.add_item(new TplLink("#", "{mproject.nitdoc_name}"), true) - else - topmenu.add_item(new TplLink(mproject.nitdoc_url, "{mproject.nitdoc_name}"), false) - topmenu.add_item(new TplLink("#", "{mgroup.nitdoc_name}"), true) + if not mgroup.is_root then + topmenu.add_link new TplLink(mproject.nitdoc_url, mproject.nitdoc_name) end - topmenu.add_item(new TplLink("search.html", "Index"), false) + topmenu.add_link new TplLink(page_url, mproject.nitdoc_name) return topmenu end @@ -679,7 +727,7 @@ class NitdocGroup tpl_sidebar.boxes.add new TplSideBox.with_content("All classes", list) end - private fun tpl_sidebar_item(def: MClass): Template do + private fun tpl_sidebar_item(def: MClass): TplListItem do var classes = def.intro.tpl_css_classes.to_a if intros.has(def) then classes.add "intro" @@ -689,7 +737,7 @@ class NitdocGroup var lnk = new Template lnk.add new TplLabel.with_classes(classes) lnk.add def.tpl_link - return lnk + return new TplListItem.with_content(lnk) end # intro text @@ -756,10 +804,10 @@ class NitdocModule private var mclasses2mdefs: Map[MClass, Set[MClassDef]] private var mmodules2mclasses: Map[MModule, Set[MClass]] - init(mmodule: MModule, ctx: NitdocContext) do - self.mmodule = mmodule - super(ctx) + init(ctx: ToolContext, model: Model, mainmodule: MModule, mmodule: MModule) do + super + self.mmodule = mmodule var mclassdefs = new HashSet[MClassDef] mclassdefs.add_all mmodule.intro_mclassdefs(ctx.min_visibility) mclassdefs.add_all mmodule.redef_mclassdefs(ctx.min_visibility) @@ -782,15 +830,14 @@ class NitdocModule private var sidebar = new TplSidebar redef fun tpl_sidebar do return sidebar - redef fun tpl_title do return "{mmodule.nitdoc_name}" + redef fun tpl_title do return mmodule.nitdoc_name + redef fun page_url do return mmodule.nitdoc_url redef fun tpl_topmenu do var topmenu = super var mproject = mmodule.mgroup.mproject - topmenu.add_item(new TplLink("index.html", "Overview"), false) - topmenu.add_item(new TplLink("{mproject.nitdoc_url}", "{mproject.nitdoc_name}"), false) - topmenu.add_item(new TplLink("#", "{mmodule.nitdoc_name}"), true) - topmenu.add_item(new TplLink("search.html", "Index"), false) + topmenu.add_link new TplLink(mproject.nitdoc_url, mproject.nitdoc_name) + topmenu.add_link new TplLink(page_url, mmodule.nitdoc_name) return topmenu end @@ -810,7 +857,7 @@ class NitdocModule tpl_sidebar.boxes.add new TplSideBox.with_content("All classes", list) end - private fun tpl_sidebar_item(def: MClass): Template do + private fun tpl_sidebar_item(def: MClass): TplListItem do var classes = def.intro.tpl_css_classes.to_a if def.intro_mmodule == mmodule then classes.add "intro" @@ -820,7 +867,7 @@ class NitdocModule var lnk = new Template lnk.add new TplLabel.with_classes(classes) lnk.add def.tpl_link - return lnk + return new TplListItem.with_content(lnk) end # intro text @@ -1000,9 +1047,9 @@ class NitdocClass private var mprops2mdefs: Map[MProperty, Set[MPropDef]] private var mmodules2mprops: Map[MModule, Set[MProperty]] - init(mclass: MClass, ctx: NitdocContext) do + init(ctx: ToolContext, model: Model, mainmodule: MModule, mclass: MClass) do + super self.mclass = mclass - super(ctx) var mpropdefs = new HashSet[MPropDef] mpropdefs.add_all mclass.intro_mpropdefs(ctx.min_visibility) mpropdefs.add_all mclass.redef_mpropdefs(ctx.min_visibility) @@ -1019,14 +1066,13 @@ class NitdocClass redef fun tpl_sidebar do return sidebar redef fun tpl_title do return "{mclass.nitdoc_name}{mclass.tpl_signature.write_to_string}" + redef fun page_url do return mclass.nitdoc_url redef fun tpl_topmenu do var topmenu = super var mproject = mclass.intro_mmodule.mgroup.mproject - topmenu.add_item(new TplLink("index.html", "Overview"), false) - topmenu.add_item(new TplLink("{mproject.nitdoc_url}", "{mproject.nitdoc_name}"), false) - topmenu.add_item(new TplLink("#", "{mclass.nitdoc_name}"), true) - topmenu.add_item(new TplLink("search.html", "Index"), false) + topmenu.add_link new TplLink("{mproject.nitdoc_url}", "{mproject.nitdoc_name}") + topmenu.add_link new TplLink(page_url, mclass.nitdoc_name) return topmenu end @@ -1053,14 +1099,18 @@ class NitdocClass summary.elts.add entry end - private fun tpl_sidebar_item(mprop: MProperty): Template do + private fun tpl_sidebar_item(mprop: MProperty): TplListItem do var classes = mprop.intro.tpl_css_classes.to_a if not mprops2mdefs.has_key(mprop) then classes.add "inherit" - var lnk = new Template - lnk.add new TplLabel.with_classes(classes) - lnk.add mprop.intro.tpl_link - return lnk + var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url + var def_url = "{cls_url}#{mprop.nitdoc_id}" + var lnk = new TplLink(def_url, mprop.name) + if mprop.intro.mdoc != null then lnk.title = mprop.intro.mdoc.short_comment + var item = new Template + item.add new TplLabel.with_classes(classes) + item.add lnk + return new TplListItem.with_content(item) end var defs = mprops2mdefs[mprop] if defs.has(mprop.intro) then @@ -1070,8 +1120,8 @@ class NitdocClass end var lnk = new Template lnk.add new TplLabel.with_classes(classes) - lnk.add mprop.intro.tpl_anchor - return lnk + lnk.add mprop.tpl_anchor + return new TplListItem.with_content(lnk) end private fun tpl_intro: TplSection do @@ -1099,14 +1149,14 @@ class NitdocClass private fun tpl_inheritance(parent: TplSection) do # parents var hparents = new HashSet[MClass] - for c in mclass.in_hierarchy(ctx.mainmodule).direct_greaters do + for c in mclass.in_hierarchy(mainmodule).direct_greaters do if c.visibility < ctx.min_visibility then continue hparents.add c end # ancestors var hancestors = new HashSet[MClass] - for c in mclass.in_hierarchy(ctx.mainmodule).greaters do + for c in mclass.in_hierarchy(mainmodule).greaters do if c == mclass then continue if c.visibility < ctx.min_visibility then continue if hparents.has(c) then continue @@ -1115,14 +1165,14 @@ class NitdocClass # children var hchildren = new HashSet[MClass] - for c in mclass.in_hierarchy(ctx.mainmodule).direct_smallers do + for c in mclass.in_hierarchy(mainmodule).direct_smallers do if c.visibility < ctx.min_visibility then continue hchildren.add c end # descendants var hdescendants = new HashSet[MClass] - for c in mclass.in_hierarchy(ctx.mainmodule).smallers do + for c in mclass.in_hierarchy(mainmodule).smallers do if c == mclass then continue if c.visibility < ctx.min_visibility then continue if hchildren.has(c) then continue @@ -1136,8 +1186,8 @@ class NitdocClass var mclasses = new HashSet[MClass] mclasses.add_all hancestors mclasses.add_all hparents - if hchildren.length < 10 then mclasses.add_all hchildren - if hdescendants.length < 10 then mclasses.add_all hdescendants + mclasses.add_all hchildren + mclasses.add_all hdescendants mclasses.add mclass var graph = tpl_dot(mclasses) if graph != null then section.add_child graph @@ -1157,14 +1207,14 @@ class NitdocClass end # children - if not hchildren.is_empty and hchildren.length < 15 then + if not hchildren.is_empty then var lst = hchildren.to_a name_sorter.sort lst section.add_child tpl_list("children", "Children", lst) end # descendants - if not hdescendants.is_empty and hchildren.length < 15 then + if not hdescendants.is_empty then var lst = hdescendants.to_a name_sorter.sort lst section.add_child tpl_list("descendants", "Descendants", lst) @@ -1175,9 +1225,18 @@ class NitdocClass private fun tpl_list(id: String, title: String, elts: Array[MClass]): TplArticle do var article = new TplArticle.with_title(id, title) - var list = new TplList.with_classes(["list-unstyled", "list-definition"]) - for elt in elts do list.elts.add elt.tpl_list_item - article.content = list + if elts.length > 20 then + var tpl = new Template + for e in elts do + tpl.add e.tpl_link + if e != elts.last then tpl.add ", " + end + article.content = tpl + else + var list = new TplList.with_classes(["list-unstyled", "list-definition"]) + for elt in elts do list.elts.add elt.tpl_list_item + article.content = list + end return article end @@ -1201,33 +1260,48 @@ class NitdocClass var kind_map = sort_by_kind(mprops) # virtual types - var elts = kind_map["type"].to_a - name_sorter.sort(elts) - for elt in elts do - var defs = mprops2mdefs[elt].to_a - section.add_child tpl_mprop_article(elt, defs) + for article in tpl_mproperty_articles(kind_map, "type") do + section.add_child article end - # constructors - elts = kind_map["init"].to_a - name_sorter.sort(elts) - for elt in elts do - var defs = mprops2mdefs[elt].to_a - section.add_child tpl_mprop_article(elt, defs) + for article in tpl_mproperty_articles(kind_map, "init") do + section.add_child article end - # methods - elts = kind_map["fun"].to_a - name_sorter.sort(elts) - for elt in elts do - var defs = mprops2mdefs[elt].to_a - section.add_child tpl_mprop_article(elt, defs) + for article in tpl_mproperty_articles(kind_map, "fun") do + section.add_child article end parent.add_child section end end end + private fun tpl_mproperty_articles(kind_map: Map[String, Set[MProperty]], + kind_name: String): Sequence[TplArticle] do + var articles = new List[TplArticle] + var elts = kind_map[kind_name].to_a + name_sorter.sort(elts) + for elt in elts do + var local_defs = mprops2mdefs[elt] + # var all_defs = elt.mpropdefs + var all_defs = new HashSet[MPropDef] + for local_def in local_defs do + all_defs.add local_def + var mpropdef = local_def + while not mpropdef.is_intro do + mpropdef = mpropdef.lookup_next_definition(mainmodule, mpropdef.mclassdef.bound_mtype) + all_defs.add mpropdef + end + end + var loc_lin = local_defs.to_a + mainmodule.linearize_mpropdefs(loc_lin) + var all_lin = all_defs.to_a + mainmodule.linearize_mpropdefs(all_lin) + articles.add tpl_mprop_article(loc_lin.first, loc_lin, all_lin) + end + return articles + end + redef fun tpl_content do tpl_sidebar_properties var top = tpl_intro @@ -1251,7 +1325,7 @@ class NitdocClass var map = new HashMap[MModule, Set[MProperty]] for mprop in mprops do var mpropdefs = mprops2mdefs[mprop].to_a - ctx.mainmodule.linearize_mpropdefs(mpropdefs) + mainmodule.linearize_mpropdefs(mpropdefs) var mmodule = mpropdefs.first.mclassdef.mmodule if not map.has_key(mmodule) then map[mmodule] = new HashSet[MProperty] map[mmodule].add mprop @@ -1281,7 +1355,7 @@ class NitdocClass private fun mclass_inherited_mprops: Set[MProperty] do var res = new HashSet[MProperty] var local = mclass.local_mproperties(ctx.min_visibility) - for mprop in mclass.inherited_mproperties(ctx.mainmodule, ctx.min_visibility) do + for mprop in mclass.inherited_mproperties(mainmodule, ctx.min_visibility) do if local.has(mprop) then continue #if mprop isa MMethod and mprop.is_init then continue if mprop.intro.mclassdef.mclass.name == "Object" and @@ -1303,17 +1377,6 @@ class NitdocClass return res end - private fun sort_by_public_owner(mmodules: Collection[MModule]): Map[MModule, Set[MModule]] do - var map = new HashMap[MModule, Set[MModule]] - for mmodule in mmodules do - var owner = mmodule - if mmodule.public_owner != null then owner = mmodule.public_owner.as(not null) - if not map.has_key(owner) then map[owner] = new HashSet[MModule] - map[owner].add mmodule - end - return map - end - # Generate dot hierarchy for classes fun tpl_dot(mclasses: Collection[MClass]): nullable TplArticle do var poset = new POSet[MClass] @@ -1321,8 +1384,9 @@ class NitdocClass for mclass in mclasses do poset.add_node mclass for oclass in mclasses do + if mclass == oclass then continue poset.add_node oclass - if mclass.in_hierarchy(ctx.mainmodule) < oclass then + if mclass.in_hierarchy(mainmodule) < oclass then poset.add_edge(mclass, oclass) end end @@ -1331,14 +1395,28 @@ class NitdocClass var op = new FlatBuffer var name = "dep_{mclass.name}" 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") - for c in poset do + var classes = poset.to_a + var todo = new Array[MClass] + var done = new HashSet[MClass] + mainmodule.linearize_mclasses(classes) + if not classes.is_empty then todo.add classes.first + while not todo.is_empty do + var c = todo.shift + if done.has(c) then continue + done.add c if c == mclass then op.append("\"{c.name}\"[shape=box,margin=0.03];\n") else op.append("\"{c.name}\"[URL=\"{c.nitdoc_url}\"];\n") end - for c2 in poset[c].direct_greaters do - op.append("\"{c.name}\"->\"{c2.name}\";\n") + var smallers = poset[c].direct_smallers + if smallers.length < 10 then + for c2 in smallers do + op.append("\"{c2.name}\"->\"{c.name}\";\n") + end + todo.add_all smallers + else + op.append("\"...\"->\"{c.name}\";\n") end end op.append("\}\n") @@ -1354,9 +1432,9 @@ class NitdocProperty private var concerns: ConcernsTree private var mmodules2mdefs: Map[MModule, Set[MPropDef]] - init(mproperty: MProperty, ctx: NitdocContext) do + init(ctx: ToolContext, model: Model, mainmodule: MModule, mproperty: MProperty) do + super self.mproperty = mproperty - super(ctx) self.mmodules2mdefs = sort_by_mmodule(collect_mpropdefs) self.concerns = model.concerns_tree(mmodules2mdefs.keys) self.concerns.sort_with(new MConcernRankSorter) @@ -1380,27 +1458,26 @@ class NitdocProperty return "{mproperty.nitdoc_name}{mproperty.tpl_signature.write_to_string}" end + redef fun page_url do return mproperty.nitdoc_url + redef fun tpl_topmenu do var topmenu = super var mmodule = mproperty.intro_mclassdef.mmodule var mproject = mmodule.mgroup.mproject var mclass = mproperty.intro_mclassdef.mclass - topmenu.add_item(new TplLink("index.html", "Overview"), false) - topmenu.add_item(new TplLink("{mproject.nitdoc_url}", "{mproject.nitdoc_name}"), false) - topmenu.add_item(new TplLink("{mclass.nitdoc_url}", "{mclass.nitdoc_name}"), false) - topmenu.add_item(new TplLink("#", "{mproperty.nitdoc_name}"), true) - topmenu.add_item(new TplLink("search.html", "Index"), false) + topmenu.add_link new TplLink("{mproject.nitdoc_url}", "{mproject.nitdoc_name}") + topmenu.add_link new TplLink("{mclass.nitdoc_url}", "{mclass.nitdoc_name}") + topmenu.add_link new TplLink(page_url, mproperty.nitdoc_name) return topmenu end private fun tpl_intro: TplSection do - var section = new TplSection.with_title("top", tpl_title) - section.subtitle = mproperty.tpl_declaration - var article = new TplArticle("comment") - if mproperty.intro.mdoc != null then - article.content = mproperty.intro.mdoc.tpl_comment - end - section.add_child article + var title = new Template + title.add mproperty.nitdoc_name + title.add mproperty.intro.tpl_signature + var section = new TplSection.with_title("top", title) + section.subtitle = mproperty.tpl_namespace + section.summary_title = mproperty.nitdoc_name return section end