nitdoc: introduce StructurePhase
authorAlexandre Terrasa <alexandre@moz-code.org>
Wed, 4 Feb 2015 20:03:46 +0000 (21:03 +0100)
committerAlexandre Terrasa <alexandre@moz-code.org>
Wed, 4 Feb 2015 20:17:38 +0000 (21:17 +0100)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/doc/doc_pages.nit
src/doc/doc_phases/doc_phases.nit
src/doc/doc_phases/doc_structure.nit [new file with mode: 0644]
src/nitdoc.nit

index e1397b5..be6ad94 100644 (file)
@@ -502,36 +502,6 @@ class NitdocOverview
        end
 
        redef fun page_url do return "index.html"
-
-       # intro text
-       private fun tpl_intro: TplSection do
-               var section = new TplSection.with_title("overview", tpl_title)
-               var article = new TplArticle("intro")
-               if ctx.opt_custom_intro.value != null then
-                       article.content = ctx.opt_custom_intro.value.to_s
-               end
-               section.add_child article
-               return section
-       end
-
-       # projects list
-       private fun tpl_projects(section: TplSection) do
-               # Projects list
-               var mprojects = model.mprojects.to_a
-               var sorter = new MConcernRankSorter
-               sorter.sort mprojects
-               var ssection = new TplSection.with_title("projects", "Projects")
-               for mproject in mprojects do
-                       ssection.add_child tpl_mproject_article(mproject)
-               end
-               section.add_child ssection
-       end
-
-       redef fun tpl_content do
-               var top = tpl_intro
-               tpl_projects(top)
-               tpl_page.add_section top
-       end
 end
 
 # The search page
@@ -545,64 +515,6 @@ class NitdocSearch
        redef fun tpl_title do return "Index"
 
        redef fun page_url do return "search.html"
-
-       redef fun tpl_content do
-               var tpl = new TplSearchPage("search_all")
-               var section = new TplSection("search")
-               # title
-               tpl.title = "Index"
-               # modules list
-               for mmodule in modules_list do
-                       tpl.modules.add mmodule.tpl_link
-               end
-               # classes list
-               for mclass in classes_list do
-                       tpl.classes.add mclass.tpl_link
-               end
-               # properties list
-               for mproperty in mprops_list do
-                       var m = new Template
-                       m.add mproperty.intro.tpl_link
-                       m.add " ("
-                       m.add mproperty.intro.mclassdef.mclass.tpl_link
-                       m.add ")"
-                       tpl.props.add m
-               end
-               section.add_child tpl
-               tpl_page.add_section section
-       end
-
-       # Extract mmodule list to display (sorted by name)
-       private fun modules_list: Array[MModule] do
-               var sorted = new Array[MModule]
-               for mmodule in model.mmodule_importation_hierarchy do
-                       if mmodule.is_fictive or mmodule.is_test_suite then continue
-                       sorted.add mmodule
-               end
-               name_sorter.sort(sorted)
-               return sorted
-       end
-
-       # Extract mclass list to display (sorted by name)
-       private fun classes_list: Array[MClass] do
-               var sorted = new Array[MClass]
-               for mclass in model.mclasses do
-                       if not ctx.filter_mclass(mclass) then continue
-                       sorted.add mclass
-               end
-               name_sorter.sort(sorted)
-               return sorted
-       end
-
-       # Extract mproperty list to display (sorted by name)
-       private fun mprops_list: Array[MProperty] do
-               var sorted = new Array[MProperty]
-               for mproperty in model.mproperties do
-                       if ctx.filter_mproperty(mproperty) then sorted.add mproperty
-               end
-               name_sorter.sort(sorted)
-               return sorted
-       end
 end
 
 # A group page
@@ -660,49 +572,6 @@ class NitdocGroup
                lnk.add def.tpl_link
                return new TplListItem.with_content(lnk)
        end
-
-       # intro text
-       private fun tpl_intro: TplSection do
-               var section = new TplSection.with_title("top", tpl_title)
-               var article = new TplArticle("intro")
-
-               if mgroup.is_root then
-                       section.subtitle = mgroup.mproject.tpl_declaration
-                       article.content = mgroup.mproject.tpl_definition
-               else
-                       section.subtitle = mgroup.tpl_declaration
-                       article.content = mgroup.tpl_definition
-               end
-               section.add_child article
-               return section
-       end
-
-       private fun tpl_concerns(section: TplSection) do
-               if concerns.is_empty then return
-               section.add_child new TplArticle.with_content("concerns", "Concerns", concerns.to_tpl)
-       end
-
-       private fun tpl_groups(parent: TplSection) do
-               var lst = concerns.to_a
-               var section = parent
-               for mentity in lst do
-                       if mentity isa MProject then
-                               section.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MGroup then
-                               section.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MModule then
-                               section.add_child tpl_mmodule_article(mentity)
-                       end
-               end
-       end
-
-       redef fun tpl_content do
-               tpl_sidebar_mclasses
-               var top = tpl_intro
-               tpl_concerns(top)
-               tpl_groups(top)
-               tpl_page.add_section top
-       end
 end
 
 # A module page
@@ -758,20 +627,6 @@ class NitdocModule
                return new TplListItem.with_content(lnk)
        end
 
-       # intro text
-       private fun tpl_intro: TplSection do
-               var section = new TplSection.with_title("top", tpl_title)
-               section.subtitle = mmodule.tpl_declaration
-
-               var article = new TplArticle("intro")
-               var def = mmodule.tpl_definition
-               var location = mmodule.location
-               article.source_link = tpl_showsource(location)
-               article.content = def
-               section.add_child article
-               return section
-       end
-
        # inheritance section
        private fun tpl_inheritance(parent: TplSection) do
                # Extract relevent modules
@@ -827,49 +682,6 @@ class NitdocModule
                return article
        end
 
-       private fun tpl_concerns(parent: TplSection) do
-               if concerns.is_empty then return
-               parent.add_child new TplArticle.with_content("concerns", "Concerns", concerns.to_tpl)
-       end
-
-       private fun tpl_mclasses(parent: TplSection) do
-               for mentity in concerns do
-                       if mentity isa MProject then
-                               parent.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MGroup then
-                               parent.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MModule then
-                               var section = new TplSection(mentity.nitdoc_id)
-                               var title = new Template
-                               if mentity == mmodule then
-                                       title.add "in "
-                                       section.summary_title = "in {mentity.nitdoc_name}"
-                               else
-                                       title.add "from "
-                                       section.summary_title = "from {mentity.nitdoc_name}"
-                               end
-                               title.add mentity.tpl_namespace
-                               section.title = title
-
-                               var mclasses = mmodules2mclasses[mentity].to_a
-                               name_sorter.sort(mclasses)
-                               for mclass in mclasses do
-                                       section.add_child tpl_mclass_article(mclass, mclasses2mdefs[mclass].to_a)
-                               end
-                               parent.add_child section
-                       end
-               end
-       end
-
-       redef fun tpl_content do
-               tpl_sidebar_mclasses
-               var top = tpl_intro
-               tpl_inheritance(top)
-               tpl_concerns(top)
-               tpl_mclasses(top)
-               tpl_page.add_section top
-       end
-
        # Genrate dot hierarchy for class inheritance
        fun tpl_dot(mmodules: Collection[MModule]): nullable TplArticle do
                var poset = new POSet[MModule]
@@ -974,29 +786,6 @@ class NitdocClass
                return new TplListItem.with_content(lnk)
        end
 
-       private fun tpl_intro: TplSection do
-               var section = new TplSection.with_title("top", tpl_title)
-               section.subtitle = mclass.intro.tpl_declaration
-               var article = new TplArticle("comment")
-               var mdoc = mclass.mdoc_or_fallback
-               if mdoc != null then
-                       article.content = mdoc.tpl_comment
-               end
-               section.add_child article
-               return section
-       end
-
-       private fun tpl_concerns(parent: TplSection) do
-               # intro title
-               var section = new TplSection.with_title("intro", "Introduction")
-               section.summary_title = "Introduction"
-               section.add_child tpl_mclassdef_article(mclass.intro)
-               parent.add_child section
-               # concerns
-               if concerns.is_empty then return
-               parent.add_child new TplArticle.with_content("concerns", "Concerns", concerns.to_tpl)
-       end
-
        private fun tpl_inheritance(parent: TplSection) do
                # parents
                var hparents = new HashSet[MClass]
@@ -1089,83 +878,6 @@ class NitdocClass
                return article
        end
 
-       private fun tpl_properties(parent: TplSection) do
-               var lst = concerns.to_a
-               for mentity in lst do
-                       if mentity isa MProject then
-                               parent.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MGroup then
-                               parent.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MModule then
-                               var section = new TplSection(mentity.nitdoc_id)
-                               var title = new Template
-                               title.add "in "
-                               title.add mentity.tpl_namespace
-                               section.title = title
-                               section.summary_title = "in {mentity.nitdoc_name}"
-
-                               # properties
-                               var mprops = mmodules2mprops[mentity]
-                               var by_kind = new PropertiesByKind.with_elements(mprops)
-
-                               for g in by_kind.groups do
-                                       for article in tpl_mproperty_articles(g) do
-                                               section.add_child article
-                                       end
-                               end
-                               parent.add_child section
-                       end
-               end
-       end
-
-       private fun tpl_mproperty_articles(elts: Collection[MProperty]):
-                       Sequence[TplArticle] do
-               var articles = new List[TplArticle]
-               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
-               tpl_inheritance(top)
-               tpl_concerns(top)
-               tpl_properties(top)
-               tpl_page.add_section top
-       end
-
-       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(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
-                               (mprop.visibility == protected_visibility or
-                               mprop.intro.mclassdef.mmodule.name != "kernel") then continue
-                       res.add mprop
-               end
-               res.add_all local
-               return res
-       end
-
        # Generate dot hierarchy for classes
        fun tpl_dot(mclasses: Collection[MClass]): nullable TplArticle do
                var poset = new POSet[MClass]
@@ -1241,63 +953,5 @@ class NitdocProperty
                topmenu.add_link new TplLink(page_url, mproperty.nitdoc_name)
                return topmenu
        end
-
-       private fun tpl_intro: TplSection do
-               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
-
-       private fun tpl_properties(parent: TplSection) do
-               # intro title
-               var ns = mproperty.intro.mclassdef.mmodule.tpl_namespace
-               var section = new TplSection("intro")
-               var title = new Template
-               title.add "Introduction in "
-               title.add ns
-               section.title = title
-               section.summary_title = "Introduction"
-               section.add_child tpl_mpropdef_article(mproperty.intro)
-               parent.add_child section
-
-               # concerns
-               if concerns.is_empty then return
-               parent.add_child new TplArticle.with_content("Concerns", "Concerns", concerns.to_tpl)
-
-               # redef list
-               var lst = concerns.to_a
-               for mentity in lst do
-                       if mentity isa MProject then
-                               parent.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MGroup then
-                               parent.add_child new TplSection(mentity.nitdoc_id)
-                       else if mentity isa MModule then
-                               var ssection = new TplSection(mentity.nitdoc_id)
-                               title = new Template
-                               title.add "in "
-                               title.add mentity.tpl_namespace
-                               ssection.title = title
-                               ssection.summary_title = "in {mentity.nitdoc_name}"
-
-                               # properties
-                               var mpropdefs = mmodules2mdefs[mentity].to_a
-                               name_sorter.sort(mpropdefs)
-                               for mpropdef in mpropdefs do
-                                       ssection.add_child tpl_mpropdef_article(mpropdef)
-                               end
-                               parent.add_child ssection
-                       end
-               end
-       end
-
-       redef fun tpl_content do
-               var top = tpl_intro
-               tpl_properties(top)
-               tpl_page.add_section top
-       end
 end
 
index 7b3c779..02041b0 100644 (file)
@@ -17,4 +17,4 @@
 # See `DocPhase`.
 module doc_phases
 
-import doc_concerns
+import doc_structure
diff --git a/src/doc/doc_phases/doc_structure.nit b/src/doc/doc_phases/doc_structure.nit
new file mode 100644 (file)
index 0000000..6fc7468
--- /dev/null
@@ -0,0 +1,280 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Composes the DocComposite tree of a DocPage and organizes its content.
+module doc_structure
+
+import doc_concerns
+
+# StructurePhase populates the DocPage content with section and article.
+#
+# This phase only applies structure.
+# The content of the structure is choosen by the rendering phases.
+class StructurePhase
+       super DocPhase
+
+       # Used to sort ConcernsTree by rank.
+       private var concerns_sorter = new MConcernRankSorter
+
+       # Used to sort ConcernsTree by name.
+       private var name_sorter = new MEntityNameSorter
+
+       # Populates the given DocModel.
+       redef fun apply do
+               for page in doc.pages do
+                       if page isa MEntityPage then page.apply_structure(self, doc)
+               end
+       end
+
+       # TODO index and search page should also be structured here
+end
+
+redef class MEntityPage
+
+       # Populates `self` with structure elements like DocComposite ones.
+       #
+       # See `StructurePhase`.
+       fun apply_structure(v: StructurePhase, doc: DocModel) do end
+end
+
+redef class MGroupPage
+       redef fun apply_structure(v, doc) do
+               if mentity.is_root then
+                       root.add new IntroArticle(mentity.mproject)
+               else
+                       root.add new IntroArticle(mentity)
+               end
+               var concerns = self.concerns
+               if concerns == null or concerns.is_empty then return
+               # FIXME avoid diff
+               mentity.mproject.booster_rank = -1000
+               mentity.booster_rank = -1000
+               concerns.sort_with(v.concerns_sorter)
+               mentity.mproject.booster_rank = 0
+               mentity.booster_rank = 0
+               root.add new ConcernsArticle(mentity, concerns)
+               for mentity in concerns do
+                       if mentity isa MModule then
+                               root.add new DefinitionArticle(mentity)
+                       else
+                               root.add new ConcernSection(mentity)
+                       end
+               end
+       end
+end
+
+redef class MModulePage
+       redef fun apply_structure(v, doc) do
+               root.add new IntroArticle(mentity)
+               var concerns = self.concerns
+               if concerns == null or concerns.is_empty then return
+               # FIXME avoid diff
+               mentity.mgroup.mproject.booster_rank = -1000
+               mentity.mgroup.booster_rank = -1000
+               mentity.booster_rank = -1000
+               concerns.sort_with(v.concerns_sorter)
+               mentity.mgroup.mproject.booster_rank = 0
+               mentity.mgroup.booster_rank = 0
+               mentity.booster_rank = 0
+               root.add new ConcernsArticle(mentity, concerns)
+               # reference list
+               for mentity in concerns do
+                       var section = new ConcernSection(mentity)
+                       if mentity isa MModule then
+                               var mclasses = mclasses_for_mmodule(mentity).to_a
+                               v.name_sorter.sort(mclasses)
+                               for mclass in mclasses do
+                                       var article = new DefinitionArticle(mclass)
+                                       var mclassdefs = mclassdefs_for(mclass).to_a
+                                       if not mclassdefs.has(mclass.intro) then
+                                               article.add(new DefinitionArticle(mclass.intro))
+                                       end
+                                       doc.mainmodule.linearize_mclassdefs(mclassdefs)
+                                       for mclassdef in mclassdefs do
+                                               article.add(new DefinitionArticle(mclassdef))
+                                       end
+                                       section.add article
+                               end
+                       end
+                       root.add section
+               end
+       end
+
+       # Filters `self.mclassses` by intro `mmodule`.
+       private fun mclasses_for_mmodule(mmodule: MModule): Set[MClass] do
+               var mclasses = new HashSet[MClass]
+               for mclass in self.mclasses do
+                       if mclass.intro.mmodule == mmodule then
+                               mclasses.add mclass
+                       end
+               end
+               return mclasses
+       end
+
+       # Filters `self.mclassdefs` by `mclass`.
+       private fun mclassdefs_for(mclass: MClass): Set[MClassDef] do
+               var mclassdefs = new HashSet[MClassDef]
+               for mclassdef in self.mclassdefs do
+                       if mclassdef.mclass == mclass then
+                               mclassdefs.add mclassdef
+                       end
+               end
+               return mclassdefs
+       end
+end
+
+redef class MClassPage
+       redef fun apply_structure(v, doc) do
+               root.add new IntroArticle(mentity)
+               var concerns = self.concerns
+               if concerns == null or concerns.is_empty then return
+               # FIXME diff hack
+               mentity.intro_mmodule.mgroup.mproject.booster_rank = -1000
+               mentity.intro_mmodule.mgroup.booster_rank = -1000
+               mentity.intro_mmodule.booster_rank = -1000
+               concerns.sort_with(v.concerns_sorter)
+               mentity.intro_mmodule.mgroup.mproject.booster_rank = 0
+               mentity.intro_mmodule.mgroup.booster_rank = 0
+               mentity.intro_mmodule.booster_rank = 0
+               root.add new ConcernsArticle(mentity, concerns)
+               for mentity in concerns do
+                       var section = new ConcernSection(mentity)
+                       if mentity isa MModule then
+                               var mprops = mproperties_for(mentity)
+                               var by_kind = new PropertiesByKind.with_elements(mprops)
+                               for group in by_kind.groups do
+                                       v.name_sorter.sort(group)
+                                       for mprop in group do
+                                               for mpropdef in mpropdefs_for(mprop, mentity) do
+                                                       section.add new DefinitionArticle(mpropdef)
+                                               end
+                                       end
+                               end
+                       end
+                       root.add section
+               end
+       end
+
+       # Filters `self.mpropdefs` by `mmodule`.
+       #
+       # FIXME diff hack
+       private fun mproperties_for(mmodule: MModule): Set[MProperty] do
+               var mprops = new HashSet[MProperty]
+               for mpropdef in self.mpropdefs do
+                       if mpropdef.mclassdef.mmodule == mmodule then
+                               mprops.add mpropdef.mproperty
+                       end
+               end
+               return mprops
+       end
+
+       # Filters `self.mpropdefs` by `mproperty`.
+       #
+       # FIXME diff hack
+       private fun mpropdefs_for(mproperty: MProperty, mmodule: MModule): Set[MPropDef] do
+               var mpropdefs = new HashSet[MPropDef]
+               for mpropdef in self.mpropdefs do
+                       if mpropdef.mproperty == mproperty and
+                               mpropdef.mclassdef.mmodule == mmodule then
+                               mpropdefs.add mpropdef
+                       end
+               end
+               return mpropdefs
+       end
+end
+
+redef class MPropertyPage
+       redef fun apply_structure(v, doc) do
+               root.add new IntroArticle(mentity)
+               var concerns = self.concerns
+               if concerns == null or concerns.is_empty then return
+               # FIXME diff hack
+               mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = -1000
+               mentity.intro.mclassdef.mmodule.mgroup.booster_rank = -1000
+               mentity.intro.mclassdef.mmodule.booster_rank = -1000
+               concerns.sort_with(v.concerns_sorter)
+               mentity.intro.mclassdef.mmodule.mgroup.mproject.booster_rank = 0
+               mentity.intro.mclassdef.mmodule.mgroup.booster_rank = 0
+               mentity.intro.mclassdef.mmodule.booster_rank = 0
+               root.add new ConcernsArticle(mentity, concerns)
+               for mentity in concerns do
+                       var section = new ConcernSection(mentity)
+                       if mentity isa MModule then
+                               # Add mproperties
+                               var mpropdefs = mpropdefs_for(mentity).to_a
+                               v.name_sorter.sort(mpropdefs)
+                               for mpropdef in mpropdefs do
+                                       section.add new DefinitionArticle(mpropdef)
+                               end
+                       end
+                       root.add section
+               end
+       end
+
+       # Filters `self.mpropdefs` by `mmodule`.
+       private fun mpropdefs_for(mmodule: MModule): Set[MPropDef] do
+               var mpropdefs = new HashSet[MPropDef]
+               for mpropdef in self.mpropdefs do
+                       if mpropdef.mclassdef.mmodule == mmodule then
+                               mpropdefs.add mpropdef
+                       end
+               end
+               return mpropdefs
+       end
+end
+
+# A DocComposite element about a MEntity.
+class MEntityComposite
+       super DocComposite
+
+       # MEntity documented by this page element.
+       var mentity: MEntity
+end
+
+# A Section about a Concern.
+#
+# Those sections are used to build the page summary.
+class ConcernSection
+       super MEntityComposite
+       super DocSection
+end
+
+# An article about a Mentity.
+#
+# Used to display textual content about a MEntity.
+abstract class MEntityArticle
+       super MEntityComposite
+       super DocArticle
+end
+
+# An introduction article about a MEntity.
+#
+# Used at the top of a documentation page to introduce the documented MEntity.
+class IntroArticle
+       super MEntityComposite
+       super DocArticle
+end
+
+# An article that display a ConcernsTreee as a list.
+class ConcernsArticle
+       super MEntityArticle
+
+       # Concerns to list in this article.
+       var concerns: ConcernsTree
+end
+
+# An article that display the definition text of a MEntity.
+class DefinitionArticle
+       super MEntityArticle
+end
index 2240c4e..e0990e7 100644 (file)
@@ -35,7 +35,8 @@ private class Nitdoc
                var phases = [
                        new ExtractionPhase(toolcontext, doc),
                        new MakePagePhase(toolcontext, doc),
-                       new ConcernsPhase(toolcontext, doc): DocPhase]
+                       new ConcernsPhase(toolcontext, doc),
+                       new StructurePhase(toolcontext, doc): DocPhase]
 
                for phase in phases do
                        toolcontext.info("# {phase.class_name}", 1)