nitdoc: Avoid HTML ID collisions.
[nit.git] / src / doc / doc_pages.nit
index aeb7cb1..b400c6d 100644 (file)
@@ -24,6 +24,8 @@ redef class ToolContext
        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")
        private var opt_shareurl = new OptionString("use shareurl instead of copy shared files", "--shareurl")
+       private var opt_no_attributes = new OptionBool("ignore the attributes",
+                       "--no-attributes")
        private var opt_nodot = new OptionBool("do not generate graphes with graphviz", "--no-dot")
        private var opt_private = new OptionBool("also generate private API", "--private")
 
@@ -46,7 +48,8 @@ redef class ToolContext
                super
 
                var opts = option_context
-               opts.add_option(opt_dir, opt_source, opt_sharedir, opt_shareurl, opt_nodot, opt_private)
+               opts.add_option(opt_dir, opt_source, opt_sharedir, opt_shareurl,
+                               opt_no_attributes, 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)
                opts.add_option(opt_piwik_tracker, opt_piwik_site_id)
@@ -83,6 +86,23 @@ redef class ToolContext
                        end
                end
        end
+
+       # Filter the entity based on the options specified by the user.
+       #
+       # Return `true` if the specified entity has to be included in the generated
+       # documentation
+       private fun filter_mclass(mclass: MClass): Bool do
+               return mclass.visibility >= min_visibility
+       end
+
+       # Filter the entity based on the options specified by the user.
+       #
+       # Return `true` if the specified entity has to be included in the generated
+       # documentation
+       private fun filter_mproperty(mproperty: MProperty): Bool do
+               return mproperty.visibility >= min_visibility and
+                       not (opt_no_attributes.value and mproperty isa MAttribute)
+       end
 end
 
 # The Nitdoc class explores the model and generate pages for each mentities found
@@ -154,7 +174,7 @@ class Nitdoc
 
        private fun classes do
                for mclass in model.mclasses do
-                       if mclass.visibility <= ctx.min_visibility then continue
+                       if not ctx.filter_mclass(mclass) then continue
                        var page = new NitdocClass(ctx, model, mainmodule, mclass)
                        page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}")
                end
@@ -162,9 +182,8 @@ class Nitdoc
 
        private fun properties do
                for mproperty in model.mproperties do
-                       if mproperty.visibility <= ctx.min_visibility then continue
+                       if not ctx.filter_mproperty(mproperty) then continue
                        if mproperty isa MInnerClass then continue
-                       if mproperty isa MAttribute then continue
                        var page = new NitdocProperty(ctx, model, mainmodule, mproperty)
                        page.render.write_to_file("{ctx.output_dir.to_s}/{page.page_url}")
                end
@@ -196,12 +215,11 @@ class QuickSearch
                        add_result_for(mmodule.name, mmodule.full_name, mmodule.nitdoc_url)
                end
                for mclass in model.mclasses do
-                       if mclass.visibility < ctx.min_visibility then continue
+                       if not ctx.filter_mclass(mclass) then continue
                        add_result_for(mclass.name, mclass.full_name, mclass.nitdoc_url)
                end
                for mproperty in model.mproperties do
-                       if mproperty.visibility < ctx.min_visibility then continue
-                       if mproperty isa MAttribute then continue
+                       if not ctx.filter_mproperty(mproperty) then continue
                        for mpropdef in mproperty.mpropdefs do
                                var full_name = mpropdef.mclassdef.mclass.full_name
                                var cls_url = mpropdef.mclassdef.mclass.nitdoc_url
@@ -409,7 +427,7 @@ abstract class NitdocPage
                var intros = mmodule.intro_mclassdefs(ctx.min_visibility).to_a
                if not intros.is_empty then
                        mainmodule.linearize_mclassdefs(intros)
-                       var intros_art = new TplArticle.with_title("{mmodule.nitdoc_id}_intros", "Introduces")
+                       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
@@ -422,7 +440,7 @@ abstract class NitdocPage
                var redefs = mmodule.redef_mclassdefs(ctx.min_visibility).to_a
                if not redefs.is_empty then
                        mainmodule.linearize_mclassdefs(redefs)
-                       var redefs_art = new TplArticle.with_title("{mmodule.nitdoc_id}_redefs", "Redefines")
+                       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
@@ -451,7 +469,7 @@ abstract class NitdocPage
                        redef_article.source_link = tpl_showsource(mclassdef.location)
                        article.add_child redef_article
                        # mpropdefs list
-                       var intros = new TplArticle.with_title("{mclassdef.nitdoc_id}_intros", "Introduces")
+                       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 mpropdef.tpl_list_item
@@ -460,7 +478,7 @@ abstract class NitdocPage
                                intros.content = intros_lst
                                redef_article.add_child intros
                        end
-                       var redefs = new TplArticle.with_title("{mclassdef.nitdoc_id}_redefs", "Redefines")
+                       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 mpropdef.tpl_list_item
@@ -510,7 +528,7 @@ abstract class NitdocPage
                if main_mpropdef.mdoc != null then
                        article.content = main_mpropdef.mdoc.tpl_comment
                end
-               var subarticle = new TplArticle("{main_mpropdef.nitdoc_id}_redefs")
+               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
@@ -532,7 +550,7 @@ abstract class NitdocPage
                end
                # Add linearization
                if lin.length > 1 then
-                       var lin_article = new TplArticle("{main_mpropdef.nitdoc_id}_lin")
+                       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
@@ -658,7 +676,7 @@ class NitdocSearch
        private fun classes_list: Array[MClass] do
                var sorted = new Array[MClass]
                for mclass in model.mclasses do
-                       if mclass.visibility < ctx.min_visibility then continue
+                       if not ctx.filter_mclass(mclass) then continue
                        sorted.add mclass
                end
                name_sorter.sort(sorted)
@@ -669,9 +687,7 @@ class NitdocSearch
        private fun mprops_list: Array[MProperty] do
                var sorted = new Array[MProperty]
                for mproperty in model.mproperties do
-                       if mproperty.visibility < ctx.min_visibility then continue
-                       if mproperty isa MAttribute then continue
-                       sorted.add mproperty
+                       if ctx.filter_mproperty(mproperty) then sorted.add mproperty
                end
                name_sorter.sort(sorted)
                return sorted
@@ -1154,15 +1170,14 @@ class NitdocClass
                # parents
                var hparents = new HashSet[MClass]
                for c in mclass.in_hierarchy(mainmodule).direct_greaters do
-                       if c.visibility < ctx.min_visibility then continue
-                       hparents.add c
+                       if ctx.filter_mclass(c) then hparents.add c
                end
 
                # ancestors
                var hancestors = new HashSet[MClass]
                for c in mclass.in_hierarchy(mainmodule).greaters do
                        if c == mclass then continue
-                       if c.visibility < ctx.min_visibility then continue
+                       if not ctx.filter_mclass(c) then continue
                        if hparents.has(c) then continue
                        hancestors.add c
                end
@@ -1170,15 +1185,14 @@ class NitdocClass
                # children
                var hchildren = new HashSet[MClass]
                for c in mclass.in_hierarchy(mainmodule).direct_smallers do
-                       if c.visibility < ctx.min_visibility then continue
-                       hchildren.add c
+                       if ctx.filter_mclass(c) then hchildren.add c
                end
 
                # descendants
                var hdescendants = new HashSet[MClass]
                for c in mclass.in_hierarchy(mainmodule).smallers do
                        if c == mclass then continue
-                       if c.visibility < ctx.min_visibility then continue
+                       if not ctx.filter_mclass(c) then continue
                        if hchildren.has(c) then continue
                        hdescendants.add c
                end
@@ -1408,6 +1422,9 @@ private class PropertiesByKind
        # The constructors.
        var constructors = new PropertyGroup[MMethod]("Contructors")
 
+       # The attributes.
+       var attributes = new PropertyGroup[MAttribute]("Attributes")
+
        # The methods.
        var methods = new PropertyGroup[MMethod]("Methods")
 
@@ -1420,6 +1437,7 @@ private class PropertiesByKind
        var groups: SequenceRead[PropertyGroup[MProperty]] = [
                        virtual_types,
                        constructors,
+                       attributes,
                        methods,
                        inner_classes: PropertyGroup[MProperty]]
 
@@ -1436,6 +1454,8 @@ private class PropertiesByKind
                        end
                else if property isa MVirtualTypeProp then
                        virtual_types.add property
+               else if property isa MAttribute then
+                       attributes.add property
                else if property isa MInnerClass then
                        inner_classes.add property
                else