doc: List the inner classes in the side panel.
[nit.git] / src / doc / doc_pages.nit
index 74315d4..4b81d86 100644 (file)
@@ -17,6 +17,7 @@ module doc_pages
 
 import toolcontext
 import doc_model
+private import json::static
 
 redef class ToolContext
        private var opt_dir = new OptionString("output directory", "-d", "--dir")
@@ -117,9 +118,9 @@ class Nitdoc
                end
                # copy shared files
                if ctx.opt_shareurl.value == null then
-                       sys.system("cp -r {sharedir.to_s}/* {output_dir.to_s}/")
+                       sys.system("cp -r -- {sharedir.to_s.escape_to_sh}/* {output_dir.to_s.escape_to_sh}/")
                else
-                       sys.system("cp -r {sharedir.to_s}/resources/ {output_dir.to_s}/resources/")
+                       sys.system("cp -r -- {sharedir.to_s.escape_to_sh}/resources/ {output_dir.to_s.escape_to_sh}/resources/")
                end
 
        end
@@ -162,6 +163,8 @@ class Nitdoc
        private fun properties do
                for mproperty in model.mproperties do
                        if mproperty.visibility <= ctx.min_visibility 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
@@ -182,9 +185,7 @@ end
 # All entities are grouped by name to make the research easier.
 class QuickSearch
 
-       private var mmodules = new HashSet[MModule]
-       private var mclasses = new HashSet[MClass]
-       private var mpropdefs = new HashMap[String, Set[MPropDef]]
+       private var table = new QuickSearchTable
 
        var ctx: ToolContext
        var model: Model
@@ -192,51 +193,72 @@ class QuickSearch
        init do
                for mmodule in model.mmodules do
                        if mmodule.is_fictive then continue
-                       mmodules.add mmodule
+                       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
-                       mclasses.add mclass
+                       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 mpropdefs.has_key(mproperty.name) then
-                               mpropdefs[mproperty.name] = new HashSet[MPropDef]
+                       for mpropdef in mproperty.mpropdefs do
+                               var full_name = mpropdef.mclassdef.mclass.full_name
+                               var cls_url = mpropdef.mclassdef.mclass.nitdoc_url
+                               var def_url = "{cls_url}#{mpropdef.mproperty.nitdoc_id}"
+                               add_result_for(mproperty.name, full_name, def_url)
                        end
-                       mpropdefs[mproperty.name].add_all(mproperty.mpropdefs)
                end
        end
 
+       private fun add_result_for(query: String, txt: String, url: String) do
+               table[query].add new QuickSearchResult(txt, url)
+       end
+
        fun render: Template do
                var tpl = new Template
-               tpl.add "var nitdocQuickSearchRawList=\{ "
-               for mmodule in mmodules do
-                       tpl.add "\"{mmodule.name}\":["
-                       tpl.add "\{txt:\"{mmodule.full_name}\",url:\"{mmodule.nitdoc_url}\"\},"
-                       tpl.add "],"
-               end
-               for mclass in mclasses do
-                       var full_name = mclass.intro.mmodule.full_name
-                       tpl.add "\"{mclass.name}\":["
-                       tpl.add "\{txt:\"{full_name}\",url:\"{mclass.nitdoc_url}\"\},"
-                       tpl.add "],"
-               end
-               for mproperty, mprops in mpropdefs do
-                       tpl.add "\"{mproperty}\":["
-                       for mpropdef in mprops do
-                               var full_name = mpropdef.mclassdef.mclass.full_name
-                               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
-               tpl.add " \};"
+               var buffer = new RopeBuffer
+               tpl.add buffer
+               buffer.append "var nitdocQuickSearchRawList="
+               table.append_json buffer
+               buffer.append ";"
                return tpl
        end
 end
 
+# The result map for QuickSearch.
+private class QuickSearchTable
+       super JsonMapRead[String, QuickSearchResultList]
+       super HashMap[String, QuickSearchResultList]
+
+       redef fun provide_default_value(key) do
+               var v = new QuickSearchResultList
+               self[key] = v
+               return v
+       end
+end
+
+# A QuickSearch result list.
+private class QuickSearchResultList
+       super JsonSequenceRead[QuickSearchResult]
+       super Array[QuickSearchResult]
+end
+
+# A QuickSearch result.
+private class QuickSearchResult
+       super Jsonable
+
+       # The text of the link.
+       var txt: String
+
+       # The destination of the link.
+       var url: String
+
+       redef fun to_json do
+               return "\{\"txt\":{txt.to_json},\"url\":{url.to_json}\}"
+       end
+end
+
 # Nitdoc base page
 # Define page structure and properties
 abstract class NitdocPage
@@ -314,11 +336,13 @@ abstract class NitdocPage
        fun tpl_graph(dot: Buffer, name: String, title: nullable String): nullable TplArticle do
                if ctx.opt_nodot.value then return null
                var output_dir = ctx.output_dir
-               var file = new OFStream.open("{output_dir}/{name}.dot")
+               var path = output_dir / name
+               var path_sh = path.escape_to_sh
+               var file = new OFStream.open("{path}.dot")
                file.write(dot)
                file.close
-               sys.system("\{ test -f {output_dir}/{name}.png && test -f {output_dir}/{name}.s.dot && diff {output_dir}/{name}.dot {output_dir}/{name}.s.dot >/dev/null 2>&1 ; \} || \{ cp {output_dir}/{name}.dot {output_dir}/{name}.s.dot && dot -Tpng -o{output_dir}/{name}.png -Tcmapx -o{output_dir}/{name}.map {output_dir}/{name}.s.dot ; \}")
-               var fmap = new IFStream.open("{output_dir}/{name}.map")
+               sys.system("\{ test -f {path_sh}.png && test -f {path_sh}.s.dot && diff -- {path_sh}.dot {path_sh}.s.dot >/dev/null 2>&1 ; \} || \{ cp -- {path_sh}.dot {path_sh}.s.dot && dot -Tpng -o{path_sh}.png -Tcmapx -o{path_sh}.map {path_sh}.s.dot ; \}")
+               var fmap = new IFStream.open("{path}.map")
                var map = fmap.read_all
                fmap.close
 
@@ -326,11 +350,12 @@ abstract class NitdocPage
                var alt = ""
                if title != null then
                        article.title = title
-                       alt = "alt='{title}'"
+                       alt = "alt='{title.html_escape}'"
                end
                article.css_classes.add "text-center"
                var content = new Template
-               content.add "<img src='{name}.png' usemap='#{name}' style='margin:auto' {alt}/>"
+               var name_html = name.html_escape
+               content.add "<img src='{name_html}.png' usemap='#{name_html}' style='margin:auto' {alt}/>"
                content.add map
                article.content = content
                return article
@@ -1065,6 +1090,9 @@ class NitdocClass
                tpl_sidebar_list("Virtual types", kind_map["type"].to_a, summary)
                tpl_sidebar_list("Constructors", kind_map["init"].to_a, summary)
                tpl_sidebar_list("Methods", kind_map["fun"].to_a, summary)
+               if not kind_map["inner"].is_empty then
+                       tpl_sidebar_list("Inner classes", kind_map["inner"].to_a, summary)
+               end
                tpl_sidebar.boxes.add new TplSideBox.with_content("All properties", summary)
        end
 
@@ -1252,6 +1280,10 @@ class NitdocClass
                                for article in tpl_mproperty_articles(kind_map, "fun") do
                                        section.add_child article
                                end
+                               # inner classes
+                               for article in tpl_mproperty_articles(kind_map, "inner") do
+                                       section.add_child article
+                               end
                                parent.add_child section
                        end
                end