Merge: lib/markdown2: introduce a new Markdown engine
authorJean Privat <jean@pryen.org>
Tue, 26 Jun 2018 13:28:20 +0000 (09:28 -0400)
committerJean Privat <jean@pryen.org>
Tue, 26 Jun 2018 13:28:20 +0000 (09:28 -0400)
This PR introduces a new Markdown engine called `markdown2`.

The current Markdown implementation is functional but does not follows the [CommonMark](http://commonmark.org/) specification as it passes only 273 tests of the 627 from the [CommonMark test suite](https://github.com/CommonMark/CommonMark).

Also there is a few issues with it as stated in #791, #1394, #1525 and #2507.

This new implementation aims at resolving these issues and follow the CommonMark specification.

Features:
* Markdown AST creation and rendering
* Rendering to HTML
* Rendering to Markdown
* Rendering to Man format
* Rendering to LaTeX
* Parsing of Github extended mode
* Parsing of wikilinks
* Parsing of LaTeX/Maths expression (upcoming in next PR)
* Respect of the CommonMark specification with only 10 tests failed (UTF-8 related)
* Extensive testing with a total of 980 test units...

I didn't remove the old markdown implementation since the benchmarks are not really good for now. Since `markdown2` uses a lot of regular expressions, performances can be an issue compared to `markdown`:

![screenshot from 2018-06-20 19 21 08](https://user-images.githubusercontent.com/583144/41689548-1a8bc5d0-74bf-11e8-899e-52b0eb093d57.png)

In the following PR some Nit tools will be migrated to the new implementation:
* nitunit
* nitiwiki
* nitdoc
* nitweb

Pull-Request: #2720

83 files changed:
.gitignore
Makefile
lib/core/core.nit
lib/core/file.nit
lib/github/README.md
lib/posix/README.md [new file with mode: 0644]
lib/posix/ext.nit [moved from lib/posix_ext/posix_ext.nit with 91% similarity]
lib/posix/package.ini [moved from lib/posix_ext/package.ini with 55% similarity]
lib/posix/posix.nit [moved from lib/core/posix.nit with 94% similarity]
lib/privileges/privileges.nit
lib/trees/bktree.nit [new file with mode: 0644]
lib/vsm/vsm.nit
share/nitdoc/css/Nitdoc.GitHub.css [deleted file]
share/nitdoc/css/Nitdoc.ModalBox.css [deleted file]
share/nitdoc/css/Nitdoc.QuickSearch.css [deleted file]
share/nitdoc/css/Nitdoc.UI.css [deleted file]
share/nitdoc/css/nitdoc.bootstrap.css
share/nitdoc/css/nitdoc.cards.css [new file with mode: 0644]
share/nitdoc/css/nitdoc.code.css [new file with mode: 0644]
share/nitdoc/css/nitdoc.css
share/nitdoc/css/nitdoc.quicksearch.css [new file with mode: 0644]
share/nitdoc/js/lib/github-api.js [deleted file]
share/nitdoc/js/lib/highlight.js [deleted file]
share/nitdoc/js/lib/nit.js [deleted file]
share/nitdoc/js/lib/utils.js [deleted file]
share/nitdoc/js/nitdoc.quicksearch.js [new file with mode: 0644]
share/nitdoc/js/nitdoc.utils.js [new file with mode: 0644]
share/nitdoc/js/plugins/filtering.js [deleted file]
share/nitdoc/js/plugins/github.js [deleted file]
share/nitdoc/js/plugins/github/commentbox.js [deleted file]
share/nitdoc/js/plugins/github/loginbox.js [deleted file]
share/nitdoc/js/plugins/modalbox.js [deleted file]
share/nitdoc/js/plugins/quicksearch.js [deleted file]
share/nitdoc/resources/icons/github-icon-green.png [deleted file]
share/nitdoc/resources/icons/github-icon-white.png [deleted file]
share/nitdoc/resources/icons/github-icon.png [deleted file]
share/nitweb/directives/entity/card.html
share/nitweb/directives/ui/search-field.html
share/nitweb/views/catalog/person.html
share/nitweb/views/search.html
src/catalog/catalog.nit
src/doc/api/api_base.nit
src/doc/commands/commands_model.nit
src/doc/doc_base.nit [deleted file]
src/doc/doc_commands.nit [deleted file]
src/doc/doc_down.nit
src/doc/doc_phases/doc_concerns.nit [deleted file]
src/doc/doc_phases/doc_graphs.nit [deleted file]
src/doc/doc_phases/doc_hierarchies.nit [deleted file]
src/doc/doc_phases/doc_html.nit [deleted file]
src/doc/doc_phases/doc_indexing.nit [deleted file]
src/doc/doc_phases/doc_intros_redefs.nit [deleted file]
src/doc/doc_phases/doc_lin.nit [deleted file]
src/doc/doc_phases/doc_pages.nit [deleted file]
src/doc/doc_phases/doc_phases.nit [deleted file]
src/doc/doc_phases/doc_poset.nit [deleted file]
src/doc/doc_phases/doc_readme.nit [deleted file]
src/doc/doc_phases/doc_structure.nit [deleted file]
src/doc/doc_phases/doc_test.nit [deleted file]
src/doc/html_templates/html_components.nit [deleted file]
src/doc/html_templates/html_model.nit [deleted file]
src/doc/html_templates/html_templates.nit [deleted file]
src/doc/html_templates/model_html.nit [deleted file]
src/doc/static/static.nit [moved from src/doc/doc.nit with 85% similarity]
src/doc/static/static_base.nit [new file with mode: 0644]
src/doc/static/static_cards.nit [new file with mode: 0644]
src/doc/static/static_html.nit [new file with mode: 0644]
src/doc/static/static_index.nit [new file with mode: 0644]
src/doc/static/static_structure.nit [new file with mode: 0644]
src/doc/templates/templates_html.nit
src/doc/test_doc_commands.nit [deleted file]
src/indexing/code_index.nit [new file with mode: 0644]
src/indexing/tests/test_code_index.nit [new file with mode: 0644]
src/nitdoc.nit
tests/MINGW64_NT.skip
tests/nitdoc.args
tests/niti.skip
tests/nitvm.skip
tests/sav/nitdoc_args1.res
tests/sav/nitdoc_args2.res
tests/sav/nitdoc_args3.res
tests/sav/nitdoc_args4.res
tests/testall.sh

index c4cb96e..1463ddf 100644 (file)
@@ -31,10 +31,12 @@ src/*.dat
 src/*.gnu
 src/*.bin
 src/nitc_0
+src/nitc_0.exe
 
 c_src/*.o
 c_src/*.cksum
 c_src/nitc
+c_src/nitc.exe
 
 csrc2/
 
index 5029f2a..3557372 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -60,10 +60,6 @@ doc/stdlib/index.html: bin/nitdoc bin/nitls
                --custom-brand "<a href=\"http://nitlanguage.org/\">Nitlanguage.org</a>" \
                --custom-overview-text "<p>Documentation for the standard library of Nit<br/>Version $$(git describe)<br/>Date: $$(git show --format="%cd" | head -1)</p>" \
                --custom-footer-text "Nit standard library. Version $$(git describe)." \
-               --github-upstream "nitlang:nit:master" \
-               --github-base-sha1 "$$(git rev-parse HEAD)" \
-               --github-gitdir "." \
-               --source "https://github.com/nitlang/nit/blob/$$(git rev-parse HEAD)/%f#L%l-%L" \
                --piwik-tracker "pratchett.info.uqam.ca/piwik/" \
                --piwik-site-id "2" \
 
@@ -74,10 +70,6 @@ doc/nitc/index.html: bin/nitdoc bin/nitls
                --custom-brand "<a href=\"http://nitlanguage.org/\">Nitlanguage.org</a>" \
                --custom-overview-text "<p>Documentation for the Nit tools<br/>Version $$(git describe)<br/>Date: $$(git show --format="%cd" | head -1)</p>" \
                --custom-footer-text "Nit tools. Version $$(git describe)." \
-               --github-upstream "nitlang:nit:master" \
-               --github-base-sha1 "$$(git rev-parse HEAD)" \
-               --github-gitdir "." \
-               --source "https://github.com/nitlang/nit/blob/$$(git rev-parse HEAD)/%f#L%l-%L" \
                --piwik-tracker "pratchett.info.uqam.ca/piwik/" \
                --piwik-site-id "3"
 
index 54f2550..5261077 100644 (file)
@@ -15,7 +15,6 @@
 # This module is implicitly imported by every module.
 module core
 
-import posix
 import environ
 import time
 import file
index fa50549..ed4c6c8 100644 (file)
@@ -306,6 +306,9 @@ redef class Int
        private fun fd_to_stream(mode: CString): NativeFile `{
                return fdopen((int)self, mode);
        `}
+
+       # Does the file descriptor `self` refer to a terminal?
+       fun isatty: Bool `{ return isatty(self); `}
 end
 
 # Constant for read-only file streams
index 041e753..18814ee 100644 (file)
@@ -18,17 +18,17 @@ Token can also be recovered from user config with `get_github_oauth`.
 
 [[doc: load_user]]
 [[doc: User]]
-[[list: User]]
+[[defs: User]]
 
 ### Retrieving repo data
 
 [[doc: load_repo]]
 [[doc: Repo]]
-[[list: Repo]]
+[[defs: Repo]]
 
 ### Other data
 
-[[list: github::api]]
+[[defs: github::api]]
 
 ### Advanced uses
 
@@ -68,4 +68,4 @@ GithubAPI can trigger different events depending on the hook configuration.
 
 [[doc: GithubEvent]]
 
-[[list: github::events]]
+[[defs: github::events]]
diff --git a/lib/posix/README.md b/lib/posix/README.md
new file mode 100644 (file)
index 0000000..3b73f9c
--- /dev/null
@@ -0,0 +1,5 @@
+Services conforming to POSIX
+
+The core module `posix` includes POSIX services available on all POSIX compliant systems.
+For services provided by some implementations of POSIX but absent from any POSIX version,
+import `posix::ext`.
similarity index 91%
rename from lib/posix_ext/posix_ext.nit
rename to lib/posix/ext.nit
index 8dd83c3..85da40a 100644 (file)
@@ -1,7 +1,5 @@
 # This file is part of NIT ( http://www.nitlanguage.org ).
 #
-# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
-#
 # 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
@@ -15,7 +13,9 @@
 # limitations under the License.
 
 # Services not defined in POSIX but provided by most implementations
-module posix_ext
+module ext
+
+import posix
 
 redef extern class Passwd
        # User information
similarity index 55%
rename from lib/posix_ext/package.ini
rename to lib/posix/package.ini
index 6b78527..79c6ca1 100644 (file)
@@ -1,12 +1,12 @@
 [package]
-name=posix_ext
+name=posix
 tags=wrapper,lib
 maintainer=Alexis Laferrière <alexis.laf@xymus.net>
 license=Apache-2.0
-desc=Services not defined in POSIX but provided by most implementations
+desc=Services conforming to POSIX
 [upstream]
-browse=https://github.com/nitlang/nit/tree/master/lib/posix_ext/
+browse=https://github.com/nitlang/nit/tree/master/lib/posix/
 git=https://github.com/nitlang/nit.git
-git.directory=lib/posix_ext/
+git.directory=lib/posix/
 homepage=http://nitlanguage.org
 issues=https://github.com/nitlang/nit/issues
similarity index 94%
rename from lib/core/posix.nit
rename to lib/posix/posix.nit
index 587e606..03a8a2e 100644 (file)
@@ -1,7 +1,5 @@
 # This file is part of NIT ( http://www.nitlanguage.org ).
 #
-# Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
-#
 # 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
@@ -17,8 +15,6 @@
 # Services conforming to POSIX
 module posix
 
-import text
-
 in "C Header" `{
 #include <sys/types.h>
 #include <unistd.h>
@@ -111,8 +107,3 @@ extern class Group `{struct group*`}
                return ret;
        `}
 end
-
-redef class Int
-       # Does the file descriptor `self` refer to a terminal?
-       fun isatty: Bool `{ return isatty(self); `}
-end
index f17a28e..c3a9466 100644 (file)
@@ -21,6 +21,7 @@
 module privileges
 
 import opts
+import posix
 
 redef class Text
        # Does the operating system know the user named `self`?
diff --git a/lib/trees/bktree.nit b/lib/trees/bktree.nit
new file mode 100644 (file)
index 0000000..b7d0d48
--- /dev/null
@@ -0,0 +1,149 @@
+# 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.
+
+# Implementation of BKTree
+#
+# As proposed by W. A. Burkhard and R. M. Keller in
+# "Some approaches to best-match file searching" the BKTree data structure
+# is usefull to speed-up spell checking based on the Levenshtein distance between
+# words.
+#
+# With a BKTree, the complexity to find mispelled words in a dictionnary is *O(log n)*
+# instead of *O(n)* with a dummy list.
+#
+# Example:
+#
+# ~~~
+# # Create a new BKTree
+# var tree = new BKTree
+#
+# # Index some words in the dictionnary for spell checking
+# tree.add("book")
+# tree.add("books")
+# tree.add("cake")
+# tree.add("boo")
+# tree.add("cape")
+# tree.add("boon")
+# tree.add("cook")
+# tree.add("cart")
+#
+# # Search suggestions in the BKTree
+# assert tree.search("caqe").join(", ") == "\{1: cake\}, \{1: cape\}"
+# ~~~
+#
+# See <https://dl.acm.org/citation.cfm?id=362003.362025>.
+module bktree
+
+import abstract_tree
+
+# A BKTree implementation
+#
+# See `add` to insert a new word.
+# See `search` to find matches from a `key`.
+class BKTree
+
+       # Default tolerance used to find matches
+       #
+       # Default is `2`.
+       var default_tolerance = 2 is writable
+
+       # Tree root
+       private var root: nullable BKNode = null
+
+       # Add a `key` in the tree
+       fun add(key: String) do
+               var root = self.root
+               if root == null then
+                       self.root = new BKNode(key)
+                       return
+               end
+
+               var node = root
+               var dist = node.key.levenshtein_distance(key)
+
+               while node.has_key(dist) do
+                       if dist == 0 then return
+                       node = node[dist]
+                       dist = node.key.levenshtein_distance(key)
+               end
+               node[dist] = new BKNode(key)
+       end
+
+       # Search `key` with a distance of `tolerance` in `self`.
+       #
+       # If `tolerance` is null, the use `default_tolerance` instead.
+       fun search(key: String, tolerance: nullable Int): Array[BKMatch] do
+               var res = new Array[BKMatch]
+               var root = self.root
+               if root != null then
+                       if tolerance == null then tolerance = self.default_tolerance
+                       search_recursive(root, res, key, tolerance)
+               end
+               default_comparator.sort(res)
+               return res
+       end
+
+       private fun search_recursive(node: BKNode, res: Array[BKMatch], key: String, tolerance: Int) do
+               var dist = node.key.levenshtein_distance(key)
+               var min = dist - tolerance
+               var max = dist + tolerance
+
+               if dist < tolerance then
+                       res.add new BKMatch(dist, node.key)
+               end
+
+               for odist, child in node do
+                       if odist < min or odist > max then continue
+                       search_recursive(child, res, key, tolerance)
+               end
+       end
+end
+
+# A node that goes in a BKTree
+#
+# Each child is mapped from `self` by its distance as an Int.
+private class BKNode
+       super HashMap[Int, BKNode]
+
+       # Key stored in `self`
+       var key: String
+
+       redef fun to_s do return "\{{key}\}"
+end
+
+# A match in a BKTree
+#
+# Used to order results returned by `BKTree::search`.
+class BKMatch
+       super Comparable
+
+       redef type OTHER: BKMatch
+
+       # Distance of `key` from the search query
+       var distance: Int
+
+       # Matched `key`
+       var key: String
+
+       redef fun ==(o) do return o isa BKMatch and distance == o.distance and key == o.key
+
+       redef fun <=>(o) do
+               if distance == o.distance then
+                       return key <=> o.key
+               end
+               return distance <=> o.distance
+       end
+
+       redef fun to_s do return "\{{distance}: {key}\}"
+end
index 4a64f99..ad3d928 100644 (file)
@@ -77,6 +77,17 @@ class Vector
                return super
        end
 
+       # Increment value for `obj` term
+       #
+       # If the term isn't already in the vector, the new value is 1.0.
+       fun inc(obj: nullable Object) do
+               if has_key(obj) then
+                       self[obj] += 1.0
+               else
+                       self[obj] = 1.0
+               end
+       end
+
        # The norm of the vector.
        #
        # `||x|| = (x1 ** 2 ... + xn ** 2).sqrt`
@@ -112,10 +123,18 @@ end
 # Documents can then be matched to query vectors.
 class VSMIndex
 
+       # Kind of documents stored in this index
+       #
+       # Clients can redefine this type to specialize the index.
+       type DOC: Document
+
        # Documents index
+       var documents = new HashSet[DOC]
+
+       # Inversed index
        #
-       # TODO use a more efficient representation.
-       var documents = new HashSet[Document]
+       # Link documents to existing terms.
+       var inversed_index = new HashMap[nullable Object, Array[DOC]]
 
        # Count for all terms in all indexed documents
        #
@@ -137,12 +156,18 @@ class VSMIndex
        #
        # Returns an `IndexMatch` for each indexed document.
        # Results are ordered by descending similarity.
-       fun match_vector(query: Vector): Array[IndexMatch] do
-               var matches = new Array[IndexMatch]
+       fun match_vector(query: Vector): Array[IndexMatch[DOC]] do
+               var documents = new HashSet[DOC]
+               for term, count in query do
+                       if inversed_index.has_key(term) then
+                               documents.add_all inversed_index[term]
+                       end
+               end
+               var matches = new Array[IndexMatch[DOC]]
                for doc in documents do
                        var sim = query.cosine_similarity(doc.tfidf)
                        if sim == 0.0 then continue
-                       matches.add new IndexMatch(doc, sim)
+                       matches.add new IndexMatch[DOC](doc, sim)
                end
                sorter.sort(matches)
                return matches
@@ -156,13 +181,13 @@ class VSMIndex
        #
        # When processing batch documents, use `auto_update = false` to disable
        # the auto update of the index.
-       fun index_document(doc: Document, auto_update: nullable Bool) do
+       fun index_document(doc: DOC, auto_update: nullable Bool) do
                for term, count in doc.terms_count do
-                       if not terms_doc_count.has_key(term) then
-                               terms_doc_count[term] = 1.0
-                       else
-                               terms_doc_count[term] += 1.0
+                       terms_doc_count.inc(term)
+                       if not inversed_index.has_key(term) then
+                               inversed_index[term] = new Array[DOC]
                        end
+                       inversed_index[term].add doc
                end
                documents.add doc
                if auto_update == null or auto_update then update_index
@@ -196,7 +221,7 @@ class StringIndex
        # Return the Document created.
        #
        # See `index_document`.
-       fun index_string(title, uri, string: String, auto_update: nullable Bool): Document do
+       fun index_string(title, uri, string: String, auto_update: nullable Bool): DOC do
                var vector = parse_string(string)
                var doc = new Document(title, uri, vector)
                index_document(doc, auto_update)
@@ -206,7 +231,7 @@ class StringIndex
        # Match the `query` string against all indexed documents
        #
        # See `match_vector`.
-       fun match_string(query: String): Array[IndexMatch] do
+       fun match_string(query: String): Array[IndexMatch[DOC]] do
                var vector = parse_string(query)
                var doc = new Document("", "", vector)
                return match_vector(doc.terms_frequency)
@@ -221,12 +246,7 @@ class StringIndex
                loop
                        var token = reader.read_word
                        if token == "" then break
-
-                       if not vector.has_key(token) then
-                               vector[token] = 1.0
-                       else
-                               vector[token] += 1.0
-                       end
+                       vector.inc(token)
                end
                return vector
        end
@@ -241,7 +261,7 @@ class FileIndex
        # Return the created document or null if `path` is not accepted by `accept_file`.
        #
        # See `index_document`.
-       fun index_file(path: String, auto_update: nullable Bool): nullable Document do
+       fun index_file(path: String, auto_update: nullable Bool): nullable DOC do
                if not accept_file(path) then return null
                var vector = parse_file(path)
                var doc = new Document(path, path, vector)
@@ -347,17 +367,17 @@ class Document
        # A high weight in tf–idf is reached by a high term frequency
        # (in the given document) and a low document frequency of the term in the
        # whole collection of documents
-       var tfidf = new Vector
+       var tfidf: Vector = terms_count is lazy
 
        redef fun to_s do return "{title}"
 end
 
 # A match to a `request` in an `Index`
-class IndexMatch
+class IndexMatch[DOC: Document]
        super Comparable
 
        # Document matching the `request_vector`
-       var document: Document
+       var document: DOC
 
        # Similarity between the `request` and the `doc`.
        #
@@ -372,7 +392,7 @@ end
 class IndexMatchSorter
        super DefaultComparator
 
-       redef type COMPARED: IndexMatch
+       redef type COMPARED: IndexMatch[Document]
 
        redef fun compare(a, b) do
                return b.similarity <=> a.similarity
diff --git a/share/nitdoc/css/Nitdoc.GitHub.css b/share/nitdoc/css/Nitdoc.GitHub.css
deleted file mode 100644 (file)
index a2d675f..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-\r
-   Documentation generator for the nit language.\r
-   Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc Github Login Box\r
- */\r
-\r
-#nitdoc-github-li.current {\r
-       color: #999;\r
-}\r
-\r
-#nitdoc-github-li .glyphicon {\r
-       cursor: pointer;\r
-}\r
-\r
-#nitdoc-github-loginbox {\r
-       cursor: default;\r
-       position: absolute;\r
-       width : 220px;\r
-       margin-top: 2px;\r
-       margin-left: -10px;\r
-       display: block;\r
-       padding: 10px;\r
-       text-align: left;\r
-       white-space: normal;\r
-       background-color: #ffffff;\r
-       border: 1px solid #ccc;\r
-       border: 1px solid rgba(0, 0, 0, 0.2);\r
-       -webkit-border-radius: 2px;\r
-       -moz-border-radius: 2px;\r
-       border-radius: 2px;\r
-       -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
-       -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
-       box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
-       -webkit-background-clip: padding-box;\r
-       -moz-background-clip: padding;\r
-       background-clip: padding-box;\r
-}\r
-\r
-#nitdoc-github-loginbox .nitdoc-github-loginbox-arrow {\r
-       position: absolute;\r
-       display: block;\r
-       width: 0;\r
-       height: 0;\r
-       border-color: transparent;\r
-       border-style: solid;\r
-       border-width: 7px;\r
-       top: -7px;\r
-       margin-left: 2px;\r
-       border-bottom-color: #999;\r
-       border-bottom-color: rgba(0, 0, 0, 0.25);\r
-       border-top-width: 0;\r
-}\r
-\r
-#nitdoc-github-loginbox .nitdoc-github-loginbox-arrow:after {\r
-       position: absolute;\r
-       display: block;\r
-       width: 0;\r
-       height: 0;\r
-       border-color: transparent;\r
-       border-style: solid;\r
-       border-width: 10px;\r
-       content: "";\r
-       top: 1px;\r
-       margin-left: -10px;\r
-       border-bottom-color: #ffffff;\r
-       border-top-width: 0;\r
-}\r
-\r
-#nitdoc-github-loginbox h3 {\r
-       text-align:center;\r
-}\r
-\r
-#nitdoc-github-loginbox h4 {\r
-       display: block;\r
-       width: 100%;\r
-       color: #6C6C6C;\r
-       font-style: normal;\r
-       text-align: center;\r
-       margin-bottom: 20px;\r
-}\r
-\r
-\r
-#nitdoc-github-loginbox a.nitdoc-github-loginbox-githublink {\r
-       display: block;\r
-       margin: 10px;\r
-       color: #0D8921;\r
-}\r
-\r
-/* Comment editing */\r
-\r
-.nitdoc-github-commentbox {\r
-       margin: 1em 5px;\r
-       border: 1px solid #eee;\r
-       padding: 1em;\r
-       background: #fff;\r
-       -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\r
-       -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\r
-       box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\r
-}\r
-\r
-.nitdoc-github-commentbox h3 {\r
-       margin: 0;\r
-}\r
-\r
-.nitdoc-github-commentbox-buttons {\r
-       text-align: right;\r
-}\r
-\r
-.nitdoc-github-commentbox dl {\r
-       margin-bottom: 0;\r
-}\r
-\r
-.nitdoc-github-commentbox dt {\r
-       margin-bottom: 0.5em;\r
-}\r
-\r
-.nitdoc-github-commentbox dd {\r
-       margin: 0 0 1em 0;\r
-}\r
-\r
-.nitdoc-github-commentbox textarea {\r
-       display: block;\r
-       font-family: monospace;\r
-       font-size: 1em;\r
-       width: 100%;\r
-       padding: 4px;\r
-       padding-left: 11px;\r
-       overflow-y: hidden;\r
-       border: 1px solid #CCC;\r
-}\r
-\r
-.nitdoc-github-preview {\r
-       margin: 0 15px;\r
-       cursor: pointer;\r
-}\r
-\r
-.nitdoc-github-button.nitdoc-github-cancel {\r
-       background-color: #b33630;\r
-       background-image: -webkit-gradient(linear, left top, left bottom, from(#E97A74), to(#9f312c)); /* Saf4+, Chrome */\r
-       background-image: -webkit-linear-gradient(top, #E97A74, #9f312c); /* Chrome 10+, Saf5.1+ */\r
-       background-image:    -moz-linear-gradient(top, #E97A74, #9f312c); /* FF3.6 */\r
-       background-image:     -ms-linear-gradient(top, #E97A74, #9f312c); /* IE10 */\r
-       background-image:      -o-linear-gradient(top, #E97A74, #9f312c); /* Opera 11.10+ */\r
-       background-image:         linear-gradient(top, #E97A74, #9f312c);\r
-       filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#E97A74', EndColorStr='#9f312c'); /* IE6–IE9 */\r
-       border: 1px solid #9f312c;\r
-}\r
-\r
-div.comment.locked {\r
-       color: gray;\r
-}\r
-p.locked {\r
-       color: black;\r
-}\r
-\r
-a.nitdoc-github-cancel {\r
-       color: #b33630;\r
-       cursor: pointer;\r
-}\r
-\r
-a.nitdoc-github-update {\r
-       color: orange;\r
-       cursor: pointer;\r
-}\r
-\r
-.nitdoc-dialog h4 {\r
-       font-weight: bold;\r
-}\r
-\r
-/* hljs */\r
-\r
-.hljs.nitcode {\r
-       padding-left: 10px;\r
-}\r
-\r
-.hljs-comment, .hljs-comment-block {\r
-       color: #777;\r
-}\r
-\r
-.hljs-keyword {\r
-       color: #000;\r
-       font-weight: bold;\r
-}\r
-\r
-.hljs-title {\r
-       font-weight: bold;\r
-}\r
-\r
-.hljs-module {\r
-       color: #3762E4;\r
-}\r
-\r
-.hljs-class .hljs-title {\r
-       color: #3762E4;\r
-}\r
-\r
-.hljs-type {\r
-       color: #3762E4;\r
-}\r
-\r
-.hljs-string {\r
-       color: #8F1546;\r
-}\r
-\r
-.hljs-subst {\r
-       color: #9E6BEB;\r
-}\r
-\r
-.hljs-fun .hljs-title {\r
-       color: #3762E4;\r
-}\r
-\r
-.hljs-char, .hljs-number {\r
-       color: #009999;\r
-}\r
diff --git a/share/nitdoc/css/Nitdoc.ModalBox.css b/share/nitdoc/css/Nitdoc.ModalBox.css
deleted file mode 100644 (file)
index bf9f9aa..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-\r
-   Documentation generator for the nit language.\r
-   Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc ModalBox style\r
- */\r
-\r
-.nitdoc-dialog-fade {\r
-       background: #000;\r
-       position: fixed; left: 0; top: 0;\r
-       width: 100%; height: 100%;\r
-       opacity: .80;\r
-       filter: alpha(opacity=80);\r
-       z-index: 9999;\r
-}\r
-\r
-.nitdoc-dialog {\r
-       background: #fff;\r
-       border: 1px solid #ddd;\r
-       float: left;\r
-       position: fixed;\r
-       z-index: 99999;\r
-       -webkit-box-shadow: 0px 0px 20px #000;\r
-       -moz-box-shadow: 0px 0px 20px #000;\r
-       box-shadow: 0px 0px 20px #000;\r
-       -webkit-border-radius: 2px;\r
-       -moz-border-radius: 2px;\r
-       border-radius: 2px;\r
-       text-align: left;\r
-       min-width: 300px;\r
-}\r
-\r
-.nitdoc-dialog-header {\r
-       padding: 10px 10px 10px 20px;\r
-       background: #f1f1f1;\r
-       border-bottom: 1px solid #ddd;\r
-}\r
-\r
-.nitdoc-dialog-error .nitdoc-dialog-header {\r
-       background: #C92020;\r
-}\r
-.nitdoc-dialog-error .nitdoc-dialog-header h3 {\r
-       color: white;\r
-}\r
-\r
-.nitdoc-dialog h3 {\r
-       display: inline;\r
-       margin: 0;\r
-}\r
-\r
-.nitdoc-dialog-content {\r
-       max-height: 450px;\r
-       overflow-y: scroll;\r
-       padding: 10px;\r
-}\r
-\r
-.nitdoc-dialog-buttons {\r
-       text-align: right;\r
-       padding: 5px;\r
-       border-top: 1px solid #ddd;\r
-}\r
-\r
-.nitdoc-dialog textarea {\r
-       min-width: 300px;\r
-       width: 100%;\r
-}\r
-\r
-.nitdoc-dialog button {\r
-       cursor: pointer;\r
-       border-radius: 2px;\r
-       -moz-border-radius: 2px;\r
-       -webkit-border-radius: 2px;\r
-       font-size: 14px;\r
-       padding: 5px 7px 5px 7px;\r
-       text-align: center;\r
-       background: #eee;\r
-       color: #333;\r
-       border: 1px solid #ddd;\r
-       font-weight: bold;\r
-}\r
-\r
-.nitdoc-dialog button:hover {\r
-       background: #0D8921;\r
-       color: #fff;\r
-       border: 1px solid #1d7900;\r
-}\r
-\r
-.nitdoc-dialog-close {\r
-       float: right;\r
-       padding: 5px;\r
-       margin: 0px;\r
-       line-height: 10px;\r
-       text-transform: lowercase;\r
-}\r
-\r
diff --git a/share/nitdoc/css/Nitdoc.QuickSearch.css b/share/nitdoc/css/Nitdoc.QuickSearch.css
deleted file mode 100644 (file)
index 81bba5d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-\r
-   Documentation generator for the nit language.\r
-   Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc Quick Search JS module \r
- */\r
-\r
-#nitdoc-qs-field {\r
-       width: 300px;\r
-       margin-top: 3px;\r
-}\r
-\r
-#nitdoc-qs-table {\r
-       background-color: #FFFFFF;\r
-       border: 1px solid #E0E0E0;\r
-       border-spacing: 0px;\r
-       z-index: 1000;\r
-       -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
-       -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
-       box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
-}\r
-\r
-#nitdoc-qs-table .nitdoc-qs-active {\r
-       cursor: pointer;\r
-       background: #EEE;\r
-}\r
-\r
-#nitdoc-qs-table td, th {\r
-       white-space: nowrap;\r
-       overflow: hidden;\r
-       line-height: 22px;\r
-       padding: 2px;\r
-}\r
-\r
-#nitdoc-qs-table td.nitdoc-qs-sub {\r
-       color: #6C6C6C;\r
-       padding-left: 12px;\r
-}\r
-\r
-#nitdoc-qs-table td.nitdoc-qs-info {\r
-       color: #0D8921;\r
-       font-size: smaller;\r
-       text-align: right;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-noresult td {\r
-       color: #6C6C6C;\r
-       font-size: small;\r
-       line-height: 15px;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-overflow td {\r
-       text-align: center;\r
-       font-size:      x-small;\r
-       line-height: 10px;\r
-       color: #FFF;\r
-       -webkit-touch-callout: none;\r
-       -webkit-user-select: none;\r
-       -khtml-user-select: none;\r
-       -moz-user-select: none;\r
-       -ms-user-select: none;\r
-       user-select: none;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-overflow-active td {\r
-       color: #0D8921;\r
-       cursor: pointer;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-overflow-active td:hover {\r
-       background-color: #E0E0E0;\r
-}\r
diff --git a/share/nitdoc/css/Nitdoc.UI.css b/share/nitdoc/css/Nitdoc.UI.css
deleted file mode 100644 (file)
index 17b248d..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-\r
-   Documentation generator for the nit language.\r
-   Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc UI JS module \r
- */\r
-\r
-\r
-/* Folding */\r
-\r
-a.nitdoc-ui-fold {\r
-       margin: 0 5px;\r
-       color: #999;\r
-       font-family: monospace;\r
-       font-weight: bold;\r
-       font-size: 120%;\r
-}\r
-\r
-/* Search page field */\r
-\r
-.nitdoc-ui-searchpage-field {\r
-       width: 750px;\r
-}\r
-\r
-/* Side bar boxes text filtering */\r
-\r
-.nitdoc-ui-filter {\r
-       text-align: center;\r
-       padding: 5px;\r
-}\r
-\r
-.nitdoc-ui-filter-field {\r
-       width: 150px;\r
-       margin-right: 5px;\r
-}\r
-\r
-.nitdoc-ui-filter-field-notused {\r
-       color: #999;\r
-       font-style: italic;\r
-}\r
-\r
-/* Side bar boxes type filtering */\r
-\r
-a.nitdoc-ui-filter-link {\r
-       color: #0D8921;\r
-       cursor: pointer;\r
-       font-family: monospace;\r
-       margin-right: 5px;\r
-       font-weight: bold;\r
-}\r
-\r
-a.nitdoc-ui-filter-link:hover {\r
-       text-decoration: underline;\r
-}\r
-\r
-a.nitdoc-ui-filter-hidden {\r
-       color: #999;\r
-       font-weight: normal;\r
-}\r
-\r
index 0351b6f..fd80998 100644 (file)
@@ -1,13 +1,3 @@
-/*!
- * Bootstrap v3.1.1
- *
- * Copyright 2014 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world by @mdo and @fat.
- * BootSwatchr built and provided by @DrewStrickland
- */
 /*! normalize.css v3.0.0 | MIT License | git.io/normalize */
 html {
   font-family: sans-serif;
@@ -275,11 +265,11 @@ html {
   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
 }
 body {
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-family: sans-serif;
   font-size: 14px;
   line-height: 1.428571429;
   color: #333333;
-  background-color: #ffffff;
+  background-color: #f2f2f2;
 }
 input,
 button,
@@ -290,12 +280,12 @@ textarea {
   line-height: inherit;
 }
 a {
-  color: #222222;
+  color: #0d8921;
   text-decoration: none;
 }
 a:hover,
 a:focus {
-  color: #0d8921;
+  color: #064310;
   text-decoration: underline;
 }
 a:focus {
@@ -319,14 +309,14 @@ img {
   height: auto;
 }
 .img-rounded {
-  border-radius: 4px;
+  border-radius: 0px;
 }
 .img-thumbnail {
   padding: 4px;
   line-height: 1.428571429;
-  background-color: #ffffff;
+  background-color: #f2f2f2;
   border: 1px solid #dddddd;
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-transition: all 0.2s ease-in-out;
   transition: all 0.2s ease-in-out;
   display: inline-block;
@@ -340,7 +330,7 @@ hr {
   margin-top: 20px;
   margin-bottom: 20px;
   border: 0;
-  border-top: 1px solid #eeeeee;
+  border-top: 1px solid #ddd;
 }
 .sr-only {
   position: absolute;
@@ -364,7 +354,7 @@ h6,
 .h4,
 .h5,
 .h6 {
-  font-family: inherit;
+  font-family: sans-serif;
   font-weight: 500;
   line-height: 1.1;
   color: inherit;
@@ -453,11 +443,11 @@ h2,
 }
 h3,
 .h3 {
-  font-size: 24px;
+  font-size: 23px;
 }
 h4,
 .h4 {
-  font-size: 18px;
+  font-size: 17px;
 }
 h5,
 .h5 {
@@ -465,7 +455,7 @@ h5,
 }
 h6,
 .h6 {
-  font-size: 12px;
+  font-size: 11px;
 }
 p {
   margin: 0 0 10px;
@@ -516,10 +506,10 @@ a.text-success:hover {
   color: #449d44;
 }
 .text-info {
-  color: #6c6c6c;
+  color: #5bc0de;
 }
 a.text-info:hover {
-  color: #525252;
+  color: #31b0d5;
 }
 .text-warning {
   color: #f0ad4e;
@@ -541,28 +531,28 @@ a.bg-primary:hover {
   background-color: #095a16;
 }
 .bg-success {
-  background-color: #eaf6ea;
+  background-color: #dff0d8;
 }
 a.bg-success:hover {
-  background-color: #c7e6c7;
+  background-color: #c1e2b3;
 }
 .bg-info {
-  background-color: #ececec;
+  background-color: #d9edf7;
 }
 a.bg-info:hover {
-  background-color: #d2d2d2;
+  background-color: #afd9ee;
 }
 .bg-warning {
-  background-color: #fef9f3;
+  background-color: #fcf8e3;
 }
 a.bg-warning:hover {
-  background-color: #fae3c4;
+  background-color: #f7ecb5;
 }
 .bg-danger {
-  background-color: #f9e2e2;
+  background-color: #f2dede;
 }
 a.bg-danger:hover {
-  background-color: #f0b9b8;
+  background-color: #e4b9b9;
 }
 .page-header {
   padding-bottom: 9px;
@@ -587,13 +577,15 @@ ol ol {
 .list-inline {
   padding-left: 0;
   list-style: none;
-  margin-left: -5px;
 }
 .list-inline > li {
   display: inline-block;
   padding-left: 5px;
   padding-right: 5px;
 }
+.list-inline > li:first-child {
+  padding-left: 0;
+}
 dl {
   margin-top: 0;
   margin-bottom: 20px;
@@ -692,7 +684,7 @@ code,
 kbd,
 pre,
 samp {
-  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+  font-family: monospace;
 }
 code {
   padding: 2px 4px;
@@ -700,14 +692,14 @@ code {
   color: #c7254e;
   background-color: #f9f2f4;
   white-space: nowrap;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 kbd {
   padding: 2px 4px;
   font-size: 90%;
   color: #ffffff;
   background-color: #333333;
-  border-radius: 2px;
+  border-radius: 0px;
   box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
 }
 pre {
@@ -721,7 +713,7 @@ pre {
   color: #333333;
   background-color: #f5f5f5;
   border: 1px solid #cccccc;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 pre code {
   padding: 0;
@@ -1440,7 +1432,7 @@ th {
   border-top: 2px solid #dddddd;
 }
 .table .table {
-  background-color: #ffffff;
+  background-color: #f2f2f2;
 }
 .table-condensed > thead > tr > th,
 .table-condensed > tbody > tr > th,
@@ -1471,7 +1463,7 @@ th {
 }
 .table-hover > tbody > tr:hover > td,
 .table-hover > tbody > tr:hover > th {
-  background-color: #f5f5f5;
+  background-color: #dbdbdb;
 }
 table col[class*="col-"] {
   position: static;
@@ -1496,13 +1488,13 @@ table th[class*="col-"] {
 .table > thead > tr.active > th,
 .table > tbody > tr.active > th,
 .table > tfoot > tr.active > th {
-  background-color: #f5f5f5;
+  background-color: #dbdbdb;
 }
 .table-hover > tbody > tr > td.active:hover,
 .table-hover > tbody > tr > th.active:hover,
 .table-hover > tbody > tr.active:hover > td,
 .table-hover > tbody > tr.active:hover > th {
-  background-color: #e8e8e8;
+  background-color: #cecece;
 }
 .table > thead > tr > td.success,
 .table > tbody > tr > td.success,
@@ -1516,13 +1508,13 @@ table th[class*="col-"] {
 .table > thead > tr.success > th,
 .table > tbody > tr.success > th,
 .table > tfoot > tr.success > th {
-  background-color: #eaf6ea;
+  background-color: #dff0d8;
 }
 .table-hover > tbody > tr > td.success:hover,
 .table-hover > tbody > tr > th.success:hover,
 .table-hover > tbody > tr.success:hover > td,
 .table-hover > tbody > tr.success:hover > th {
-  background-color: #d8eed8;
+  background-color: #d0e9c6;
 }
 .table > thead > tr > td.info,
 .table > tbody > tr > td.info,
@@ -1536,13 +1528,13 @@ table th[class*="col-"] {
 .table > thead > tr.info > th,
 .table > tbody > tr.info > th,
 .table > tfoot > tr.info > th {
-  background-color: #ececec;
+  background-color: #d9edf7;
 }
 .table-hover > tbody > tr > td.info:hover,
 .table-hover > tbody > tr > th.info:hover,
 .table-hover > tbody > tr.info:hover > td,
 .table-hover > tbody > tr.info:hover > th {
-  background-color: #dfdfdf;
+  background-color: #c4e3f3;
 }
 .table > thead > tr > td.warning,
 .table > tbody > tr > td.warning,
@@ -1556,13 +1548,13 @@ table th[class*="col-"] {
 .table > thead > tr.warning > th,
 .table > tbody > tr.warning > th,
 .table > tfoot > tr.warning > th {
-  background-color: #fef9f3;
+  background-color: #fcf8e3;
 }
 .table-hover > tbody > tr > td.warning:hover,
 .table-hover > tbody > tr > th.warning:hover,
 .table-hover > tbody > tr.warning:hover > td,
 .table-hover > tbody > tr.warning:hover > th {
-  background-color: #fceedb;
+  background-color: #faf2cc;
 }
 .table > thead > tr > td.danger,
 .table > tbody > tr > td.danger,
@@ -1576,13 +1568,13 @@ table th[class*="col-"] {
 .table > thead > tr.danger > th,
 .table > tbody > tr.danger > th,
 .table > tfoot > tr.danger > th {
-  background-color: #f9e2e2;
+  background-color: #f2dede;
 }
 .table-hover > tbody > tr > td.danger:hover,
 .table-hover > tbody > tr > th.danger:hover,
 .table-hover > tbody > tr.danger:hover > td,
 .table-hover > tbody > tr.danger:hover > th {
-  background-color: #f4cecd;
+  background-color: #ebcccc;
 }
 @media (max-width: 767px) {
   .table-responsive {
@@ -1663,6 +1655,7 @@ input[type="checkbox"] {
   margin: 4px 0 0;
   margin-top: 1px \9;
   /* IE8-9 */
+
   line-height: normal;
 }
 input[type="file"] {
@@ -1685,7 +1678,7 @@ input[type="checkbox"]:focus {
 }
 output {
   display: block;
-  padding-top: 3px;
+  padding-top: 7px;
   font-size: 14px;
   line-height: 1.428571429;
   color: #555555;
@@ -1693,25 +1686,25 @@ output {
 .form-control {
   display: block;
   width: 100%;
-  height: 26px;
-  padding: 2px 5px;
+  height: 34px;
+  padding: 6px 12px;
   font-size: 14px;
   line-height: 1.428571429;
   color: #555555;
   background-color: #ffffff;
   background-image: none;
   border: 1px solid #cccccc;
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
   -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
   transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
 }
 .form-control:focus {
-  border-color: #6c6c6c;
+  border-color: #66afe9;
   outline: 0;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(108, 108, 108, 0.6);
-  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(108, 108, 108, 0.6);
+  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
+  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
 }
 .form-control::-moz-placeholder {
   color: #999999;
@@ -1737,7 +1730,7 @@ input[type="search"] {
   -webkit-appearance: none;
 }
 input[type="date"] {
-  line-height: 26px;
+  line-height: 34px;
 }
 .form-group {
   margin-bottom: 15px;
@@ -1796,30 +1789,30 @@ fieldset[disabled] .checkbox-inline {
   cursor: not-allowed;
 }
 .input-sm {
-  height: 22px;
-  padding: 1px 5px;
+  height: 30px;
+  padding: 5px 10px;
   font-size: 12px;
   line-height: 1.5;
-  border-radius: 2px;
+  border-radius: 0px;
 }
 select.input-sm {
-  height: 22px;
-  line-height: 22px;
+  height: 30px;
+  line-height: 30px;
 }
 textarea.input-sm,
 select[multiple].input-sm {
   height: auto;
 }
 .input-lg {
-  height: 36px;
-  padding: 5px 10px;
+  height: 45px;
+  padding: 10px 16px;
   font-size: 18px;
   line-height: 1.33;
-  border-radius: 4px;
+  border-radius: 0px;
 }
 select.input-lg {
-  height: 36px;
-  line-height: 36px;
+  height: 45px;
+  line-height: 45px;
 }
 textarea.input-lg,
 select[multiple].input-lg {
@@ -1829,16 +1822,16 @@ select[multiple].input-lg {
   position: relative;
 }
 .has-feedback .form-control {
-  padding-right: 32.5px;
+  padding-right: 42.5px;
 }
 .has-feedback .form-control-feedback {
   position: absolute;
   top: 25px;
   right: 0;
   display: block;
-  width: 26px;
-  height: 26px;
-  line-height: 26px;
+  width: 34px;
+  height: 34px;
+  line-height: 34px;
   text-align: center;
 }
 .has-success .help-block,
@@ -1862,7 +1855,7 @@ select[multiple].input-lg {
 .has-success .input-group-addon {
   color: #5cb85c;
   border-color: #5cb85c;
-  background-color: #eaf6ea;
+  background-color: #dff0d8;
 }
 .has-success .form-control-feedback {
   color: #5cb85c;
@@ -1888,7 +1881,7 @@ select[multiple].input-lg {
 .has-warning .input-group-addon {
   color: #f0ad4e;
   border-color: #f0ad4e;
-  background-color: #fef9f3;
+  background-color: #fcf8e3;
 }
 .has-warning .form-control-feedback {
   color: #f0ad4e;
@@ -1914,7 +1907,7 @@ select[multiple].input-lg {
 .has-error .input-group-addon {
   color: #d9534f;
   border-color: #d9534f;
-  background-color: #f9e2e2;
+  background-color: #f2dede;
 }
 .has-error .form-control-feedback {
   color: #d9534f;
@@ -1970,18 +1963,18 @@ select[multiple].input-lg {
 .form-horizontal .checkbox-inline {
   margin-top: 0;
   margin-bottom: 0;
-  padding-top: 3px;
+  padding-top: 7px;
 }
 .form-horizontal .radio,
 .form-horizontal .checkbox {
-  min-height: 23px;
+  min-height: 27px;
 }
 .form-horizontal .form-group {
   margin-left: -15px;
   margin-right: -15px;
 }
 .form-horizontal .form-control-static {
-  padding-top: 3px;
+  padding-top: 7px;
 }
 @media (min-width: 768px) {
   .form-horizontal .control-label {
@@ -2002,18 +1995,17 @@ select[multiple].input-lg {
   background-image: none;
   border: 1px solid transparent;
   white-space: nowrap;
-  padding: 2px 5px;
+  padding: 6px 12px;
   font-size: 14px;
   line-height: 1.428571429;
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
+  -o-user-select: none;
   user-select: none;
 }
-.btn:focus,
-.btn:active:focus,
-.btn.active:focus {
+.btn:focus {
   outline: thin dotted;
   outline: 5px auto -webkit-focus-ring-color;
   outline-offset: -2px;
@@ -2165,8 +2157,8 @@ fieldset[disabled] .btn-success.active {
 }
 .btn-info {
   color: #ffffff;
-  background-color: #6c6c6c;
-  border-color: #5f5f5f;
+  background-color: #5bc0de;
+  border-color: #46b8da;
 }
 .btn-info:hover,
 .btn-info:focus,
@@ -2174,8 +2166,8 @@ fieldset[disabled] .btn-success.active {
 .btn-info.active,
 .open .dropdown-toggle.btn-info {
   color: #ffffff;
-  background-color: #585858;
-  border-color: #414141;
+  background-color: #39b3d7;
+  border-color: #269abc;
 }
 .btn-info:active,
 .btn-info.active,
@@ -2197,11 +2189,11 @@ fieldset[disabled] .btn-info:active,
 .btn-info.disabled.active,
 .btn-info[disabled].active,
 fieldset[disabled] .btn-info.active {
-  background-color: #6c6c6c;
-  border-color: #5f5f5f;
+  background-color: #5bc0de;
+  border-color: #46b8da;
 }
 .btn-info .badge {
-  color: #6c6c6c;
+  color: #5bc0de;
   background-color: #ffffff;
 }
 .btn-warning {
@@ -2287,7 +2279,7 @@ fieldset[disabled] .btn-danger.active {
   background-color: #ffffff;
 }
 .btn-link {
-  color: #222222;
+  color: #0d8921;
   font-weight: normal;
   cursor: pointer;
   border-radius: 0;
@@ -2308,7 +2300,7 @@ fieldset[disabled] .btn-link {
 }
 .btn-link:hover,
 .btn-link:focus {
-  color: #0d8921;
+  color: #064310;
   text-decoration: underline;
   background-color: transparent;
 }
@@ -2321,24 +2313,24 @@ fieldset[disabled] .btn-link:focus {
 }
 .btn-lg,
 .btn-group-lg > .btn {
-  padding: 5px 10px;
+  padding: 10px 16px;
   font-size: 18px;
   line-height: 1.33;
-  border-radius: 4px;
+  border-radius: 0px;
 }
 .btn-sm,
 .btn-group-sm > .btn {
-  padding: 1px 5px;
+  padding: 5px 10px;
   font-size: 12px;
   line-height: 1.5;
-  border-radius: 2px;
+  border-radius: 0px;
 }
 .btn-xs,
 .btn-group-xs > .btn {
-  padding: 0px 3px;
+  padding: 1px 5px;
   font-size: 12px;
   line-height: 1.5;
-  border-radius: 2px;
+  border-radius: 0px;
 }
 .btn-block {
   display: block;
@@ -2377,8 +2369,8 @@ input[type="button"].btn-block {
 }
 @font-face {
   font-family: 'Glyphicons Halflings';
-  src: url('../fonts/glyphicons-halflings-regular.eot');
-  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+  src: url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/fonts/glyphicons-halflings-regular.eot');
+  src: url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/fonts/glyphicons-halflings-regular.woff') format('woff'), url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
 }
 .glyphicon {
   position: relative;
@@ -3022,7 +3014,7 @@ input[type="button"].btn-block {
   background-color: #ffffff;
   border: 1px solid #cccccc;
   border: 1px solid rgba(0, 0, 0, 0.15);
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
   box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
   background-clip: padding-box;
@@ -3049,8 +3041,8 @@ input[type="button"].btn-block {
 .dropdown-menu > li > a:hover,
 .dropdown-menu > li > a:focus {
   text-decoration: none;
-  color: #262626;
-  background-color: #f5f5f5;
+  color: #ffffff;
+  background-color: #0d8921;
 }
 .dropdown-menu > .active > a,
 .dropdown-menu > .active > a:hover,
@@ -3253,12 +3245,12 @@ input[type="button"].btn-block {
   border-radius: 0;
 }
 .btn-group-vertical > .btn:first-child:not(:last-child) {
-  border-top-right-radius: 3px;
+  border-top-right-radius: 0px;
   border-bottom-right-radius: 0;
   border-bottom-left-radius: 0;
 }
 .btn-group-vertical > .btn:last-child:not(:first-child) {
-  border-bottom-left-radius: 3px;
+  border-bottom-left-radius: 0px;
   border-top-right-radius: 0;
   border-top-left-radius: 0;
 }
@@ -3304,8 +3296,6 @@ input[type="button"].btn-block {
   padding-right: 0;
 }
 .input-group .form-control {
-  position: relative;
-  z-index: 2;
   float: left;
   width: 100%;
   margin-bottom: 0;
@@ -3313,17 +3303,17 @@ input[type="button"].btn-block {
 .input-group-lg > .form-control,
 .input-group-lg > .input-group-addon,
 .input-group-lg > .input-group-btn > .btn {
-  height: 36px;
-  padding: 5px 10px;
+  height: 45px;
+  padding: 10px 16px;
   font-size: 18px;
   line-height: 1.33;
-  border-radius: 4px;
+  border-radius: 0px;
 }
 select.input-group-lg > .form-control,
 select.input-group-lg > .input-group-addon,
 select.input-group-lg > .input-group-btn > .btn {
-  height: 36px;
-  line-height: 36px;
+  height: 45px;
+  line-height: 45px;
 }
 textarea.input-group-lg > .form-control,
 textarea.input-group-lg > .input-group-addon,
@@ -3336,17 +3326,17 @@ select[multiple].input-group-lg > .input-group-btn > .btn {
 .input-group-sm > .form-control,
 .input-group-sm > .input-group-addon,
 .input-group-sm > .input-group-btn > .btn {
-  height: 22px;
-  padding: 1px 5px;
+  height: 30px;
+  padding: 5px 10px;
   font-size: 12px;
   line-height: 1.5;
-  border-radius: 2px;
+  border-radius: 0px;
 }
 select.input-group-sm > .form-control,
 select.input-group-sm > .input-group-addon,
 select.input-group-sm > .input-group-btn > .btn {
-  height: 22px;
-  line-height: 22px;
+  height: 30px;
+  line-height: 30px;
 }
 textarea.input-group-sm > .form-control,
 textarea.input-group-sm > .input-group-addon,
@@ -3373,7 +3363,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   vertical-align: middle;
 }
 .input-group-addon {
-  padding: 2px 5px;
+  padding: 6px 12px;
   font-size: 14px;
   font-weight: normal;
   line-height: 1;
@@ -3381,17 +3371,17 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   text-align: center;
   background-color: #eeeeee;
   border: 1px solid #cccccc;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .input-group-addon.input-sm {
-  padding: 1px 5px;
+  padding: 5px 10px;
   font-size: 12px;
-  border-radius: 2px;
+  border-radius: 0px;
 }
 .input-group-addon.input-lg {
-  padding: 5px 10px;
+  padding: 10px 16px;
   font-size: 18px;
-  border-radius: 4px;
+  border-radius: 0px;
 }
 .input-group-addon input[type="radio"],
 .input-group-addon input[type="checkbox"] {
@@ -3459,12 +3449,12 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 .nav > li > a {
   position: relative;
   display: block;
-  padding: 5px 10px;
+  padding: 10px 15px;
 }
 .nav > li > a:hover,
 .nav > li > a:focus {
   text-decoration: none;
-  background-color: #eeeeee;
+  background-color: #dddddd;
 }
 .nav > li.disabled > a {
   color: #999999;
@@ -3479,8 +3469,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 .nav .open > a,
 .nav .open > a:hover,
 .nav .open > a:focus {
-  background-color: #eeeeee;
-  border-color: #222222;
+  background-color: #dddddd;
+  border-color: #0d8921;
 }
 .nav .nav-divider {
   height: 1px;
@@ -3502,7 +3492,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   margin-right: 2px;
   line-height: 1.428571429;
   border: 1px solid transparent;
-  border-radius: 3px 3px 0 0;
+  border-radius: 0px 0px 0 0;
 }
 .nav-tabs > li > a:hover {
   border-color: #eeeeee #eeeeee #dddddd;
@@ -3511,7 +3501,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 .nav-tabs > li.active > a:hover,
 .nav-tabs > li.active > a:focus {
   color: #555555;
-  background-color: #ffffff;
+  background-color: #f2f2f2;
   border: 1px solid #dddddd;
   border-bottom-color: transparent;
   cursor: default;
@@ -3542,7 +3532,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 }
 .nav-tabs.nav-justified > li > a {
   margin-right: 0;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .nav-tabs.nav-justified > .active > a,
 .nav-tabs.nav-justified > .active > a:hover,
@@ -3552,19 +3542,19 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 @media (min-width: 768px) {
   .nav-tabs.nav-justified > li > a {
     border-bottom: 1px solid #dddddd;
-    border-radius: 3px 3px 0 0;
+    border-radius: 0px 0px 0 0;
   }
   .nav-tabs.nav-justified > .active > a,
   .nav-tabs.nav-justified > .active > a:hover,
   .nav-tabs.nav-justified > .active > a:focus {
-    border-bottom-color: #ffffff;
+    border-bottom-color: #f2f2f2;
   }
 }
 .nav-pills > li {
   float: left;
 }
 .nav-pills > li > a {
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .nav-pills > li + li {
   margin-left: 2px;
@@ -3610,7 +3600,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 }
 .nav-tabs-justified > li > a {
   margin-right: 0;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .nav-tabs-justified > .active > a,
 .nav-tabs-justified > .active > a:hover,
@@ -3620,12 +3610,12 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 @media (min-width: 768px) {
   .nav-tabs-justified > li > a {
     border-bottom: 1px solid #dddddd;
-    border-radius: 3px 3px 0 0;
+    border-radius: 0px 0px 0 0;
   }
   .nav-tabs-justified > .active > a,
   .nav-tabs-justified > .active > a:hover,
   .nav-tabs-justified > .active > a:focus {
-    border-bottom-color: #ffffff;
+    border-bottom-color: #f2f2f2;
   }
 }
 .tab-content > .tab-pane {
@@ -3641,13 +3631,13 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 }
 .navbar {
   position: relative;
-  min-height: 30px;
+  min-height: 50px;
   margin-bottom: 20px;
   border: 1px solid transparent;
 }
 @media (min-width: 768px) {
   .navbar {
-    border-radius: 3px;
+    border-radius: 0px;
   }
 }
 @media (min-width: 768px) {
@@ -3738,10 +3728,10 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 }
 .navbar-brand {
   float: left;
-  padding: 5px 15px;
+  padding: 15px 15px;
   font-size: 18px;
   line-height: 20px;
-  height: 30px;
+  height: 50px;
 }
 .navbar-brand:hover,
 .navbar-brand:focus {
@@ -3758,12 +3748,12 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   float: right;
   margin-right: 15px;
   padding: 9px 10px;
-  margin-top: -2px;
-  margin-bottom: -2px;
+  margin-top: 8px;
+  margin-bottom: 8px;
   background-color: transparent;
   background-image: none;
   border: 1px solid transparent;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .navbar-toggle:focus {
   outline: none;
@@ -3783,7 +3773,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   }
 }
 .navbar-nav {
-  margin: 2.5px -15px;
+  margin: 7.5px -15px;
 }
 .navbar-nav > li > a {
   padding-top: 10px;
@@ -3821,8 +3811,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
     float: left;
   }
   .navbar-nav > li > a {
-    padding-top: 5px;
-    padding-bottom: 5px;
+    padding-top: 15px;
+    padding-bottom: 15px;
   }
   .navbar-nav.navbar-right:last-child {
     margin-right: -15px;
@@ -3844,8 +3834,8 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   border-bottom: 1px solid transparent;
   -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
   box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
-  margin-top: 2px;
-  margin-bottom: 2px;
+  margin-top: 8px;
+  margin-bottom: 8px;
 }
 @media (min-width: 768px) {
   .navbar-form .form-group {
@@ -3912,20 +3902,20 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   border-bottom-left-radius: 0;
 }
 .navbar-btn {
-  margin-top: 2px;
-  margin-bottom: 2px;
+  margin-top: 8px;
+  margin-bottom: 8px;
 }
 .navbar-btn.btn-sm {
-  margin-top: 4px;
-  margin-bottom: 4px;
+  margin-top: 10px;
+  margin-bottom: 10px;
 }
 .navbar-btn.btn-xs {
-  margin-top: 4px;
-  margin-bottom: 4px;
+  margin-top: 14px;
+  margin-bottom: 14px;
 }
 .navbar-text {
-  margin-top: 5px;
-  margin-bottom: 5px;
+  margin-top: 15px;
+  margin-bottom: 15px;
 }
 @media (min-width: 768px) {
   .navbar-text {
@@ -3938,33 +3928,33 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   }
 }
 .navbar-default {
-  background-color: #f1f1f1;
-  border-color: #e0e0e0;
+  background-color: #0d8921;
+  border-color: none;
 }
 .navbar-default .navbar-brand {
-  color: #333333;
+  color: #ffffff;
 }
 .navbar-default .navbar-brand:hover,
 .navbar-default .navbar-brand:focus {
-  color: #1a1a1a;
+  color: #e6e6e6;
   background-color: transparent;
 }
 .navbar-default .navbar-text {
-  color: #333333;
+  color: #ffffff;
 }
 .navbar-default .navbar-nav > li > a {
-  color: #333333;
+  color: #ffffff;
 }
 .navbar-default .navbar-nav > li > a:hover,
 .navbar-default .navbar-nav > li > a:focus {
-  color: #0d8921;
+  color: #dddddd;
   background-color: transparent;
 }
 .navbar-default .navbar-nav > .active > a,
 .navbar-default .navbar-nav > .active > a:hover,
 .navbar-default .navbar-nav > .active > a:focus {
   color: #ffffff;
-  background-color: #0d8921;
+  background-color: #0a6b1a;
 }
 .navbar-default .navbar-nav > .disabled > a,
 .navbar-default .navbar-nav > .disabled > a:hover,
@@ -3980,32 +3970,32 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   background-color: #dddddd;
 }
 .navbar-default .navbar-toggle .icon-bar {
-  background-color: #888888;
+  background-color: #ffffff;
 }
 .navbar-default .navbar-collapse,
 .navbar-default .navbar-form {
-  border-color: #e0e0e0;
+  border-color: none;
 }
 .navbar-default .navbar-nav > .open > a,
 .navbar-default .navbar-nav > .open > a:hover,
 .navbar-default .navbar-nav > .open > a:focus {
-  background-color: #0d8921;
+  background-color: #0a6b1a;
   color: #ffffff;
 }
 @media (max-width: 767px) {
   .navbar-default .navbar-nav .open .dropdown-menu > li > a {
-    color: #333333;
+    color: #ffffff;
   }
   .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
   .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
-    color: #0d8921;
+    color: #dddddd;
     background-color: transparent;
   }
   .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
   .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
   .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
     color: #ffffff;
-    background-color: #0d8921;
+    background-color: #0a6b1a;
   }
   .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
   .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
@@ -4015,10 +4005,10 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   }
 }
 .navbar-default .navbar-link {
-  color: #333333;
+  color: #ffffff;
 }
 .navbar-default .navbar-link:hover {
-  color: #0d8921;
+  color: #dddddd;
 }
 .navbar-inverse {
   background-color: #222222;
@@ -4114,13 +4104,13 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   margin-bottom: 20px;
   list-style: none;
   background-color: #f5f5f5;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .breadcrumb > li {
   display: inline-block;
 }
 .breadcrumb > li + li:before {
-  content: "/\00a0";
+  content: "\00a0";
   padding: 0 5px;
   color: #cccccc;
 }
@@ -4131,7 +4121,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   display: inline-block;
   padding-left: 0;
   margin: 20px 0;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .pagination > li {
   display: inline;
@@ -4140,10 +4130,10 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 .pagination > li > span {
   position: relative;
   float: left;
-  padding: 2px 5px;
+  padding: 6px 12px;
   line-height: 1.428571429;
   text-decoration: none;
-  color: #222222;
+  color: #0d8921;
   background-color: #ffffff;
   border: 1px solid #dddddd;
   margin-left: -1px;
@@ -4151,19 +4141,19 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 .pagination > li:first-child > a,
 .pagination > li:first-child > span {
   margin-left: 0;
-  border-bottom-left-radius: 3px;
-  border-top-left-radius: 3px;
+  border-bottom-left-radius: 0px;
+  border-top-left-radius: 0px;
 }
 .pagination > li:last-child > a,
 .pagination > li:last-child > span {
-  border-bottom-right-radius: 3px;
-  border-top-right-radius: 3px;
+  border-bottom-right-radius: 0px;
+  border-top-right-radius: 0px;
 }
 .pagination > li > a:hover,
 .pagination > li > span:hover,
 .pagination > li > a:focus,
 .pagination > li > span:focus {
-  color: #0d8921;
+  color: #064310;
   background-color: #eeeeee;
   border-color: #dddddd;
 }
@@ -4192,33 +4182,33 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
 }
 .pagination-lg > li > a,
 .pagination-lg > li > span {
-  padding: 5px 10px;
+  padding: 10px 16px;
   font-size: 18px;
 }
 .pagination-lg > li:first-child > a,
 .pagination-lg > li:first-child > span {
-  border-bottom-left-radius: 4px;
-  border-top-left-radius: 4px;
+  border-bottom-left-radius: 0px;
+  border-top-left-radius: 0px;
 }
 .pagination-lg > li:last-child > a,
 .pagination-lg > li:last-child > span {
-  border-bottom-right-radius: 4px;
-  border-top-right-radius: 4px;
+  border-bottom-right-radius: 0px;
+  border-top-right-radius: 0px;
 }
 .pagination-sm > li > a,
 .pagination-sm > li > span {
-  padding: 1px 5px;
+  padding: 5px 10px;
   font-size: 12px;
 }
 .pagination-sm > li:first-child > a,
 .pagination-sm > li:first-child > span {
-  border-bottom-left-radius: 2px;
-  border-top-left-radius: 2px;
+  border-bottom-left-radius: 0px;
+  border-top-left-radius: 0px;
 }
 .pagination-sm > li:last-child > a,
 .pagination-sm > li:last-child > span {
-  border-bottom-right-radius: 2px;
-  border-top-right-radius: 2px;
+  border-bottom-right-radius: 0px;
+  border-top-right-radius: 0px;
 }
 .pager {
   padding-left: 0;
@@ -4305,11 +4295,11 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   background-color: #449d44;
 }
 .label-info {
-  background-color: #6c6c6c;
+  background-color: #5bc0de;
 }
 .label-info[href]:hover,
 .label-info[href]:focus {
-  background-color: #525252;
+  background-color: #31b0d5;
 }
 .label-warning {
   background-color: #f0ad4e;
@@ -4331,7 +4321,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
   padding: 3px 7px;
   font-size: 12px;
   font-weight: bold;
-  color: #ffffff;
+  color: : #fff;
   line-height: 1;
   vertical-align: baseline;
   white-space: nowrap;
@@ -4358,41 +4348,41 @@ a.badge:focus {
 }
 a.list-group-item.active > .badge,
 .nav-pills > .active > a > .badge {
-  color: #222222;
+  color: #0d8921;
   background-color: #ffffff;
 }
 .nav-pills > li > a > .badge {
   margin-left: 3px;
 }
 .jumbotron {
-  padding: 20px;
-  margin-bottom: 20px;
+  padding: 30px;
+  margin-bottom: 30px;
   color: inherit;
-  background-color: #eeeeee;
+  background-color: #ffffff;
 }
 .jumbotron h1,
 .jumbotron .h1 {
   color: inherit;
 }
 .jumbotron p {
-  margin-bottom: 10px;
-  font-size: 17px;
+  margin-bottom: 15px;
+  font-size: 21px;
   font-weight: 200;
 }
 .container .jumbotron {
-  border-radius: 4px;
+  border-radius: 0px;
 }
 .jumbotron .container {
   max-width: 100%;
 }
 @media screen and (min-width: 768px) {
   .jumbotron {
-    padding-top: 32px;
-    padding-bottom: 32px;
+    padding-top: 48px;
+    padding-bottom: 48px;
   }
   .container .jumbotron {
-    padding-left: 40px;
-    padding-right: 40px;
+    padding-left: 60px;
+    padding-right: 60px;
   }
   .jumbotron h1,
   .jumbotron .h1 {
@@ -4404,9 +4394,9 @@ a.list-group-item.active > .badge,
   padding: 4px;
   margin-bottom: 20px;
   line-height: 1.428571429;
-  background-color: #ffffff;
+  background-color: #f2f2f2;
   border: 1px solid #dddddd;
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-transition: all 0.2s ease-in-out;
   transition: all 0.2s ease-in-out;
 }
@@ -4418,7 +4408,7 @@ a.list-group-item.active > .badge,
 a.thumbnail:hover,
 a.thumbnail:focus,
 a.thumbnail.active {
-  border-color: #222222;
+  border-color: #0d8921;
 }
 .thumbnail .caption {
   padding: 9px;
@@ -4428,7 +4418,7 @@ a.thumbnail.active {
   padding: 15px;
   margin-bottom: 20px;
   border: 1px solid transparent;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .alert h4 {
   margin-top: 0;
@@ -4454,45 +4444,45 @@ a.thumbnail.active {
   color: inherit;
 }
 .alert-success {
-  background-color: #eaf6ea;
-  border-color: #bcdfb5;
+  background-color: #dff0d8;
+  border-color: #d6e9c6;
   color: #5cb85c;
 }
 .alert-success hr {
-  border-top-color: #acd7a3;
+  border-top-color: #c9e2b3;
 }
 .alert-success .alert-link {
   color: #449d44;
 }
 .alert-info {
-  background-color: #ececec;
-  border-color: #d2d2d2;
-  color: #6c6c6c;
+  background-color: #d9edf7;
+  border-color: #bce8f1;
+  color: #5bc0de;
 }
 .alert-info hr {
-  border-top-color: #c5c5c5;
+  border-top-color: #a6e1ec;
 }
 .alert-info .alert-link {
-  color: #525252;
+  color: #31b0d5;
 }
 .alert-warning {
-  background-color: #fef9f3;
-  border-color: #fadac4;
+  background-color: #fcf8e3;
+  border-color: #fbeed5;
   color: #f0ad4e;
 }
 .alert-warning hr {
-  border-top-color: #f8ccac;
+  border-top-color: #f8e5be;
 }
 .alert-warning .alert-link {
   color: #ec971f;
 }
 .alert-danger {
-  background-color: #f9e2e2;
-  border-color: #f0b8c0;
+  background-color: #f2dede;
+  border-color: #eed3d7;
   color: #d9534f;
 }
 .alert-danger hr {
-  border-top-color: #eba3ad;
+  border-top-color: #e6c1c7;
 }
 .alert-danger .alert-link {
   color: #c9302c;
@@ -4518,7 +4508,7 @@ a.thumbnail.active {
   height: 20px;
   margin-bottom: 20px;
   background-color: #f5f5f5;
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
   box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
 }
@@ -4553,7 +4543,7 @@ a.thumbnail.active {
   background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
 }
 .progress-bar-info {
-  background-color: #6c6c6c;
+  background-color: #5bc0de;
 }
 .progress-striped .progress-bar-info {
   background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
@@ -4614,13 +4604,13 @@ a.thumbnail.active {
   border: 1px solid #dddddd;
 }
 .list-group-item:first-child {
-  border-top-right-radius: 3px;
-  border-top-left-radius: 3px;
+  border-top-right-radius: 0px;
+  border-top-left-radius: 0px;
 }
 .list-group-item:last-child {
   margin-bottom: 0;
-  border-bottom-right-radius: 3px;
-  border-bottom-left-radius: 3px;
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 0px;
 }
 .list-group-item > .badge {
   float: right;
@@ -4655,11 +4645,11 @@ a.list-group-item.active:focus .list-group-item-heading {
 a.list-group-item.active .list-group-item-text,
 a.list-group-item.active:hover .list-group-item-text,
 a.list-group-item.active:focus .list-group-item-text {
-  color: #71f185;
+  color: #cccccc;
 }
 .list-group-item-success {
   color: #5cb85c;
-  background-color: #eaf6ea;
+  background-color: #dff0d8;
 }
 a.list-group-item-success {
   color: #5cb85c;
@@ -4670,7 +4660,7 @@ a.list-group-item-success .list-group-item-heading {
 a.list-group-item-success:hover,
 a.list-group-item-success:focus {
   color: #5cb85c;
-  background-color: #d8eed8;
+  background-color: #d0e9c6;
 }
 a.list-group-item-success.active,
 a.list-group-item-success.active:hover,
@@ -4680,30 +4670,30 @@ a.list-group-item-success.active:focus {
   border-color: #5cb85c;
 }
 .list-group-item-info {
-  color: #6c6c6c;
-  background-color: #ececec;
+  color: #5bc0de;
+  background-color: #d9edf7;
 }
 a.list-group-item-info {
-  color: #6c6c6c;
+  color: #5bc0de;
 }
 a.list-group-item-info .list-group-item-heading {
   color: inherit;
 }
 a.list-group-item-info:hover,
 a.list-group-item-info:focus {
-  color: #6c6c6c;
-  background-color: #dfdfdf;
+  color: #5bc0de;
+  background-color: #c4e3f3;
 }
 a.list-group-item-info.active,
 a.list-group-item-info.active:hover,
 a.list-group-item-info.active:focus {
   color: #fff;
-  background-color: #6c6c6c;
-  border-color: #6c6c6c;
+  background-color: #5bc0de;
+  border-color: #5bc0de;
 }
 .list-group-item-warning {
   color: #f0ad4e;
-  background-color: #fef9f3;
+  background-color: #fcf8e3;
 }
 a.list-group-item-warning {
   color: #f0ad4e;
@@ -4714,7 +4704,7 @@ a.list-group-item-warning .list-group-item-heading {
 a.list-group-item-warning:hover,
 a.list-group-item-warning:focus {
   color: #f0ad4e;
-  background-color: #fceedb;
+  background-color: #faf2cc;
 }
 a.list-group-item-warning.active,
 a.list-group-item-warning.active:hover,
@@ -4725,7 +4715,7 @@ a.list-group-item-warning.active:focus {
 }
 .list-group-item-danger {
   color: #d9534f;
-  background-color: #f9e2e2;
+  background-color: #f2dede;
 }
 a.list-group-item-danger {
   color: #d9534f;
@@ -4736,7 +4726,7 @@ a.list-group-item-danger .list-group-item-heading {
 a.list-group-item-danger:hover,
 a.list-group-item-danger:focus {
   color: #d9534f;
-  background-color: #f4cecd;
+  background-color: #ebcccc;
 }
 a.list-group-item-danger.active,
 a.list-group-item-danger.active:hover,
@@ -4757,7 +4747,7 @@ a.list-group-item-danger.active:focus {
   margin-bottom: 20px;
   background-color: #ffffff;
   border: 1px solid transparent;
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
   box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
 }
@@ -4767,8 +4757,8 @@ a.list-group-item-danger.active:focus {
 .panel-heading {
   padding: 10px 15px;
   border-bottom: 1px solid transparent;
-  border-top-right-radius: 2px;
-  border-top-left-radius: 2px;
+  border-top-right-radius: -1px;
+  border-top-left-radius: -1px;
 }
 .panel-heading > .dropdown .dropdown-toggle {
   color: inherit;
@@ -4786,8 +4776,8 @@ a.list-group-item-danger.active:focus {
   padding: 10px 15px;
   background-color: #f5f5f5;
   border-top: 1px solid #dddddd;
-  border-bottom-right-radius: 2px;
-  border-bottom-left-radius: 2px;
+  border-bottom-right-radius: -1px;
+  border-bottom-left-radius: -1px;
 }
 .panel > .list-group {
   margin-bottom: 0;
@@ -4796,15 +4786,19 @@ a.list-group-item-danger.active:focus {
   border-width: 1px 0;
   border-radius: 0;
 }
-.panel > .list-group:first-child .list-group-item:first-child {
+.panel > .list-group .list-group-item:first-child {
   border-top: 0;
-  border-top-right-radius: 2px;
-  border-top-left-radius: 2px;
 }
-.panel > .list-group:last-child .list-group-item:last-child {
+.panel > .list-group .list-group-item:last-child {
   border-bottom: 0;
-  border-bottom-right-radius: 2px;
-  border-bottom-left-radius: 2px;
+}
+.panel > .list-group:first-child .list-group-item:first-child {
+  border-top-right-radius: -1px;
+  border-top-left-radius: -1px;
+}
+.panel > .list-group:last-child .list-group-item:last-child {
+  border-bottom-right-radius: -1px;
+  border-bottom-left-radius: -1px;
 }
 .panel-heading + .list-group .list-group-item:first-child {
   border-top-width: 0;
@@ -4813,11 +4807,6 @@ a.list-group-item-danger.active:focus {
 .panel > .table-responsive > .table {
   margin-bottom: 0;
 }
-.panel > .table:first-child,
-.panel > .table-responsive:first-child > .table:first-child {
-  border-top-right-radius: 2px;
-  border-top-left-radius: 2px;
-}
 .panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
 .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
@@ -4826,7 +4815,7 @@ a.list-group-item-danger.active:focus {
 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
 .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
-  border-top-left-radius: 2px;
+  border-top-left-radius: -1px;
 }
 .panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
@@ -4836,12 +4825,7 @@ a.list-group-item-danger.active:focus {
 .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
 .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
 .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
-  border-top-right-radius: 2px;
-}
-.panel > .table:last-child,
-.panel > .table-responsive:last-child > .table:last-child {
-  border-bottom-right-radius: 2px;
-  border-bottom-left-radius: 2px;
+  border-top-right-radius: -1px;
 }
 .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
@@ -4851,7 +4835,7 @@ a.list-group-item-danger.active:focus {
 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
 .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
-  border-bottom-left-radius: 2px;
+  border-bottom-left-radius: -1px;
 }
 .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
@@ -4861,7 +4845,7 @@ a.list-group-item-danger.active:focus {
 .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
 .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
 .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
-  border-bottom-right-radius: 2px;
+  border-bottom-right-radius: -1px;
 }
 .panel > .panel-body + .table,
 .panel > .panel-body + .table-responsive {
@@ -4932,7 +4916,7 @@ a.list-group-item-danger.active:focus {
 }
 .panel-group .panel {
   margin-bottom: 0;
-  border-radius: 3px;
+  border-radius: 0px;
   overflow: hidden;
 }
 .panel-group .panel + .panel {
@@ -4979,60 +4963,60 @@ a.list-group-item-danger.active:focus {
   border-bottom-color: #0d8921;
 }
 .panel-success {
-  border-color: #bcdfb5;
+  border-color: #d6e9c6;
 }
 .panel-success > .panel-heading {
   color: #5cb85c;
-  background-color: #eaf6ea;
-  border-color: #bcdfb5;
+  background-color: #dff0d8;
+  border-color: #d6e9c6;
 }
 .panel-success > .panel-heading + .panel-collapse .panel-body {
-  border-top-color: #bcdfb5;
+  border-top-color: #d6e9c6;
 }
 .panel-success > .panel-footer + .panel-collapse .panel-body {
-  border-bottom-color: #bcdfb5;
+  border-bottom-color: #d6e9c6;
 }
 .panel-info {
-  border-color: #d2d2d2;
+  border-color: #bce8f1;
 }
 .panel-info > .panel-heading {
-  color: #6c6c6c;
-  background-color: #ececec;
-  border-color: #d2d2d2;
+  color: #5bc0de;
+  background-color: #d9edf7;
+  border-color: #bce8f1;
 }
 .panel-info > .panel-heading + .panel-collapse .panel-body {
-  border-top-color: #d2d2d2;
+  border-top-color: #bce8f1;
 }
 .panel-info > .panel-footer + .panel-collapse .panel-body {
-  border-bottom-color: #d2d2d2;
+  border-bottom-color: #bce8f1;
 }
 .panel-warning {
-  border-color: #fadac4;
+  border-color: #fbeed5;
 }
 .panel-warning > .panel-heading {
   color: #f0ad4e;
-  background-color: #fef9f3;
-  border-color: #fadac4;
+  background-color: #fcf8e3;
+  border-color: #fbeed5;
 }
 .panel-warning > .panel-heading + .panel-collapse .panel-body {
-  border-top-color: #fadac4;
+  border-top-color: #fbeed5;
 }
 .panel-warning > .panel-footer + .panel-collapse .panel-body {
-  border-bottom-color: #fadac4;
+  border-bottom-color: #fbeed5;
 }
 .panel-danger {
-  border-color: #f0b8c0;
+  border-color: #eed3d7;
 }
 .panel-danger > .panel-heading {
   color: #d9534f;
-  background-color: #f9e2e2;
-  border-color: #f0b8c0;
+  background-color: #f2dede;
+  border-color: #eed3d7;
 }
 .panel-danger > .panel-heading + .panel-collapse .panel-body {
-  border-top-color: #f0b8c0;
+  border-top-color: #eed3d7;
 }
 .panel-danger > .panel-footer + .panel-collapse .panel-body {
-  border-bottom-color: #f0b8c0;
+  border-bottom-color: #eed3d7;
 }
 .well {
   min-height: 20px;
@@ -5040,7 +5024,7 @@ a.list-group-item-danger.active:focus {
   margin-bottom: 20px;
   background-color: #f5f5f5;
   border: 1px solid #e3e3e3;
-  border-radius: 3px;
+  border-radius: 0px;
   -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
 }
@@ -5050,11 +5034,11 @@ a.list-group-item-danger.active:focus {
 }
 .well-lg {
   padding: 24px;
-  border-radius: 4px;
+  border-radius: 0px;
 }
 .well-sm {
   padding: 9px;
-  border-radius: 2px;
+  border-radius: 0px;
 }
 .close {
   float: right;
@@ -5121,7 +5105,7 @@ button.close {
   background-color: #ffffff;
   border: 1px solid #999999;
   border: 1px solid rgba(0, 0, 0, 0.2);
-  border-radius: 4px;
+  border-radius: 0px;
   -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
   box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
   background-clip: padding-box;
@@ -5231,7 +5215,7 @@ button.close {
   text-align: center;
   text-decoration: none;
   background-color: #000000;
-  border-radius: 3px;
+  border-radius: 0px;
 }
 .tooltip-arrow {
   position: absolute;
@@ -5305,7 +5289,7 @@ button.close {
   background-clip: padding-box;
   border: 1px solid #cccccc;
   border: 1px solid rgba(0, 0, 0, 0.2);
-  border-radius: 4px;
+  border-radius: 0px;
   -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
   box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
   white-space: normal;
@@ -5570,8 +5554,8 @@ button.close {
   text-shadow: none;
 }
 @media screen and (min-width: 768px) {
-  .carousel-control .glyphicon-chevron-left,
-  .carousel-control .glyphicon-chevron-right,
+  .carousel-control .glyphicons-chevron-left,
+  .carousel-control .glyphicons-chevron-right,
   .carousel-control .icon-prev,
   .carousel-control .icon-next {
     width: 30px;
diff --git a/share/nitdoc/css/nitdoc.cards.css b/share/nitdoc/css/nitdoc.cards.css
new file mode 100644 (file)
index 0000000..fc3e5ef
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/* cards */
+
+.card.active {
+       border: 1px solid #1E9431;
+}
+
+.card-heading {
+    margin-top: 0;
+    margin-bottom: 5px;
+}
+
+.card {
+       display: table;
+       width: 100%;
+       background: #fff;
+       border: 1px solid #eee;
+       margin-top: 10px;
+       box-shadow: -1px -1px 3px rgba(0,0,0,.06), 1px 1px 3px rgba(0,0,0,.12);
+}
+
+.card-body, .card-left, .card-right {
+       display: table-cell;
+       padding: 15px;
+}
+
+.card-body {
+       padding: 15px 0;
+       width: 100%
+}
+
+.card-body:first-child {
+       padding-left: 15px;
+}
+
+.card-body:last-child {
+       padding-right: 15px;
+}
+
+.card-list {
+       margin-top: 10px;
+}
+
+.card-list > .card:first-child {
+       border-top: 1px solid #ddd;
+}
+
+.card-list > .card {
+       margin-top: 0;
+       border-top: none;
+}
+
+.card-title {
+    margin-top: 0;
+}
diff --git a/share/nitdoc/css/nitdoc.code.css b/share/nitdoc/css/nitdoc.code.css
new file mode 100644 (file)
index 0000000..2a944aa
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+/* Code Highlighting */
+
+.nitcode a { color: inherit; text-decoration: inherit; } /* hide links */
+.nitcode a:hover { text-decoration: underline; } /* underline links */
+
+/* lexical raw tokens. independent of usage or semantic: */
+.nitcode .nc_c { color: gray; font-style: italic; } /* comment */
+.nitcode .nc_d { color: #3D8127; font-style: italic; } /* documentation comments */
+.nitcode .nc_k { font-weight: bold; } /* keyword */
+.nitcode .nc_o {} /* operator */
+.nitcode .nc_i {} /* standard identifier */
+.nitcode .nc_t { color: #445588; font-weight: bold; } /* type/class identifier */
+.nitcode .nc_a { color: #445588; font-style: italic; } /* old style attribute identifier */
+.nitcode .nc_l { color: #009999; } /* char and number literal */
+.nitcode .nc_s { color: #8F1546; } /* string literal */
+
+/* syntactic token usage. added because of their position in the AST */
+.nitcode .nc_ast { color: blue; } /* assert label */
+.nitcode .nc_la { color: blue; } /* break/continue label */
+.nitcode .nc_m { color: #445588; } /* module name */
+
+/* syntactic groups */
+.nitcode .nc_def { font-weight: bold; color: blue; } /* name used in a definition */
+.nitcode .nc_def.nc_a { color: blue; } /* name used in a attribute definition */
+.nitcode .nc_def.nc_t { color: blue; } /* name used in a class or vt definition */
+.nitcode .nc_ss { color: #9E6BEB; } /* superstrings */
+.nitcode .nc_cdef {} /* A whole class definition */
+.nitcode .nc_pdef {} /* A whole property definition */
+
+/* semantic token usage */
+.nitcode .nc_v { font-style: italic; } /* local variable or parameter */
+.nitcode .nc_vt { font-style: italic; } /* virtual type or formal type */
+.nitcode .nc_error { border: 1px red solid;} /* not used */
index 01da471..81153c7 100644 (file)
 /*
- * Global
+ * 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.
  */
 
-body {
-       text-align: justify;
-}
-
-a:hover {
-       text-decoration: none;
-}
-
-ul li .label {
-       padding: 1px 4px;
-       font-size: 70%;
-       vertical-align: middle;
-       border-radius: .25em;
-       margin: 3px;
-       font-family: monospace;
-}
-
-code {
-       color: #333;
-       border: 1px solid #ddd;
-}
+/* Top menu */
 
-pre code {
-       border: none;
+.navbar-fixed-top {
+       background-color: #1E9431;
+       box-shadow: 0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28);
 }
 
-.navbar-default .navbar-toggle {
-       margin-top: 2px;
-       padding: 5px 10px;
+.navbar-brand > a {
+       color: #fff;
 }
 
-h3 {
-       margin: 10px 0;
+.container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse {
+    margin-right: auto;
+    margin-left: auto;
 }
 
-article {
-       padding: 10px 0px;
+.navbar-default .navbar-collapse, .navbar-default .navbar-form {
+       border-color: transparent;
 }
 
-article.nospace {
-       padding: 0;
-       margin: 0;
+.navbar-toggle {
+       float: left;
 }
 
-/*
- * Sidebar
- */
+/* Body */
 
-#sidebar .panel {
-       margin-top: 15px;
-       box-shadow: none;
-}
-
-#sidebar .panel-heading {
-       padding: 3px 0 0 0;
-       font-size: 16px;
-}
-
-#sidebar .panel-body {
-       padding: 0;
-}
-
-#sidebar .panel-body ul>li>a {
-       padding: 0;
-}
-
-#sidebar .panel-body ul>li {
-       padding: 0 0 0 15px;
-       font-size: 15px;
-       color: #333;
+body {
+       background: #f2f2f2;
+       margin-top: 70px;
+       margin-bottom: 70px;
 }
 
-#sidebar .panel-body ul ul>li,
-#sidebar .panel-body ul ul>li a {
-       padding: 0 0 0 0;
-       font-size: 14px;
+h1, h2, h3, h4, h5, h6 {
        color: #666;
 }
 
-#sidebar .panel-body ul ul ul>li {
-       font-size: 13px;
-       color: #999;
+.page-header {
+    margin-top: 0;
+    border: none;
 }
 
-#sidebar .panel-heading a:hover, #sidebar .panel ul a:hover {
-       color: #0d8921;
-       background-color: transparent;
-}
-
-#sidebar .summary .nav>li>a {
-       padding: 3px 0 0 10px;
-       font-size: 15px;
-       border-left: 2px solid transparent;
-       color: #333;
-}
+#sidebar { margin-top: 15px; }
 
-#sidebar .summary .nav .nav>li>a {
-       padding-top: 2px;
-       padding-left: 15px;
-       font-size: 14px;
-       color: #666;
+pre {
+       white-space: pre-wrap;
 }
 
-#sidebar .summary .nav .nav .nav>li>a {
-       padding-left: 20px;
-       font-size: 13px;
+.footer {
        color: #999;
+       text-align: center;
+       padding: 10px;
+       margin: 20px 0;
 }
 
-#sidebar .summary .nav .nav .nav .nav>li>a {
-       font-size: 12px;
-       color: #CCC;
-}
-
-#sidebar .summary .nav>.active>a,
-#sidebar .summary .nav>.active>a:hover,
-#sidebar .summary .nav>li>a:hover {
-       color: #0d8921;
-       background-color: transparent;
-}
-
-#sidebar .summary .nav>.active>a,
-#sidebar .summary .nav>.active>a:hover,
-#sidebar .summary .nav .nav>.active>a,
-#sidebar .summary .nav .nav>.active>a:hover,
-#sidebar .summary .nav .nav .nav>.active>a,
-#sidebar .summary .nav .nav .nav>.active>a:hover {
-       color: #0d8921;
-       border-left: 2px solid #0d8921;
-       margin-left: 0px;
-}
-
-#sidebar .summary .nav>li>a:hover,
-#sidebar .summary .nav .nav>li>a:hover,
-#sidebar .summary .nav .nav .nav>li>a:hover {
-       color: #0d8921;
-       border-left: 1px solid #0d8921;
-       margin-left: 1px;
-       background-color: transparent;
-}
-
-/*
- * Content
- */
-
-#content {
-       position: fixed;
-       top: 30px;
-       bottom: 0;
-       left: 10px;
-       right: 15px;
-}
-
-#content>.col {
-       height: 100%;
-       overflow-y: scroll;
-}
-
-#content>.col::-webkit-scrollbar-thumb {
-       background: transparent;
-}
+/* ui */
 
-#content>.col:hover::-webkit-scrollbar-thumb {
-       background: #CCC;
-       -webkit-box-shadow: inset 1px 1px 0 rgba(0,0,0,0.10),inset 0 -1px 0 rgba(0,0,0,0.07);
-}
+.btn-bar { margin-top: -5px; float: right }
+.btn-bar .btn { padding: 5px 10px; }
 
-#content>.col::-webkit-scrollbar {
-    width: 7px;
-       height: 7px;
-}
+/* Doc */
 
-#content>.col::-webkit-scrollbar-thumb:hover {
-       background: #999;
+.nitdoc > *:first-child {
+       margin-top: 0;
 }
 
-#content>.col::-webkit-scrollbar-corner {
-       background: transparent;
+.signature {
+       color: #777;
+       font-family: monospace;
 }
 
-#content>.col::-webkit-scrollbar-button {
-       width: 0;
-       height: 0;
-       display: none;
+.signature .name {
+       font-weight: bold;
 }
 
-#content article:target {
-       padding-left: 10px;
-       margin-left: -10px;
-       border-left: 2px solid #0d8921;
+.page-header .signature .name, .signature .signature .name {
+       font-weight: normal;
 }
 
+/* Summary */
 
-.pull-right .dropdown-toggle {
-       padding: 0 5px;
-}
-
-/* Hide the "..." link */
+.summary h1 { font-size: 14px; margin: 10px 0 5px 0;   font-weight: bold; }
+.summary h2 { font-size: 13px; margin:  9px 0 5px 5px; font-weight: bold; }
+.summary h3 { font-size: 12px; margin:  8px 0 5px 10px; }
+.summary h4 { font-size: 11px; margin:  7px 0 5px 15px; }
+.summary h5 { font-size: 10px; margin:  6px 0 5px 20px; }
+.summary h6 { font-size:  9px; margin:  5px 0 5px 25px; }
 
-article .dropdown, article .dropdown {
-       visibility: hidden;
-}
-article:hover .dropdown, article:target .dropdown {
-       visibility: visible;
-}
+.summary a, .summary a:hover { color: #666; }
 
 /*
- * Page parts
+ * Nit
  */
 
-.footer {
-       padding: 10px;
-       margin: 20px 0;
-}
-
-.subtitle {
-       margin-bottom: 10px;
-}
-
-.label:empty {
-       display:inline;
-}
-
-.label.intro:before {
-       content: "I";
-}
-.label.redef:before {
-       content: "R";
-}
-.label.inherit:before {
-       content: "H";
-}
-
-.signature span.glyphicon {
-       margin: 0 10px 5px 0;
-       font-size: 55%;
-       vertical-align: middle;
-}
-
-.signature a, .list-definition a, .info.signature a {
-       color: #0d8921;
-}
-
-.info {
-       color: #888;
-}
-
-.info a {
-       color: #666;
-}
-
-.info a:hover {
+.nitdoc h1, .nitdoc h2, .nitdoc h3, .nitdoc h4, .nitdoc h5, .nitdoc h6 {
        color: #333;
 }
 
-.graph {
-       text-align: center;
-}
-
 .nitdoc .synopsys {
-       margin: 5px 0;
-       font-size: 16px;
-       font-weight: bold;
-       line-height: 1.4;
+       margin-top: 0;
 }
 
 .public {
@@ -279,41 +124,3 @@ article:hover .dropdown, article:target .dropdown {
 .private {
        color: #a94442;
 }
-
-.list-definition .list-definition {
-       margin-left: 30px;
-}
-
-/*
- * Code Highlighting
- */
-
-.nitcode a { color: inherit; text-decoration: inherit; } /* hide links */
-.nitcode a:hover { text-decoration: underline; } /* underline links */
-.nitcode span[title]:hover { text-decoration: underline; } /* underline titles */
-/* lexical raw tokens. independent of usage or semantic: */
-.nitcode .nc_c { color: gray; font-style: italic; } /* comment */
-.nitcode .nc_d { color: #3D8127; font-style: italic; } /* documentation comments */
-.nitcode .nc_k { font-weight: bold; } /* keyword */
-.nitcode .nc_o {} /* operator */
-.nitcode .nc_i {} /* standard identifier */
-.nitcode .nc_t { color: #445588; font-weight: bold; } /* type/class identifier */
-.nitcode .nc_a { color: #445588; font-style: italic; } /* old style attribute identifier */
-.nitcode .nc_l { color: #009999; } /* char and number literal */
-.nitcode .nc_s { color: #8F1546; } /* string literal */
-/* syntactic token usage. added because of their position in the AST */
-.nitcode .nc_ast { color: blue; } /* assert label */
-.nitcode .nc_la { color: blue; } /* break/continue label */
-.nitcode .nc_m { color: #445588; } /* module name */
-/* syntactic groups */
-.nitcode .nc_def { font-weight: bold; color: blue; } /* name used in a definition */
-.nitcode .nc_def.nc_a { color: blue; } /* name used in a attribute definition */
-.nitcode .nc_def.nc_t { color: blue; } /* name used in a class or vt definition */
-.nitcode .nc_ss { color: #9E6BEB; } /* superstrings */
-.nitcode .nc_cdef {} /* A whole class definition */
-.nitcode .nc_pdef {} /* A whole property definition */
-/* semantic token usage */
-.nitcode .nc_v { font-style: italic; } /* local variable or parameter */
-.nitcode .nc_vt { font-style: italic; } /* virtual type or formal type */
-.nitcode .nc_error { border: 1px red solid;} /* not used */
-
diff --git a/share/nitdoc/css/nitdoc.quicksearch.css b/share/nitdoc/css/nitdoc.quicksearch.css
new file mode 100644 (file)
index 0000000..3e306c3
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+/* Nitdoc Quick Search JS module */
+
+.has-icon {
+    position: relative;
+}
+
+.has-icon .form-control {
+       padding-left: 35px;
+}
+
+.form-control-icon {
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 2;
+    display: block;
+    width: 34px;
+    height: 34px;
+    line-height: 34px;
+    text-align: center;
+    pointer-events: none;
+}
+
+.navbar-fixed-top .form-control:hover, .navbar-fixed-top .form-control:focus {
+       background: rgba(255, 255, 255, 0.2);
+}
+
+.navbar-fixed-top .form-control {
+       background: rgba(255, 255, 255, 0.1);
+    border: none;
+    color: #fff;
+    box-shadow: none;
+}
+
+.navbar-fixed-top .form-control-icon {
+       color: #fff;
+}
+
+.navbar-fixed-top .form-group {
+       margin-top: 8px;
+       margin-bottom: 0px;
+}
+
+.navbar-fixed-top *::-webkit-input-placeholder { color: #fff; }
+.navbar-fixed-top *:-moz-placeholder { color: #fff; }
+.navbar-fixed-top *::-moz-placeholder { color: #fff; }
+.navbar-fixed-top *:-ms-input-placeholder { color: #fff; }
+
+.search-input {
+       width: 100%;
+}
+
+#nitdoc-qs-popup {
+       background-color: #FFFFFF;
+       border: 1px solid #E0E0E0;
+       z-index: 1000;
+       -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
+       -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
+       box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
+}
+
+.qs-card {
+       cursor: pointer;
+       padding: 5px;
+       border-bottom: 1px solid #F0F0F0;
+       overflow: hidden;
+}
+
+.qs-card h1 {
+       color: #0D8921;
+       font-size: 1.2em;
+       margin-top: 5px;
+       margin-bottom: 0;
+}
+
+.qs-info {
+       color: #6C6C6C;
+       font-size: smaller;
+}
+
+.qs-noresult {
+       color: #6C6C6C;
+       font-size: small;
+}
+
+.qs-overflow {
+       text-align: center;
+       font-size:      x-small;
+       color: #6C6C6C;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+       -khtml-user-select: none;
+       -moz-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
+}
+
+.qs-overflow-active {
+       color: #0D8921;
+       cursor: pointer;
+}
+
+.qs-overflow-active:hover {
+       background-color: #E0E0E0;
+}
+
+.qs-active {
+       background: #EEE;
+}
diff --git a/share/nitdoc/js/lib/github-api.js b/share/nitdoc/js/lib/github-api.js
deleted file mode 100644 (file)
index f03188a..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-\r
-   Documentation generator for the nit language.\r
-   Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * GitHub API wrapper for github plugin\r
- */\r
-define([\r
-       "jquery",\r
-       "utils"\r
-], function($, Utils) {\r
-       return {\r
-\r
-               // try to login the user to github API\r
-               login: function(user) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "GET",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo,\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function() {\r
-                                       res = true;\r
-                               }\r
-                       });\r
-                       user.infos = this.getUserInfos(user);\r
-                       user.signedOff = this.getSignedOff(user)\r
-                       return res;\r
-               },\r
-\r
-               // request for user github account infos\r
-               getUserInfos: function(user) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "GET",\r
-                                       url: "https://api.github.com/users/" + user.login,\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               // build signedoff user default signature\r
-               getSignedOff: function(user) {\r
-                       return user.infos.name + " <" + user.infos.email + ">";\r
-               },\r
-\r
-               // get the branches list from a repo\r
-               getBranches: function(user) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "GET",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/branches",\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               /* GitHub commits */\r
-\r
-               // get the latest commit on `branchName`\r
-               getCommit: function(user, sha) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "GET",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits/" + sha,\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               // get the base tree for a commit sha\r
-               getTree: function(user, sha) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "GET",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees/" + sha + "?recursive=1",\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               // create a new blob\r
-               createBlob: function(user, content) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "POST",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/blobs",\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               data: JSON.stringify({\r
-                                       content: content.base64Encode(),\r
-                                       encoding: "base64"\r
-                               }),\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               // create a new tree from a base tree\r
-               createTree: function(user, baseTree, path, blob) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "POST",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees",\r
-                               data: JSON.stringify({\r
-                                       base_tree: baseTree.sha,\r
-                                       tree: [{\r
-                                               path: path,\r
-                                               mode: "100644", // file (blob)\r
-                                               type: "blob",\r
-                                               sha: blob.sha\r
-                                       }]\r
-                               }),\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               // create a new commit\r
-               createCommit: function(user, message, parentCommit, tree) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "POST",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits",\r
-                               data: JSON.stringify({\r
-                                       message: message,\r
-                                       parents: parentCommit,\r
-                                       tree: tree.sha,\r
-                               }),\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               // create a pull request\r
-               createPullRequest: function(user, title, body, origin, head) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                       xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "POST",\r
-                               url: "https://api.github.com/repos/" + origin.user + "/" + origin.repo + "/pulls",\r
-                               data: JSON.stringify({\r
-                                       title: title,\r
-                                       body: body,\r
-                                       base: origin.branch,\r
-                                       head: user.login + ":" + head\r
-                               }),\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               // update a pull request\r
-               updatePullRequest: function(user, title, body, state, request) {\r
-                       var res = false;\r
-                               $.ajax({\r
-                               beforeSend: function (xhr) {\r
-                                               xhr.setRequestHeader ("Authorization", user.auth);\r
-                               },\r
-                               type: "PATCH",\r
-                               url: request.url,\r
-                               data: JSON.stringify({\r
-                                       title: title,\r
-                                       body: body,\r
-                                       state: state\r
-                               }),\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               },\r
-\r
-               /* Files */\r
-\r
-               getFile: function(user, path, branch) {\r
-                       var res = false;\r
-                       $.ajax({\r
-                               type: "GET",\r
-                               url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/contents/" + path,\r
-                               data: {\r
-                                       ref: branch\r
-                               },\r
-                               async: false,\r
-                               dataType: 'json',\r
-                               success: function(response) {\r
-                                       res = response;\r
-                               },\r
-                               error: function(response) {\r
-                                       res = response;\r
-                               }\r
-                       });\r
-                       return res;\r
-               }\r
-       }\r
-});\r
diff --git a/share/nitdoc/js/lib/highlight.js b/share/nitdoc/js/lib/highlight.js
deleted file mode 100644 (file)
index bd277ee..0000000
+++ /dev/null
@@ -1,715 +0,0 @@
-/*     Copyright (c) 2006, Ivan Sagalaev
-       All rights reserved.
-       Redistribution and use in source and binary forms, with or without
-       modification, are permitted provided that the following conditions are met:
-
-               * Redistributions of source code must retain the above copyright
-                 notice, this list of conditions and the following disclaimer.
-               * Redistributions in binary form must reproduce the above copyright
-                 notice, this list of conditions and the following disclaimer in the
-                 documentation and/or other materials provided with the distribution.
-               * Neither the name of highlight.js nor the names of its contributors
-                 may be used to endorse or promote products derived from this software
-                 without specific prior written permission.
-
-       THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
-       EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-       DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
-       DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-       (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-       LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-       ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-       SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-var hljs = new function() {
-
-  /* Utility functions */
-
-  function escape(value) {
-       return value.replace(/&/gm, '&amp;').replace(/</gm, '&lt;').replace(/>/gm, '&gt;');
-  }
-
-  function tag(node) {
-       return node.nodeName.toLowerCase();
-  }
-
-  function testRe(re, lexeme) {
-       var match = re && re.exec(lexeme);
-       return match && match.index == 0;
-  }
-
-  function blockLanguage(block) {
-       var classes = (block.className + ' ' + (block.parentNode ? block.parentNode.className : '')).split(/\s+/);
-       classes = classes.map(function(c) {return c.replace(/^lang(uage)?-/, '');});
-       return classes.filter(function(c) {return getLanguage(c) || c == 'no-highlight';})[0];
-  }
-
-  function inherit(parent, obj) {
-       var result = {};
-       for (var key in parent)
-         result[key] = parent[key];
-       if (obj)
-         for (var key in obj)
-           result[key] = obj[key];
-       return result;
-  };
-
-  /* Stream merging */
-
-  function nodeStream(node) {
-       var result = [];
-       (function _nodeStream(node, offset) {
-         for (var child = node.firstChild; child; child = child.nextSibling) {
-           if (child.nodeType == 3)
-             offset += child.nodeValue.length;
-           else if (tag(child) == 'br')
-             offset += 1;
-           else if (child.nodeType == 1) {
-             result.push({
-               event: 'start',
-               offset: offset,
-               node: child
-             });
-             offset = _nodeStream(child, offset);
-             result.push({
-               event: 'stop',
-               offset: offset,
-               node: child
-             });
-           }
-         }
-         return offset;
-       })(node, 0);
-       return result;
-  }
-
-  function mergeStreams(original, highlighted, value) {
-       var processed = 0;
-       var result = '';
-       var nodeStack = [];
-
-       function selectStream() {
-         if (!original.length || !highlighted.length) {
-           return original.length ? original : highlighted;
-         }
-         if (original[0].offset != highlighted[0].offset) {
-           return (original[0].offset < highlighted[0].offset) ? original : highlighted;
-         }
-
-         /*
-         To avoid starting the stream just before it should stop the order is
-         ensured that original always starts first and closes last:
-
-         if (event1 == 'start' && event2 == 'start')
-           return original;
-         if (event1 == 'start' && event2 == 'stop')
-           return highlighted;
-         if (event1 == 'stop' && event2 == 'start')
-           return original;
-         if (event1 == 'stop' && event2 == 'stop')
-           return highlighted;
-
-         ... which is collapsed to:
-         */
-         return highlighted[0].event == 'start' ? original : highlighted;
-       }
-
-       function open(node) {
-         function attr_str(a) {return ' ' + a.nodeName + '="' + escape(a.value) + '"';}
-         result += '<' + tag(node) + Array.prototype.map.call(node.attributes, attr_str).join('') + '>';
-       }
-
-       function close(node) {
-         result += '</' + tag(node) + '>';
-       }
-
-       function render(event) {
-         (event.event == 'start' ? open : close)(event.node);
-       }
-
-       while (original.length || highlighted.length) {
-         var stream = selectStream();
-         result += escape(value.substr(processed, stream[0].offset - processed));
-         processed = stream[0].offset;
-         if (stream == original) {
-           /*
-           On any opening or closing tag of the original markup we first close
-           the entire highlighted node stack, then render the original tag along
-           with all the following original tags at the same offset and then
-           reopen all the tags on the highlighted stack.
-           */
-           nodeStack.reverse().forEach(close);
-           do {
-             render(stream.splice(0, 1)[0]);
-             stream = selectStream();
-           } while (stream == original && stream.length && stream[0].offset == processed);
-           nodeStack.reverse().forEach(open);
-         } else {
-           if (stream[0].event == 'start') {
-             nodeStack.push(stream[0].node);
-           } else {
-             nodeStack.pop();
-           }
-           render(stream.splice(0, 1)[0]);
-         }
-       }
-       return result + escape(value.substr(processed));
-  }
-
-  /* Initialization */
-
-  function compileLanguage(language) {
-
-       function reStr(re) {
-           return (re && re.source) || re;
-       }
-
-       function langRe(value, global) {
-         return RegExp(
-           reStr(value),
-           'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')
-         );
-       }
-
-       function compileMode(mode, parent) {
-         if (mode.compiled)
-           return;
-         mode.compiled = true;
-
-         mode.keywords = mode.keywords || mode.beginKeywords;
-         if (mode.keywords) {
-           var compiled_keywords = {};
-
-           function flatten(className, str) {
-             if (language.case_insensitive) {
-               str = str.toLowerCase();
-             }
-             str.split(' ').forEach(function(kw) {
-               var pair = kw.split('|');
-               compiled_keywords[pair[0]] = [className, pair[1] ? Number(pair[1]) : 1];
-             });
-           }
-
-           if (typeof mode.keywords == 'string') { // string
-             flatten('keyword', mode.keywords);
-           } else {
-             Object.keys(mode.keywords).forEach(function (className) {
-               flatten(className, mode.keywords[className]);
-             });
-           }
-           mode.keywords = compiled_keywords;
-         }
-         mode.lexemesRe = langRe(mode.lexemes || /\b[A-Za-z0-9_]+\b/, true);
-
-         if (parent) {
-           if (mode.beginKeywords) {
-             mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')\\b';
-           }
-           if (!mode.begin)
-             mode.begin = /\B|\b/;
-           mode.beginRe = langRe(mode.begin);
-           if (!mode.end && !mode.endsWithParent)
-             mode.end = /\B|\b/;
-           if (mode.end)
-             mode.endRe = langRe(mode.end);
-           mode.terminator_end = reStr(mode.end) || '';
-           if (mode.endsWithParent && parent.terminator_end)
-             mode.terminator_end += (mode.end ? '|' : '') + parent.terminator_end;
-         }
-         if (mode.illegal)
-           mode.illegalRe = langRe(mode.illegal);
-         if (mode.relevance === undefined)
-           mode.relevance = 1;
-         if (!mode.contains) {
-           mode.contains = [];
-         }
-         var expanded_contains = [];
-         mode.contains.forEach(function(c) {
-           if (c.variants) {
-             c.variants.forEach(function(v) {expanded_contains.push(inherit(c, v));});
-           } else {
-             expanded_contains.push(c == 'self' ? mode : c);
-           }
-         });
-         mode.contains = expanded_contains;
-         mode.contains.forEach(function(c) {compileMode(c, mode);});
-
-         if (mode.starts) {
-           compileMode(mode.starts, parent);
-         }
-
-         var terminators =
-           mode.contains.map(function(c) {
-             return c.beginKeywords ? '\\.?(' + c.begin + ')\\.?' : c.begin;
-           })
-           .concat([mode.terminator_end, mode.illegal])
-           .map(reStr)
-           .filter(Boolean);
-         mode.terminators = terminators.length ? langRe(terminators.join('|'), true) : {exec: function(s) {return null;}};
-
-         mode.continuation = {};
-       }
-
-       compileMode(language);
-  }
-
-  /*
-  Core highlighting function. Accepts a language name, or an alias, and a
-  string with the code to highlight. Returns an object with the following
-  properties:
-
-  - relevance (int)
-  - value (an HTML string with highlighting markup)
-
-  */
-  function highlight(name, value, ignore_illegals, continuation) {
-
-       function subMode(lexeme, mode) {
-         for (var i = 0; i < mode.contains.length; i++) {
-           if (testRe(mode.contains[i].beginRe, lexeme)) {
-             return mode.contains[i];
-           }
-         }
-       }
-
-       function endOfMode(mode, lexeme) {
-         if (testRe(mode.endRe, lexeme)) {
-           return mode;
-         }
-         if (mode.endsWithParent) {
-           return endOfMode(mode.parent, lexeme);
-         }
-       }
-
-       function isIllegal(lexeme, mode) {
-         return !ignore_illegals && testRe(mode.illegalRe, lexeme);
-       }
-
-       function keywordMatch(mode, match) {
-         var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0];
-         return mode.keywords.hasOwnProperty(match_str) && mode.keywords[match_str];
-       }
-
-       function buildSpan(classname, insideSpan, leaveOpen, noPrefix) {
-         var classPrefix = noPrefix ? '' : options.classPrefix,
-             openSpan    = '<span class="' + classPrefix,
-             closeSpan   = leaveOpen ? '' : '</span>';
-
-         openSpan += classname + '">';
-
-         return openSpan + insideSpan + closeSpan;
-       }
-
-       function processKeywords() {
-         if (!top.keywords)
-           return escape(mode_buffer);
-         var result = '';
-         var last_index = 0;
-         top.lexemesRe.lastIndex = 0;
-         var match = top.lexemesRe.exec(mode_buffer);
-         while (match) {
-           result += escape(mode_buffer.substr(last_index, match.index - last_index));
-           var keyword_match = keywordMatch(top, match);
-           if (keyword_match) {
-             relevance += keyword_match[1];
-             result += buildSpan(keyword_match[0], escape(match[0]));
-           } else {
-             result += escape(match[0]);
-           }
-           last_index = top.lexemesRe.lastIndex;
-           match = top.lexemesRe.exec(mode_buffer);
-         }
-         return result + escape(mode_buffer.substr(last_index));
-       }
-
-       function processSubLanguage() {
-         if (top.subLanguage && !languages[top.subLanguage]) {
-           return escape(mode_buffer);
-         }
-         var result = top.subLanguage ? highlight(top.subLanguage, mode_buffer, true, top.continuation.top) : highlightAuto(mode_buffer);
-         // Counting embedded language score towards the host language may be disabled
-         // with zeroing the containing mode relevance. Usecase in point is Markdown that
-         // allows XML everywhere and makes every XML snippet to have a much larger Markdown
-         // score.
-         if (top.relevance > 0) {
-           relevance += result.relevance;
-         }
-         if (top.subLanguageMode == 'continuous') {
-           top.continuation.top = result.top;
-         }
-         return buildSpan(result.language, result.value, false, true);
-       }
-
-       function processBuffer() {
-         return top.subLanguage !== undefined ? processSubLanguage() : processKeywords();
-       }
-
-       function startNewMode(mode, lexeme) {
-         var markup = mode.className? buildSpan(mode.className, '', true): '';
-         if (mode.returnBegin) {
-           result += markup;
-           mode_buffer = '';
-         } else if (mode.excludeBegin) {
-           result += escape(lexeme) + markup;
-           mode_buffer = '';
-         } else {
-           result += markup;
-           mode_buffer = lexeme;
-         }
-         top = Object.create(mode, {parent: {value: top}});
-       }
-
-       function processLexeme(buffer, lexeme) {
-
-         mode_buffer += buffer;
-         if (lexeme === undefined) {
-           result += processBuffer();
-           return 0;
-         }
-
-         var new_mode = subMode(lexeme, top);
-         if (new_mode) {
-           result += processBuffer();
-           startNewMode(new_mode, lexeme);
-           return new_mode.returnBegin ? 0 : lexeme.length;
-         }
-
-         var end_mode = endOfMode(top, lexeme);
-         if (end_mode) {
-           var origin = top;
-           if (!(origin.returnEnd || origin.excludeEnd)) {
-             mode_buffer += lexeme;
-           }
-           result += processBuffer();
-           do {
-             if (top.className) {
-               result += '</span>';
-             }
-             relevance += top.relevance;
-             top = top.parent;
-           } while (top != end_mode.parent);
-           if (origin.excludeEnd) {
-             result += escape(lexeme);
-           }
-           mode_buffer = '';
-           if (end_mode.starts) {
-             startNewMode(end_mode.starts, '');
-           }
-           return origin.returnEnd ? 0 : lexeme.length;
-         }
-
-         if (isIllegal(lexeme, top))
-           throw new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.className || '<unnamed>') + '"');
-
-         /*
-         Parser should not reach this point as all types of lexemes should be caught
-         earlier, but if it does due to some bug make sure it advances at least one
-         character forward to prevent infinite looping.
-         */
-         mode_buffer += lexeme;
-         return lexeme.length || 1;
-       }
-
-       var language = getLanguage(name);
-       if (!language) {
-         throw new Error('Unknown language: "' + name + '"');
-       }
-
-       compileLanguage(language);
-       var top = continuation || language;
-       var result = '';
-       for(var current = top; current != language; current = current.parent) {
-         if (current.className) {
-           result += buildSpan(current.className, result, true);
-         }
-       }
-       var mode_buffer = '';
-       var relevance = 0;
-       try {
-         var match, count, index = 0;
-         while (true) {
-           top.terminators.lastIndex = index;
-           match = top.terminators.exec(value);
-           if (!match)
-             break;
-           count = processLexeme(value.substr(index, match.index - index), match[0]);
-           index = match.index + count;
-         }
-         processLexeme(value.substr(index));
-         for(var current = top; current.parent; current = current.parent) { // close dangling modes
-           if (current.className) {
-             result += '</span>';
-           }
-         };
-         return {
-           relevance: relevance,
-           value: result,
-           language: name,
-           top: top
-         };
-       } catch (e) {
-         if (e.message.indexOf('Illegal') != -1) {
-           return {
-             relevance: 0,
-             value: escape(value)
-           };
-         } else {
-           throw e;
-         }
-       }
-  }
-
-  /*
-  Highlighting with language detection. Accepts a string with the code to
-  highlight. Returns an object with the following properties:
-
-  - language (detected language)
-  - relevance (int)
-  - value (an HTML string with highlighting markup)
-  - second_best (object with the same structure for second-best heuristically
-       detected language, may be absent)
-
-  */
-  function highlightAuto(text, languageSubset) {
-       languageSubset = languageSubset || options.languages || Object.keys(languages);
-       var result = {
-         relevance: 0,
-         value: escape(text)
-       };
-       var second_best = result;
-       languageSubset.forEach(function(name) {
-         if (!getLanguage(name)) {
-           return;
-         }
-         var current = highlight(name, text, false);
-         current.language = name;
-         if (current.relevance > second_best.relevance) {
-           second_best = current;
-         }
-         if (current.relevance > result.relevance) {
-           second_best = result;
-           result = current;
-         }
-       });
-       if (second_best.language) {
-         result.second_best = second_best;
-       }
-       return result;
-  }
-
-  /*
-  Post-processing of the highlighted markup:
-
-  - replace TABs with something more useful
-  - replace real line-breaks with '<br>' for non-pre containers
-
-  */
-  function fixMarkup(value) {
-       if (options.tabReplace) {
-         value = value.replace(/^((<[^>]+>|\t)+)/gm, function(match, p1, offset, s) {
-           return p1.replace(/\t/g, options.tabReplace);
-         });
-       }
-       if (options.useBR) {
-         value = value.replace(/\n/g, '<br>');
-       }
-       return value;
-  }
-
-  /*
-  Applies highlighting to a DOM node containing code. Accepts a DOM node and
-  two optional parameters for fixMarkup.
-  */
-  function highlightBlock(block) {
-       var text = options.useBR ? block.innerHTML
-         .replace(/\n/g,'').replace(/<br>|<br [^>]*>/g, '\n').replace(/<[^>]*>/g,'')
-         : block.textContent;
-       var language = blockLanguage(block);
-       if (language == 'no-highlight')
-           return;
-       var result = language ? highlight(language, text, true) : highlightAuto(text);
-       var original = nodeStream(block);
-       if (original.length) {
-         var pre = document.createElementNS('http://www.w3.org/1999/xhtml', 'pre');
-         pre.innerHTML = result.value;
-         result.value = mergeStreams(original, nodeStream(pre), text);
-       }
-       result.value = fixMarkup(result.value);
-
-       block.innerHTML = result.value;
-       block.className += ' hljs ' + (!language && result.language || '');
-       block.result = {
-         language: result.language,
-         re: result.relevance
-       };
-       if (result.second_best) {
-         block.second_best = {
-           language: result.second_best.language,
-           re: result.second_best.relevance
-         };
-       }
-  }
-
-  var options = {
-       classPrefix: 'hljs-',
-       tabReplace: null,
-       useBR: false,
-       languages: undefined
-  };
-
-  /*
-  Updates highlight.js global options with values passed in the form of an object
-  */
-  function configure(user_options) {
-       options = inherit(options, user_options);
-  }
-
-  /*
-  Applies highlighting to all <pre><code>..</code></pre> blocks on a page.
-  */
-  function initHighlighting() {
-       if (initHighlighting.called)
-         return;
-       initHighlighting.called = true;
-
-       var blocks = document.querySelectorAll('pre code');
-       Array.prototype.forEach.call(blocks, highlightBlock);
-  }
-
-  /*
-  Attaches highlighting to the page load event.
-  */
-  function initHighlightingOnLoad() {
-       addEventListener('DOMContentLoaded', initHighlighting, false);
-       addEventListener('load', initHighlighting, false);
-  }
-
-  var languages = {};
-  var aliases = {};
-
-  function registerLanguage(name, language) {
-       var lang = languages[name] = language(this);
-       if (lang.aliases) {
-         lang.aliases.forEach(function(alias) {aliases[alias] = name;});
-       }
-  }
-
-  function listLanguages() {
-       return Object.keys(languages);
-  }
-
-  function getLanguage(name) {
-       return languages[name] || languages[aliases[name]];
-  }
-
-  /* Interface definition */
-
-  this.highlight = highlight;
-  this.highlightAuto = highlightAuto;
-  this.fixMarkup = fixMarkup;
-  this.highlightBlock = highlightBlock;
-  this.configure = configure;
-  this.initHighlighting = initHighlighting;
-  this.initHighlightingOnLoad = initHighlightingOnLoad;
-  this.registerLanguage = registerLanguage;
-  this.listLanguages = listLanguages;
-  this.getLanguage = getLanguage;
-  this.inherit = inherit;
-
-  // Common regexps
-  this.IDENT_RE = '[a-zA-Z][a-zA-Z0-9_]*';
-  this.UNDERSCORE_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*';
-  this.NUMBER_RE = '\\b\\d+(\\.\\d+)?';
-  this.C_NUMBER_RE = '(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float
-  this.BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b...
-  this.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
-
-  // Common modes
-  this.BACKSLASH_ESCAPE = {
-       begin: '\\\\[\\s\\S]', relevance: 0
-  };
-  this.APOS_STRING_MODE = {
-       className: 'string',
-       begin: '\'', end: '\'',
-       illegal: '\\n',
-       contains: [this.BACKSLASH_ESCAPE]
-  };
-  this.QUOTE_STRING_MODE = {
-       className: 'string',
-       begin: '"', end: '"',
-       illegal: '\\n',
-       contains: [this.BACKSLASH_ESCAPE]
-  };
-  this.PHRASAL_WORDS_MODE = {
-       begin: /\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/
-  };
-  this.C_LINE_COMMENT_MODE = {
-       className: 'comment',
-       begin: '//', end: '$',
-       contains: [this.PHRASAL_WORDS_MODE]
-  };
-  this.C_BLOCK_COMMENT_MODE = {
-       className: 'comment',
-       begin: '/\\*', end: '\\*/',
-       contains: [this.PHRASAL_WORDS_MODE]
-  };
-  this.HASH_COMMENT_MODE = {
-       className: 'comment',
-       begin: '#', end: '$',
-       contains: [this.PHRASAL_WORDS_MODE]
-  };
-  this.NUMBER_MODE = {
-       className: 'number',
-       begin: this.NUMBER_RE,
-       relevance: 0
-  };
-  this.C_NUMBER_MODE = {
-       className: 'number',
-       begin: this.C_NUMBER_RE,
-       relevance: 0
-  };
-  this.BINARY_NUMBER_MODE = {
-       className: 'number',
-       begin: this.BINARY_NUMBER_RE,
-       relevance: 0
-  };
-  this.CSS_NUMBER_MODE = {
-       className: 'number',
-       begin: this.NUMBER_RE + '(' +
-         '%|em|ex|ch|rem'  +
-         '|vw|vh|vmin|vmax' +
-         '|cm|mm|in|pt|pc|px' +
-         '|deg|grad|rad|turn' +
-         '|s|ms' +
-         '|Hz|kHz' +
-         '|dpi|dpcm|dppx' +
-         ')?',
-       relevance: 0
-  };
-  this.REGEXP_MODE = {
-       className: 'regexp',
-       begin: /\//, end: /\/[gim]*/,
-       illegal: /\n/,
-       contains: [
-         this.BACKSLASH_ESCAPE,
-         {
-           begin: /\[/, end: /\]/,
-           relevance: 0,
-           contains: [this.BACKSLASH_ESCAPE]
-         }
-       ]
-  };
-  this.TITLE_MODE = {
-       className: 'title',
-       begin: this.IDENT_RE,
-       relevance: 0
-  };
-  this.UNDERSCORE_TITLE_MODE = {
-       className: 'title',
-       begin: this.UNDERSCORE_IDENT_RE,
-       relevance: 0
-  };
-};
diff --git a/share/nitdoc/js/lib/nit.js b/share/nitdoc/js/lib/nit.js
deleted file mode 100644 (file)
index 1b4aff3..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/* 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.
-
-   Documentation generator for the nit language.
-   Generate API documentation in HTML format from nit source code.
-*/
-
-hljs.registerLanguage('nit', function(hljs) {
-       var METHOD_RE = '[a-z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
-       var KEYWORDS = {
-               keyword: 'abort abstract and as assert break class continue do else end enum extern for fun ' +
-               'if import in init interface intern intrude is isa isset label loop module new nullable not ' +
-               'once or protected private redef return self super then type universal var ' +
-               'when while writable',
-               literal: "true false null"
-       };
-       var COMMENT = {
-               className: 'comment',
-               begin: '#', end: '$',
-       };
-       var SUBST = {
-               className: 'subst',
-               begin: '{', end: '}',
-               keywords: KEYWORDS
-       };
-       var STRING = {
-               className: 'string',
-               contains: [hljs.BACKSLASH_ESCAPE, SUBST],
-               variants: [
-                       {begin: /"/, end: /"/},
-               ]
-       };
-       var CHAR = {
-               className: 'char',
-               contains: [hljs.BACKSLASH_ESCAPE, SUBST],
-               begin: /'/, end: /'/,
-       };
-       var TYPE = {
-               className: 'type',
-               begin: '[A-Z]\\w*'
-       }
-       var PARAMS = {
-               className: 'params',
-               begin: '\\(', end: '\\)',
-               keywords: KEYWORDS,
-               contains: [TYPE]
-       };
-       var RET_TYPE = {
-               className: 'rettype',
-               begin: ':', end: '$|do|is|=',
-               keywords: 'nullable',
-               returnEnd: true,
-               contains: [TYPE]
-       }
-       var DO_BLOCK = {
-               className: 'block',
-               begin: 'do', end: '$|end',
-               keywords: KEYWORDS
-       }
-       var IS_BLOCK = {
-               className: 'modifiers',
-               begin: 'is', end: '$',
-               keywords: KEYWORDS
-       }
-       var CONTAINS = [
-               STRING,
-               CHAR,
-               COMMENT,
-               TYPE,
-               {
-                       className: 'module',
-                       beginKeywords: 'module', end: '$',
-                       contains: [
-                               hljs.inherit(hljs.TITLE_MODE, {begin: '[a-z_]\\w*'}),
-                               COMMENT
-                       ]
-               },
-               {
-                       className: 'import',
-                       begin: '(intrude )?import', end: '$',
-                       keywords: 'intrude import',
-                       contains: [
-                               {
-                                       className: 'module',
-                                       begin: '[a-z_]\\w*'
-                               },
-                               COMMENT
-                       ]
-               },
-               {
-                       className: 'class',
-                       begin: '(redef |private |protected )?(abstract )?(class|interface)', end: '$',
-                       keywords: 'redef private protected abstract class interface',
-                       contains: [
-                               hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Z]\\w*'}),
-                               {
-                                       className: 'super',
-                                       begin: '\\bsuper', end: '$',
-                                       keywords: 'super',
-                                       contains: [TYPE]
-                               },
-                               COMMENT
-                       ]
-               },
-               {
-                       className: 'fun',
-                       begin: '(redef |private |protected )?(fun|init|type)\\b', end: '$',
-                       keywords: KEYWORDS,
-                       contains: [
-                               PARAMS,
-                               RET_TYPE,
-                               DO_BLOCK,
-                               IS_BLOCK,
-                               {
-                                       className: 'title',
-                                       begin: '\\b[a-zA-Z_][a-zA-Z_]*\\b'
-                               },
-                               COMMENT
-                       ]
-               },
-               {
-                       className: 'number',
-                       begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
-                       relevance: 0
-               }
-       ];
-       SUBST.contains = CONTAINS;
-
-       return {
-               keywords: KEYWORDS,
-               contains: CONTAINS
-       };
-});
diff --git a/share/nitdoc/js/lib/utils.js b/share/nitdoc/js/lib/utils.js
deleted file mode 100644 (file)
index 26304d8..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/* 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.
-
-   Documentation generator for the nit language.
-   Generate API documentation in HTML format from nit source code.
-*/
-
-/*
- * Utils module
- */
-String.prototype.startsWith = function(prefix, caseSensitive) {
-       if(caseSensitive) {
-               return this.toUpperCase().indexOf(prefix.toUpperCase()) === 0;
-       }
-       return this.indexOf(prefix) === 0;
-}
-
-// Compare two strings using Sorensen-Dice Coefficient
-// see: http://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient
-String.prototype.dice = function(other) {
-       var length1 = this.length - 1;
-       var length2 = other.length - 1;
-       if(length1 < 1 || length2 < 1) return 0;
-
-       var bigrams2 = [];
-       for(var i = 0; i < length2; i++) {
-               bigrams2.push(other.substr(i, 2));
-       }
-
-       var intersection = 0;
-       for(var i = 0; i < length1; i++) {
-               var bigram1 = this.substr(i, 2);
-               for(var j = 0; j < length2; j++) {
-                       if(bigram1 == bigrams2[j]) {
-                               intersection++;
-                               bigrams2[j] = null;
-                               break;
-                       }
-               }
-       }
-       return (2.0 * intersection) / (length1 + length2);
-}
-
-/* base64 */
-
-String.prototype._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
-// public method for encoding
-String.prototype.base64Encode = function () {
-       var output = "";
-       var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
-       var i = 0;
-
-       input = this._utf8_encode();
-
-       while (i < input.length) {
-
-               chr1 = input.charCodeAt(i++);
-               chr2 = input.charCodeAt(i++);
-               chr3 = input.charCodeAt(i++);
-
-               enc1 = chr1 >> 2;
-               enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
-               enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
-               enc4 = chr3 & 63;
-
-               if (isNaN(chr2)) {
-                       enc3 = enc4 = 64;
-               } else if (isNaN(chr3)) {
-                       enc4 = 64;
-               }
-
-               output = output +
-               this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
-               this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
-
-       }
-       return output;
-};
-
-// public method for decoding
-String.prototype.base64Decode = function () {
-       var output = "";
-       var chr1, chr2, chr3;
-       var enc1, enc2, enc3, enc4;
-       var i = 0;
-
-       input = this.replace(/[^A-Za-z0-9\+\/\=]/g, "");
-
-       while (i < input.length) {
-
-               enc1 = this._keyStr.indexOf(input.charAt(i++));
-               enc2 = this._keyStr.indexOf(input.charAt(i++));
-               enc3 = this._keyStr.indexOf(input.charAt(i++));
-               enc4 = this._keyStr.indexOf(input.charAt(i++));
-
-               chr1 = (enc1 << 2) | (enc2 >> 4);
-               chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
-               chr3 = ((enc3 & 3) << 6) | enc4;
-
-               output = output + String.fromCharCode(chr1);
-
-               if (enc3 != 64) {
-                       output = output + String.fromCharCode(chr2);
-               }
-               if (enc4 != 64) {
-                       output = output + String.fromCharCode(chr3);
-               }
-
-       }
-       return output._utf8_decode();;
-};
-
-// private method for UTF-8 encoding
-String.prototype._utf8_encode = function () {
-       string = this.replace(/\r\n/g,"\n");
-       var utftext = "";
-
-       for (var n = 0; n < string.length; n++) {
-
-               var c = string.charCodeAt(n);
-
-               if (c < 128) {
-                       utftext += String.fromCharCode(c);
-               }
-               else if((c > 127) && (c < 2048)) {
-                       utftext += String.fromCharCode((c >> 6) | 192);
-                       utftext += String.fromCharCode((c & 63) | 128);
-               }
-               else {
-                       utftext += String.fromCharCode((c >> 12) | 224);
-                       utftext += String.fromCharCode(((c >> 6) & 63) | 128);
-                       utftext += String.fromCharCode((c & 63) | 128);
-               }
-
-       }
-       return utftext;
-};
-
-// private method for UTF-8 decoding
-String.prototype._utf8_decode = function () {
-       var string = "";
-       var i = 0;
-       var c = c1 = c2 = 0;
-
-       while ( i < this.length ) {
-
-               c = this.charCodeAt(i);
-
-               if (c < 128) {
-                       string += String.fromCharCode(c);
-                       i++;
-               }
-               else if((c > 191) && (c < 224)) {
-                       c2 = this.charCodeAt(i+1);
-                       string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
-                       i += 2;
-               }
-               else {
-                       c2 = this.charCodeAt(i+1);
-                       c3 = this.charCodeAt(i+2);
-                       string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
-                       i += 3;
-               }
-
-       }
-       return string;
-};
-
-// JQuery Case Insensitive :icontains selector
-$.expr[':'].icontains = function(obj, index, meta, stack){
-       return (obj.textContent.replace(/\[[0-9]+\]/g, "") || obj.innerText.replace(/\[[0-9]+\]/g, "") || jQuery(obj).text().replace(/\[[0-9]+\]/g, "") || '').toLowerCase().indexOf(meta[3].toLowerCase()) >= 0;
-};
-
-var Utils = {
-       // Extract anchor part (after #) from URL string
-       extractAnchor: function(url) {
-               var index = url.indexOf("#");
-               if (index >= 0) {
-                       return url.substring(index + 1);
-               }
-               return null;
-       },
-
-       delayEvent: function(handler, event) {
-               if(this.delayEvent.timeout) {
-                       clearTimeout(this.delayEvent.timeout);
-               }
-               this.delayEvent.timeout = setTimeout(function() {
-                   handler.call(event);
-               }, 50);
-       }
-};
diff --git a/share/nitdoc/js/nitdoc.quicksearch.js b/share/nitdoc/js/nitdoc.quicksearch.js
new file mode 100644 (file)
index 0000000..746d2e6
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ * 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.
+ */
+
+/* Nitdoc QuickSearch widget */
+
+$.widget("nitdoc.quicksearch", {
+
+       options: {
+               list: {}, // List of raw results generated by nitdoc tool
+               fieldAttrs: {
+                       autocomplete: "off",
+               },
+               maxSize: 10
+       },
+
+       _create: function() {
+               // set widget options
+               this.element.attr(this.options.fieldAttrs);
+               // event dispatch
+               this._on(this.element, {
+                       "keydown": this._doKeyDown,
+                       "keyup": this._doKeyUp,
+                       "input": this._doInput
+               });
+               // add result table element once
+               this._popup = $("<div/>")
+                       .attr("id", "nitdoc-qs-popup")
+                       .css("position", "absolute")
+                       .css("z-index", 10000)
+                       .hide();
+               $("body").append(this._popup);
+               // make table disappear when a click occurs outside
+               $(document).click($.proxy(this.close, this));
+               this._autosizeTable();
+       },
+
+       /* events */
+
+       _doKeyDown: function(event) {
+               switch(event.keyCode) {
+                       case 38: // Up
+                               this._selectPrev();
+                               return false;
+                       case 40: // Down
+                               this._selectNext();
+                               return false;
+                       default:
+                               return true;
+                }
+       },
+
+       _doKeyUp: function(event) {
+               switch(event.keyCode) {
+                       case 38: // Up
+                       case 40: // Down
+                               break;
+                       case 13: // Enter
+                               this._loadResult();
+                               return false;
+                       case 27: // Escape
+                               this.element.blur();
+                               this.close();
+                               return true;
+                       default: // Other keys
+                               return true;
+               }
+       },
+
+       _doInput: function(event) {
+               Utils.delayEvent($.proxy(this.search, this));
+       },
+
+       /* Result lookup */
+
+       _getResults: function(query) {
+               var results = [];
+
+               // Prefix matches
+               var prefix_matches = [];
+               for(var entry in this.options.list) {
+                       if(!entry.startsWith(query, true)) {
+                               continue;
+                       }
+                       var cat = {
+                               name: entry,
+                               entries: this.options.list[entry]
+                       };
+                       prefix_matches.push(cat);
+
+                       if(entry == query) {
+                               cat.rank = 10;
+                       } else if(entry.toUpperCase() == query.toUpperCase()) {
+                               cat.rank = 5;
+                       } else if(entry[0] == query[0]) {
+                               cat.rank = 1.1 + query.dice(entry);
+                       } else {
+                               cat.rank = 1 + query.dice(entry);
+                       }
+               }
+               if(prefix_matches.length > 0) {
+                       prefix_matches.sort(this._rankSorter);
+                       for(var i in prefix_matches) {
+                               var cat = prefix_matches[i];
+                               for(var j in cat.entries) {
+                                       var entry = cat.entries[j];
+                                       entry.name = cat.name;
+                                       results.push(entry);
+                               }
+                       }
+                       return results;
+               }
+
+               // Partial matches
+               var partial_matches = [];
+               for(var entry in this.options.list) {
+                       var cat = {
+                               name: entry,
+                               entries: this.options.list[entry]
+                       }
+                       cat.rank = query.dice(entry);
+                       if(cat.rank > 0) {
+                               partial_matches.push(cat);
+                       }
+               }
+               if(partial_matches.length > 0) {
+                       partial_matches.sort(this._rankSorter);
+                       for(var i in partial_matches) {
+                               var cat = partial_matches[i];
+                               for(var j in cat.entries) {
+                                       var entry = cat.entries[j];
+                                       entry.name = cat.name;
+                                       results.push(entry);
+                               }
+                       }
+               }
+
+               return results;
+       },
+
+       _rankSorter: function(a, b){
+               if(a.rank < b.rank) {
+                       return 1;
+               } else if(a.rank > b.rank) {
+                       return -1;
+               }
+               return 0;
+       },
+
+       /* Results table */
+
+       search: function() {
+               var query = this.element.val();
+               if(query) {
+                       var results = this._getResults(query);
+                       this.open(query, results);
+               }
+       },
+
+       open: function(query, results) {
+               this._popup.empty();
+               this._cards = [];
+               this._index = -1;
+
+               if(results.length == 0) {
+                       this.addNoResultCard();
+               }
+
+               if(results.length >= this.options.maxSize) {
+                       this.addOverflowUp(false);
+               }
+
+               for(var i in results) {
+                       var result = results[i];
+                       this.addCard(result.name, result.txt, result.url, this.options.rowCatClass)
+               }
+
+               if(results.length >= this.options.maxSize) {
+                       this.addOverflowDown(true);
+               }
+
+               if(results.length > 0) {
+                       this._setIndex(0);
+               }
+
+               this._popup.show();
+               this._autosizeTable();
+       },
+
+       close: function(target) {
+               if(target != this.element && target != this._popup) {
+                       this._popup.hide();
+               }
+       },
+
+       addCard: function(name, txt, url, cls) {
+               var card = $("<div/>")
+                       .addClass("qs-card")
+                       .addClass("qs-result")
+                       .data("searchDetails", {name: name, url: url})
+                       .data("index", this._cards.length)
+                       .append(
+                               $("<h1/>")
+                               .html(name)
+                               .addClass(cls)
+                       )
+                       .append(
+                               $("<span/>")
+                               .html(txt)
+                               .addClass("qs-info")
+                       )
+                       .mouseover($.proxy(this._mouseOverRow, this))
+                       .click($.proxy(this._clickRow, this))
+               this._cards.push(card);
+               if(this._cards.length >= this.options.maxSize) {
+                       card.hide();
+               }
+               this._popup.append(card);
+       },
+
+       addOverflowUp: function(active) {
+               this._popup.append(
+                       $("<div/>")
+                       .addClass("qs-overflow")
+                       .addClass("qs-overflow-up")
+                       .addClass(active ? "qs-overflow-active": "")
+                       .html("&#x25B2;")
+                       .click($.proxy(this._clickPrev, this))
+               );
+       },
+
+       addOverflowDown: function(active) {
+               this._popup.append(
+                       $("<div/>")
+                       .addClass("qs-overflow")
+                       .addClass("qs-overflow-down")
+                       .addClass(active ? "qs-overflow-active": "")
+                       .html("&#x25BC;")
+                       .click($.proxy(this._clickNext, this))
+               );
+       },
+
+       addNoResultCard: function() {
+               var card = $("<div/>")
+                       .addClass("qs-card qs-noresult")
+                       .html("Sorry, there is no match...");
+               this._popup.append(card);
+       },
+
+       _autosizeTable: function() {
+               this._popup.position({
+                       my: "left top",
+                       at: "left bottom",
+                       of: this.element
+               });
+               this._popup
+                       .css("min-width", this.element.outerWidth())
+                       .css("max-width", this.element.outerWidth());
+       },
+
+       _hasIndex: function(index) {
+               return index >= 0 && index < this._cards.length;
+       },
+
+       _hasPrev: function(index) {
+               return index - 1 >= 0;
+       },
+
+       _hasNext: function(index) {
+               return index + 1 < this._cards.length;
+       },
+
+       _setIndex: function(index) {
+               if(this._hasIndex(this._index)) {
+                       this._cards[this._index].removeClass("qs-active");
+               }
+               this._index = index;
+               if(this._hasIndex(this._index)) {
+                       this._cards[this._index].addClass("qs-active");
+               }
+       },
+
+       _selectPrev: function() {
+               if(this._hasPrev(this._index)) {
+                       this._setIndex(this._index - 1);
+                       if(!this._cards[this._index].is(":visible")) {
+                               this._popup.find(".qs-result:visible").last().hide();
+                               this._popup.find(".qs-overflow-down").addClass("qs-overflow-active");
+                               this._cards[this._index].show();
+                               if(!this._hasPrev(this._index)) {
+                                       this._popup.find(".qs-overflow-up").removeClass("qs-overflow-active");
+                               }
+                       }
+               } else {
+               }
+       },
+
+       _selectNext: function() {
+               if(this._hasNext(this._index)) {
+                       this._setIndex(this._index + 1);
+                       if(!this._cards[this._index].is(":visible")) {
+                               this._popup.find(".qs-result:visible").first().hide();
+                               this._popup.find(".qs-overflow-up").addClass("qs-overflow-active");
+                               this._cards[this._index].show();
+                               if(!this._hasNext(this._index)) {
+                                       this._popup.find(".qs-overflow-down").removeClass("qs-overflow-active");
+                               }
+                       }
+               }
+       },
+
+       // Load selected search result page
+       _loadResult: function() {
+               if(this._index > -1) {
+                       window.location = this._cards[this._index].data("searchDetails").url;
+                       return;
+               }
+               if(this.element.val().length == 0) { return; }
+
+               window.location = this.options.gotoPage + "#q=" + this.element.val();
+               if(window.location.href.indexOf(this.options.gotoPage) > -1) {
+                       location.reload();
+               }
+       },
+
+       /* table events */
+
+       _clickNext: function(event) {
+               event.stopPropagation();
+               this._selectNext();
+       },
+
+       _clickPrev: function(event) {
+               event.stopPropagation();
+               this._selectPrev();
+       },
+
+       _clickRow: function(event) {
+               window.location = $(event.currentTarget).data("searchDetails")["url"];
+       },
+
+       _mouseOverRow: function(event) {
+               this._setIndex($(event.currentTarget).data("index"));
+       }
+});
+
+var searchField = $("<input/>")
+.addClass("form-control search-input")
+.attr({
+       id: "nitdoc-qs-field",
+       type: "text",
+       placeholder: "Search..."
+})
+
+$("#search-placeholder").append(
+       $("<form>")
+       .addClass("navbar-form navbar-right")
+       .on("submit", function() { return false; })
+       .css("margin-bottom", 0)
+       .css("margin-top", 0)
+       .append(
+               $("<div>")
+               .addClass("form-group has-icon")
+               .append(searchField)
+               .append(
+                       $("<span>")
+                       .addClass("glyphicon glyphicon-search form-control-icon text-muted")
+               )
+       )
+);
+
+searchField.quicksearch({
+       list: this.nitdocQuickSearchRawList
+});
diff --git a/share/nitdoc/js/nitdoc.utils.js b/share/nitdoc/js/nitdoc.utils.js
new file mode 100644 (file)
index 0000000..ac19c29
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+/* Utils module */
+
+String.prototype.startsWith = function(prefix, caseSensitive) {
+       if(caseSensitive) {
+               return this.toUpperCase().indexOf(prefix.toUpperCase()) === 0;
+       }
+       return this.indexOf(prefix) === 0;
+}
+
+// Compare two strings using Sorensen-Dice Coefficient
+// see: http://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient
+String.prototype.dice = function(other) {
+       var length1 = this.length - 1;
+       var length2 = other.length - 1;
+       if(length1 < 1 || length2 < 1) return 0;
+
+       var bigrams2 = [];
+       for(var i = 0; i < length2; i++) {
+               bigrams2.push(other.substr(i, 2));
+       }
+
+       var intersection = 0;
+       for(var i = 0; i < length1; i++) {
+               var bigram1 = this.substr(i, 2);
+               for(var j = 0; j < length2; j++) {
+                       if(bigram1 == bigrams2[j]) {
+                               intersection++;
+                               bigrams2[j] = null;
+                               break;
+                       }
+               }
+       }
+       return (2.0 * intersection) / (length1 + length2);
+}
+
+var Utils = {
+       delayEvent: function(handler, event) {
+               if(this.delayEvent.timeout) {
+                       clearTimeout(this.delayEvent.timeout);
+               }
+               this.delayEvent.timeout = setTimeout(function() {
+                   handler.call(event);
+               }, 100);
+       },
+
+       scrollTo: function(target) {
+               var element = $(target);
+               if(element[0]) {
+                       $("body, html").animate({
+                               scrollTop: element.offset().top - 60
+                       });
+               }
+       },
+
+       openTab: function(e) {
+               // Open tab
+               var url = document.location.toString();
+               if (url.match('#')) {
+                       var hash = url.split('#')[1];
+                       var element = $('.nav-tabs a[href="#' + hash + '"]');
+                       if(element[0]) {
+                               element.tab('show');
+                       } else {
+                               Utils.scrollTo('#' + hash);
+                       }
+               }
+
+               // Jump to id
+               var obj = new URL(url);
+               var arg = obj.searchParams.get("def");
+               if(arg) {
+                       var def = '#' + arg;
+                       $('.card.active').removeClass('active');
+                       $(def).addClass('active');
+                       $(def).find('.collapse').collapse();
+                       Utils.scrollTo(def);
+               }
+       }
+};
+
+Utils.openTab();
+
+window.addEventListener("hashchange", Utils.openTab, false);
+
+// Scroll on hash click
+$('.summary a[href*=#]').on('click', function(e) {
+       e.preventDefault();
+       Utils.scrollTo(e.currentTarget.hash);
+       history.pushState({}, '', e.currentTarget.hash);
+});
+
+// Change hash for page-reload
+$('.nav-tabs a[href]').on('shown.bs.tab', function (e) {
+       history.pushState({}, '', e.target.hash)
+});
diff --git a/share/nitdoc/js/plugins/filtering.js b/share/nitdoc/js/plugins/filtering.js
deleted file mode 100644 (file)
index fa0f12e..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/* 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.
-
-   Documentation generator for the nit language.
-   Generate API documentation in HTML format from nit source code.
-*/
-
-/*
- * Nitdoc Filtering
- *
- * Allow user to filter sidebar entries and search page
- */
-var Filtering = {
-
-       // Allow user to filter sidebar box entries by name
-       enableSidebarTextFilters: function(filterSelector) {
-               var div = $(document.createElement("div"))
-               .addClass("nitdoc-ui-filter")
-               .append(
-                       $(document.createElement("input"))
-                       .addClass("nitdoc-ui-filter-field")
-                       .addClass("nitdoc-ui-filter-field-notused")
-                       .attr("type", "text")
-                       .attr("value",  "filter...")
-                       .keyup(function() {
-                               var box = $(this).parents("nav.filterable");
-                               var value = $(this).val();
-                               box.find("ul li:not(:icontains('" + value + "'))").hide();
-                               box.find("ul li:icontains('" + value + "')").show();
-                       })
-                       .focusout(function() {
-                               if($(this).val() == "") {
-                                       $(this).addClass("nitdoc-ui-filter-field-notused");
-                                       $(this).val("filter...");
-                               }
-                       })
-                       .focusin(function() {
-                               if($(this).val() == "filter...") {
-                                       $(this).removeClass("nitdoc-ui-filter-field-notused");
-                                       $(this).val("");
-                               }
-                       })
-               );
-               $(filterSelector).after(div);
-               this.preloadSidebarTextFilters();
-       },
-
-       // Prealod filters using search query
-       preloadSidebarTextFilters: function() {
-               var anchor = Utils.extractAnchor(document.location.hash);
-               if(!anchor || anchor.indexOf("q=") == -1) return;
-
-               var query = anchor.substring(2);
-               if(!query) return;
-
-               $(".nitdoc-ui-filter input:text")
-               .val(query)
-               .removeClass("nitdoc-ui-notused")
-               .trigger("keyup");
-       },
-
-       // Allow user to filter side bar box entries by Introduced/Refined/inHerited type
-       enableSidebarTypeFilters: function(filterSelector) {
-               var box = $(filterSelector);
-               var types = {};
-
-               box.find("li").each(function() {
-                       var span = $(this).find("span:first");
-                       if(!types[span.html()]) types[span.html()] = {
-                               title: span.attr("title"),
-                               class: $(this).attr("class")
-                       }
-               });
-
-               for(var type in types) {
-                       var a = $(document.createElement("a"))
-                       .addClass("nitdoc-ui-filter-link")
-                       .html(type)
-                       .attr("title", "Hide " + types[type].title)
-                       .attr("data-filter-class", types[type].class)
-                       .toggle(
-                               function() {
-                                       var hclass = $(this).attr("data-filter-class");
-                                       $(this).parents(filterSelector).find("li." + hclass).hide();
-                                       $(this).addClass("nitdoc-ui-filter-hidden")
-                               },
-                               function() {
-                                       var hclass = $(this).attr("data-filter-class");
-                                       $(this).parents(filterSelector).find("li." + hclass).show();
-                                       $(this).removeClass("nitdoc-ui-filter-hidden")
-                               }
-                       )
-                       $(filterSelector).find(".nitdoc-ui-filter").append(a);
-               }
-       },
-
-       // Allow user to filter sidebar box entries by name
-       enableSearchPageField: function(filterSelector) {
-               var div = $(document.createElement("div"))
-               .addClass("nitdoc-ui-searchpage-filter")
-               .append(
-                       $(document.createElement("input"))
-                       .addClass("nitdoc-ui-searchpage-field")
-                       .addClass("nitdoc-ui-filter-field-notused")
-                       .attr("type", "text")
-                       .attr("value",  "filter...")
-                       .keyup(function() {
-                               var box = $(this).parents(".content.fullpage").find("article.filterable");
-                               var value = $(this).val();
-                               box.find("ul li:not(:icontains('" + value + "'))").hide();
-                               box.find("ul li:icontains('" + value + "')").show();
-                       })
-                       .focusout(function() {
-                               if($(this).val() == "") {
-                                       $(this).addClass("nitdoc-ui-filter-field-notused");
-                                       $(this).val("filter...");
-                               }
-                       })
-                       .focusin(function() {
-                               if($(this).val() == "filter...") {
-                                       $(this).removeClass("nitdoc-ui-filter-field-notused");
-                                       $(this).val("");
-                               }
-                       })
-               );
-               $(filterSelector).after(div);
-               this.preloadSearchPageField();
-       },
-
-       // Prealod filter using search query
-       preloadSearchPageField: function() {
-               var anchor = Utils.extractAnchor(document.location.hash);
-               if(!anchor || anchor.indexOf("q=") == -1) return;
-
-               var query = anchor.substring(2);
-               if(!query) return;
-
-               $(".nitdoc-ui-searchpage-field")
-               .val(query)
-               .removeClass("nitdoc-ui-notused")
-               .trigger("keyup");
-       }
-};
-
-Filtering.enableSidebarTextFilters("nav.filterable h3");
-Filtering.enableSidebarTypeFilters("nav.filterable");
-Filtering.enableSearchPageField(".content.fullpage h1:contains('Search')");
diff --git a/share/nitdoc/js/plugins/github.js b/share/nitdoc/js/plugins/github.js
deleted file mode 100644 (file)
index c77c0d0..0000000
+++ /dev/null
@@ -1,593 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-\r
-   Documentation generator for the nit language.\r
-   Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/*\r
- * Nitdoc.Github comment edition module\r
- *\r
- * Allows user to modify source code comments directly from the Nitdoc\r
- */\r
-define([\r
-       "jquery",\r
-       "github-api",\r
-       "highlight",\r
-       "marked",\r
-       "nit",\r
-       "plugins/modalbox",\r
-       "plugins/github/loginbox",\r
-       "plugins/github/commentbox",\r
-       "utils"\r
-], function($, GithubAPI, hljs, marked) {\r
-       var GithubUser = function(login, password, repo, branch) {\r
-               this.login = login;\r
-               this.password = password;\r
-               this.repo = repo;\r
-               this.auth = "Basic " +  (login + ':' + password).base64Encode();\r
-               this.branch = branch;\r
-       }\r
-\r
-       var GithubUI = {\r
-               init: function(upstream, basesha1) {\r
-                       console.info("Github plugin: init GitHub module (upstream: "+ upstream +", base: " + basesha1 + ")");\r
-                       this.origin = this._parseUpstream(upstream);\r
-                       this._initMarked();\r
-                       // Add github menu\r
-                       $("#topmenu>.container-fluid").append(\r
-                               $("<a/>")\r
-                               .attr({\r
-                                       "id": "nitdoc-github-li",\r
-                                       "type": "button",\r
-                                       "class": "navbar-btn navbar-right btn-link",\r
-                                       "href": "#",\r
-                                       "data-container": "body",\r
-                                       "data-toggle": "popover",\r
-                                       "data-placement": "bottom",\r
-                                       "data-content": "bottom",\r
-                                       "data-html": "true",\r
-                               })\r
-                               .loginbox()\r
-                               //.loginbox("displayLogin")\r
-                               .bind("loginbox_logoff", function() {\r
-                                       GithubUI.disactivate();\r
-                               })\r
-                               .bind("loginbox_login", function(event, infos) {\r
-                                       GithubUI._tryLoginFromCredentials(infos);\r
-                               })\r
-                       );\r
-                       // check local session\r
-                       this._tryLoginFromLocalSession();\r
-               },\r
-\r
-               activate: function(user, origin) {\r
-                       this.openedComments = 0;\r
-                       this._saveSession(user);\r
-                       $("#nitdoc-github-li").loginbox("displayLogout", origin, user);\r
-                       this._attachCommentBoxes();\r
-                       this._reloadComments();\r
-\r
-                       // Prevent page unload if there is comments in editing mode\r
-                       $(window).on('beforeunload', function() {\r
-                               if(GithubUI.openedComments > 0){\r
-                                       return "There is uncommited modified comments. Are you sure you want to leave this page?";\r
-                               }\r
-                       });\r
-               },\r
-\r
-               disactivate: function() {\r
-                       if(this.openedComments > 0){\r
-                               if(!confirm('There is uncommited modified comments. Are you sure you want to leave this page?')) {\r
-                                       return false;\r
-                               }\r
-                       }\r
-\r
-                       localStorage.clear();\r
-                       $("#nitdoc-github-li").loginbox("toggle");\r
-                       $("#nitdoc-github-li").loginbox("displayLogin");\r
-                       $(window).unbind('beforeunload');\r
-                       //window.location.reload();\r
-               },\r
-\r
-               /* login */\r
-\r
-               _checkLoginInfos: function(infos) {\r
-                       if(!infos.login || !infos.password || !infos.repo || !infos.branch) {\r
-                               $("<p/>")\r
-                               .text("Please enter your GitHub username, password, repository and branch.")\r
-                               .modalbox({\r
-                                       title: "Sign in error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       } else {\r
-                               return true;\r
-                       }\r
-               },\r
-\r
-               _tryLoginFromCredentials: function(infos) {\r
-                       if(this._checkLoginInfos(infos)) {\r
-                               var isok = this._tryLogin(infos.login, infos.password, infos.repo, infos.branch);\r
-                               if(isok === true) {\r
-                                       this.activate(this.user, this.origin);\r
-                               } else {\r
-                                       if(isok == "error:login") {\r
-                                               $("<p/>")\r
-                                               .text("The username, password, repo or branch you entered is incorrect.")\r
-                                               .modalbox({\r
-                                                       title: "Github sign in error",\r
-                                                       isError: true\r
-                                               })\r
-                                               .modalbox("open");\r
-                                       } else if(isok == "error:sha") {\r
-                                               $("<p/>")\r
-                                               .text("The provided Github repository must contain the base commit '" + this.origin.sha + "'.")\r
-                                               .modalbox({\r
-                                                       title: "Github base commit error",\r
-                                                       isError: true\r
-                                               })\r
-                                               .modalbox("open");\r
-                                       } else if(isok == "error:profile") {\r
-                                               $("<p/>")\r
-                                               .text("Please set your public name and email in your " +\r
-                                                       "<a href='https://github.com/settings/profile'>GitHub profile</a>." +\r
-                                                       "<br/><br/>Your public profile informations are used to sign-off your commits.")\r
-                                               .modalbox({\r
-                                                       title: "Github profile error",\r
-                                                       isError: true\r
-                                               })\r
-                                               .modalbox("open");\r
-                                       }\r
-                               }\r
-                       }\r
-               },\r
-\r
-               _tryLoginFromLocalSession: function() {\r
-                       if(localStorage.user) {\r
-                               var session = JSON.parse(localStorage.user);\r
-                               var isok = this._tryLogin(\r
-                                       session.login,\r
-                                       session.password.base64Decode(),\r
-                                       session.repo,\r
-                                       session.branch\r
-                               );\r
-                               if(isok === true) {\r
-                                       this.activate(this.user, this.origin);\r
-                               } else {\r
-                                       console.debug("Github plugin: Session found but authentification failed");\r
-                                       localStorage.clear();\r
-                               }\r
-                       } else {\r
-                               console.debug("Github plugin: No session found");\r
-                       }\r
-               },\r
-\r
-               _tryLogin: function(login, password, repo, branch) {\r
-                       var tmpUser = new GithubUser(login, password, repo, branch);\r
-                       if(!GithubAPI.login(tmpUser)) {\r
-                               return "error:login";\r
-                       }\r
-                       if(!tmpUser.infos.name || !tmpUser.infos.email) {\r
-                               return "error:profile";\r
-                       }\r
-                       var commit = GithubAPI.getCommit(tmpUser, this.origin.sha);\r
-                       if(!commit || !commit.sha) {\r
-                               return "error:sha";\r
-                       }\r
-                       this.user = tmpUser;\r
-                       return true;\r
-               },\r
-\r
-               _saveSession: function(user) {\r
-                       localStorage.user = JSON.stringify({\r
-                               login: user.login,\r
-                               password: user.password.base64Encode(),\r
-                               repo: user.repo,\r
-                               branch: user.branch,\r
-                       });\r
-                       // check local storage synchro with branch\r
-                       if(localStorage.base != this.origin.sha) {\r
-                               console.log("Base changed: cleaned cache");\r
-                               localStorage.requests = "[]";\r
-                               localStorage.base = this.origin.sha;\r
-                       }\r
-               },\r
-\r
-               /* html decoration */\r
-\r
-               // Attach edit button on each comment\r
-               _attachCommentBoxes: function() {\r
-                       $("textarea.baseComment").each(function() {\r
-                               $(this).commentbox();\r
-\r
-                               var isNew = false;\r
-                               if(!$(this).val()) {\r
-                                       isNew = true;\r
-                                       $(this).nextAll(".info:first").find(".noComment").hide()\r
-                                       $(this).nextAll(".info:first").before(\r
-                                               $("<div/>")\r
-                                               .hide()\r
-                                               .addClass("comment")\r
-                                               .append(\r
-                                                       $("<div/>").addClass("nitdoc")\r
-                                               )\r
-                                       )\r
-                               }\r
-\r
-                               $(this).nextAll(".info:first").prepend(\r
-                                       $("<a/>")\r
-                                       .addClass("nitdoc-github-editComment")\r
-                                       .css("cursor", "pointer")\r
-                                       .text((isNew ? "add" : "edit") + " comment")\r
-                                       .click($.proxy(GithubUI._openCommentBox, GithubUI, null, $(this)))\r
-                                       .after(" for ")\r
-                               )\r
-\r
-                               $(this).bind("commentbox_commit", function(event, data) {\r
-                                       GithubUI._saveChanges(data);\r
-                                       $(this).commentbox("close");\r
-                                       GithubUI._reloadComments();\r
-                               })\r
-                               .bind("commentbox_preview", function(event, data) {\r
-                                       $("<div/>")\r
-                                       .append($("<h4/>").text("Comment:"))\r
-                                       .append(\r
-                                               $("<div/>")\r
-                                               .addClass("description")\r
-                                               .append(\r
-                                                       $("<div/>")\r
-                                                       .addClass("comment")\r
-                                                       .append(\r
-                                                               $("<div/>")\r
-                                                               .addClass("nitdoc")\r
-                                                               .html(marked(data.value))\r
-                                                       )\r
-                                               )\r
-                                       )\r
-                                       .append($("<h4/>").text("Message:"))\r
-                                       .append(\r
-                                               $("<div/>")\r
-                                               .addClass("description")\r
-                                               .append(\r
-                                                       $("<div/>")\r
-                                                       .addClass("comment")\r
-                                                       .append(\r
-                                                               $("<div/>").html(marked(data.message))\r
-                                                       )\r
-                                               )\r
-                                       )\r
-                                       .modalbox({\r
-                                               title: "Preview comment",\r
-                                               css: {"min-width": "500px"}\r
-                                       })\r
-                                       .modalbox("open");\r
-                               })\r
-                               .bind("commentbox_open", function(event, data) {\r
-                                       GithubUI.openedComments++;\r
-                                       $(this).nextAll(".comment").hide();\r
-                               })\r
-                               .bind("commentbox_close", function(event, data) {\r
-                                       GithubUI.openedComments--;\r
-                                       $(this).nextAll(".comment").show();\r
-                               });\r
-                       });\r
-               },\r
-\r
-               // reload comments from saved pull request\r
-               _reloadComments: function() {\r
-                       if(!localStorage.requests){ return; }\r
-                       $("p.pullRequest").remove();\r
-                       var requests = JSON.parse(localStorage.requests);\r
-                       // Look for modified comments in page\r
-                       for(i in requests) {\r
-                               if(!requests[i]) { continue; }\r
-                               var request = requests[i];\r
-                               $("textarea[data-comment-location=\"" + request.location + "\"]").each(function () {\r
-                                       if(request.isClosed) {\r
-                                               var oldComment = request.oldComment.base64Decode();\r
-                                               var htmlComment = marked(oldComment);\r
-                                               $(this).val(oldComment);\r
-                                               if(!$(this).val()) {\r
-                                                       $(this).nextAll("div.comment:first").hide();\r
-                                               } else {\r
-                                                       $(this).nextAll("div.comment:first").show();\r
-                                               }\r
-                                               $(this).nextAll("div.comment").find("div.nitdoc").empty().html(htmlComment);\r
-                                               $(this).nextAll("p.info").find("a.nitdoc-github-editComment").show();\r
-                                       } else {\r
-                                               var newComment = request.comment.base64Decode();\r
-                                               var htmlComment = marked(newComment);\r
-                                               $(this).val(newComment);\r
-                                               if(!$(this).val()) {\r
-                                                       $(this).nextAll("div.comment:first").hide();\r
-                                               } else {\r
-                                                       $(this).nextAll("div.comment:first").show();\r
-                                               }\r
-                                               $(this).nextAll("div.comment").find("div.nitdoc").empty().html(htmlComment);\r
-                                               GithubUI._addPullRequestLink($(this), request);\r
-                                               $(this).nextAll("p.info").find("a.nitdoc-github-editComment").hide();\r
-                                       }\r
-                               });\r
-                       }\r
-               },\r
-\r
-               _addPullRequestLink: function(baseArea, request) {\r
-                       baseArea.nextAll("p.info").before(\r
-                               $("<p/>")\r
-                               .addClass("pullRequest inheritance")\r
-                               .text("comment modified in ")\r
-                               .append(\r
-                                       $("<a/>")\r
-                                       .attr({\r
-                                               href: request.request.html_url,\r
-                                               title: "Review on GitHub"\r
-                                       })\r
-                                       .text("pull request #" + request.request.number)\r
-                               )\r
-                               .append(" ")\r
-                               .append(\r
-                                       $("<a/>")\r
-                                       .data("pullrequest-number", request.request.number)\r
-                                       .addClass("nitdoc-github-update")\r
-                                       .text("update")\r
-                                       .click($.proxy(GithubUI._doUpdateRequest, GithubUI, null, baseArea, request))\r
-                               )\r
-                               .append(" ")\r
-                               .append(\r
-                                       $("<a/>")\r
-                                       .data("pullrequest-number", request.request.number)\r
-                                       .addClass("nitdoc-github-cancel")\r
-                                       .text("cancel")\r
-                                       .click($.proxy(GithubUI._doCancelRequest, GithubUI, null, baseArea, request))\r
-                               )\r
-                       );\r
-               },\r
-\r
-               /* github calls */\r
-\r
-               _saveChanges: function(edit) {\r
-                       // if pull request update close existing pull request for the comment\r
-                       if(edit.requestID) {\r
-                               this._closePullRequest(edit.requestID);\r
-                       }\r
-                       edit.oldContent = this._getFileContent(edit.location.path);\r
-                       edit.newContent = this._mergeComment(edit.oldContent, edit.newComment, edit.location);\r
-                       edit.request = this._pushChanges(edit)\r
-                       if(!edit.request) {\r
-                               $("<p/>")\r
-                               .text("Unable to commit changes.<br/>" + response)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return;\r
-                       }\r
-                       this._saveRequest(edit);\r
-               },\r
-\r
-               // save pull request in local storage\r
-               _saveRequest: function(edit) {\r
-                       var requests = {};\r
-                       if(localStorage.requests) {requests = JSON.parse(localStorage.requests)}\r
-                       requests[edit.request.number] = {\r
-                               request: edit.request,\r
-                               location: edit.location.origin,\r
-                               comment: edit.newComment.base64Encode(),\r
-                               oldComment: edit.oldComment.base64Encode()\r
-                       };\r
-                       localStorage.requests = JSON.stringify(requests);\r
-               },\r
-\r
-               /*\r
-                  Creating a new pull request with the new comment take 5 steps:\r
-                       1. get the base tree from latest commit\r
-\r
-                       2. create a new blob with updated file content\r
-                       3. post a new tree from base tree and blob\r
-                       4. post the new commit with new tree\r
-                       5. create the pull request\r
-               */\r
-               _pushChanges: function(edit) {\r
-                       var baseTree = GithubAPI.getTree(this.user, this.origin.sha);\r
-                       if(!baseTree.sha) {\r
-                               $("<p/>")\r
-                               .text("Unable to locate base tree.<br/>" + baseTree.status + ": " + baseTree.statusText)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       }\r
-                       console.log("Base tree: " + baseTree.url);\r
-                       var newBlob = GithubAPI.createBlob(this.user, edit.newContent);\r
-                       if(!newBlob.sha) {\r
-                               $("<p/>")\r
-                               .text("Unable to create new blob.<br/>" + newBlob.status + ": " + newBlob.statusText)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       }\r
-                       console.log("New blob: " + newBlob.url);\r
-                       var newTree = GithubAPI.createTree(this.user, baseTree, edit.location.path, newBlob);\r
-                       if(!newTree.sha) {\r
-                               $("<p/>")\r
-                               .text("Unable to create new tree.<br/>" + newTree.status + ": " + newTree.statusText)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       }\r
-                       console.log("New tree: " + newTree.url);\r
-                       var newCommit = GithubAPI.createCommit(this.user, edit.message, baseTree.sha, newTree);\r
-                       if(!newCommit.sha) {\r
-                               $("<p/>")\r
-                               .text("Unable to create new commit.<br/>" + newCommit.status + ": " + newCommit.statusText)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       }\r
-                       console.log("New commit: " + newCommit.url);\r
-                       var pullRequest = GithubAPI.createPullRequest(this.user, edit.title, "Pull request from Nitdoc", this.origin, newCommit.sha);\r
-                       if(!pullRequest.number) {\r
-                               $("<p/>")\r
-                               .text("Unable to create pull request.<br/>" + pullRequest.status + ": " + pullRequest.statusText)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       }\r
-                       console.log("New pull request: " + pullRequest.url);\r
-                       return pullRequest;\r
-               },\r
-\r
-               // close previously opened pull request\r
-               _closePullRequest: function(number) {\r
-                       var requests = JSON.parse(localStorage.requests);\r
-                       if(!requests[number]) {\r
-                               $("<p/>")\r
-                               .text("Unable to close pull request.<br/>" + "Pull request " + number + "not found")\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       }\r
-                       // close pull request\r
-                       var res = GithubAPI.updatePullRequest(this.user, "Closed from Nitdoc", "", "closed", requests[number].request);\r
-                       if(!res.id) {\r
-                               $("<p/>")\r
-                               .text("Unable to close pull request.<br/>" + res.status + ": " + res.statusText)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return false;\r
-                       }\r
-                       // update in localstorage\r
-                       requests[number].isClosed = true;\r
-                       localStorage.requests = JSON.stringify(requests);\r
-               },\r
-\r
-               /* internals */\r
-\r
-               _initMarked: function() {\r
-                       var renderer = new marked.Renderer();\r
-                       renderer.code = function(code) {\r
-                               return '<pre class="nitcode hljs">' + hljs.highlight('nit', code).value + '</pre>';\r
-                       }\r
-                       renderer.codespan = function(code) {\r
-                               return '<code class="nitcode hljs">' + hljs.highlight('nit', code).value + '</code>';\r
-                       }\r
-                       marked.setOptions({\r
-                               renderer: renderer,\r
-                               gfm: true,\r
-                               tables: true,\r
-                               breaks: true,\r
-                               pedantic: false,\r
-                               sanitize: true,\r
-                               smartLists: true,\r
-                               smartypants: false\r
-                       });\r
-               },\r
-\r
-               _parseUpstream: function(upstream) {\r
-                       var parts = upstream.split(":");\r
-                       return {\r
-                               user: parts[0],\r
-                               repo: parts[1],\r
-                               branch: parts[2],\r
-                               sha: basesha1\r
-                       };\r
-               },\r
-\r
-               _getFileContent: function(githubUrl) {\r
-                       var origFile = GithubAPI.getFile(this.user, githubUrl);\r
-                       if(!origFile.content) {\r
-                               $("<p/>")\r
-                               .text("Unable to locate source file.<br/>" + origFile.status + ": " + origFile.statusText)\r
-                               .modalbox({\r
-                                       title: "Github commit error",\r
-                                       isError: true\r
-                               })\r
-                               .modalbox("open");\r
-                               return;\r
-                       }\r
-                       var base64Content = origFile.content.substring(0, origFile.content.length - 1)\r
-                       return base64Content.base64Decode();\r
-               },\r
-\r
-               _mergeComment: function(fileContent, comment, location) {\r
-                       // replace comment in file content\r
-                       var res = new String();\r
-                       var lines = fileContent.split("\n");\r
-                       // copy lines fron 0 to lstart\r
-                       for(var i = 0; i < location.lstart - 1; i++) {\r
-                               res += lines[i] + "\n";\r
-                       }\r
-                       // set comment\r
-                       if(comment && comment != "") {\r
-                               var commentLines = comment.split("\n");\r
-                               for(var i = 0; i < commentLines.length; i++) {\r
-                                       var line = commentLines[i];\r
-                                       var tab = location.tabpos > 1 ? "\t" : "";\r
-                                       res += tab + (line.length > 0 ? "# " : "#") + line + "\n";\r
-                               }\r
-                       }\r
-                       // copy lines fron lend to end\r
-                       for(var i = location.lend - 1; i < lines.length; i++) {\r
-                               res += lines[i];\r
-                               if(i < lines.length - 1) { res += "\n"; }\r
-                       }\r
-                       return res;\r
-               },\r
-\r
-               /* events */\r
-\r
-               _openCommentBox: function(event, baseArea) {\r
-                       baseArea.commentbox("open", this.user);\r
-               },\r
-\r
-               _doCancelRequest: function(event, baseArea, request) {\r
-                       this._closePullRequest(request.request.number);\r
-                       this._reloadComments();\r
-               },\r
-\r
-               _doUpdateRequest: function(event, baseArea, request) {\r
-                       baseArea.commentbox("open", this.user, request.request.number);\r
-               },\r
-       }\r
-\r
-       // Get github plugin data\r
-       var upstream = $("body").attr("data-github-upstream");\r
-       var basesha1 = $("body").attr("data-github-base-sha1");\r
-       if(upstream && basesha1) {\r
-               GithubUI.init(upstream, basesha1);\r
-       }\r
-});\r
diff --git a/share/nitdoc/js/plugins/github/commentbox.js b/share/nitdoc/js/plugins/github/commentbox.js
deleted file mode 100644 (file)
index 2bb6a18..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-*/\r
-\r
-/*\r
- * CommentBox allows user to edit comments then preview, commit or cancel the changes\r
- */\r
-define([\r
-       "jquery",\r
-       "jQueryUI"\r
-], function($) {\r
-       var Location = function(location) {\r
-               var parts = location.split(":");\r
-               this.origin = location;\r
-               this.path = parts[0];\r
-               this.lstart = parseInt(parts[1].split("--")[0].split(",")[0]);\r
-               this.tabpos = parseInt(parts[1].split("--")[0].split(",")[1]);\r
-               this.lend = parseInt(parts[1].split("--")[1].split(",")[0]);\r
-               this.toString = function() {\r
-                       return this.path + ":" + this.lstart + "," + this.tabpos + "--" + this.lend + ",0";\r
-               }\r
-       }\r
-\r
-       $.widget("nitdoc.commentbox", {\r
-\r
-               options: {\r
-                       previewTxt: "preview",\r
-                       commitTxt: "Commit",\r
-                       cancelTxt: "Cancel",\r
-                       commentboxTitle: "Edit comment",\r
-                       messageTxt: "Commit message"\r
-               },\r
-\r
-               _create: function() {\r
-                       this._id = $(".nitdoc-github-commentbox").length\r
-                       this._oldComment = this.element.val();\r
-                       this._namespace = this.element.data("comment-namespace");\r
-                       this._location = new Location(this.element.data("comment-location"));\r
-                       this.commentBox = $("<div/>")\r
-                       .hide()\r
-                       .addClass("nitdoc-github-commentbox")\r
-                       .append(\r
-                               $("<h3/>")\r
-                               .text(this.options.commentboxTitle)\r
-                       )\r
-                       .append(\r
-                               $("<dl/>")\r
-                               .addClass("nitdoc-github-commentbox-fields")\r
-                               .append(\r
-                                       $("<dd/>")\r
-                                       .append(\r
-                                               $("<textarea/>")\r
-                                               .attr("id", "nitdoc-github-commentbox-comment" + this._id)\r
-                                               .addClass("nitdoc-github-commentarea")\r
-                                               .keyup($.proxy(this._doKeyUp, this))\r
-                                               .keydown($.proxy(this._doKeyDown, this))\r
-                                       )\r
-                               )\r
-                               .append(\r
-                                       $("<dt/>")\r
-                                       .append(\r
-                                               $("<label/>")\r
-                                               .attr("for", "nitdoc-github-commentbox-message" + this._id)\r
-                                               .text(this.options.messageTxt + ":")\r
-                                       )\r
-                               )\r
-                               .append(\r
-                                       $("<dd/>")\r
-                                       .append(\r
-                                               $("<textarea/>")\r
-                                               .attr("id", "nitdoc-github-commentbox-message" + this._id)\r
-                                               .keyup($.proxy(this._doKeyUp, this))\r
-                                               .keydown($.proxy(this._doKeyDown, this))\r
-                                       )\r
-                               )\r
-                               .append(\r
-                                       $("<dt/>")\r
-                                       .append(\r
-                                               $("<input/>")\r
-                                               .attr({\r
-                                                       id: "nitdoc-github-commentbox-signedoff" + this._id,\r
-                                                       type: "checkbox"\r
-                                               })\r
-                                               .change($.proxy(this._doSignedChange, this))\r
-                                       )\r
-                                       .append(\r
-                                               $("<label/>")\r
-                                               .attr({\r
-                                                       "id": "nitdoc-github-commentbox-signedoff-label" + this._id,\r
-                                                       "for": "nitdoc-github-commentbox-signedoff" + this._id\r
-                                               })\r
-                                       )\r
-                               )\r
-                       )\r
-                       this._buildButtonBar();\r
-                       this.element.after(this.commentBox);\r
-               },\r
-\r
-               _buildButtonBar: function() {\r
-                       this.commentBox.append(\r
-                               $("<div/>")\r
-                               .addClass("nitdoc-github-commentbox-buttons")\r
-                               .append(\r
-                                       $("<a/>")\r
-                                       .addClass("nitdoc-github-preview")\r
-                                       .html(this.options.previewTxt)\r
-                                       .click($.proxy(this._doPreviewClick, this))\r
-                               )\r
-                               .append(\r
-                                       $("<button/>")\r
-                                       .addClass("nitdoc-github-button")\r
-                                       .addClass("nitdoc-github-commit")\r
-                                       .attr("disabled", "disabled")\r
-                                       .html(this.options.commitTxt)\r
-                                       .click($.proxy(this._doCommitClick, this))\r
-                               )\r
-                               .append(\r
-                                       $("<button/>")\r
-                                       .addClass("nitdoc-github-button")\r
-                                       .addClass("nitdoc-github-cancel")\r
-                                       .html(this.options.cancelTxt)\r
-                                       .click($.proxy(this._doCancelClick, this))\r
-                               )\r
-                       );\r
-               },\r
-\r
-               /* public actions */\r
-\r
-               open: function(user, requestID) {\r
-                       this._requestID = requestID;\r
-                       var value = this.element.val();\r
-                       var isNew = !value;\r
-                       var message = "doc: " + (isNew ? "added" : "modified") + " comment for " + this._namespace;\r
-                       this._setMessage(message);\r
-                       this._setSignedOff("Signed-off-by: " + user.signedOff);\r
-                       this._setComment(value);\r
-                       this.commentBox.show();\r
-                       this.commentBox.find("textarea").width(this.commentBox.innerWidth() - 45)\r
-                       $("#nitdoc-github-commentbox-comment" + this._id).focus();\r
-                       $("#nitdoc-github-commentbox-comment" + this._id).trigger("keyup");\r
-                       $("#nitdoc-github-commentbox-message" + this._id).trigger("keyup");\r
-                       this._trigger("_open", null, {commentBox: this});\r
-               },\r
-\r
-               close: function() {\r
-                       this.commentBox.hide();\r
-                       this._trigger("_close", null, {commentBox: this});\r
-               },\r
-\r
-               /* internals */\r
-\r
-               _setComment: function(value) {\r
-                       $("#nitdoc-github-commentbox-comment" + this._id).val(value);\r
-               },\r
-\r
-               _getComment: function() {\r
-                       return $("#nitdoc-github-commentbox-comment" + this._id).val();\r
-               },\r
-\r
-               _getMessage: function() {\r
-                       return $("#nitdoc-github-commentbox-message" + this._id).val();\r
-               },\r
-\r
-               _setMessage: function(message) {\r
-                       $("#nitdoc-github-commentbox-message" + this._id).val(message);\r
-               },\r
-\r
-               _getSignedOff: function() {\r
-                       return $("#nitdoc-github-commentbox-signedoff" + this._id).val();\r
-               },\r
-\r
-               _setSignedOff: function(signedoff) {\r
-                       $("#nitdoc-github-commentbox-signedoff" + this._id).val(signedoff);\r
-                       $("#nitdoc-github-commentbox-signedoff-label" + this._id).text(signedoff);\r
-               },\r
-\r
-               /* events */\r
-\r
-               _doKeyUp: function(event) {\r
-                       $(event.target).height($(event.target).val().split(/\r|\n/).length * 16);\r
-               },\r
-\r
-               _doKeyDown: function(event) {\r
-                       if(event.keyCode == 13){\r
-                               $(event.target).css("height", ($(event.target).outerHeight() + 6) + "px");\r
-                       }\r
-               },\r
-\r
-               _doSignedChange: function(event) {\r
-                       if ($(event.currentTarget).is(':checked')) {\r
-                               this.commentBox.find("button.nitdoc-github-commit").removeAttr("disabled");\r
-                       } else {\r
-                               this.commentBox.find("button.nitdoc-github-commit").attr("disabled", "disabled");\r
-                       }\r
-               },\r
-\r
-               _doPreviewClick: function(event) {\r
-                       this._trigger("_preview", event, {\r
-                               value: this._getComment(),\r
-                               message: this._getMessage() + "\n\n" + this._getSignedOff()\r
-                       });\r
-               },\r
-\r
-               _doCommitClick: function() {\r
-                       this._trigger("_commit", event, {\r
-                               requestID: this._requestID,\r
-                               location: this._location,\r
-                               namespace: this._namespace,\r
-                               oldComment: this._oldComment,\r
-                               newComment: this._getComment(),\r
-                               title: this._getMessage(),\r
-                               message: this._getMessage() + "\n\n" + this._getSignedOff()\r
-                       });\r
-               },\r
-\r
-               _doCancelClick: function() {\r
-                       this.close();\r
-               }\r
-       });\r
-});\r
diff --git a/share/nitdoc/js/plugins/github/loginbox.js b/share/nitdoc/js/plugins/github/loginbox.js
deleted file mode 100644 (file)
index 55fbffe..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-*/\r
-\r
-/*\r
- * LoginBox allows user to login and logoff from GitHub API\r
- */\r
-define([\r
-       "jquery",\r
-       "jQueryUI"\r
-], function($) {\r
-       $.widget("nitdoc.loginbox", {\r
-               options: {\r
-                       icon: "resources/icons/github-icon.png",\r
-                       iconActive: "resources/icons/github-icon-green.png",\r
-                       iconAlt: "GitHub",\r
-                       signedinTxt: "Signed in Github",\r
-                       signedoutTxt: "Sign in Github",\r
-                       welcomeTxt: "Hello",\r
-                       upstreamTxt: "Upstream branch",\r
-                       baseTxt: "Base",\r
-                       signoffTxt: "Sign Off",\r
-                       usernameTxt: "Username",\r
-                       passwordTxt: "Password",\r
-                       repoTxt: "Repository",\r
-                       branchTxt: "Branch",\r
-                       signinTxt: "Sign In"\r
-               },\r
-\r
-               _create: function() {\r
-                       this.element.append(\r
-                               $("<span/>")\r
-                               .addClass("glyphicon glyphicon-off")\r
-                               //.click($.proxy(this.toggle, this))\r
-                               .attr({\r
-                                       "data-container": "body",\r
-                                       "data-toggle": "popover",\r
-                                       "data-placement": "bottom",\r
-                                       "data-content": "bottom",\r
-                                       "data-html": "true",\r
-                               })\r
-                       );\r
-\r
-                       this.content = $("<div/>");\r
-                       this.loginBox = $("<div/>")\r
-                       .attr("id", "nitdoc-github-loginbox")\r
-                       .css("display", "none")\r
-                       .append(\r
-                               $(document.createElement("div"))\r
-                               .addClass("nitdoc-github-loginbox-arrow")\r
-                               .append("&nbsp;")\r
-                       )\r
-                       .append(this.content);\r
-                       this.element.append(this.loginBox);\r
-               },\r
-\r
-               /* public actions */\r
-\r
-               displayLogout: function(origin, user) {\r
-                       this.content.empty();\r
-                       this.content.append(\r
-                               $("<h3/>").text(this.options.signedinTxt)\r
-                       )\r
-                       this.content.append(\r
-                               $("<div/>")\r
-                               .append(\r
-                                       $("<h4/>")\r
-                                       .append(this.options.welcomeTxt + " ")\r
-                                       .append(\r
-                                               $("<a/>")\r
-                                               .attr("href", "https://github.com/" + user.login)\r
-                                               .append(user.login)\r
-                                       ).append(",")\r
-                               )\r
-                               .append(\r
-                                       $("<label/>")\r
-                                       .text("Upstream Branch")\r
-                               )\r
-                               .append(\r
-                                       $("<a/>")\r
-                                       .text(origin.user + ":" + origin.repo + ":" + origin.branch)\r
-                                       .addClass("nitdoc-github-loginbox-githublink")\r
-                                       .attr({\r
-                                               title: "Open branch in GitHub",\r
-                                               href: "https://github.com/" + origin.user + "/" + origin.repo + "/tree/" + origin.branch\r
-                                       })\r
-                               )\r
-                               .append(\r
-                                       $("<label/>")\r
-                                       .attr("for", "github-base")\r
-                                       .append("Your branch")\r
-                               )\r
-                               .append(\r
-                                       $("<a/>")\r
-                                       .text(user.login + ":" + user.repo + ":" + user.branch)\r
-                                       .addClass("nitdoc-github-loginbox-githublink")\r
-                                       .attr({\r
-                                               title: "Open branch in GitHub",\r
-                                               href: "https://github.com/" + user.login + "/" + user.repo + "/tree/" + user.branch\r
-                                       })\r
-                               )\r
-                               .append(\r
-                                       $("<button/>")\r
-                                       .addClass("nitdoc-github-button")\r
-                                       .addClass("nitdoc-github-cancel")\r
-                                       .append(\r
-                                               $("<img/>")\r
-                                               .attr("src", this.options.icon)\r
-                                       ).text(this.options.signoffTxt)\r
-                                       .click($.proxy(this._doClickLogoff, this))\r
-                               )\r
-                       );\r
-                       $(".nitdoc-github-li-img").attr("src", this.options.iconActive);\r
-               },\r
-\r
-               displayLogin: function() {\r
-                       this.content.empty();\r
-                       this.content.append(\r
-                               $("<h3/>").text(this.options.signedoutTxt)\r
-                       )\r
-                       this.content.append(\r
-                               $("<form/>")\r
-                               .keyup($.proxy(this._doFormChange, this))\r
-                               .append(\r
-                                       $("<div/>")\r
-                                       .addClass("form-group")\r
-                                       .append(\r
-                                               $("<label/>")\r
-                                               .attr("for", "nitdoc-github-login-field")\r
-                                               .append(this.options.usernameTxt)\r
-                                       )\r
-                                       .addClass("form-group")\r
-                                       .append(\r
-                                               $("<input/>")\r
-                                               .attr({\r
-                                                       id: "nitdoc-github-login-field",\r
-                                                       type: "text",\r
-                                                       "class": "form-control"\r
-                                               })\r
-                                       )\r
-                               )\r
-                               .append(\r
-                                       $("<div/>")\r
-                                       .addClass("form-group")\r
-                                       .append(\r
-                                               $("<label/>")\r
-                                               .attr("for", "nitdoc-github-password-field")\r
-                                               .append(this.options.passwordTxt)\r
-                                       )\r
-                                       .append(\r
-                                               $("<input/>")\r
-                                               .attr({\r
-                                                       id: "nitdoc-github-password-field",\r
-                                                       type: "password",\r
-                                                       "class": "form-control"\r
-                                               })\r
-                                       )\r
-                               )\r
-                               .append(\r
-                                       $("<div/>")\r
-                                       .addClass("form-group")\r
-                                       .append(\r
-                                               $("<label/>")\r
-                                               .attr("for", "nitdoc-github-repo-field")\r
-                                               .append(this.options.repoTxt)\r
-                                       )\r
-                                       .append(\r
-                                               $("<input/>")\r
-                                               .attr({\r
-                                                       id: "nitdoc-github-repo-field",\r
-                                                       type: "text",\r
-                                                       "class": "form-control"\r
-                                               })\r
-                                       )\r
-                               )\r
-                               .append(\r
-                                       $("<div/>")\r
-                                       .addClass("form-group")\r
-                                       .append(\r
-                                               $("<label/>")\r
-                                               .attr("for", "nitdoc-github-branch-field")\r
-                                               .append(this.options.branchTxt)\r
-                                       )\r
-                                       .append(\r
-                                               $("<input/>")\r
-                                               .attr({\r
-                                                       id: "nitdoc-github-branch-field",\r
-                                                       type: "text",\r
-                                                       "class": "form-control"\r
-                                               })\r
-                                       )\r
-                               )\r
-                               .append(\r
-                                       $("<button/>")\r
-                                       .addClass("nitdoc-github-button btn btn-primary btn-lg pull-right")\r
-                                       .attr("disabled", "disabled")\r
-                                       .append(\r
-                                               $("<img/>")\r
-                                               .attr("src", this.options.icon)\r
-                                       ).text(this.options.signinTxt)\r
-                                       .click($.proxy(this._doClickLogin, this))\r
-                               )\r
-                       );\r
-                       $(".nitdoc-github-li-img").attr("src", this.options.icon);\r
-               },\r
-\r
-               toggle: function() {\r
-                       if(this.loginBox.is(':hidden')) {\r
-                               this.loginBox.show();\r
-                               if ($('#nitdoc-github-login-field').is(':visible')) { $('#nitdoc-github-login-field').focus(); }\r
-                       } else {\r
-                               this.loginBox.hide();\r
-                       }\r
-               },\r
-\r
-               /* events */\r
-\r
-               _doClickLogoff: function(event) {\r
-                       this._trigger("_logoff", event);\r
-               },\r
-\r
-               _doClickLogin: function(event) {\r
-                       this._trigger("_login", event, {\r
-                               login: $('#nitdoc-github-login-field').val(),\r
-                               password: $('#nitdoc-github-password-field').val(),\r
-                               repo: $('#nitdoc-github-repo-field').val(),\r
-                               branch: $('#nitdoc-github-branch-field').val()\r
-                       });\r
-                       return false;\r
-               },\r
-\r
-               _doFormChange: function(event) {\r
-                       login = $('#nitdoc-github-login-field').val();\r
-                       password = $('#nitdoc-github-password-field').val();\r
-                       repo = $('#nitdoc-github-repo-field').val();\r
-                       branch = $('#nitdoc-github-branch-field').val();\r
-                       if(login && password && repo && branch) {\r
-                               this.loginBox.find("form .nitdoc-github-button").removeAttr("disabled");\r
-                       } else {\r
-                               this.loginBox.find("form .nitdoc-github-button").attr("disabled", "disabled");\r
-                       }\r
-               }\r
-       });\r
-});\r
diff --git a/share/nitdoc/js/plugins/modalbox.js b/share/nitdoc/js/plugins/modalbox.js
deleted file mode 100644 (file)
index 71bbbad..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
-   Licensed under the Apache License, Version 2.0 (the "License");\r
-   you may not use this file except in compliance with the License.\r
-   You may obtain a copy of the License at\r
-\r
-   http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-   Unless required by applicable law or agreed to in writing, software\r
-   distributed under the License is distributed on an "AS IS" BASIS,\r
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-   See the License for the specific language governing permissions and\r
-   limitations under the License.\r
-\r
-   Documentation generator for the nit language.\r
-   Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-define([\r
-       "jquery",\r
-       "jQueryUI"\r
-], function($) {\r
-       $.widget("nitdoc.modalbox", {\r
-               options: {\r
-                       id: "nitdoc-dialog",\r
-                       classes: "nitdoc-dialog",\r
-                       css: {},\r
-                       title: "Title",\r
-                       isError: false,\r
-               },\r
-\r
-               _create: function() {\r
-                       this._addFade();\r
-                       this._makeDialog();\r
-               },\r
-\r
-               open: function() {\r
-                       this._dialog\r
-                       .show()\r
-                       .css({\r
-                               top: "50%",\r
-                               marginTop: -(this._dialog.outerHeight() / 2) + "px",\r
-                               left: "50%",\r
-                               marginLeft: -(this._dialog.outerWidth() / 2) + "px"\r
-                       })\r
-                       .find(".nitdoc-dialog-buttons button:first").focus();\r
-\r
-                       this._fade.show();\r
-               },\r
-\r
-               close: function() {\r
-                       this._fade.hide();\r
-                       this._dialog.hide();\r
-               },\r
-\r
-               _addFade: function() {\r
-                       this._fade = $("<div/>")\r
-                       .hide()\r
-                       .attr("id", "nitdoc-dialog-fade-" + this.options.id)\r
-                       .addClass("nitdoc-dialog-fade");\r
-                       $("body").append(this._fade);\r
-               },\r
-\r
-               _makeDialog: function() {\r
-                       this._dialog = $("<div/>")\r
-                       .hide()\r
-                       .attr("id", this.options.id)\r
-                       .addClass(this.options.classes)\r
-                       .css(this.options.css)\r
-                       .append(\r
-                               $("<div/>")\r
-                               .addClass("nitdoc-dialog-header")\r
-                               .append(\r
-                                       $("<h3/>")\r
-                                       .text(this.options.title)\r
-                               )\r
-                               .append(\r
-                                       $("<button/>")\r
-                                       .addClass("nitdoc-dialog-close")\r
-                                       .append("x")\r
-                                       .click($.proxy(this.close, this))\r
-                               )\r
-                       )\r
-                       .append(\r
-                               $("<div/>")\r
-                               .addClass("nitdoc-dialog-content")\r
-                               .html(this.element)\r
-                       )\r
-                       .append(\r
-                               $("<div/>")\r
-                               .addClass("nitdoc-dialog-buttons")\r
-                               .append(\r
-                                       $("<button/>")\r
-                                       .append("Ok")\r
-                                       .click($.proxy(this.close, this))\r
-                               )\r
-                       );\r
-                       if(this.options.isError) {\r
-                               this._dialog.addClass("nitdoc-dialog-error");\r
-                       }\r
-                       $("body").append(this._dialog);\r
-               }\r
-       });\r
-});\r
diff --git a/share/nitdoc/js/plugins/quicksearch.js b/share/nitdoc/js/plugins/quicksearch.js
deleted file mode 100644 (file)
index f8cd520..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/* 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.
-
-   Documentation generator for the nit language.
-   Generate API documentation in HTML format from nit source code.
-*/
-
-/*
- * Nitdoc QuickSearch widget
- */
-$.widget("nitdoc.quicksearch", {
-
-       options: {
-               list: {}, // List of raw results generated by nitdoc tool
-               fieldAttrs: {
-                       autocomplete: "off",
-               },
-               tableID: "nitdoc-qs-table",
-               tableCSS: {
-                       "position": "absolute"
-               },
-               rowClass: "nitdoc-qs-row",
-               rowCatClass: "nitdoc-qs-cat",
-               rowSubClass: "nitdoc-qs-sub",
-               rowActiveClass: "nitdoc-qs-active",
-               rowOverflowClass: "nitdoc-qs-overflow",
-               rowOverflowActive: "nitdoc-qs-overflow-active",
-               rowNoResultClass: "nitdoc-qs-noresult",
-               overflowUpHtml: "&#x25B2;",
-               overflowDownHtml: "&#x25BC;",
-               noresultText: "Sorry, there is no match, best results are:",
-               infoClass: "nitdoc-qs-info",
-               gotoPage: "search.html",
-               maxSize: 10
-       },
-
-       _create: function() {
-               // set widget options
-               this.element.attr(this.options.fieldAttrs);
-               // event dispatch
-               this._on(this.element, {
-                       "keydown": this._doKeyDown,
-                       "keyup": this._doKeyUp,
-                       "input": this._doInput
-               });
-               // add result table element once
-               this._table = $("<table/>")
-                       .attr("id", this.options.tableID)
-                       .css(this.options.tableCSS)
-                       .css("min-width", this.element.outerWidth());
-               $("body").append(this._table);
-               // make table disappear when a click occurs outside
-               $(document).click($.proxy(this.closeTable, this));
-       },
-
-       /* events */
-
-       _doKeyDown: function(event) {
-               switch(event.keyCode) {
-                       case 38: // Up
-                               this._selectPrev();
-                               return false;
-                       case 40: // Down
-                               this._selectNext();
-                               return false;
-                       default:
-                               return true;
-                }
-       },
-
-       _doKeyUp: function(event) {
-               switch(event.keyCode) {
-                       case 38: // Up
-                       case 40: // Down
-                               break;
-                       case 13: // Enter
-                               this._loadResult();
-                               return false;
-                       case 27: // Escape
-                               this.element.blur();
-                               this.closeTable();
-                               return true;
-                       default: // Other keys
-                               return true;
-               }
-       },
-
-       _doInput: function(event) {
-               Utils.delayEvent($.proxy(this.search, this));
-       },
-
-       /* Result lookup */
-
-       _getResults: function(query) {
-               var results = {};
-               results.matches = [];
-               for(var entry in this.options.list) {
-                       if(!entry.startsWith(query, true)) {
-                               continue;
-                       }
-                       var cat = {
-                               name: entry,
-                               entries: this.options.list[entry]
-                       };
-                       results.matches[results.matches.length] = cat;
-
-                       if(entry == query) {
-                               cat.rank = 3;
-                       } else if(entry.toUpperCase() == query.toUpperCase()) {
-                               cat.rank = 2;
-                       } else {
-                               cat.rank = 1 + query.dice(entry);
-                       }
-               }
-               results.matches.sort(this._rankSorter);
-               results.partials = new Array();
-               if(results.matches.length == 0) {
-                       for(var entry in this.options.list) {
-                               var cat = {
-                                       name: entry,
-                                       entries: this.options.list[entry]
-                               }
-                               cat.rank = query.dice(entry);
-                               if(cat.rank > 0) {
-                                       results.partials[results.partials.length] = cat;
-                               }
-                       }
-                       results.partials.sort(this._rankSorter);
-               }
-               return results;
-       },
-
-       _rankSorter: function(a, b){
-               if(a.rank < b.rank) {
-                       return 1;
-               } else if(a.rank > b.rank) {
-                       return -1;
-               }
-               return 0;
-       },
-
-       /* Results table */
-
-       search: function() {
-               var query = this.element.val();
-               if(query) {
-                       var results = this._getResults(query);
-                       this.openTable(query, results);
-               }
-       },
-
-       openTable: function(query, results) {
-               this._table.empty();
-               this._rows = [];
-               this._index = -1;
-
-               var resultSet = results.matches;
-               if(resultSet.length == 0) {
-                       resultSet = results.partials
-               }
-
-               for(var i in resultSet) {
-                       var cat = resultSet[i];
-                       var result = cat.entries[0];
-                       this.addRow(cat.name, result.txt, result.url, this.options.rowCatClass)
-                       for(var j = 1; j < cat.entries.length; j++) {
-                               var result = cat.entries[j];
-                               this.addRow(cat.name, result.txt, result.url, this.options.rowSubClass)
-                       }
-               }
-
-               if(this._rows.length >= this.options.maxSize) {
-                       this.addOverflowUp();
-                       this.addOverflowDown();
-               }
-               if(results.matches.length == 0) {
-                       this.addNoResultRow();
-               }
-
-               if(resultSet.length > 0) {
-                       this._setIndex(0);
-               }
-               this._table.show();
-               this._autosizeTable();
-       },
-
-       closeTable: function(target) {
-               if(target != this.element && target != this._table) {
-                       this._table.hide();
-               }
-       },
-
-       addRow: function(name, txt, url, cls) {
-               var row = $("<tr/>")
-                       .addClass(this.options.rowClass)
-                       .data("searchDetails", {name: name, url: url})
-                       .data("index", this._rows.length)
-                       .append(
-                               $("<td/>")
-                                       .html(name)
-                                       .addClass(cls)
-                       )
-                       .append(
-                               $("<td/>")
-                                       .html(txt + "&nbsp;&raquo;")
-                                       .addClass(this.options.infoClass)
-                       )
-                       .mouseover($.proxy(this._mouseOverRow, this))
-                       .click($.proxy(this._clickRow, this))
-               this._rows.push(row);
-               if(this._rows.length >= this.options.maxSize) {
-                       row.hide();
-               }
-               this._table.append(row);
-       },
-
-       addOverflowUp: function() {
-               this._table.prepend(
-                       $("<tr/>")
-                               .addClass(this.options.rowOverflowClass)
-                               .append(
-                                       $("<td/>")
-                                               .attr("colspan", 2)
-                                               .html(this.options.overflowUpHtml)
-                               )
-                               .click($.proxy(this._clickPrev, this))
-               );
-       },
-
-       addOverflowDown: function() {
-               this._table.append(
-                       $("<tr/>")
-                               .addClass(this.options.rowOverflowClass)
-                               .addClass(this.options.rowOverflowActive)
-                               .append(
-                                       $("<td/>")
-                                               .attr("colspan", 2)
-                                               .html(this.options.overflowDownHtml)
-                               )
-                               .click($.proxy(this._clickNext, this))
-               );
-       },
-
-       addNoResultRow: function() {
-               this._table.prepend(
-                       $("<tr/>")
-                       .addClass(this.options.rowNoResultClass)
-                       .append(
-                               $("<td/>")
-                               .attr("colspan", "2")
-                               .text(this.options.noresultText)
-                       )
-               );
-       },
-
-       _autosizeTable: function() {
-               this._table.position({
-                       my: "right top",
-                       at: "right bottom",
-                       of: this.element
-               });
-       },
-
-       _hasIndex: function(index) {
-               return index >= 0 && index < this._rows.length;
-       },
-
-       _hasPrev: function(index) {
-               return index - 1 >= 0;
-       },
-
-       _hasNext: function(index) {
-               return index + 1 < this._rows.length;
-       },
-
-       _setIndex: function(index) {
-               if(this._hasIndex(this._index)) {
-                       this._rows[this._index].removeClass(this.options.rowActiveClass);
-               }
-               this._index = index;
-               if(this._hasIndex(this._index)) {
-                       this._rows[this._index].addClass(this.options.rowActiveClass);
-               }
-       },
-
-       _selectPrev: function() {
-               if(this._hasPrev(this._index)) {
-                       this._setIndex(this._index - 1);
-                       if(!this._rows[this._index].is(":visible")) {
-                               this._table.find("tr." + this.options.rowClass + ":visible").last().hide();
-                               this._table.find("tr." + this.options.rowOverflowClass).addClass(this.options.rowOverflowActive);
-                               this._rows[this._index].show();
-                               if(!this._hasPrev(this._index)) {
-                                       this._table.find("tr." + this.options.rowOverflowClass).removeClass(this.options.rowOverflowActive);
-                               }
-                               this._autosizeTable();
-                       }
-               }
-       },
-
-       _selectNext: function() {
-               if(this._hasNext(this._index)) {
-                       this._setIndex(this._index + 1);
-                       if(!this._rows[this._index].is(":visible")) {
-                               this._table.find("tr." + this.options.rowClass + ":visible").first().hide();
-                               this._table.find("tr." + this.options.rowOverflowClass).addClass(this.options.rowOverflowActive);
-                               this._rows[this._index].show();
-                               if(!this._hasNext(this._index)) {
-                                       this._table.find("tr." + this.options.rowOverflowClass).removeClass(this.options.rowOverflowActive);
-                               }
-                               this._autosizeTable();
-                       }
-               }
-       },
-
-       // Load selected search result page
-       _loadResult: function() {
-               if(this._index > -1) {
-                       window.location = this._rows[this._index].data("searchDetails").url;
-                       return;
-               }
-               if(this.element.val().length == 0) { return; }
-
-               window.location = this.options.gotoPage + "#q=" + this.element.val();
-               if(window.location.href.indexOf(this.options.gotoPage) > -1) {
-                       location.reload();
-               }
-       },
-
-       /* table events */
-
-       _clickNext: function(event) {
-               event.stopPropagation();
-               this._selectNext();
-       },
-
-       _clickPrev: function(event) {
-               event.stopPropagation();
-               this._selectPrev();
-       },
-
-       _clickRow: function(event) {
-               window.location = $(event.currentTarget).data("searchDetails")["url"];
-       },
-
-       _mouseOverRow: function(event) {
-               this._setIndex($(event.currentTarget).data("index"));
-       }
-});
-
-var searchField = $("<input/>")
-.addClass("form-control input-sm")
-.attr({
-       id: "nitdoc-qs-field",
-       type: "text",
-       placeholder: "Search..."
-})
-
-$("#topmenu-collapse").append(
-       $("<div>")
-       .addClass("navbar-form navbar-right")
-       .append(
-               $("<div>")
-               .addClass("form-group")
-               .append(searchField)
-       )
-);
-
-searchField.quicksearch({
-       list: this.nitdocQuickSearchRawList
-});
diff --git a/share/nitdoc/resources/icons/github-icon-green.png b/share/nitdoc/resources/icons/github-icon-green.png
deleted file mode 100644 (file)
index d291056..0000000
Binary files a/share/nitdoc/resources/icons/github-icon-green.png and /dev/null differ
diff --git a/share/nitdoc/resources/icons/github-icon-white.png b/share/nitdoc/resources/icons/github-icon-white.png
deleted file mode 100644 (file)
index 98ae072..0000000
Binary files a/share/nitdoc/resources/icons/github-icon-white.png and /dev/null differ
diff --git a/share/nitdoc/resources/icons/github-icon.png b/share/nitdoc/resources/icons/github-icon.png
deleted file mode 100644 (file)
index 8b25551..0000000
Binary files a/share/nitdoc/resources/icons/github-icon.png and /dev/null differ
index 9b295be..34ec170 100644 (file)
@@ -17,6 +17,7 @@
        <div class='card-body' ng-if='mentity.class_name != "MPackage"'>
                <h5 class='card-heading'>
                        <entity-signature mentity='mentity' />
+                       <small><br/><entity-namespace namespace='mentity.namespace' /></small>
                </h5>
                <span class='synopsis' ng-bind-html='mentity.html_synopsis' />
        </div>
index a4d06a6..949a6e3 100644 (file)
@@ -9,7 +9,7 @@
                <entity-card ng-click='vm.selectEnter()' ng-class='{active: vm.activeItem == $index}' ng-mouseover='vm.setActive($index)' mentity='mentity' ng-repeat='mentity in vm.results.results' />
                <div class='card' ng-click='vm.selectEnter()' ng-mouseover='vm.setActive(vm.results.results.length)' ng-class='{active: vm.activeItem == vm.results.results.length}'>
                        <div class='card-body'>
-                               Show all {{vm.results.total}} results for <a>"{{vm.query}}"</a>
+                               Show all {{vm.results.count}} results for <a>"{{vm.query}}"</a>
                        </div>
                </div>
        </div>
index 433b73d..54d9471 100644 (file)
@@ -13,7 +13,7 @@
 <br><br>
 <div class='container'>
        <div ng-if='vm.maintaining.results.length > 0'>
-               <h3 id='maintaining'>{{vm.maintaining.total}} maintained projects</h3>
+               <h3 id='maintaining'>{{vm.maintaining.count}} maintained projects</h3>
                <div class='card-list'>
                        <entity-card mentity='package' ng-repeat='package in vm.maintaining.results' />
                </div>
@@ -22,7 +22,7 @@
                </div>
        </div>
        <div ng-if='vm.contributing.results.length > 0'>
-               <h3 id='contributing'>{{vm.contributing.total}} contributed projects</h3>
+               <h3 id='contributing'>{{vm.contributing.count}} contributed projects</h3>
                <div class='card-list'>
                        <entity-card mentity='package' ng-repeat='package in vm.contributing.results' />
                </div>
index 6614e9c..ddf9f4c 100644 (file)
@@ -1,6 +1,6 @@
 <div class='container'>
        <h2>
-               {{vm.entities.total}} matches for
+               {{vm.entities.count}} matches for
                <a ui-sref='search({q: vm.query})'>{{vm.query}}</a>
        </h2>
        <div class='card-list'>
index dd891ac..6a12238 100644 (file)
@@ -586,6 +586,20 @@ class CatalogStats
 
        # Number of line of codes
        var loc = 0
+
+       # Return the stats as a Map associating each stat key to its value
+       fun to_map: Map[String, Int] do
+               var map = new HashMap[String, Int]
+               map["packages"] = packages
+               map["maintainers"] = maintainers
+               map["contributors"] = contributors
+               map["tags"] = tags
+               map["modules"] = modules
+               map["classes"] = classes
+               map["methods"] = methods
+               map["loc"] = loc
+               return map
+       end
 end
 
 # MPackage statistics for the catalog
index 9b84a35..4c3db90 100644 (file)
@@ -225,6 +225,10 @@ redef class MVirtualType
        redef var api_url = mproperty.api_url is lazy
 end
 
+redef class HtmlightVisitor
+       redef fun hrefto(mentity) do return mentity.html_url
+end
+
 redef class CmdLicenseFile
        redef var file_url is lazy do
                var mentity = self.mentity
index ffb530d..abf5d7d 100644 (file)
@@ -369,7 +369,7 @@ end
 class CmdRedefs
        super CmdInheritance
 
-       redef fun init_command do
+       redef fun init_results do
                if results != null then return new CmdSuccess
 
                var res = super
@@ -377,10 +377,10 @@ class CmdRedefs
                var mentity = self.mentity.as(not null)
 
                if mentity isa MModule then
-                       var mentities = mentity.collect_redef_mclasses(filter).to_a
+                       var mentities = mentity.collect_redef_mclassdefs(filter).to_a
                        self.results = mentities
                else if mentity isa MClass then
-                       var mentities = mentity.collect_redef_mproperties(filter).to_a
+                       var mentities = mentity.collect_redef_mpropdefs(filter).to_a
                        self.results = mentities
                else if mentity isa MClassDef then
                        var mentities = mentity.collect_redef_mpropdefs(filter).to_a
diff --git a/src/doc/doc_base.nit b/src/doc/doc_base.nit
deleted file mode 100644 (file)
index 98362ce..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-# 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.
-
-# Base entities shared by all the nitdoc code.
-module doc_base
-
-import toolcontext
-import model_ext
-import model::model_collect
-
-# The model of a Nitdoc documentation.
-#
-# `DocModel` contains the list of the `DocPage` to be generated.
-#
-# The model is populated through `DocPhase` to be constructed.
-# It is a placeholder to share data between each phase.
-class DocModel
-
-       # Model to generate the documentation for
-       var model: Model
-
-       # Main module of the sources behing documented
-       var mainmodule: MModule
-
-       # Model filters to apply
-       var filter: ModelFilter
-
-       # `DocPage` composing the documentation associated to their ids.
-       #
-       # This is where `DocPhase` store and access pages to produce documentation.
-       #
-       # See `add_page`.
-       var pages: Map[String, DocPage] = new HashMap[String, DocPage]
-
-       # Add a `page` to this documentation.
-       fun add_page(page: DocPage) do
-               if pages.has_key(page.id) then
-                       print "Warning: multiple page with the same id `{page.id}`"
-               end
-               pages[page.id] = page
-       end
-end
-
-# A documentation page abstraction.
-#
-# The page contains a link to the `root` of the `DocComposite` that compose the
-# the page.
-class DocPage
-
-       # Page uniq id.
-       #
-       # The `id` is used as name for the generated file corresponding to the page
-       # (if any).
-       # Because multiple pages can be generated in the same directory it should be
-       # uniq.
-       #
-       # The `id` can also be used to establish links between pages (HTML links,
-       # HTML anchors, vim links, etc.).
-       var id: String is writable
-
-       # Title of this page.
-       var title: String is writable
-
-       # Root element of the page.
-       #
-       # `DocPhase` access the structure of the page from the `DocRoot`.
-       var root = new DocRoot
-
-       redef fun to_s do return title
-
-       # Pretty prints the content of this page.
-       fun pretty_print: Writable do
-               var res = new Template
-               res.addn "{class_name} {title}"
-               for child in root.children do
-                       child.pretty_print_in(res)
-               end
-               return res
-       end
-end
-
-# `DocPage` elements that can be nested in another.
-#
-# `DocComposite` is an abstraction for everything that go in a `DocPage` like
-# sections, articles, images, lists, graphs...
-#
-# It provides base services for nesting mechanisms following the
-# *Composite pattern*.
-# The composed structure is a tree from a `DocRoot` that can be manipulated
-# recursively.
-abstract class DocComposite
-
-       # Parent element.
-       var parent: nullable DocComposite = null is writable
-
-       # Element uniq id.
-       #
-       # The `id` is used as name for the generated element (if any).
-       # Because multiple elements can be generated in the same container
-       # it should be uniq.
-       #
-       # The `id` can also be used to establish links between elements
-       # (HTML links, HTML anchors, vim links, etc.).
-       var id: String is writable
-
-       # Item title if any.
-       var title: nullable String is writable
-
-       # Does `self` have a `parent`?
-       fun is_root: Bool do return parent == null
-
-       # Children elements contained in `self`.
-       #
-       # Children are ordered, this order can be changed by the `DocPhase`.
-       var children = new Array[DocComposite]
-
-       # Is `self` not displayed in the page.
-       #
-       # By default, empty elements are hidden.
-       fun is_hidden: Bool do return children.is_empty
-
-       # Title used in table of content if any.
-       var toc_title: nullable String is writable, lazy do return title
-
-       # Is `self` hidden in the table of content?
-       var is_toc_hidden: Bool is writable, lazy do
-               return toc_title == null or is_hidden
-       end
-
-       # Add a `child` to `self`.
-       #
-       # Shortcut for `children.add`.
-       fun add_child(child: DocComposite) do
-               child.parent = self
-               children.add child
-       end
-
-       # Depth of `self` in the composite tree.
-       fun depth: Int do
-               var parent = self.parent
-               if parent == null then return 0
-               return parent.depth + 1
-       end
-
-       # Pretty prints this composite recursively.
-       fun pretty_print: Writable do
-               var res = new Template
-               pretty_print_in(res)
-               return res
-       end
-
-       # Appends the Pretty print of this composite in `res`.
-       private fun pretty_print_in(res: Template) do
-               res.add "\t" * depth
-               res.add "#" * depth
-               res.addn " {id}"
-               for child in children do child.pretty_print_in(res)
-       end
-end
-
-# The `DocComposite` element that contains all the other.
-#
-# The root uses a specific subclass to provide different a different behavior
-# than other `DocComposite` elements.
-class DocRoot
-       noautoinit
-       super DocComposite
-
-       redef var id = "<root>"
-       redef var title = "<root>"
-
-       # No op for `RootSection`.
-       redef fun parent=(p) do end
-end
-
-# Base page elements.
-
-# `DocSection` are used to break the documentation page into meaningfull parts.
-#
-# The content of the documentation summary is based on the section structure
-# contained in the DocComposite tree.
-class DocSection
-       super DocComposite
-end
-
-# `DocArticle` are pieces of documentation.
-#
-# They maintains the content (text, list, image...) of a documentation page.
-class DocArticle
-       super DocComposite
-end
-
-# A DocPhase is a step in the production of a Nitdoc documentation.
-#
-# Phases work from a `DocModel`.
-# Specific phases are used to populate, organize, enhance and render the content
-# of the documentation pages.
-#
-# See `doc_phases` for available DocPhase.
-class DocPhase
-
-       # Link to the ToolContext to access Nitdoc tool options.
-       var ctx: ToolContext
-
-       # `DocModel` used by this phase to work.
-       var doc: DocModel
-
-       # Starting point of a `DocPhase`.
-       #
-       # This is where the behavior of the phase is implemented.
-       # Phases can populate, edit or render the `doc` from here.
-       fun apply is abstract
-end
-
-redef class ToolContext
-
-       # Directory where the Nitdoc is rendered.
-       var opt_dir = new OptionString("Output directory", "-d", "--dir")
-
-       # Shortcut for `opt_dir.value` with default "doc".
-       var output_dir: String is lazy do return opt_dir.value or else "doc"
-
-       redef init do
-               super
-               option_context.add_option(opt_dir)
-       end
-end
-
-# Catalog properties by kind.
-class PropertiesByKind
-       # The virtual types.
-       var virtual_types = new PropertyGroup[MVirtualTypeProp]("Virtual types")
-
-       # The constructors.
-       var constructors = new PropertyGroup[MMethod]("Contructors")
-
-       # The attributes.
-       var attributes = new PropertyGroup[MAttribute]("Attributes")
-
-       # The methods.
-       var methods = new PropertyGroup[MMethod]("Methods")
-
-       # The inner classes.
-       var inner_classes = new PropertyGroup[MInnerClass]("Inner classes")
-
-       # All the groups.
-       #
-       # Sorted in the order they are displayed to the user.
-       var groups: SequenceRead[PropertyGroup[MProperty]] = [
-                       virtual_types,
-                       constructors,
-                       attributes,
-                       methods,
-                       inner_classes: PropertyGroup[MProperty]]
-
-       # Add each the specified property to the appropriate list.
-       init with_elements(properties: Collection[MProperty]) do add_all(properties)
-
-       # Add the specified property to the appropriate list.
-       fun add(property: MProperty) do
-               if property isa MMethod then
-                       if property.is_init then
-                               constructors.add property
-                       else
-                               methods.add property
-                       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
-                       abort
-               end
-       end
-
-       # Add each the specified property to the appropriate list.
-       fun add_all(properties: Collection[MProperty]) do
-               for p in properties do add(p)
-       end
-
-       # Sort each group with the specified comparator.
-       fun sort_groups(comparator: Comparator) do
-               for g in groups do comparator.sort(g)
-       end
-end
-
-# An ordered list of properties of the same kind.
-class PropertyGroup[E: MProperty]
-       super Array[E]
-
-       # The title of the group, as displayed to the user.
-       var title: String
-end
-
-redef class MEntity
-       # ID used as a unique ID and in file names.
-       #
-       # **Must** match the following (POSIX ERE) regular expression:
-       #
-       # ~~~POSIX ERE
-       # ^[A-Za-z_][A-Za-z0-9._-]*$
-       # ~~~
-       #
-       # That way, the ID is always a valid URI component and a valid XML name.
-       fun nitdoc_id: String do return full_name.to_cmangle
-
-       # Name displayed in console for debug and tests.
-       fun nitdoc_name: String do return name.html_escape
-end
-
-redef class MModule
-
-       # Avoid id conflict with group
-       redef fun nitdoc_id do
-               var mgroup = self.mgroup
-               if mgroup == null then return super
-               return "{mgroup.full_name}::{full_name}".to_cmangle
-       end
-end
-
-redef class MClassDef
-       redef fun nitdoc_name do return mclass.nitdoc_name
-end
-
-redef class MPropDef
-       redef fun nitdoc_name do return mproperty.nitdoc_name
-end
diff --git a/src/doc/doc_commands.nit b/src/doc/doc_commands.nit
deleted file mode 100644 (file)
index 208738b..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-# 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.
-
-# Parsing of commands understood by documentation tools.
-#
-# This can be through:
-# * `nitx` commands like `code: MEntity::name`
-# * `nitdoc` wikilinks like `[[doc: MEntity::name]]`
-module doc_commands
-
-#
-class DocCommandParser
-
-       # List of allowed command names for this parser
-       var allowed_commands: Array[String] = [ "doc", "list", "param", "return",
-               "new", "call", "code", "graph"] is writable
-
-       # Parse `string` as a DocCommand
-       #
-       # Returns `null` if the string cannot be parsed.
-       #
-       # ~~~
-       # var parser = new DocCommandParser
-       #
-       # var command = parser.parse("doc: core::Array")
-       # assert command isa CommentCommand
-       # assert command.arg == "core::Array"
-       #
-       # command = parser.parse(":") # syntax error
-       # assert command == null
-       # assert parser.errors.not_empty
-       # ~~~
-       fun parse(string: String): nullable DocCommand do
-               var pos = 0
-               var tmp = new FlatBuffer
-               errors.clear
-
-               # Parse command name
-               pos = string.read_until(tmp, pos, ':')
-               var name = tmp.write_to_string.trim
-
-               # Check allowed commands
-               if name.is_empty then
-                       error("empty command name", 0)
-                       return null
-               end
-               if not allowed_commands.has(name) then
-                       error("unknown command name", 0)
-                       return null
-               end
-
-               # Build the command
-               var command = new_command(name, string)
-               if command == null then
-                       error("unknown command name", 0)
-                       return null
-               end
-
-               # Parse the argument
-               tmp.clear
-               pos = string.read_until(tmp, pos + 1, '|')
-               var arg = tmp.write_to_string.trim
-               if arg.is_empty then
-                       error("empty command arg", pos)
-                       return null
-               end
-               command.arg = arg
-
-               # Parse command options
-               while pos < string.length do
-                       # Parse option name
-                       tmp.clear
-                       pos = string.read_until(tmp, pos + 1, ':', ',')
-                       var oname = tmp.write_to_string.trim
-                       var oval = ""
-                       if oname.is_empty then break
-                       # Parse option value
-                       if pos < string.length and string[pos] == ':' then
-                               tmp.clear
-                               pos = string.read_until(tmp, pos + 1, ',')
-                               oval = tmp.write_to_string.trim
-                       end
-                       command.opts[oname] = oval
-                       # TODO Check options
-               end
-
-               return command
-       end
-
-       # Init a new DocCommand from its `name`
-       #
-       # You must redefine this method to add new custom commands.
-       fun new_command(name, string: String): nullable DocCommand do
-               if name == "doc" then return new CommentCommand(string)
-               if name == "list" then return new ListCommand(string)
-               if name == "param" then return new ParamCommand(string)
-               if name == "return" then return new ReturnCommand(string)
-               if name == "new" then return new NewCommand(string)
-               if name == "call" then return new CallCommand(string)
-               if name == "code" then return new CodeCommand(string)
-               if name == "graph" then return new GraphCommand(string)
-               return null
-       end
-
-       # Errors and warnings from last call to `parse`
-       var errors = new Array[DocMessage]
-
-       # Generate an error
-       fun error(message: String, col: nullable Int) do
-               errors.add new DocMessage(1, message, col)
-       end
-
-       # Generate a warning
-       fun warning(message: String, col: nullable Int) do
-               errors.add new DocMessage(2, message, col)
-       end
-end
-
-# A message generated by the DocCommandParser
-class DocMessage
-
-       # Message severity
-       #
-       # 1- Error
-       # 2- Warning
-       var level: Int
-
-       # Message explanatory string
-       var message: String
-
-       # Related column in original string if any
-       var col: nullable Int
-
-       redef fun to_s do
-               var str = new FlatBuffer
-               if level == 1 then
-                       str.append "Error: "
-               else
-                       str.append "Warning: "
-               end
-               str.append message
-               var col = self.col
-               if col != null then
-                       str.append " (col: {col})"
-               end
-               return str.write_to_string
-       end
-end
-
-redef class Text
-       # Read `self` as raw text until `nend` and append it to the `out` buffer.
-       private fun read_until(out: FlatBuffer, start: Int, nend: Char...): Int do
-               var pos = start
-               while pos < length do
-                       var c = self[pos]
-                       var end_reached = false
-                       for n in nend do
-                               if c == n then
-                                       end_reached = true
-                                       break
-                               end
-                       end
-                       if end_reached then break
-                       out.add c
-                       pos += 1
-               end
-               return pos
-       end
-end
-
-# A command aimed at a documentation tool like `nitdoc` or `nitx`.
-#
-# `DocCommand` are generally of the form `command: arg | opt1: val1, opt2: val2`.
-abstract class DocCommand
-
-       # Original command string.
-       var string: String
-
-       # Command name.
-       var name: String is noinit
-
-       # Command arguments.
-       var arg: String is noinit, writable
-
-       # Command options.
-       var opts = new HashMap[String, String] is writable
-
-       redef fun to_s do
-               if opts.is_empty then
-                       return "{name}: {arg}"
-               end
-               return "{name}: {arg} | {opts.join(", ", ": ")}"
-       end
-end
-
-# A `DocCommand` that includes the documentation article of a `MEntity`.
-#
-# Syntax: `doc: MEntity::name`.
-class CommentCommand
-       super DocCommand
-
-       redef var name = "doc"
-end
-
-# A `DocCommand` that includes a list of something.
-#
-# Syntax: `list:kind: <arg>`.
-class ListCommand
-       super DocCommand
-
-       redef var name = "list"
-end
-
-# A `DocCommand` that includes the list of methods tanking a `MType` as parameter.
-#
-# Syntax: `param: MType`.
-class ParamCommand
-       super DocCommand
-
-       redef var name = "param"
-end
-
-# A `DocCommand` that includes the list of methods returning a `MType` as parameter.
-#
-# Syntax: `return: MType`.
-class ReturnCommand
-       super DocCommand
-
-       redef var name = "return"
-end
-
-# A `DocCommand` that includes the list of methods creating new instances of a specific `MType`
-#
-# Syntax: `new: MType`.
-class NewCommand
-       super DocCommand
-
-       redef var name = "new"
-end
-
-# A `DocCommand` that includes the list of methods calling a specific `MProperty`.
-#
-# Syntax: `call: MEntity::name`.
-class CallCommand
-       super DocCommand
-
-       redef var name = "call"
-end
-
-# A `DocCommand` that includes the source code of a `MEntity`.
-#
-# Syntax:
-# * `code: MEntity::name`
-# * `./src/file.nit` to include source code from a file.
-# * `./src/file.nit:1,2--3,4` to select code between positions.
-class CodeCommand
-       super DocCommand
-
-       redef var name = "code"
-end
-
-# A `DocCommand` that display an graph for a `MEntity`.
-#
-# Syntax:
-# * `graph: MEntity::name`
-class GraphCommand
-       super DocCommand
-
-       redef var name = "graph"
-end
index 7bb330b..f02b1fd 100644 (file)
@@ -204,6 +204,14 @@ private class InlineDecorator
        end
 
        redef fun add_headline(v, block) do
+               # save headline
+               var line = block.block.first_line
+               if line == null then return
+               var txt = line.value
+               var id = strip_id(txt)
+               var lvl = block.depth
+               headlines[id] = new HeadLine(id, txt, lvl)
+
                v.emit_in block
        end
 
diff --git a/src/doc/doc_phases/doc_concerns.nit b/src/doc/doc_phases/doc_concerns.nit
deleted file mode 100644 (file)
index a61233f..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-# 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.
-
-# Concerns computation.
-module doc_concerns
-
-import doc_pages
-import model::model_collect
-
-# ConcernsPhase computes the ConcernsTree used for each page layout.
-class ConcernsPhase
-       super DocPhase
-
-       # Populates the given DocModel.
-       redef fun apply do
-               for page in doc.pages.values do page.build_concerns(self)
-       end
-end
-
-redef class DocPage
-
-       # Build the `concerns` tree for this page.
-       #
-       # Since only `MEntityPage`, this method is a no-op for everything else.
-       private fun build_concerns(v: ConcernsPhase) do end
-end
-
-redef class MEntityPage
-
-       # Concerns to display in this page.
-       var concerns: nullable ConcernsTree = null
-end
-
-# TODO ConcernsTrees are a PITA, following redef should not be needed here...
-# The bad, so baaaadddd, ConcernsTree interface induces a lot of useless code
-# in all phases.
-
-redef class MGroupPage
-
-       # Introduced classes in `mentity` that should appear in this page.
-       var intros = new HashSet[MClass]
-
-       # Refined classes in `mentity` that should appear in this page.
-       var redefs = new HashSet[MClass]
-
-       redef fun build_concerns(v) do
-               var doc = v.doc
-               var mmodules = new HashSet[MModule]
-               for mmodule in mentity.mmodules do
-                       if doc.filter.accept_mentity(mmodule) then mmodules.add mmodule
-                       # collect mclasses
-                       for mclass in mmodule.intro_mclasses do
-                               if doc.filter.accept_mentity(mclass) then intros.add mclass
-                       end
-                       for mclass in mmodule.collect_redef_mclasses(doc.filter) do
-                               if doc.filter.accept_mentity(mclass) then redefs.add mclass
-                       end
-               end
-               concerns = doc.model.concerns_tree(mmodules)
-       end
-end
-
-redef class MModulePage
-
-       # MClasses defined in `mentity` to display in this page.
-       var mclasses = new HashSet[MClass]
-
-       # MClassDefs located in `mentity` to display in this page.
-       var mclassdefs = new HashSet[MClassDef]
-
-       redef fun build_concerns(v) do
-               var doc = v.doc
-               # extract mclassdefs in mmodule
-               for mclassdef in mentity.mclassdefs do
-                       if doc.filter.accept_mentity(mclassdef) then mclassdefs.add mclassdef
-               end
-               # extract mclasses in mmodule
-               for mclassdef in mclassdefs do
-                       var mclass = mclassdef.mclass
-                       if doc.filter.accept_mentity(mclass) then mclasses.add mclass
-               end
-               # extract concerns
-               var mods = new HashSet[MModule]
-               for mclass in mclasses do
-                       var mod = mclass.intro_mmodule
-                       if doc.filter.accept_mentity(mod) then mods.add mod
-               end
-               concerns = doc.model.concerns_tree(mods)
-       end
-end
-
-redef class MClassPage
-
-       # MClassDefs to display in this page.
-       var mclassdefs = new HashSet[MClassDef]
-
-       # MPropdefs to display in this page.
-       var mpropdefs = new HashSet[MPropDef]
-
-       redef fun build_concerns(v) do
-               var doc = v.doc
-               # collect mclassdefs
-               for mclassdef in mentity.mclassdefs do
-                       if doc.filter.accept_mentity(mclassdef) then mclassdefs.add mclassdef
-               end
-               # collect mpropdefs
-               for mclassdef in mclassdefs do
-                       for mpropdef in mclassdef.mpropdefs do
-                               if doc.filter.accept_mentity(mpropdef) then mpropdefs.add mpropdef
-                       end
-               end
-               # collect concerns
-               var mods = new HashSet[MModule]
-               for mpropdef in mpropdefs do
-                       var mod = mpropdef.mclassdef.mmodule
-                       if doc.filter.accept_mentity(mod) then mods.add mod
-               end
-               concerns = doc.model.concerns_tree(mods)
-       end
-end
-
-redef class MPropertyPage
-
-       # MPropdefs to display in this page.
-       var mpropdefs = new HashSet[MPropDef]
-
-       redef fun build_concerns(v) do
-               var doc = v.doc
-               # collect mpropdefs
-               for mpropdef in mentity.mpropdefs do
-                       # FIXME diff hack
-                       if mpropdef.is_intro then continue
-                       if doc.filter.accept_mentity(mpropdef) then mpropdefs.add mpropdef
-               end
-               # collect concerns
-               var mods = new HashSet[MModule]
-               for mpropdef in mpropdefs do
-                       var mod = mpropdef.mclassdef.mmodule
-                       if doc.filter.accept_mentity(mod) then mods.add mod
-               end
-               concerns = doc.model.concerns_tree(mods)
-       end
-end
diff --git a/src/doc/doc_phases/doc_graphs.nit b/src/doc/doc_phases/doc_graphs.nit
deleted file mode 100644 (file)
index c559e80..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-# 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.
-
-# Adds importation and class hierarchy graphs.
-module doc_graphs
-
-import doc_structure
-import doc_poset
-import html_templates::html_model # FIXME maybe this phase should depend on `html_render`
-
-redef class ToolContext
-
-       # Do not generate `graphviz` diagrams.
-       var opt_nodot = new OptionBool("Do not generate graphs with graphviz", "--no-dot")
-
-       redef init do
-               super
-               option_context.add_option(opt_nodot)
-       end
-end
-
-# This phase insert importation and inheritance graphs into pages.
-class GraphPhase
-       super DocPhase
-
-       redef fun apply do
-               if ctx.opt_nodot.value then return
-               for page in doc.pages.values do
-                       var article = page.build_graph(self, doc)
-                       if article == null then continue
-                       # FIXME avoid diff
-                       # page.root.add article
-                       article.parent = page.root.children.first.children[1]
-                       page.root.children.first.children[1].children.insert(article, 0)
-               end
-       end
-end
-
-redef class DocPage
-       # Build dot graph articles from `mmodules` list.
-       #
-       # Since only `MEntity pages` contain a graph, this method returns null in all
-       # other cases.
-       private fun build_graph(v: GraphPhase, doc: DocModel): nullable GraphArticle do return null
-end
-
-# TODO graph generation can be factorized in POSet.
-
-redef class MModulePage
-       redef fun build_graph(v, doc) do
-               var op = new FlatBuffer
-               var name = "dep_module_{mentity.nitdoc_id}"
-               op.append("digraph \"{name.escape_to_dot}\" \{ 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 mmodule in poset do
-                       if mmodule == self.mentity then
-                               op.append("\"{mmodule.name.escape_to_dot}\"[shape=box,margin=0.03];\n")
-                       else
-                               op.append("\"{mmodule.name.escape_to_dot}\"[URL=\"{mmodule.nitdoc_url.escape_to_dot}\"];\n")
-                       end
-                       for omodule in poset[mmodule].direct_greaters do
-                               op.append("\"{mmodule.name.escape_to_dot}\"->\"{omodule.name.escape_to_dot}\";\n")
-                       end
-               end
-               op.append("\}\n")
-               return new GraphArticle("{mentity.nitdoc_id}.graph", "Importation Graph", name, op)
-       end
-end
-
-redef class MClassPage
-       redef fun build_graph(v, doc) do
-               var op = new FlatBuffer
-               var name = "dep_class_{mentity.nitdoc_id}"
-               op.append("digraph \"{name.escape_to_dot}\" \{ 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")
-               var classes = poset.to_a
-               var todo = new Array[MClass]
-               var done = new HashSet[MClass]
-               doc.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 == self.mentity then
-                               op.append("\"{c.name.escape_to_dot}\"[shape=box,margin=0.03];\n")
-                       else
-                               op.append("\"{c.name.escape_to_dot}\"[URL=\"{c.nitdoc_url.escape_to_dot}\"];\n")
-                       end
-                       var smallers = poset[c].direct_smallers
-                       if smallers.length < 10 then
-                               for c2 in smallers do
-                                       op.append("\"{c2.name.escape_to_dot}\"->\"{c.name.escape_to_dot}\";\n")
-                               end
-                               todo.add_all smallers
-                       else
-                               op.append("\"...\"->\"{c.name.escape_to_dot}\";\n")
-                       end
-               end
-               op.append("\}\n")
-               return new GraphArticle("{mentity.nitdoc_id}.graph", "Inheritance Graph", name, op)
-       end
-end
-
-# An article that display an importation or inheritance graph.
-#
-# The graph is stored in dot format.
-# The final output is delayed untill rendering.
-class GraphArticle
-       super DocArticle
-
-       # Graph ID (used for outputing file with names).
-       var graph_id: String
-
-       # Dot script of the graph.
-       var dot: Text
-
-       redef var is_hidden = false
-       redef var is_toc_hidden = true
-end
diff --git a/src/doc/doc_phases/doc_hierarchies.nit b/src/doc/doc_phases/doc_hierarchies.nit
deleted file mode 100644 (file)
index fa9de2d..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-# 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.
-
-# Computes importation and class hierarchy lists.
-module doc_hierarchies
-
-import doc_structure
-import doc_poset
-
-# Insert inheritance / importation lists in the page.
-class InheritanceListsPhase
-       super DocPhase
-
-       # Used to sort list by name.
-       var name_sorter = new MEntityNameSorter
-
-       redef fun apply do
-               for page in doc.pages.values do
-                       if page isa MEntityPage then page.build_inh_list(self, doc)
-               end
-       end
-end
-
-redef class MEntityPage
-
-       # Build importation / inheritance list for this page.
-       fun build_inh_list(v: InheritanceListsPhase, doc: DocModel) do end
-end
-
-redef class MModulePage
-       redef fun build_inh_list(v, doc) do
-               var id = mentity.nitdoc_id
-               var section = new TabbedGroup("{id}.importation", "Dependencies")
-               var group = new PanelGroup("list.group", "List")
-               var imports = self.imports.to_a
-               v.name_sorter.sort(imports)
-               group.add_child new MEntitiesListArticle("{id}.imports", "Imports", imports)
-               var clients = self.clients.to_a
-               v.name_sorter.sort(clients)
-               group.add_child new MEntitiesListArticle("{id}.clients", "Clients", clients)
-               section.add_child group
-               section.parent = root.children.first
-               root.children.first.children.insert(section, 1)
-       end
-end
-
-redef class MClassPage
-       redef fun build_inh_list(v, doc) do
-               var id = mentity.nitdoc_id
-               var section = new TabbedGroup("{id}.inheritance", "Inheritance")
-               var group = new PanelGroup("list.group", "List")
-               var parents = self.parents.to_a
-               v.name_sorter.sort(parents)
-               group.add_child new MEntitiesListArticle("{id}.parents", "Parents", parents)
-               var ancestors = self.ancestors.to_a
-               v.name_sorter.sort(ancestors)
-               group.add_child new MEntitiesListArticle("{id}.ancestors", "Ancestors", ancestors)
-               var children = self.children.to_a
-               v.name_sorter.sort(children)
-               group.add_child new MEntitiesListArticle("{id}.children", "Children", children)
-               var descendants = self.descendants.to_a
-               v.name_sorter.sort(descendants)
-               group.add_child new MEntitiesListArticle("{id}.descendants", "Descendants", descendants)
-               section.add_child group
-               section.parent = root.children.first
-               root.children.first.children.insert(section, 1)
-       end
-end
diff --git a/src/doc/doc_phases/doc_html.nit b/src/doc/doc_phases/doc_html.nit
deleted file mode 100644 (file)
index 3f1a3e7..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-# 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.
-
-# Render the DocModel pages as HTML pages.
-#
-# FIXME this module is all f*cked up to maintain compatibility with
-# the original `doc_templates` and `doc_model` modules.
-# This will change in further refactorings.
-module doc_html
-
-import doc_structure
-import doc_hierarchies
-import doc_intros_redefs
-import doc_graphs
-import html_templates
-
-redef class ToolContext
-
-       # File pattern used to link documentation to source code.
-       var opt_source = new OptionString("Format to link source code (%f for filename, " +
-               "%l for first line, %L for last line)", "--source")
-
-       # Use a shareurl instead of copy shared files.
-       #
-       # This is usefull if you don't want to store the Nitdoc templates with your
-       # documentation.
-       var opt_shareurl = new OptionString("Use shareurl instead of copy shared files", "--shareurl")
-
-       # Use a custom title for the homepage.
-       var opt_custom_title = new OptionString("Custom title for homepage", "--custom-title")
-
-       # Display a custom brand or logo in the documentation top menu.
-       var opt_custom_brand = new OptionString("Custom link to external site", "--custom-brand")
-
-       # Display a custom introduction text before the packages overview.
-       var opt_custom_intro = new OptionString("Custom intro text for homepage", "--custom-overview-text")
-       # Display a custom footer on each documentation page.
-       #
-       # Generally used to display the documentation or product version.
-       var opt_custom_footer = new OptionString("Custom footer text", "--custom-footer-text")
-
-       # Piwik tracker URL.
-       #
-       # If you want to monitor your visitors.
-       var opt_piwik_tracker = new OptionString("Piwik tracker URL (ex: `nitlanguage.org/piwik/`)", "--piwik-tracker")
-
-       # Piwik tracker site id.
-       var opt_piwik_site_id = new OptionString("Piwik site ID", "--piwik-site-id")
-
-       # These options are not currently used in Nitdoc.
-
-       # FIXME redo the plugin
-       var opt_github_upstream = new OptionString("Git branch where edited commits will be pulled into (ex: user:repo:branch)", "--github-upstream")
-       # FIXME redo the plugin
-       var opt_github_base_sha1 = new OptionString("Git sha1 of base commit used to create pull request", "--github-base-sha1")
-       # FIXME redo the plugin
-       var opt_github_gitdir = new OptionString("Git working directory used to resolve path name (ex: /home/me/mypackage/)", "--github-gitdir")
-
-       # Do not produce HTML files
-       var opt_no_render = new OptionBool("Do not render HTML files", "--no-render")
-
-       redef init do
-               super
-
-               option_context.add_option(
-                       opt_source, opt_share_dir, opt_shareurl, opt_custom_title,
-                       opt_custom_footer, opt_custom_intro, opt_custom_brand,
-                       opt_github_upstream, opt_github_base_sha1, opt_github_gitdir,
-                       opt_piwik_tracker, opt_piwik_site_id,
-                       opt_no_render)
-       end
-
-       redef fun process_options(args) do
-               super
-               var upstream = opt_github_upstream
-               var base_sha = opt_github_base_sha1
-               var git_dir = opt_github_gitdir
-               var opts = [upstream.value, base_sha.value, git_dir.value]
-               if not opts.has_only(null) and opts.has(null) then
-                       print "Option Error: options {upstream.names.first}, " +
-                               "{base_sha.names.first} and {git_dir.names.first} " +
-                               "are required to enable the GitHub plugin"
-                       exit 1
-               end
-       end
-end
-
-# Render the Nitdoc as a HTML website.
-class RenderHTMLPhase
-       super DocPhase
-
-       # Used to sort sidebar elements by name.
-       var name_sorter = new MEntityNameSorter
-
-       redef fun apply do
-               if ctx.opt_no_render.value then return
-               init_output_dir
-               for page in doc.pages.values do
-                       page.render(self, doc).write_to_file("{ctx.output_dir.to_s}/{page.html_url}")
-               end
-       end
-
-       # Creates the output directory and imports assets files form `resources/`.
-       fun init_output_dir do
-               # 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 = ctx.share_dir / "nitdoc"
-               # copy shared files
-               if ctx.opt_shareurl.value == null then
-                       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.escape_to_sh}/resources/ {output_dir.to_s.escape_to_sh}/resources/")
-               end
-
-       end
-
-       # Returns a HTML link for a given `location`.
-       fun html_source_link(location: nullable Location): nullable String
-       do
-               if location == null then return null
-               var source = ctx.opt_source.value
-               if source == null then
-                       var url = location.file.filename.simplify_path
-                       return "<a target='_blank' title='Show source' href=\"{url.html_escape}\">View Source</a>"
-               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)
-               x = source.split_with("%l")
-               source = x.join(location.line_start.to_s)
-               x = source.split_with("%L")
-               source = x.join(location.line_end.to_s)
-               source = source.simplify_path
-               return "<a target='_blank' title='Show source' href=\"{source.to_s.html_escape}\">View Source</a>"
-       end
-end
-
-redef class DocPage
-
-       # Render the page as a html template.
-       private fun render(v: RenderHTMLPhase, doc: DocModel): Writable do
-               var shareurl = "."
-               if v.ctx.opt_shareurl.value != null then
-                       shareurl = v.ctx.opt_shareurl.value.as(not null)
-               end
-
-               # init page options
-               self.shareurl = shareurl
-               self.footer = v.ctx.opt_custom_footer.value
-               self.body_attrs.add(new TagAttribute("data-bootstrap-share", shareurl))
-
-               # build page
-               init_title(v, doc)
-               init_topmenu(v, doc)
-               init_content(v, doc)
-               init_sidebar(v, doc)
-
-               # piwik tracking
-               var tracker_url = v.ctx.opt_piwik_tracker.value
-               var site_id = v.ctx.opt_piwik_site_id.value
-               if tracker_url != null and site_id != null then
-                       self.scripts.add new TplPiwikScript(tracker_url, site_id)
-               end
-               return self
-       end
-
-       # FIXME diff hack
-       # all properties below are roughly copied from `doc_pages`
-
-       # Build page title string
-       fun init_title(v: RenderHTMLPhase, doc: DocModel) do end
-
-       # Build top menu template if any.
-       fun init_topmenu(v: RenderHTMLPhase, doc: DocModel) do
-               topmenu = new DocTopMenu
-               topmenu.brand = v.ctx.opt_custom_brand.value
-               var title = "Overview"
-               if v.ctx.opt_custom_title.value != null then
-                       title = v.ctx.opt_custom_title.value.to_s
-               end
-               topmenu.add_li new ListItem(new Link("index.html", title))
-               topmenu.add_li new ListItem(new Link("search.html", "Index"))
-               topmenu.active_item = topmenu.items.first
-       end
-
-       # Build page sidebar if any.
-       fun init_sidebar(v: RenderHTMLPhase, doc: DocModel) do
-               sidebar = new DocSideBar
-               sidebar.boxes.add new DocSideBox("Summary", html_toc)
-       end
-
-       # Build page content template.
-       fun init_content(v: RenderHTMLPhase, doc: DocModel) do
-               root.init_html_render(v, doc, self)
-       end
-end
-
-redef class OverviewPage
-       redef var html_url = "index.html"
-
-       redef fun init_title(v, doc) do
-               title = "Overview"
-               if v.ctx.opt_custom_title.value != null then
-                       title = v.ctx.opt_custom_title.value.to_s
-               end
-       end
-end
-
-redef class SearchPage
-       redef var html_url = "search.html"
-       redef fun init_title(v, doc) do title = "Index"
-
-       redef fun init_topmenu(v, doc) do
-               super
-               topmenu.active_item = topmenu.items.last
-       end
-
-       redef fun init_sidebar(v, doc) do end
-end
-
-redef class MEntityPage
-       redef var html_url is lazy do
-               if mentity isa MGroup and mentity.mdoc != null then
-                       return "api_{mentity.nitdoc_url}"
-               end
-               return mentity.nitdoc_url
-       end
-
-       redef fun init_title(v, doc) do title = mentity.html_name
-end
-
-# FIXME all clases below are roughly copied from `doc_pages` and adapted to new
-# doc phases. This is to preserve the compatibility with the current
-# `doc_templates` module.
-
-redef class ReadmePage
-       redef var html_url is lazy do return mentity.nitdoc_url
-
-       redef fun init_topmenu(v, doc) do
-               super
-               var mpackage = mentity.mpackage
-               if not mentity.is_root then
-                       topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
-               end
-               topmenu.add_li new ListItem(new Link(html_url, mpackage.html_name))
-               topmenu.active_item = topmenu.items.last
-       end
-
-       redef fun init_sidebar(v, doc) do
-               super
-               var api_lnk = """<a href="api_{{{mentity.nitdoc_url}}}">Go to API</a>"""
-               sidebar.boxes.unshift new DocSideBox(api_lnk, "")
-       end
-end
-
-redef class MGroupPage
-       redef fun init_topmenu(v, doc) do
-               super
-               var mpackage = mentity.mpackage
-               if not mentity.is_root then
-                       topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
-               end
-               topmenu.add_li new ListItem(new Link(html_url, mpackage.html_name))
-               topmenu.active_item = topmenu.items.last
-       end
-
-       redef fun init_sidebar(v, doc) do
-               super
-               # README link
-               if mentity.mdoc != null then
-                       var doc_lnk = """<a href="{{{mentity.nitdoc_url}}}">Go to README</a>"""
-                       sidebar.boxes.unshift new DocSideBox(doc_lnk, "")
-               end
-               # MClasses list
-               var mclasses = new HashSet[MClass]
-               mclasses.add_all intros
-               mclasses.add_all redefs
-               if mclasses.is_empty then return
-               var list = new UnorderedList
-               list.css_classes.add "list-unstyled list-labeled"
-               var sorted = mclasses.to_a
-               v.name_sorter.sort(sorted)
-               for mclass in sorted do
-                       list.add_li tpl_sidebar_item(mclass)
-               end
-               sidebar.boxes.add new DocSideBox("All classes", list)
-               sidebar.boxes.last.is_open = false
-       end
-
-       private fun tpl_sidebar_item(def: MClass): ListItem do
-               var classes = def.intro.css_classes
-               if intros.has(def) then
-                       classes.add "intro"
-               else
-                       classes.add "redef"
-               end
-               var lnk = new Template
-               lnk.add new DocHTMLLabel.with_classes(classes)
-               lnk.add def.html_link
-               return new ListItem(lnk)
-       end
-end
-
-redef class MModulePage
-       redef fun init_topmenu(v, doc) do
-               super
-               var mpackage = mentity.mpackage
-               if mpackage != null then
-                       topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
-               end
-               topmenu.add_li new ListItem(new Link(mentity.nitdoc_url, mentity.html_name))
-               topmenu.active_item = topmenu.items.last
-       end
-
-       # Class list to display in sidebar
-       redef fun init_sidebar(v, doc) do
-               # TODO filter here?
-               super
-               var mclasses = new HashSet[MClass]
-               mclasses.add_all mentity.collect_intro_mclasses(v.doc.filter)
-               mclasses.add_all mentity.collect_redef_mclasses(v.doc.filter)
-               if mclasses.is_empty then return
-               var list = new UnorderedList
-               list.css_classes.add "list-unstyled list-labeled"
-
-               var sorted = mclasses.to_a
-               v.name_sorter.sort(sorted)
-               for mclass in sorted do
-                       list.add_li tpl_sidebar_item(mclass)
-               end
-               sidebar.boxes.add new DocSideBox("All classes", list)
-               sidebar.boxes.last.is_open = false
-       end
-
-       private fun tpl_sidebar_item(def: MClass): ListItem do
-               var classes = def.intro.css_classes
-               if def.intro_mmodule == self.mentity then
-                       classes.add "intro"
-               else
-                       classes.add "redef"
-               end
-               var lnk = new Template
-               lnk.add new DocHTMLLabel.with_classes(classes)
-               lnk.add def.html_link
-               return new ListItem(lnk)
-       end
-end
-
-redef class MClassPage
-
-       redef fun init_topmenu(v, doc) do
-               super
-               var mpackage = mentity.intro_mmodule.mgroup.mpackage
-               topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
-               topmenu.add_li new ListItem(new Link(html_url, mentity.html_name))
-               topmenu.active_item = topmenu.items.last
-       end
-
-       redef fun init_sidebar(v, doc) do
-               super
-               var by_kind = new PropertiesByKind.with_elements(mclass_inherited_mprops(v, doc))
-               var summary = new UnorderedList
-               summary.css_classes.add "list-unstyled"
-
-               by_kind.sort_groups(v.name_sorter)
-               for g in by_kind.groups do tpl_sidebar_list(g, summary)
-               sidebar.boxes.add new DocSideBox("All properties", summary)
-               sidebar.boxes.last.is_open = false
-       end
-
-       private fun tpl_sidebar_list(mprops: PropertyGroup[MProperty], summary: UnorderedList) do
-               if mprops.is_empty then return
-               var list = new UnorderedList
-               list.css_classes.add "list-unstyled list-labeled"
-               for mprop in mprops do
-                       list.add_li tpl_sidebar_item(mprop)
-               end
-               var content = new Template
-               content.add mprops.title
-               content.add list
-               var li = new ListItem(content)
-               summary.add_li li
-       end
-
-       private fun tpl_sidebar_item(mprop: MProperty): ListItem do
-               var classes = mprop.intro.css_classes
-               if not mprop_is_local(mprop) then
-                       classes.add "inherit"
-                       var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url
-                       var def_url = "{cls_url}#{mprop.nitdoc_id}.definition"
-                       var lnk = new Link(def_url, mprop.html_name)
-                       var mdoc = mprop.intro.mdoc_or_fallback
-                       if mdoc != null then lnk.title = mdoc.synopsis
-                       var item = new Template
-                       item.add new DocHTMLLabel.with_classes(classes)
-                       item.add lnk
-                       return new ListItem(item)
-               end
-               if mpropdefs.has(mprop.intro) then
-                       classes.add "intro"
-               else
-                       classes.add "redef"
-               end
-               var def = select_mpropdef(mprop)
-               var anc = def.html_link_to_anchor
-               anc.href = "#{def.nitdoc_id}.definition"
-               var lnk = new Template
-               lnk.add new DocHTMLLabel.with_classes(classes)
-               lnk.add anc
-               return new ListItem(lnk)
-       end
-
-       # Get the mpropdef contained in `self` page for a mprop.
-       #
-       # FIXME this method is used to translate a mprop into a mpropdefs for
-       # section linking. A better page structure should avoid this...
-       private fun select_mpropdef(mprop: MProperty): MPropDef do
-               for mclassdef in mentity.mclassdefs do
-                       for mpropdef in mclassdef.mpropdefs do
-                               if mpropdef.mproperty == mprop then return mpropdef
-                       end
-               end
-               abort # FIXME is there a case where the prop is not found?
-       end
-
-       private fun mclass_inherited_mprops(v: RenderHTMLPhase, doc: DocModel): Set[MProperty] do
-               var res = new HashSet[MProperty]
-               var local = mentity.collect_local_mproperties(v.doc.filter)
-               for mprop in mentity.collect_inherited_mproperties(doc.mainmodule, v.doc.filter) 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
-
-       private fun mprop_is_local(mprop: MProperty): Bool do
-               for mpropdef in mprop.mpropdefs do
-                       if self.mpropdefs.has(mpropdef) then return true
-               end
-               return false
-       end
-end
-
-redef class MPropertyPage
-       redef fun init_title(v, doc) do
-               title = "{mentity.html_name}{mentity.html_short_signature.write_to_string}"
-       end
-
-       redef fun init_topmenu(v, doc) do
-               super
-               var mmodule = mentity.intro_mclassdef.mmodule
-               var mpackage = mmodule.mgroup.mpackage
-               var mclass = mentity.intro_mclassdef.mclass
-               topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
-               topmenu.add_li new ListItem(new Link(mclass.nitdoc_url, mclass.html_name))
-               topmenu.add_li new ListItem(new Link(html_url, mentity.html_name))
-               topmenu.active_item = topmenu.items.last
-       end
-end
-
-redef class DocComposite
-       # Prepares the HTML rendering for this element.
-       #
-       # This visit is mainly used to set template attributes before rendering.
-       fun init_html_render(v: RenderHTMLPhase, doc: DocModel, page: DocPage) do
-               for child in children do child.init_html_render(v, doc, page)
-       end
-end
-
-# FIXME hideous hacks to avoid diff
-redef class MEntitySection
-       redef fun init_html_render(v, doc, page) do
-               if not page isa MEntityPage then return
-               var mentity = self.mentity
-               if mentity isa MGroup and mentity.is_root then
-                       html_title = mentity.mpackage.html_name
-                       html_subtitle = mentity.mpackage.html_declaration
-               else if mentity isa MProperty then
-                       var title = new Template
-                       title.add mentity.html_name
-                       title.add mentity.html_signature
-                       html_title = title
-                       html_subtitle = mentity.html_namespace
-                       html_toc_title = mentity.html_name
-               end
-               super
-       end
-end
-
-# FIXME hideous hacks to avoid diff
-redef class ConcernSection
-       redef fun init_html_render(v, doc, page) do
-               if not page isa MEntityPage then return
-               var mentity = self.mentity
-               if page isa MGroupPage then
-                       html_title = null
-                       html_toc_title = mentity.html_name
-                       is_toc_hidden = false
-               else if page.mentity isa MModule and mentity isa MModule then
-                       var title = new Template
-                       if mentity == page.mentity then
-                               title.add "in "
-                               html_toc_title = "in {mentity.html_name}"
-                       else
-                               title.add "from "
-                               html_toc_title = "from {mentity.html_name}"
-                       end
-                       title.add mentity.html_namespace
-                       html_title = title
-               else if (page.mentity isa MClass and mentity isa MModule) or
-                               (page.mentity isa MProperty and mentity isa MModule) then
-                       var title = new Template
-                       title.add "in "
-                       title.add mentity.html_namespace
-                       html_title = title
-                       html_toc_title = "in {mentity.html_name}"
-               end
-               super
-       end
-end
-
-# TODO redo showlink
-redef class IntroArticle
-       redef fun init_html_render(v, doc, page) do
-               var mentity = self.mentity
-               if mentity isa MModule then
-                       html_source_link = v.html_source_link(mentity.location)
-               else if mentity isa MClassDef then
-                       html_source_link = v.html_source_link(mentity.location)
-               else if mentity isa MPropDef then
-                       html_source_link = v.html_source_link(mentity.location)
-               end
-       end
-end
-
-# FIXME less hideous hacks...
-redef class DefinitionArticle
-       redef fun init_html_render(v, doc, page) do
-               var mentity = self.mentity
-               if mentity isa MPackage or mentity isa MModule then
-                       var title = new Template
-                       title.add mentity.html_icon
-                       title.add mentity.html_namespace
-                       html_title = title
-                       html_toc_title = mentity.html_name
-                       if mentity isa MModule then
-                               html_source_link = v.html_source_link(mentity.location)
-                       end
-               else if mentity isa MClassDef then
-                       var title = new Template
-                       title.add "in "
-                       title.add mentity.mmodule.html_namespace
-                       html_title = mentity.html_declaration
-                       html_subtitle = title
-                       html_toc_title = "in {mentity.html_name}"
-                       html_source_link = v.html_source_link(mentity.location)
-                       if page isa MEntityPage and mentity.is_intro and mentity.mmodule != page.mentity then
-                               is_short_comment = true
-                       end
-                       if page isa MModulePage then is_toc_hidden = true
-               else if mentity isa MPropDef then
-                       if page isa MClassPage then
-                               var title = new Template
-                               title.add mentity.html_icon
-                               title.add mentity.html_declaration
-                               html_title = title
-                               html_subtitle = mentity.html_namespace
-                               html_toc_title = mentity.html_name
-                       else
-                               var title = new Template
-                               title.add "in "
-                               title.add mentity.mclassdef.html_link
-                               html_title = title
-                               html_toc_title = "in {mentity.mclassdef.html_name}"
-                       end
-                       html_source_link = v.html_source_link(mentity.location)
-               end
-               if page isa MGroupPage and mentity isa MModule then
-                       is_toc_hidden = true
-               end
-               super
-       end
-end
-
-redef class HomeArticle
-       redef fun init_html_render(v, doc, page) do
-               if v.ctx.opt_custom_title.value != null then
-                       self.html_title = v.ctx.opt_custom_title.value.to_s
-                       self.html_toc_title = v.ctx.opt_custom_title.value.to_s
-               end
-               self.content = v.ctx.opt_custom_intro.value
-               super
-       end
-end
-
-redef class GraphArticle
-       redef fun init_html_render(v, doc, page) do
-               var path = v.ctx.output_dir / graph_id
-               var file = new FileWriter.open("{path}.dot")
-               file.write(dot)
-               file.close
-               var proc = new ProcessReader("dot", "-Tsvg", "-Tcmapx", "{path}.dot")
-               var svg = new Buffer
-               var i = 0
-               while not proc.eof do
-                       i += 1
-                       if i < 6 then continue # skip dot default header
-                       svg.append proc.read_line
-               end
-               proc.close
-               self.svg = svg.write_to_string
-       end
-end
diff --git a/src/doc/doc_phases/doc_indexing.nit b/src/doc/doc_phases/doc_indexing.nit
deleted file mode 100644 (file)
index 8719011..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-# 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.
-
-# Manage indexing of Nit model for Nitdoc QuickSearch.
-module doc_indexing
-
-import doc_base
-import html_templates::html_model # FIXME maybe this phase should depend on `html_render`
-private import json::static
-private import json
-
-# Generate the index for then Nitdoc QuickSearch field.
-#
-# Create a JSON object containing links to:
-#  * modules
-#  * mclasses
-#  * mpropdefs
-# All entities are grouped by name to make the research easier.
-#
-# TODO Add a way to change the output and use it from Vim or whatever.
-class IndexingPhase
-       super DocPhase
-
-       redef fun apply do
-               for mmodule in doc.model.mmodules do
-                       add_result_for(mmodule.name, mmodule.full_name, mmodule.nitdoc_url)
-               end
-               for mclass in doc.model.mclasses do
-                       add_result_for(mclass.name, mclass.full_name, mclass.nitdoc_url)
-               end
-               for mproperty in doc.model.mproperties do
-                       for mpropdef in mproperty.mpropdefs do
-                               if not doc.filter.accept_mentity(mpropdef) then continue
-                               var full_name = mpropdef.mclassdef.mclass.full_name
-                               var cls_url = mpropdef.mclassdef.mclass.nitdoc_url
-                               var def_url = "{cls_url}#{mpropdef.nitdoc_id}.definition"
-                               add_result_for(mproperty.name, full_name, def_url)
-                       end
-               end
-               # FIXME hack, generation should be done by the render phase
-               # create destination dir if it's necessary
-               var output_dir = ctx.output_dir
-               if not output_dir.file_exists then output_dir.mkdir
-
-               render.write_to_file("{ctx.output_dir.to_s}/quicksearch-list.js")
-       end
-
-       private var table = new QuickSearchTable
-
-       private fun add_result_for(query: String, txt: String, url: String) do
-               table[query].add new QuickSearchResult(txt, url)
-       end
-
-       # Render the index content.
-       fun render: Template do
-               var tpl = new Template
-               var buffer = new Buffer
-               tpl.add buffer
-               buffer.append "var nitdocQuickSearchRawList="
-               buffer.append table.to_json
-               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
-               assert key isa String
-               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
-       serialize
-
-       # The text of the link.
-       var txt: String
-
-       # The destination of the link.
-       var url: String
-end
diff --git a/src/doc/doc_phases/doc_intros_redefs.nit b/src/doc/doc_phases/doc_intros_redefs.nit
deleted file mode 100644 (file)
index 829a9ef..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-# 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.
-
-# Generates lists about intros/redefs in MEntity.
-#
-# Actually, this works only for MModules and MclassDefs.
-module doc_intros_redefs
-
-import doc_structure
-import model::model_collect
-
-# Computes intro / redef mentity list for each DefinitionArticle.
-class IntroRedefListPhase
-       super DocPhase
-
-       redef fun apply do
-               for page in doc.pages.values do
-                       if not page isa MEntityPage then continue
-                       page.root.build_intro_redef_list(self, doc, page)
-               end
-       end
-end
-
-redef class DocComposite
-
-       # Computes intro / redef lists for this page.
-       #
-       # See `IntroRedefListPhase`.
-       fun build_intro_redef_list(v: IntroRedefListPhase, doc: DocModel, page: MEntityPage) do
-               for child in children do child.build_intro_redef_list(v, doc, page)
-       end
-end
-
-redef class DefinitionArticle
-       redef fun build_intro_redef_list(v, doc, page) do
-               var mentity = self.mentity
-               if mentity isa MModule then
-                       build_mmodule_list(v, doc, mentity)
-               else if mentity isa MClassDef and mentity.mmodule == page.mentity then
-                       build_mclassdef_list(v, doc, mentity)
-               end
-               super
-       end
-
-       # TODO this should move to MEntity?
-       private fun build_mmodule_list(v: IntroRedefListPhase, doc: DocModel, mmodule: MModule) do
-               var section = new TabbedGroup("{mentity.nitdoc_id}.intros_redefs")
-               section.toc_title = "Intros / Redefs"
-               var group = new PanelGroup("list.group", "List")
-               var intros = mmodule.collect_intro_mclassdefs(v.doc.filter).to_a
-               doc.mainmodule.linearize_mclassdefs(intros)
-               group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.intros", "Introduces", intros)
-               var redefs = mmodule.collect_redef_mclassdefs(v.doc.filter).to_a
-               doc.mainmodule.linearize_mclassdefs(redefs)
-               group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.redefs", "Redefines", redefs)
-               section.add_child group
-               add_child(section)
-       end
-
-       # TODO this should move to MEntity?
-       private fun build_mclassdef_list(v: IntroRedefListPhase, doc: DocModel, mclassdef: MClassDef) do
-               var section = new TabbedGroup("{mentity.nitdoc_id}.intros_redefs")
-               section.toc_title = "Intros / Redefs"
-               var group = new PanelGroup("list.group", "List")
-               var intros = mclassdef.collect_intro_mpropdefs(v.doc.filter).to_a
-               # FIXME avoid diff changes
-               # v.ctx.mainmodule.linearize_mpropdefs(intros)
-               group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.intros", "Introduces", intros)
-               var redefs = mclassdef.collect_redef_mpropdefs(v.doc.filter).to_a
-               # FIXME avoid diff changes
-               # v.ctx.mainmodule.linearize_mpropdefs(redefs)
-               group.add_child new MEntitiesListArticle("{mentity.nitdoc_id}.redefs", "Redefines", redefs)
-               section.add_child group
-               add_child(section)
-       end
-end
diff --git a/src/doc/doc_phases/doc_lin.nit b/src/doc/doc_phases/doc_lin.nit
deleted file mode 100644 (file)
index 7864b27..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-# 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.
-
-# Add linearization lists to DefinitionArticle found in MClass pages.
-module doc_lin
-
-import doc_structure
-
-# LinPhase populates the DocPage content with linearization data.
-class LinListPhase
-       super DocPhase
-
-       # Used to sort list by linearization order
-       private var lin_sorter = new MEntityNameSorter
-
-       redef fun apply do
-               for page in doc.pages.values do page.apply_linearization(self, doc)
-       end
-end
-
-redef class DocPage
-
-       # Populates `self` with linearization data.
-       #
-       # See `LinListPhase`.
-       fun apply_linearization(v: LinListPhase, doc: DocModel) do end
-end
-
-redef class MClassPage
-       redef fun apply_linearization(v, doc) do
-               root.apply_linearization(v, doc, self)
-       end
-end
-
-redef class DocComposite
-
-       # Populates `self` with linearization data.
-       #
-       # For now, it's only used for mpropdefs linearization in MClassPage.
-       #
-       # See `LinListPhase`.
-       private fun apply_linearization(v: LinListPhase, doc: DocModel, page: DocPage) do
-               for child in children do child.apply_linearization(v, doc, page)
-       end
-end
-
-redef class DefinitionArticle
-       redef fun apply_linearization(v, doc, page) do
-               var mentity = self.mentity
-               if not mentity isa MPropDef then return
-               # Add linearization
-               var all_defs = new HashSet[MPropDef]
-               for local_def in local_defs(page.as(MClassPage), mentity.mproperty) do
-                       all_defs.add local_def
-                       var smpropdef = local_def
-                       while not smpropdef.is_intro do
-                               smpropdef = smpropdef.lookup_next_definition(
-                                       doc.mainmodule, smpropdef.mclassdef.bound_mtype)
-                               all_defs.add smpropdef
-                       end
-               end
-               var lin = all_defs.to_a
-               doc.mainmodule.linearize_mpropdefs(lin)
-               if lin.length > 1 then
-                       add_child new DefinitionLinArticle("{mentity.nitdoc_id}.lin", "Linearization", lin)
-               end
-       end
-
-       # Filter `page.mpropdefs` for this `mpropertie`.
-       #
-       # FIXME compatability with current templates.
-       private fun local_defs(page: MClassPage, mproperty: MProperty): HashSet[MPropDef] do
-               var mpropdefs = new HashSet[MPropDef]
-               for mpropdef in page.mpropdefs do
-                       if mpropdef.mproperty == mproperty then
-                               mpropdefs.add mpropdef
-                       end
-               end
-               return mpropdefs
-       end
-end
-
-# Display a linearized list of definitions.
-class DefinitionLinArticle
-       super DocArticle
-
-       # The linearized list to display.
-       var mentities: Array[MEntity]
-
-       redef fun is_hidden do return mentities.is_empty
-       redef var is_toc_hidden = true
-end
diff --git a/src/doc/doc_phases/doc_pages.nit b/src/doc/doc_phases/doc_pages.nit
deleted file mode 100644 (file)
index ec06f6a..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-# 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.
-
-# Create DocPage instances for each documentated Mentity.
-module doc_pages
-
-import doc_base
-
-# ExtractionPhase populates the DocModel with DocPage.
-class MakePagePhase
-       super DocPhase
-
-       # Instanciates documentation pages for the given DocModel.
-       redef fun apply do
-               doc.add_page new OverviewPage("overview", "Overview")
-               doc.add_page new SearchPage("search", "Index")
-               for mgroup in doc.model.collect_mgroups(doc.filter) do
-                       doc.add_page new ReadmePage(mgroup)
-                       doc.add_page new MGroupPage(mgroup)
-               end
-               for mmodule in doc.model.mmodules do
-                       doc.add_page new MModulePage(mmodule)
-               end
-               for mclass in doc.model.mclasses do
-                       doc.add_page new MClassPage(mclass)
-               end
-               for mproperty in doc.model.mproperties do
-                       doc.add_page new MPropertyPage(mproperty)
-               end
-       end
-end
-
-# The Nitdoc overview page.
-class OverviewPage
-       super DocPage
-end
-
-# The Nidoc full index page.
-class SearchPage
-       super DocPage
-end
-
-# A DocPage documenting a MEntity.
-class MEntityPage
-       autoinit mentity
-       super DocPage
-
-       # Type of MEntity documented by this page.
-       type MENTITY: MEntity
-
-       # MEntity documented by this page.
-       var mentity: MENTITY
-
-       redef var id is lazy do return mentity.nitdoc_id
-       redef var title is lazy do return mentity.nitdoc_name
-end
-
-# A page that displays a `MGroup` README.
-class ReadmePage
-       super MEntityPage
-
-       redef type MENTITY: MGroup
-       redef var id is lazy do return "readme_{mentity.nitdoc_id}"
-end
-
-# A documentation page about a MGroup.
-class MGroupPage
-       super MEntityPage
-
-       redef type MENTITY: MGroup
-end
-
-# A documentation page about a MModule.
-class MModulePage
-       super MEntityPage
-
-       redef type MENTITY: MModule
-end
-
-# A documentation page about a MClass.
-class MClassPage
-       super MEntityPage
-
-       redef type MENTITY: MClass
-end
-
-# A documentation page about a MProperty.
-class MPropertyPage
-       super MEntityPage
-
-       redef type MENTITY: MProperty
-end
diff --git a/src/doc/doc_phases/doc_phases.nit b/src/doc/doc_phases/doc_phases.nit
deleted file mode 100644 (file)
index 24969e4..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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.
-
-# Phases represent the *steps* of the NitDoc generation process.
-#
-# See `DocPhase`.
-module doc_phases
-
-import doc_html
-import doc_indexing
-import doc_test
diff --git a/src/doc/doc_phases/doc_poset.nit b/src/doc/doc_phases/doc_poset.nit
deleted file mode 100644 (file)
index 9f665b9..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-# 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.
-
-# Importation and inheritance POSet for pages.
-module doc_poset
-
-import doc_pages
-import model::model_collect
-
-# This phase computes importation and inheritance POSet for pages.
-class POSetPhase
-       super DocPhase
-
-       # Populates the given DocModel.
-       redef fun apply do
-               for page in doc.pages.values do
-                       if page isa MEntityPage then page.build_poset(self, doc)
-               end
-       end
-end
-
-redef class MEntityPage
-
-       # The poset associated with this page.
-       #
-       # FIXME should be defined in subclasses
-       # as the POSet can contains other types than `SELF`
-       var poset = new POSet[MENTITY]
-
-       # Build the POSet for this page.
-       private fun build_poset(v: POSetPhase, doc: DocModel) do end
-end
-
-redef class MModulePage
-
-       # Imported modules that should appear in the documentation.
-       var imports = new HashSet[MModule]
-
-       # Clients modules that should appear in the documentation.
-       var clients = new HashSet[MModule]
-
-       redef fun build_poset(v, doc) do
-               # collect importation
-               for dep in mentity.in_importation.greaters do
-                       if dep == mentity then continue
-                       if not doc.filter.accept_mentity(dep) then continue
-                       imports.add dep
-               end
-               # FIXME avoid diff
-               #if imports.length > 10 then
-               if mentity.in_importation.greaters.length > 10 then
-                       imports.clear
-                       for dep in mentity.in_importation.direct_greaters do
-                               if dep == mentity then continue
-                               if not doc.filter.accept_mentity(dep) then continue
-                               imports.add dep
-                       end
-               end
-               # collect clients
-               for dep in mentity.in_importation.smallers do
-                       if dep == mentity then continue
-                       if not doc.filter.accept_mentity(dep) then continue
-                       clients.add dep
-               end
-               if clients.length > 10 then
-                       clients.clear
-                       for dep in mentity.in_importation.direct_smallers do
-                               if dep == mentity then continue
-                               if not doc.filter.accept_mentity(dep) then continue
-                               clients.add dep
-                       end
-               end
-               # make poset
-               var mmodules = new HashSet[MModule]
-               var mgroup = mentity.mgroup
-               if mgroup != null and mgroup.default_mmodule == mentity then
-                       mmodules.add_all mgroup.mmodules
-               end
-               mmodules.add_all imports
-               if clients.length < 10 then mmodules.add_all clients
-               mmodules.add mentity
-               build_importation_poset(doc, mmodules)
-       end
-
-       # Build the POSet of importation from a list of `mmodules`.
-       private fun build_importation_poset(doc: DocModel, mmodules: Set[MModule]): POSet[MModule] do
-               for mmodule in mmodules do
-                       if not doc.filter.accept_mentity(mmodule) then continue
-                       poset.add_node mmodule
-                       for omodule in mmodules do
-                               if not doc.filter.accept_mentity(omodule) then continue
-                               poset.add_node mmodule
-                               if mmodule.in_importation < omodule then
-                                       poset.add_edge(mmodule, omodule)
-                               end
-                       end
-               end
-               return poset
-       end
-end
-
-redef class MClassPage
-
-       # Direct parents classes to document.
-       var parents = new HashSet[MClass]
-
-       # Transitive ancestors classes to document.
-       #
-       # Does not contain the direct ancestors.
-       # See `parents` for that.
-       var ancestors = new HashSet[MClass]
-
-       # Direct children classes to document.
-       var children = new HashSet[MClass]
-
-       # All descendants classes to document.
-       #
-       # Does not contain the direct children.
-       # See `children` for that.
-       var descendants = new HashSet[MClass]
-
-       redef fun build_poset(v, doc) do
-               poset.add_node mentity
-
-               var h = mentity.in_hierarchy(doc.mainmodule)
-               # parents
-               for mclass in h.direct_greaters do
-                       if doc.filter.accept_mentity(mclass) then parents.add mclass
-               end
-               # ancestors
-               for mclass in h.greaters do
-                       if mclass == mentity then continue
-                       if not doc.filter.accept_mentity(mclass) then continue
-                       if parents.has(mclass) then continue
-                       ancestors.add mclass
-               end
-               # children
-               for mclass in h.direct_smallers do
-                       if doc.filter.accept_mentity(mclass) then children.add mclass
-               end
-               # descendants
-               for mclass in h.smallers do
-                       if mclass == mentity then continue
-                       if not doc.filter.accept_mentity(mclass) then continue
-                       if children.has(mclass) then continue
-                       descendants.add mclass
-               end
-               # poset
-               var mclasses = new HashSet[MClass]
-               mclasses.add_all ancestors
-               mclasses.add_all parents
-               mclasses.add_all children
-               mclasses.add_all descendants
-               mclasses.add mentity
-               build_inheritance_poset(v, doc, mclasses)
-       end
-
-       private fun build_inheritance_poset(v: POSetPhase, doc: DocModel, mclasses: Set[MClass]): POSet[MClass] do
-               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(doc.mainmodule) < oclass then
-                                       poset.add_edge(mclass, oclass)
-                               end
-                       end
-               end
-               return poset
-       end
-end
diff --git a/src/doc/doc_phases/doc_readme.nit b/src/doc/doc_phases/doc_readme.nit
deleted file mode 100644 (file)
index 1dbd50e..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-# 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.
-
-# This phase parses README files.
-module doc_readme
-
-import markdown::decorators
-intrude import markdown::wikilinks
-import doc_commands
-import doc_down
-import doc_intros_redefs
-import model::model_index
-
-# Generate content of `ReadmePage`.
-#
-# This phase extracts the structure of a `ReadmePage` from the markdown content
-# of the README file.
-# It also resolves Wikilinks and commands.
-class ReadmePhase
-       super DocPhase
-
-       redef fun apply do
-               for page in doc.pages.values do page.build_content(self, doc)
-       end
-
-       # Display a warning about something wrong in the readme file.
-       fun warning(location: nullable MDLocation, page: ReadmePage, message: String) do
-               var loc = null
-               if location != null then
-                       var mdoc = page.mentity.mdoc
-                       if mdoc != null then loc = location.to_location(mdoc.location.file)
-               end
-               ctx.warning(loc, "readme-warning", message)
-       end
-end
-
-redef class DocPage
-       # Build content of `ReadmePage` based on the content of the readme file.
-       private fun build_content(v: ReadmePhase, doc: DocModel) do end
-end
-
-redef class ReadmePage
-       redef fun build_content(v, doc) do
-               var mdoc = mentity.mdoc
-               if mdoc == null then
-                       v.warning(null, self, "Empty README for group `{mentity}`")
-                       return
-               end
-               var proc = new ReadmeMdProcessor(self, v)
-               proc.decorator = new ReadmeDecorator
-               var md = mdoc.content.join("\n")
-               proc.process(md)
-       end
-end
-
-# Markdown emitter used to produce the `ReadmeArticle`.
-class ReadmeMdProcessor
-       super MarkdownProcessor
-
-       # Readme page being decorated.
-       var page: ReadmePage
-
-       # Phase used to access doc model and toolcontext.
-       var phase: ReadmePhase
-
-       init do open_article
-
-       # Push the article template on top of the buffer stack.
-       #
-       # Subsequent markdown writting will be done in the article template.
-       #
-       # See `ReadmeArticle::md`.
-       private fun push_article(article: ReadmeArticle) do
-               buffer_stack.add article.md
-       end
-
-       private var context = new Array[DocComposite]
-
-       # Creates a new ReadmeSection in `self.toc.page`.
-       #
-       # Called from `add_headline`.
-       private fun open_section(lvl: Int, title: String) do
-               var section = new ReadmeSection(title.escape_to_c, title, lvl, self)
-               var current_section = self.current_section
-               if current_section == null then
-                       page.root.add_child(section)
-               else
-                       current_section.add_child(section)
-               end
-               current_section = section
-               context.add section
-       end
-       private var current_section: nullable ReadmeSection is noinit
-
-       # Close the current section.
-       #
-       # Ensure `context.last isa ReadmeSection`.
-       private fun close_section do
-               assert context.last isa ReadmeSection
-               context.pop
-               if context.is_empty then
-                       current_section = null
-               else
-                       current_section = context.last.as(ReadmeSection)
-               end
-       end
-
-       # Add an article at current location.
-       #
-       # This closes the current article, inserts `article` then opens a new article.
-       private fun add_article(article: DocArticle) do
-               close_article
-               var current_section = self.current_section
-               if current_section == null then
-                       page.root.add_child(article)
-               else
-                       current_section.add_child(article)
-               end
-               open_article
-       end
-
-       # Creates a new ReadmeArticle in `self.toc.page`.
-       #
-       # Called from `add_headline`.
-       private fun open_article do
-               var section: DocComposite = page.root
-               if current_section != null then section = current_section.as(not null)
-               var article = new ReadmeArticle("mdarticle-{section.children.length}", null, self)
-               section.add_child(article)
-               context.add article
-               push_article article
-       end
-
-       # Close the current article.
-       #
-       # Ensure `context.last isa ReadmeArticle`.
-       fun close_article do
-               assert context.last isa ReadmeArticle
-               context.pop
-               pop_buffer
-       end
-
-       # Find mentities matching `query`.
-       fun find_mentities(query: String): Array[MEntity] do
-               # search MEntities by full_name
-               var mentity = phase.doc.model.mentity_by_full_name(query)
-               if mentity != null then return [mentity]
-               # search MEntities by name
-               return phase.doc.model.mentities_by_name(query)
-       end
-
-       # Suggest mentities based on `query`.
-       fun suggest_mentities(query: String): Array[MEntity] do
-               return phase.doc.model.find(query, 3)
-       end
-
-       # Display a warning message with suggestions.
-       fun warn(token: TokenWikiLink, message: String, suggest: nullable Array[MEntity]) do
-               var msg = new Buffer
-               msg.append message
-               if suggest != null and suggest.not_empty then
-                       msg.append " (suggestions: "
-                       var i = 0
-                       for s in suggest do
-                               msg.append "`{s.full_name}`"
-                               if i < suggest.length - 1 then msg.append ", "
-                               i += 1
-                       end
-                       msg.append ")"
-               end
-               phase.warning(token.location, page, msg.write_to_string)
-       end
-end
-
-# MarkdownDecorator used to decorated the Readme file with links between doc entities.
-class ReadmeDecorator
-       super MdDecorator
-
-       # Parser used to process doc commands
-       var parser = new DocCommandParser
-
-       redef type PROCESSOR: ReadmeMdProcessor
-
-       redef fun add_headline(v, block) do
-               var txt = block.block.first_line.as(not null).value
-               var lvl = block.depth
-               if not v.context.is_empty then
-                       v.close_article
-                       while v.current_section != null do
-                               if v.current_section.as(not null).depth < lvl then break
-                               v.close_section
-                       end
-               end
-               v.open_section(lvl, txt)
-               v.open_article
-       end
-
-       redef fun add_wikilink(v, token) do
-               var link = token.link.as(not null).to_s
-               var cmd = parser.parse(link)
-               if cmd == null then
-                       # search MEntities by name
-                       var res = v.find_mentities(link.to_s)
-                       # no match, print warning and display wikilink as is
-                       if res.is_empty then
-                               v.warn(token, "Link to unknown entity `{link}`", v.suggest_mentities(link.to_s))
-                               super
-                       else
-                               add_mentity_link(v, res.first, token.name, token.comment)
-                       end
-                       return
-               end
-               cmd.render(v, token)
-       end
-
-       # Renders a link to a mentity.
-       private fun add_mentity_link(v: PROCESSOR, mentity: MEntity, name, comment: nullable Text) do
-               # TODO real link
-               var link = mentity.full_name
-               if name == null then name = mentity.name
-               if comment == null then
-                       var mdoc = mentity.mdoc
-                       if mdoc != null then comment = mdoc.synopsis
-               end
-               add_link(v, link, name, comment)
-       end
-end
-
-redef class DocCommand
-
-       # Render the content of the doc command.
-       fun render(v: ReadmeMdProcessor, token: TokenWikiLink) is abstract
-end
-
-redef class CommentCommand
-       redef fun render(v, token) do
-               var string = args.first
-               var res = v.find_mentities(string)
-               if res.is_empty then
-                       v.warn(token,
-                               "Try to include documentation of unknown entity `{string}`",
-                               v.suggest_mentities(string))
-                       return
-               end
-               v.add_article new DocumentationArticle("readme", "Readme", res.first)
-       end
-end
-
-redef class ListCommand
-       redef fun render(v, token) do
-               var string = args.first
-               var res = v.find_mentities(string)
-               if res.is_empty then
-                       v.warn(token,
-                               "Try to include article of unknown entity `{string}`",
-                               v.suggest_mentities(string))
-                       return
-               end
-               if res.length > 1 then
-                       v.warn(token, "Conflicting article for `{args.first}`", res)
-               end
-               var mentity = res.first
-               if mentity isa MModule then
-                       v.add_article new MEntitiesListArticle("Classes", null, mentity.mclassdefs)
-               else if mentity isa MClass then
-                       var mprops = mentity.collect_intro_mproperties(v.phase.doc.filter)
-                       v.add_article new MEntitiesListArticle("Methods", null, mprops.to_a)
-               else if mentity isa MClassDef then
-                       v.add_article new MEntitiesListArticle("Methods", null, mentity.mpropdefs)
-               end
-       end
-end
-
-
-# A section found in a README.
-#
-# Produced by markdown headlines like `## Section 1.1`.
-class ReadmeSection
-       super DocSection
-
-       # The depth is based on the markdown headline depth.
-       redef var depth
-
-       # Markdown processor used to process the section title.
-       var markdown_processor: MarkdownProcessor
-
-       redef var is_hidden = false
-end
-
-# An article found in a README file.
-#
-# Basically, everything found in a README that is not a headline.
-class ReadmeArticle
-       super DocArticle
-
-       # Markdown processor used to process the article content.
-       var markdown_processor: MarkdownProcessor
-
-       # Markdown content of this article extracted from the README file.
-       var md = new FlatBuffer
-
-       redef fun is_hidden do return super and md.trim.is_empty
-end
-
-# Documentation Article to introduce from the directive `doc: Something`.
-#
-# TODO merge with DefinitionArticle once the html is simplified
-class DocumentationArticle
-       super MEntityArticle
-
-       redef var is_hidden = false
-end
-
-redef class MDLocation
-       # Translate a Markdown location in Nit location.
-       private fun to_location(file: nullable SourceFile): Location do
-               return new Location(file, line_start, line_end, column_start, column_end)
-       end
-end
diff --git a/src/doc/doc_phases/doc_structure.nit b/src/doc/doc_phases/doc_structure.nit
deleted file mode 100644 (file)
index b328fb9..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-# 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
-import modelize
-
-# 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.values do page.apply_structure(self, doc)
-       end
-end
-
-redef class DocPage
-
-       # Populates `self` with structure elements like DocComposite ones.
-       #
-       # See `StructurePhase`.
-       fun apply_structure(v: StructurePhase, doc: DocModel) do end
-end
-
-redef class OverviewPage
-       redef fun apply_structure(v, doc) do
-               var article = new HomeArticle("home.article", "Home")
-               root.add_child article
-               # Packages list
-               var mpackages = doc.model.mpackages.to_a
-               var sorter = new MConcernRankSorter
-               sorter.sort mpackages
-               var section = new DocSection("packages.section", "Packages")
-               for mpackage in mpackages do
-                       section.add_child new DefinitionArticle("{mpackage.nitdoc_id}.definition", null, mpackage)
-               end
-               article.add_child section
-       end
-end
-
-redef class SearchPage
-       redef fun apply_structure(v, doc) do
-               var mmodules = doc.model.mmodules.to_a
-               v.name_sorter.sort(mmodules)
-               var mclasses = doc.model.mclasses.to_a
-               v.name_sorter.sort(mclasses)
-               var mprops = doc.model.mproperties.to_a
-               v.name_sorter.sort(mprops)
-               root.add_child new IndexArticle("index.article", null, mmodules, mclasses, mprops)
-       end
-end
-
-redef class MGroupPage
-       redef fun apply_structure(v, doc) do
-               var section = new MEntitySection("{mentity.nitdoc_name}.section", null, mentity)
-               root.add_child section
-               if mentity.is_root then
-                       section.add_child new IntroArticle("{mentity.mpackage.nitdoc_id}.intro", null, mentity.mpackage)
-               else
-                       section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", null, mentity)
-               end
-               var concerns = self.concerns
-               if concerns == null or concerns.is_empty then return
-               # FIXME avoid diff
-               mentity.mpackage.booster_rank = -1000
-               mentity.booster_rank = -1000
-               concerns.sort_with(v.concerns_sorter)
-               mentity.mpackage.booster_rank = 0
-               mentity.booster_rank = 0
-               section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", null, mentity, concerns)
-               for mentity in concerns do
-                       var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", null, mentity)
-                       if mentity isa MModule then
-                               ssection.add_child new DefinitionArticle("{mentity.nitdoc_id}.definition", null, mentity)
-                       end
-                       section.add_child ssection
-               end
-       end
-end
-
-redef class MModulePage
-       redef fun apply_structure(v, doc) do
-               var section = new MEntitySection("{mentity.nitdoc_name}.section", null, mentity)
-               root.add_child section
-               section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", null, mentity)
-               var concerns = self.concerns
-               if concerns == null or concerns.is_empty then return
-               # FIXME avoid diff
-               mentity.mgroup.mpackage.booster_rank = -1000
-               mentity.mgroup.booster_rank = -1000
-               mentity.booster_rank = -1000
-               concerns.sort_with(v.concerns_sorter)
-               mentity.mgroup.mpackage.booster_rank = 0
-               mentity.mgroup.booster_rank = 0
-               mentity.booster_rank = 0
-               section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", null, mentity, concerns)
-               # reference list
-               for mentity in concerns do
-                       var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", null, 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 DefinitionListArticle(
-                                               "{mclass.intro.nitdoc_id}.definition-list", null, mclass)
-                                       var mclassdefs = mclassdefs_for(mclass).to_a
-                                       if not mclassdefs.has(mclass.intro) then
-                                               article.add_child(new DefinitionArticle(
-                                                       "{mclass.intro.nitdoc_id}.definition", null, mclass.intro))
-                                       end
-                                       doc.mainmodule.linearize_mclassdefs(mclassdefs)
-                                       for mclassdef in mclassdefs do
-                                               article.add_child(new DefinitionArticle(
-                                                       "{mclassdef.nitdoc_id}.definition", null, mclassdef))
-                                       end
-                                       ssection.add_child article
-                               end
-                       end
-                       section.add_child ssection
-               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
-               var section = new MEntitySection("{mentity.nitdoc_name}.section", null, mentity)
-               root.add_child section
-               section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", null, mentity)
-               var concerns = self.concerns
-               if concerns == null or concerns.is_empty then return
-               # FIXME diff hack
-               mentity.intro_mmodule.mgroup.mpackage.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.mpackage.booster_rank = 0
-               mentity.intro_mmodule.mgroup.booster_rank = 0
-               mentity.intro_mmodule.booster_rank = 0
-               var constructors = new DocSection("{mentity.nitdoc_id}.constructors", "Constructors")
-               var minit = mentity.root_init
-               if minit != null then
-                       constructors.add_child new DefinitionArticle("{minit.nitdoc_id}.definition", null, minit)
-               end
-               section.add_child constructors
-               section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", null, mentity, concerns)
-               for mentity in concerns do
-                       var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", null, 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
-                                                       if mpropdef isa MMethodDef and mpropdef.mproperty.is_init then
-                                                               if mpropdef == minit then continue
-                                                               constructors.add_child new DefinitionArticle(
-                                                                       "{mpropdef.nitdoc_id}.definition", null, mpropdef)
-                                                       else
-                                                               ssection.add_child new DefinitionArticle(
-                                                                       "{mpropdef.nitdoc_id}.definition", null, mpropdef)
-                                                       end
-                                               end
-                                       end
-                               end
-                       end
-                       section.add_child ssection
-               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
-               var section = new MEntitySection("{mentity.nitdoc_name}.section", null, mentity)
-               root.add_child section
-               section.add_child new IntroArticle("{mentity.nitdoc_id}.intro", null, mentity)
-               var concerns = self.concerns
-               if concerns == null or concerns.is_empty then return
-               # FIXME diff hack
-               mentity.intro.mclassdef.mmodule.mgroup.mpackage.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.mpackage.booster_rank = 0
-               mentity.intro.mclassdef.mmodule.mgroup.booster_rank = 0
-               mentity.intro.mclassdef.mmodule.booster_rank = 0
-               section.add_child new ConcernsArticle("{mentity.nitdoc_id}.concerns", null, mentity, concerns)
-               for mentity in concerns do
-                       var ssection = new ConcernSection("{mentity.nitdoc_id}.concern", null, 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
-                                       ssection.add_child new DefinitionArticle(
-                                               "{mpropdef.nitdoc_id}.definition", null, mpropdef)
-                               end
-                       end
-                       section.add_child ssection
-               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 group of sections that can be displayed together in a tab.
-#
-# Display the first child and hide less relevant data in other panels.
-class TabbedGroup
-       super DocSection
-end
-
-# A group of sections that can be displayed together in a tab panel.
-class PanelGroup
-       super DocSection
-end
-
-# A DocComposite element about a MEntity.
-class MEntityComposite
-       super DocComposite
-
-       redef fun title do return mentity.nitdoc_name
-
-       # 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
-
-       redef fun is_toc_hidden do return is_hidden
-end
-
-# An article about a Mentity.
-#
-# Used to display textual content about a MEntity.
-abstract class MEntityArticle
-       super MEntityComposite
-       super DocArticle
-end
-
-# An article that displays a list of mentities.
-class MEntitiesListArticle
-       super DocArticle
-
-       # MEntities to display.
-       var mentities: Array[MEntity]
-
-       redef fun is_hidden do return mentities.is_empty
-end
-
-
-# A section about a Mentity.
-#
-# Used to regroup content about a MEntity.
-class MEntitySection
-       super MEntityComposite
-       super DocSection
-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
-
-       redef var is_hidden = false
-       redef var is_toc_hidden = true
-end
-
-# An article that display a ConcernsTreee as a list.
-class ConcernsArticle
-       super MEntityArticle
-
-       # Concerns to list in this article.
-       var concerns: ConcernsTree
-
-       redef fun is_hidden do return concerns.is_empty
-end
-
-# An article that displays a list of definition belonging to a MEntity.
-class DefinitionListArticle
-       super TabbedGroup
-       super MEntityArticle
-end
-
-# An article that display the definition text of a MEntity.
-class DefinitionArticle
-       super MEntityArticle
-
-       redef var is_hidden = false
-end
-
-# The main package article.
-class HomeArticle
-       super DocArticle
-end
-
-# An article that display an index of mmodules, mclasses and mproperties.
-class IndexArticle
-       super DocArticle
-
-       # List of mmodules to display.
-       var mmodules: Array[MModule]
-
-       # List of mclasses to display.
-       var mclasses: Array[MClass]
-
-       # List of mproperties to display.
-       var mprops: Array[MProperty]
-
-       redef fun is_hidden do
-               return mmodules.is_empty and mclasses.is_empty and mprops.is_empty
-       end
-end
-
-# Concerns ranking
-
-# Sort MConcerns based on the module importation hierarchy ranking
-# see also: `MConcern::concern_rank` and `MConcern::booster_rank`
-#
-# Comparison is made with the formula:
-#
-# ~~~nitish
-# a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_ran
-# ~~~
-#
-# If both `a` and `b` have the same ranking,
-# ordering is based on lexicographic comparison of `a.name` and `b.name`
-class MConcernRankSorter
-       super Comparator
-       redef type COMPARED: MConcern
-
-       redef fun compare(a, b) do
-               if a.concern_rank == b.concern_rank then
-                       return a.name <=> b.name
-               end
-               return a.concern_rank + a.booster_rank <=> b.concern_rank + b.booster_rank
-       end
-end
-
-redef class MConcern
-
-       # Boost a MConcern rank
-       # see: `MConcernRankSorter`
-       # Use a positive booster to push down a result in the list
-       # A negative booster can be used to push up the result
-       var booster_rank: Int = 0 is writable
-
-       # Concern ranking used for ordering
-       # see: `MConcernRankSorter`
-       # Rank can be positive or negative
-       fun concern_rank: Int is abstract
-end
-
-redef class MPackage
-       redef var concern_rank is lazy do
-               var max = 0
-               for mgroup in mgroups do
-                       var mmax = mgroup.concern_rank
-                       if mmax > max then max = mmax
-               end
-               return max + 1
-       end
-end
-
-redef class MGroup
-       redef var concern_rank is lazy do
-               var max = 0
-               for mmodule in mmodules do
-                       var mmax = mmodule.concern_rank
-                       if mmax > max then max = mmax
-               end
-               return max + 1
-       end
-end
-
-redef class MModule
-       redef var concern_rank is lazy do
-               var max = 0
-               for p in in_importation.direct_greaters do
-                       var pmax = p.concern_rank
-                       if pmax > max then max = pmax
-               end
-               return max + 1
-       end
-end
diff --git a/src/doc/doc_phases/doc_test.nit b/src/doc/doc_phases/doc_test.nit
deleted file mode 100644 (file)
index 46ea9d1..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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.
-
-# Print the generated DocModel in stdout.
-#
-# Mainly used for tests.
-module doc_test
-
-import doc_structure
-import counter
-
-redef class ToolContext
-
-       # File pattern used to link documentation to source code.
-       var opt_test = new OptionBool("Print test data (metrics and structure)", "--test")
-
-       redef init do
-               super
-               option_context.add_option(opt_test)
-       end
-end
-
-# Display the DocModel in stdout.
-class DocTestPhase
-       super DocPhase
-
-       redef fun apply do
-               if not ctx.opt_test.value then return
-               # Pages metrics
-               var page_counter = new Counter[String]
-               var pages = doc.pages.keys.to_a
-               default_comparator.sort(pages)
-               for title in pages do
-                       var page = doc.pages[title]
-                       page_counter.inc page.class_name
-                       print page.pretty_print.write_to_string
-               end
-               print "Generated {doc.pages.length} pages"
-               page_counter.print_elements(100)
-               # Model metrics
-               var model_counter = new Counter[String]
-               for mentity in doc.model.collect_mentities(doc.filter) do
-                       model_counter.inc mentity.class_name
-               end
-               print "Found {doc.model.collect_mentities(doc.filter).length} mentities"
-               model_counter.print_elements(100)
-       end
-end
diff --git a/src/doc/html_templates/html_components.nit b/src/doc/html_templates/html_components.nit
deleted file mode 100644 (file)
index fa3bd69..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-# 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.
-
-# HTML templates used by Nitdoc to generate API documentation
-# Pages are assembled using `Template`
-module html_components
-
-import doc_base
-import html::bootstrap
-import json
-
-# A label with a text content.
-class DocHTMLLabel
-       super BSLabel
-
-       redef init do
-               css_classes.clear
-               css_classes.add "label"
-       end
-
-       # Init this label from css classes.
-       init with_classes(classes: Array[String]) do
-               init("label", "")
-               css_classes.add_all classes
-       end
-end
-
-# A component that display tabbed data.
-class DocTabs
-       super BSComponent
-       autoinit(html_id, drop_text, css_classes)
-
-       # HTML id of this component.
-       var html_id: String
-
-       # Text displayed on the tabs dropdown button.
-       var drop_text: String
-
-       # Panels to display in this tab group.
-       var panels = new Array[DocTabPanel]
-
-       # Droplist containing links to panels.
-       #
-       # Can also be used to add external links.
-       var drop_list: DocTabsDrop is lazy do return new DocTabsDrop(html_id, drop_text)
-
-       # Adds a new `panel` to that tab.
-       #
-       # You should always use this instead of `panels.add` because it also set the
-       # `drop_list` entry.
-       fun add_panel(panel: DocTabPanel) do
-               drop_list.add_li panel.render_tab
-               panels.add panel
-       end
-
-       redef fun rendering do
-               if panels.is_empty then return
-               panels.first.is_active = true
-               add "<div role=\"tabpanel\">"
-               if drop_list.items.length > 1 then add drop_list
-               add " <div class=\"tab-content\">"
-               for panel in panels do
-                       add panel
-               end
-               add " </div>"
-               add "</div>"
-       end
-end
-
-# A list of tab regrouped in a dropdown
-class DocTabsDrop
-       super UnorderedList
-       autoinit(html_id, html_title, items, css_classes)
-
-       # HTML id used by the tabs group.
-       var html_id: String
-
-       # Title to display in the tab item.
-       var html_title: String
-
-       redef fun rendering do
-               add """<ul id="{{{html_id}}}-tabs" class="nav pull-right" role="tablist">"""
-               add """ <li role="presentation" class="dropdown pull-right">"""
-               add """  <a href="#" id="{{{html_id}}}-drop" class="dropdown-toggle"
-                         data-toggle="dropdown" aria-controls="{{{html_id}}}-contents"
-                         aria-expanded="false">"""
-        add html_title
-               add """ <span class="glyphicon glyphicon-menu-hamburger"></span>"""
-               add """ </a>"""
-               add """ <ul class="dropdown-menu" role="menu"
-                        aria-labelledby="{{{html_id}}}-drop" id="{{{html_id}}}-contents">"""
-               for item in items do add item
-               add "  </ul>"
-        add " </li>"
-        add "</ul>"
-       end
-end
-
-# A panel that goes in a DocTabs.
-class DocTabPanel
-       super BSComponent
-       autoinit(html_id, tab_title, html_content, is_active, css_classes)
-
-       # HTML id of this panel.
-       var html_id: String
-
-       # Title of this panel as displayed in the tab label.
-       var tab_title: String
-
-       # HTML content of this panel.
-       var html_content: Writable is writable
-
-       # Is this panel visible by default?
-       var is_active = false is optional
-
-       redef fun rendering do
-               var active = ""
-               if is_active then active = "active in"
-               add "<div role=\"tabpanel\" class=\"tab-pane fade {active}\""
-               add "  id=\"{html_id}\" aria-labelledby=\"{html_id}-tab\">"
-               add html_content
-               add "</div>"
-       end
-
-       private fun render_tab: DocTabItem do return new DocTabItem(tab_title, html_id)
-end
-
-# A ListItem that goes in a DocTabsDrop.
-private class DocTabItem
-       super ListItem
-       autoinit(text, target_id, css_classes)
-
-       # Panel id to trigger when the link is clicked.
-       var target_id: String
-
-       redef fun rendering do
-               add "<li{render_css_classes}>"
-               add " <a role=\"tab\" data-toggle=\"tab\" aria-expanded=\"false\" tabindex=\"-1\""
-               add "   id=\"{target_id}-tab\" href=\"#{target_id}\" aria-controls=\"{target_id}\">"
-               add text
-               add " </a>"
-               add "</li>"
-       end
-end
-
-# A HTML tag attribute
-#  `<tag attr="value">`
-#
-# ~~~nit
-# var attr: TagAttribute
-#
-# attr = new TagAttribute("foo", null)
-# assert attr.write_to_string == " foo=\"\""
-#
-# attr = new TagAttribute("foo", "bar<>")
-# assert attr.write_to_string == " foo=\"bar&lt;&gt;\""
-# ~~~
-class TagAttribute
-       super Template
-
-       var name: String
-       var value: nullable String
-
-       redef fun rendering do
-               var value = self.value
-               if value == null then
-                       # SEE: http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes
-                       add " {name.html_escape}=\"\""
-               else
-                       add " {name.html_escape}=\"{value.html_escape}\""
-               end
-       end
-end
-
-# Javacript template that can be added into a DocPage.
-class TplScript
-       super Template
-
-       # HTML attributes to add in this tag.
-       var attrs = new Array[TagAttribute]
-
-       # Text content of this script tag.
-       var content: nullable Writable = null is writable
-
-       init do
-               attrs.add(new TagAttribute("type", "text/javascript"))
-       end
-
-       # Render the content of this script.
-       protected fun render_content do
-               if content != null then add content.as(not null)
-       end
-
-       redef fun rendering do
-               add "<script"
-               for attr in attrs do add attr
-               addn ">"
-               render_content
-               addn "</script>"
-       end
-end
-
-# JS script for Piwik Tracker
-class TplPiwikScript
-       super TplScript
-
-       # Piwik URL to use for this tracker.
-       var tracker_url: String
-
-       # Site ID used on Piwik system.
-       var site_id: String
-
-       redef fun render_content do
-               var site_id = self.site_id.to_json
-               var tracker_url = self.tracker_url.trim
-               if tracker_url.chars.last != '/' then tracker_url += "/"
-               tracker_url = "://{tracker_url}".to_json
-
-               addn "<!-- Piwik -->"
-               addn "var _paq = _paq || [];"
-               addn " _paq.push([\"trackPageView\"]);"
-               addn " _paq.push([\"enableLinkTracking\"]);"
-               addn "(function() \{"
-               addn " var u=((\"https:\" == document.location.protocol) ? \"https\" : \"http\") + {tracker_url};"
-               addn " _paq.push([\"setTrackerUrl\", u+\"piwik.php\"]);"
-               addn " _paq.push([\"setSiteId\", {site_id}]);"
-               addn " var d=document, g=d.createElement(\"script\"), s=d.getElementsByTagName(\"script\")[0]; g.type=\"text/javascript\";"
-               addn " g.defer=true; g.async=true; g.src=u+\"piwik.js\"; s.parentNode.insertBefore(g,s);"
-               addn "\})();"
-       end
-end
diff --git a/src/doc/html_templates/html_model.nit b/src/doc/html_templates/html_model.nit
deleted file mode 100644 (file)
index 820a9a3..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-# 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.
-
-# HTML templates for Nit model MEntities.
-module html_model
-
-import doc_base
-import html_components
-import ordered_tree
-import model_html
-
-redef class MEntity
-       # URL of this entity’s Nitdoc page.
-       fun nitdoc_url: String is abstract
-
-       # Returns a Link to the mentity `html_url`.
-       #
-       # Example: `<a href="html_url" title="mdoc.short_comment">html_short_name</a>
-       redef var html_link is lazy do
-               var tpl = new Link(nitdoc_url, html_name)
-               var mdoc = mdoc_or_fallback
-               if mdoc != null then
-                       tpl.title = mdoc.synopsis
-               end
-               return tpl
-       end
-
-       # Returns a Link to the mentity `nitdoc_id`.
-       #
-       # Example: `<a href="#nitdoc_id" title="mdoc.short_comment">html_short_name</a>
-       fun html_link_to_anchor: Link do
-               var tpl = new Link("#{nitdoc_id}", html_name)
-               var mdoc = mdoc_or_fallback
-               if mdoc != null then
-                       tpl.title = mdoc.synopsis
-               end
-               return tpl
-       end
-
-       # A li element that can go in a `HTMLList`.
-       fun html_list_item: ListItem do
-               var tpl = new Template
-               tpl.add new DocHTMLLabel.with_classes(css_classes)
-               tpl.add html_link
-               var comment = html_synopsis
-               if comment != null then
-                       tpl.add ": "
-                       tpl.add comment
-               end
-               return new ListItem(tpl)
-       end
-end
-
-redef class MPackage
-       redef var nitdoc_id = name.to_cmangle is lazy
-
-       redef fun nitdoc_url do
-               var root = self.root
-               if root == null then return super
-               return root.nitdoc_url
-       end
-end
-
-redef class MGroup
-       redef var nitdoc_id is lazy do
-               var parent = self.parent
-               if parent != null then
-                       return "{parent.nitdoc_id}__{name.to_cmangle}"
-               end
-               return name.to_cmangle
-       end
-
-       redef fun nitdoc_url do return "group_{nitdoc_id}.html"
-end
-
-redef class MModule
-       redef var nitdoc_id is lazy do
-               var mgroup = self.mgroup
-               if mgroup != null then
-                       if mgroup.mmodules.length == 1 then
-                               return "{mgroup.nitdoc_id}-"
-                       else
-                               return "{mgroup.nitdoc_id}__{name.to_cmangle}"
-                       end
-               end
-               return name.to_cmangle
-       end
-
-       redef fun nitdoc_url do return "module_{nitdoc_id}.html"
-end
-
-redef class MClass
-       redef var nitdoc_id = "{intro_mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
-       redef fun nitdoc_url do return "class_{nitdoc_id}.html"
-end
-
-redef class MClassDef
-       redef var nitdoc_id = "{mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
-       redef fun nitdoc_url do return "{mclass.nitdoc_url}#{nitdoc_id}"
-end
-
-redef class MProperty
-       redef var nitdoc_id = "{intro_mclassdef.mclass.nitdoc_id}__{name.to_cmangle}" is lazy
-       redef fun nitdoc_url do return "property_{nitdoc_id}.html"
-end
-
-redef class MPropDef
-       redef var nitdoc_id = "{mclassdef.nitdoc_id}__{name.to_cmangle}" is lazy
-       redef fun nitdoc_url do return "{mproperty.nitdoc_url}#{nitdoc_id}"
-end
-
-redef class MAttributeDef
-
-       redef fun html_modifiers do
-               var res = super
-               res.add "var"
-               return res
-       end
-
-       redef fun html_short_signature do return new Template
-
-       redef fun html_signature do
-               var static_mtype = self.static_mtype
-               var tpl = new Template
-               if static_mtype != null then
-                       tpl.add ": "
-                       tpl.add static_mtype.html_signature
-               end
-               return tpl
-       end
-end
-
-redef class MParameterType
-       redef fun html_link do
-               return new Link("{mclass.nitdoc_url}#FT_{name.to_cmangle}", name, "formal type")
-       end
-end
-
-redef class MVirtualType
-       redef fun html_link do return mproperty.intro.html_link
-end
-
-redef class ConcernsTree
-       # Render `self` as a hierarchical UnorderedList.
-       fun html_list: UnorderedList do
-               var lst = new UnorderedList
-               lst.css_classes.add "list-unstyled list-definition"
-               for r in roots do
-                       var li = r.html_concern_item
-                       lst.add_li li
-                       build_html_list(r, li)
-               end
-               return lst
-       end
-
-       # Build the html list recursively.
-       private fun build_html_list(e: MConcern, li: ListItem) do
-               if not sub.has_key(e) then return
-               var subs = sub[e]
-               var lst = new UnorderedList
-               lst.css_classes.add "list-unstyled list-definition"
-               for e2 in subs do
-                       if e2 isa MGroup and e2.is_root then
-                               build_html_list(e2, li)
-                       else
-                               var sli = e2.html_concern_item
-                               lst.add_li sli
-                               build_html_list(e2, sli)
-                       end
-               end
-               var text = new Template
-               text.add li.text
-               if not lst.is_empty then text.add lst
-               li.text = text
-       end
-end
-
-redef class MConcern
-       # Return a li element for `self` that can be displayed in a concern list
-       private fun html_concern_item: ListItem do
-               var lnk = html_link
-               var tpl = new Template
-               tpl.add new Link("#{nitdoc_id}.concern", lnk.text, lnk.title)
-               var comment = html_synopsis
-               if comment != null then
-                       tpl.add ": "
-                       tpl.add comment
-               end
-               return new ListItem(tpl)
-       end
-end
-
-################################################################################
-# Additions to `model_ext`.
-
-redef class MRawType
-       redef fun html_signature do
-               var tpl = new Template
-
-               for part in parts do
-                       if part.target != null then
-                               tpl.add part.target.as(not null).html_link
-                       else
-                               tpl.add part.text.html_escape
-                       end
-               end
-               return tpl
-       end
-end
-
-redef class MInnerClass
-       redef fun nitdoc_url do return inner.nitdoc_url
-       redef fun html_signature do return inner.html_signature
-end
-
-redef class MInnerClassDef
-       redef fun nitdoc_url do return inner.nitdoc_url
-
-       redef fun html_link_to_anchor do return inner.html_link_to_anchor
-       redef fun html_link do return inner.html_link
-       redef fun html_signature do return inner.html_signature
-end
diff --git a/src/doc/html_templates/html_templates.nit b/src/doc/html_templates/html_templates.nit
deleted file mode 100644 (file)
index 9f8390e..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-# 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.
-
-# Introduces templates that compose the documentation HTML rendering.
-module html_templates
-
-import html_model
-import html::bootstrap
-import doc_phases::doc_structure
-import doc_phases::doc_hierarchies
-import doc_phases::doc_graphs
-import doc_phases::doc_intros_redefs
-import doc_phases::doc_lin
-import doc_phases::doc_readme
-intrude import doc_down
-
-# Renders the page as HTML.
-redef class DocPage
-       super Template
-
-       # Page url.
-       var html_url: String is writable, noinit
-
-       # Directory where css, js and other assets can be found.
-       var shareurl: String is writable, noinit
-
-       # Attributes of the body tag element.
-       var body_attrs = new Array[TagAttribute]
-
-       # Top menu template if any.
-       var topmenu: DocTopMenu is writable, noinit
-
-       # Sidebar template if any.
-       var sidebar: nullable DocSideBar = null is writable
-
-       # Footer content if any.
-       var footer: nullable Writable = null is writable
-
-       # JS scripts to append at the end of the body
-       var scripts = new Array[TplScript]
-
-       # Renders the html `<head>`.
-       private fun render_head do
-               var css = (self.shareurl / "css").html_escape
-               var vendors = (self.shareurl / "vendors").html_escape
-
-               addn "<!DOCTYPE html>"
-               addn "<head>"
-               addn " <meta charset='utf-8'/>"
-               addn " <!--link rel='stylesheet' href='{css}/Nitdoc.UI.css' type='text/css'/-->"
-               addn " <link rel='stylesheet' href='{vendors}/bootstrap/css/bootstrap.min.css'/>"
-               addn " <link rel='stylesheet' href='{css}/nitdoc.bootstrap.css'/>"
-               addn " <link rel='stylesheet' href='{css}/nitdoc.css'/>"
-               addn " <link rel='stylesheet' href='{css}/Nitdoc.QuickSearch.css'/>"
-               addn " <link rel='stylesheet' href='{css}/Nitdoc.ModalBox.css'/>"
-               addn " <link rel='stylesheet' href='{css}/Nitdoc.GitHub.css'/>"
-               addn " <title>{title.html_escape}</title>"
-               addn "</head>"
-               add "<body"
-               for attr in body_attrs do add attr
-               addn ">"
-       end
-
-       # Renders the footer and content.
-       private fun render_content do
-               add root
-               if footer != null then
-                       addn "<div class='well footer'>"
-                       add footer.as(not null)
-                       addn "</div>"
-               end
-       end
-
-       # Render JS scripts
-       private fun render_footer do
-               var vendors = (self.shareurl / "vendors").html_escape
-               var js = (self.shareurl / "js").html_escape
-
-               addn "<script src='{vendors}/jquery/jquery-1.11.1.min.js'></script>"
-               addn "<script src='{vendors}/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
-               addn "<script src='{vendors}/bootstrap/js/bootstrap.min.js'></script>"
-               addn "<script src='{js}/lib/utils.js'></script>"
-               addn "<script src='{js}/plugins/filtering.js'></script>"
-               addn "<script src='quicksearch-list.js'></script>"
-               addn "<script src='{js}/plugins/quicksearch.js'></script>"
-               for script in scripts do add script
-               addn """<script>
-                       $(function () {
-                               $("[data-toggle='tooltip']").tooltip();
-                               $("[data-toggle='popover']").popover();
-                       });
-               </script>"""
-               addn "</body>"
-               addn "</html>"
-       end
-
-       # Render the whole page
-       redef fun rendering do
-               render_head
-               addn "<div class='container-fluid'>"
-               addn " <div class='row'>"
-               add topmenu
-               addn " </div>"
-               addn " <div class='row' id='content'>"
-               var sidebar = self.sidebar
-               if sidebar != null then
-                       addn "<div class='col col-xs-3 col-lg-2'>"
-                       add sidebar
-                       addn "</div>"
-                       addn "<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
-                       render_content
-                       addn "</div>"
-               else
-                       addn "<div class='col col-xs-12'>"
-                       render_content
-                       addn "</div>"
-               end
-               addn " </div>"
-               addn "</div>"
-               render_footer
-       end
-
-       # Render table of content for this page.
-       fun html_toc: UnorderedList do
-               var lst = new UnorderedList
-               lst.css_classes.add "nav"
-               for child in root.children do
-                       child.render_toc_item(lst)
-               end
-               return lst
-       end
-end
-
-# Top menu bar template.
-#
-# FIXME should be a Bootstrap component template
-# At this moment, the topmenu structure stills to specific to Nitdoc to use the
-# generic component.
-class DocTopMenu
-       super UnorderedList
-
-       # Brand link to display in first position of the top menu.
-       #
-       # This is where you want to put your logo.
-       var brand: nullable Writable is noinit, writable
-
-       # Active menu item.
-       #
-       # Depends on the current page, this allows to hilighted the current item.
-       #
-       # FIXME should be using Boostrap breadcrumbs component.
-       # This will still like this to avoid diff and be changed in further fixes
-       # when we will modify the output.
-       var active_item: nullable ListItem is noinit, writable
-
-       redef fun rendering do
-               addn "<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
-               addn " <div class='container-fluid'>"
-               addn "  <div class='navbar-header'>"
-               add "   <button type='button' class='navbar-toggle' "
-               addn "       data-toggle='collapse' data-target='#topmenu-collapse'>"
-               addn "    <span class='sr-only'>Toggle menu</span>"
-               addn "    <span class='icon-bar'></span>"
-               addn "    <span class='icon-bar'></span>"
-               addn "    <span class='icon-bar'></span>"
-               addn "   </button>"
-               if brand != null then
-                       add "<span class='navbar-brand'>"
-                       add brand.write_to_string
-                       add "</span>"
-               end
-               addn "  </div>"
-               addn "  <div class='collapse navbar-collapse' id='topmenu-collapse'>"
-               addn "   <ul class='nav navbar-nav'>"
-               for item in items do
-                       if item == active_item then item.css_classes.add "active"
-                       add item.write_to_string
-               end
-               addn "   </ul>"
-               addn "  </div>"
-               addn " </div>"
-               addn "</nav>"
-       end
-end
-
-# Nitdoc sidebar template.
-class DocSideBar
-       super Template
-
-       # Sidebar contains `DocSideBox`.
-       var boxes = new Array[DocSideBox]
-
-       redef fun rendering do
-               if boxes.is_empty then return
-               addn "<div id='sidebar'>"
-               for box in boxes do add box
-               addn "</div>"
-       end
-end
-
-# Something that can be put in a DocSideBar.
-class DocSideBox
-       super Template
-
-       # Box HTML id, used for Bootstrap collapsing feature.
-       #
-       # Use `html_title.to_cmangle` by default.
-       var id: String is lazy do return title.write_to_string.to_cmangle
-
-       # Title of the box to display.
-       var title: Writable
-
-       # Content to display in the box.
-       var content: Writable
-
-       # Is the box opened by default?
-       #
-       # Otherwise, the user will have to clic on the title to display the content.
-       #
-       # Default is `true`.
-       var is_open = true is writable
-
-       redef fun rendering do
-               var open = ""
-               if is_open then open = "in"
-               addn "<div class='panel'>"
-               addn " <div class='panel-heading'>"
-               add "  <a data-toggle='collapse' data-parent='#sidebar'"
-               add "   data-target='#box_{id}' href='#'>"
-               add title
-               addn "  </a>"
-               addn " </div>"
-               addn " <div id='box_{id}' class='summary panel-body collapse {open}'>"
-               add content
-               addn " </div>"
-               addn "</div>"
-       end
-end
-
-redef class DocComposite
-       super Template
-
-       # HTML anchor id
-       var html_id: String is writable, lazy do return id
-
-       # Title to display if any.
-       #
-       # This title can be decorated with HTML.
-       var html_title: nullable Writable is writable, lazy do return title
-
-       # Subtitle to display if any.
-       var html_subtitle: nullable Writable is noinit, writable
-
-       # Render the element title and subtitle.
-       private fun render_title do
-               if html_title != null then
-               var header = new Header(hlvl, html_title.write_to_string)
-               header.css_classes.add "signature"
-               addn header
-               end
-               if html_subtitle != null then
-                       addn "<div class='info subtitle'>"
-                       addn html_subtitle.write_to_string
-                       addn "</div>"
-               end
-       end
-
-       # Render the element body.
-       private fun render_body do
-               for child in children do addn child.write_to_string
-       end
-
-       redef fun rendering do
-               if is_hidden then return
-               render_title
-               render_body
-       end
-
-       # Level <hX> for HTML heading.
-       private fun hlvl: Int do return depth
-
-       # A short, undecorated title that goes in the table of contents.
-       #
-       # By default, returns `html_title.to_s`, subclasses should redefine it.
-       var html_toc_title: nullable String is lazy, writable do
-               if html_title == null then return toc_title
-               return html_title.write_to_string
-       end
-
-       # Render this element in a table of contents.
-       private fun render_toc_item(lst: UnorderedList) do
-               if is_toc_hidden or html_toc_title == null then return
-
-               var content = new Template
-               content.add new Link("#{html_id}", html_toc_title.to_s)
-               if not children.is_empty then
-                       var sublst = new UnorderedList
-                       sublst.css_classes.add "nav"
-                       for child in children do
-                               child.render_toc_item(sublst)
-                       end
-                       content.add sublst
-               end
-               lst.add_li new ListItem(content)
-       end
-
-       # ID used in HTML tab labels.
-       #
-       # We sanitize it for Boostrap JS panels that do not like ":" and "." in ids.
-       var html_tab_id: String is lazy do
-               var id = html_id.replace(":", "")
-               id = id.replace(".", "")
-               return "{id}-tab"
-       end
-end
-
-redef class DocRoot
-       redef fun rendering do
-               for child in children do addn child.write_to_string
-       end
-end
-
-redef class DocSection
-       super BSComponent
-
-       redef fun css_classes do return new Array[String]
-
-       redef fun rendering do
-               if is_hidden then
-                       addn "<a id=\"{html_id}\"></a>"
-                       return
-               end
-               addn "<section{render_css_classes} id=\"{html_id}\">"
-               render_title
-               render_body
-               addn "</section>"
-       end
-end
-
-redef class DocArticle
-       super BSComponent
-
-       redef fun css_classes do return new Array[String]
-
-       redef fun rendering do
-               if is_hidden then return
-               addn "<article{render_css_classes} id=\"{html_id}\">"
-               render_title
-               render_body
-               addn "</article>"
-       end
-end
-
-redef class TabbedGroup
-       redef fun render_body do
-               var tabs = new DocTabs("{html_id}.tabs", "")
-               for child in children do
-                       if child.is_hidden then continue
-                       var title = child.html_toc_title or else child.toc_title or else ""
-                       tabs.add_panel new DocTabPanel(child.html_tab_id, title, child)
-               end
-               addn tabs
-       end
-end
-
-redef class PanelGroup
-       redef var html_title = null
-       redef var toc_title is lazy do return title or else ""
-       redef var is_toc_hidden = true
-end
-
-redef class HomeArticle
-       redef var html_title = "Overview"
-
-       # HTML content to display on the home page.
-       #
-       # This attribute is set by the `doc_render` phase who knows the context.
-       var content: nullable String is noinit, writable
-
-       redef fun render_body do
-               var content = self.content
-               if content != null then add content
-               super
-       end
-end
-
-redef class IndexArticle
-       redef var html_title = "Index"
-
-       redef fun render_body do
-               addn "<div class='container-fluid'>"
-               addn " <div class='row'>"
-               render_list("Modules", mmodules)
-               render_list("Classes", mclasses)
-               render_list("Properties", mprops)
-               addn "</div>"
-               addn "</div>"
-       end
-
-       # Displays a list from the content of `mentities`.
-       private fun render_list(title: String, mentities: Array[MEntity]) do
-               if mentities.is_empty then return
-               addn "<div class='col-xs-4'>"
-               addn new Header(3, title)
-               var lst = new UnorderedList
-               for mentity in mentities do
-                       if mentity isa MProperty then
-                               var tpl = new Template
-                               tpl.add mentity.intro.html_link
-                               tpl.add " ("
-                               tpl.add mentity.intro.mclassdef.mclass.html_link
-                               tpl.add ")"
-                               lst.add_li new ListItem(tpl)
-                       else
-                               lst.add_li new ListItem(mentity.html_link)
-                       end
-               end
-               addn lst
-               addn "</div>"
-       end
-end
-
-redef class MEntityComposite
-       redef var html_title is lazy do return mentity.nitdoc_name
-end
-
-redef class MEntitySection
-       redef var html_title is lazy do return mentity.html_name
-       redef var html_subtitle is lazy do return mentity.html_declaration
-end
-
-redef class ConcernSection
-       redef var html_title is lazy do return "in {mentity.nitdoc_name}"
-end
-
-redef class IntroArticle
-       redef var html_title = null
-
-       # Link to source to display if any.
-       var html_source_link: nullable Writable is noinit, writable
-
-       redef fun render_body do
-               var tabs = new DocTabs("{html_id}.tabs", "")
-               var comment = mentity.html_documentation
-               if mentity isa MPackage then
-                       comment = mentity.html_synopsis
-               end
-               if comment != null then
-                       tabs.add_panel new DocTabPanel("{html_tab_id}-comment", "Comment", comment)
-               end
-               for child in children do
-                       if child.is_hidden then continue
-                       var title = child.html_toc_title or else child.toc_title or else ""
-                       tabs.add_panel new DocTabPanel(child.html_tab_id, title, child)
-               end
-               var lnk = html_source_link
-               if lnk != null then
-                       tabs.drop_list.items.add new ListItem(lnk)
-               end
-               addn tabs
-       end
-end
-
-redef class ConcernsArticle
-       redef var html_title = "Concerns"
-       redef fun render_body do add concerns.html_list
-end
-
-redef class DefinitionListArticle
-       redef var html_title is lazy do
-               var title = new Template
-               title.add mentity.html_icon
-               title.add mentity.html_link
-               return title
-       end
-
-       redef var html_subtitle is lazy do return mentity.html_namespace
-       redef var html_toc_title is lazy do return mentity.html_name
-end
-
-redef class DefinitionArticle
-       redef var html_title is lazy do return mentity.html_name
-       redef var html_subtitle is lazy do return mentity.html_declaration
-
-       # Does `self` display only it's title and no body?
-       #
-       # FIXME diff hack
-       var is_no_body: Bool = false is writable
-
-       # Does `self` display only the short content as definition?
-       #
-       # FIXME diff hack
-       var is_short_comment: Bool = false is writable
-
-       # Link to source to display if any.
-       var html_source_link: nullable Writable is noinit, writable
-
-       redef fun render_body do
-               var tabs = new DocTabs("{html_id}.tabs", "")
-               if not is_no_body then
-                       var comment
-                       if is_short_comment or mentity isa MPackage then
-                               comment = mentity.html_synopsis
-                       else
-                               comment = mentity.html_documentation
-                       end
-                       if comment != null then
-                               tabs.add_panel new DocTabPanel("{html_tab_id}-comment", "Comment", comment)
-                       end
-               end
-               for child in children do
-                       if child.is_hidden then continue
-                       var title = child.html_toc_title or else child.toc_title or else ""
-                       tabs.add_panel new DocTabPanel(child.html_tab_id, title, child)
-               end
-               var lnk = html_source_link
-               if lnk != null then
-                       tabs.drop_list.items.add new ListItem(lnk)
-               end
-               addn tabs
-       end
-end
-
-redef class MEntitiesListArticle
-       redef fun render_body do
-               var lst = new UnorderedList
-               lst.css_classes.add "list-unstyled list-definition"
-               for mentity in mentities do
-                       lst.add_li mentity.html_list_item
-               end
-               add lst
-       end
-end
-
-redef class DefinitionLinArticle
-       redef fun render_body do
-               var lst = new UnorderedList
-               lst.css_classes.add "list-unstyled list-labeled"
-               for mentity in mentities do
-                       if not mentity isa MPropDef then continue # TODO handle all mentities
-                       var tpl = new Template
-                       tpl.add mentity.mclassdef.html_namespace
-                       var comment = mentity.mclassdef.html_synopsis
-                       if comment != null then
-                               tpl.add ": "
-                               tpl.add comment
-                       end
-                       var li = new ListItem(tpl)
-                       li.css_classes.add "signature"
-                       lst.add_li li
-               end
-               add lst
-       end
-end
-
-redef class GraphArticle
-       redef var html_title = null
-
-       # Graph in SVG with clickable map.
-       #
-       # This attribute is set by the `doc_render` phase who knows the context.
-       var svg: nullable String = null is writable
-
-       redef fun render_body do
-               addn "<div class=\"text-center\">"
-               var svg = self.svg
-               if svg != null then add svg
-               addn "</div>"
-       end
-end
-
-redef class ReadmeSection
-       redef var html_id is lazy do
-               return markdown_processor.decorator.strip_id(html_title.as(not null).to_s)
-       end
-
-       redef var html_title is lazy do
-               return markdown_processor.process(title.as(not null))
-       end
-end
-
-redef class ReadmeArticle
-       redef var html_id = ""
-       redef var html_title = null
-       redef var is_toc_hidden = true
-
-       redef fun render_body do
-               add markdown_processor.process(md.trim.write_to_string)
-       end
-end
-
-redef class DocumentationArticle
-       redef var html_title is lazy do
-               var synopsis = mentity.html_synopsis
-               if synopsis == null then return mentity.html_link
-               return "{mentity.html_link.write_to_string} &ndash; {synopsis.write_to_string}"
-       end
-
-       redef var html_subtitle is lazy do return null
-       redef var html_toc_title is lazy do return mentity.html_name
-       redef var is_toc_hidden is lazy do return depth > 3
-
-       redef fun render_body do
-               var tabs = new DocTabs("{html_id}.tabs", "")
-               var comment = mentity.html_comment
-               if comment != null then
-                       tabs.add_panel new DocTabPanel("{html_tab_id}-comment", "Comment", comment)
-               end
-               for child in children do
-                       if child.is_hidden then continue
-                       var title = child.html_toc_title or else child.toc_title or else ""
-                       tabs.add_panel new DocTabPanel(child.html_tab_id, title, child)
-               end
-               addn tabs
-       end
-end
diff --git a/src/doc/html_templates/model_html.nit b/src/doc/html_templates/model_html.nit
deleted file mode 100644 (file)
index 8e89dd4..0000000
+++ /dev/null
@@ -1,676 +0,0 @@
-# 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.
-
-# Translate mentities to html blocks.
-module model_html
-
-import model
-import doc::doc_down
-import html::bootstrap
-
-redef class MEntity
-
-       # Returns the MEntity name escaped for html.
-       #
-       # * MPackage: `foo`
-       # * MGroup: `foo`
-       # * MModule: `foo`
-       # * MClass: `Foo[E]`
-       # * MClassDef: `Foo[E]`
-       # * MProperty: `foo(e)`
-       # * MPropdef: `foo(e)`
-       var html_name: String is lazy do return name.html_escape
-
-       # Returns the MEntity full_name escaped for html.
-       var html_full_name: String is lazy do return full_name.html_escape
-
-       # Link to MEntity in the web server.
-       # TODO this should be parameterizable... but how?
-       fun html_link: Link do return new Link("/doc/{full_name}", html_name)
-
-       # Returns the list of keyword used in `self` declaration.
-       fun html_modifiers: Array[String] is abstract
-
-       # Returns the complete MEntity declaration decorated with HTML.
-       #
-       # * MPackage: `package foo`
-       # * MGroup: `group foo`
-       # * MModule: `module foo`
-       # * MClass: `private abstract class Foo[E: Object]`
-       # * MClassDef: `redef class Foo[E]`
-       # * MProperty: `private fun foo(e: Object): Int`
-       # * MPropdef: `redef fun foo(e)`
-       fun html_declaration: Template do
-               var tpl = new Template
-               tpl.add "<span>"
-               tpl.add html_modifiers.join(" ")
-               tpl.add " "
-               tpl.add html_link
-               tpl.add "</span>"
-               return tpl
-       end
-
-       # Returns `self` namespace decorated with HTML links.
-       #
-       # * MPackage: `mpackage`
-       # * MGroup: `mpackage(::group)`
-       # * MModule: `mgroup::mmodule`
-       # * MClass: `mpackage::mclass`
-       # * MClassDef: `mmodule::mclassdef`
-       # * MProperty: `mclass::mprop`
-       # * MPropdef: `mclassdef:mpropdef`
-       fun html_namespace: Template is abstract
-
-       # Returns the synopsis and the comment of this MEntity formatted as HTML.
-       var html_documentation: nullable Writable is lazy do
-               var mdoc = mdoc_or_fallback
-               if mdoc == null then return null
-               return mdoc.html_documentation
-       end
-
-       # Returns the synopsis of this MEntity formatted as HTML.
-       var html_synopsis: nullable Writable is lazy do
-               var mdoc = mdoc_or_fallback
-               if mdoc == null then return null
-               return mdoc.html_synopsis
-       end
-
-       # Returns the the comment without the synopsis formatted as HTML.
-       var html_comment: nullable Writable is lazy do
-               var mdoc = mdoc_or_fallback
-               if mdoc == null then return null
-               return mdoc.html_comment
-       end
-
-       # Icon that will be displayed before the title
-       fun html_icon: BSIcon do
-               var icon = new BSIcon("tag")
-               icon.css_classes.add_all(css_classes)
-               return icon
-       end
-
-       # CSS classes used to decorate `self`.
-       #
-       # Mainly used for icons.
-       var css_classes = new Array[String]
-end
-
-redef class MPackage
-       redef var html_modifiers = ["package"]
-       redef fun html_namespace do return html_link
-       redef var css_classes = ["public"]
-end
-
-redef class MGroup
-       redef var html_modifiers = ["group"]
-
-       # Depends if `self` is root or not.
-       #
-       # * If root `mpackage`.
-       # * Else `mpackage::self`.
-       redef fun html_namespace do
-               var tpl = new Template
-               tpl.add mpackage.html_namespace
-               if mpackage.root != self then
-                       tpl.add "::"
-                       tpl.add html_link
-               end
-               return tpl
-       end
-
-       redef var css_classes = ["public"]
-end
-
-redef class MModule
-
-       redef var html_modifiers = ["module"]
-
-       # Depends if `self` belongs to a MGroup.
-       #
-       # * If mgroup `mgroup::self`.
-       # * Else `self`.
-       redef fun html_namespace do
-               var mgroup = self.mgroup
-               var tpl = new Template
-               if mgroup != null then
-                       tpl.add mgroup.html_namespace
-                       tpl.add "::"
-               end
-               tpl.add html_link
-               return tpl
-       end
-
-       redef var css_classes = ["public"]
-end
-
-redef class MClass
-       # Format: `Foo[E]`
-       redef var html_name is lazy do
-               var tpl = new Template
-               tpl.add name.html_escape
-               if arity > 0 then
-                       tpl.add "["
-                       var parameter_names = new Array[String]
-                       for p in mparameters do
-                               parameter_names.add(p.html_name)
-                       end
-                       tpl.add parameter_names.join(", ")
-                       tpl.add "]"
-               end
-               return tpl.write_to_string
-       end
-
-       redef fun html_modifiers do return intro.html_modifiers
-       redef fun html_declaration do return intro.html_declaration
-
-       # Returns `mpackage::self`.
-       redef fun html_namespace do
-               var mgroup = intro_mmodule.mgroup
-               var tpl = new Template
-               if mgroup != null then
-                       tpl.add mgroup.mpackage.html_namespace
-                       tpl.add "::"
-               end
-               tpl.add "<span>"
-               tpl.add html_link
-               tpl.add "</span>"
-               return tpl
-       end
-
-       # Returns `intro.html_short_signature`.
-       fun html_short_signature: Template do return intro.html_short_signature
-
-       # Returns `intro.html_signature`.
-       fun html_signature: Template do return intro.html_signature
-
-       redef fun html_icon do return intro.html_icon
-       redef fun css_classes do return intro.css_classes
-end
-
-redef class MClassDef
-       # Depends if `self` is an intro or not.
-       #
-       # * If intro contains the visibility and kind.
-       # * If redef contains the `redef` keyword and kind.
-       redef fun html_modifiers do
-               var res = new Array[String]
-               if not is_intro then
-                       res.add "redef"
-               else
-                       if mclass.visibility != public_visibility then
-                               res.add mclass.visibility.to_s
-                       end
-               end
-               res.add mclass.kind.to_s
-               return res
-       end
-
-       # Depends if `self` is an intro or not.
-       #
-       # For intro: `private abstract class Foo[E: Object]`
-       # For redef: `redef class Foo[E]`
-       redef fun html_declaration do
-               var tpl = new Template
-               tpl.add "<span>"
-               tpl.add html_modifiers.join(" ")
-               tpl.add " "
-               tpl.add html_link
-               if is_intro then
-                       tpl.add html_signature
-               else
-                       tpl.add html_short_signature
-               end
-               tpl.add "</span>"
-               return tpl
-       end
-
-       # Returns `mmodule::self`
-       redef fun html_namespace do
-               var tpl = new Template
-               tpl.add mmodule.html_namespace
-               tpl.add "::<span>"
-               tpl.add mclass.html_link
-               tpl.add "</span>"
-               return tpl
-       end
-
-       # Returns the MClassDef generic signature without static bounds.
-       fun html_short_signature: Template do
-               var tpl = new Template
-               var mparameters = mclass.mparameters
-               if not mparameters.is_empty then
-                       tpl.add "["
-                       for i in [0..mparameters.length[ do
-                               tpl.add mparameters[i].html_name
-                               if i < mparameters.length - 1 then tpl.add ", "
-                       end
-                       tpl.add "]"
-               end
-               return tpl
-       end
-
-       # Returns the MClassDef generic signature with static bounds.
-       fun html_signature: Template do
-               var tpl = new Template
-               var mparameters = mclass.mparameters
-               if not mparameters.is_empty then
-                       tpl.add "["
-                       for i in [0..mparameters.length[ do
-                               tpl.add "{mparameters[i].html_name}: "
-                               tpl.add bound_mtype.arguments[i].html_signature
-                               if i < mparameters.length - 1 then tpl.add ", "
-                       end
-                       tpl.add "]"
-               end
-               return tpl
-       end
-
-       redef fun css_classes do
-               var set = new HashSet[String]
-               if is_intro then set.add "intro"
-               for m in mclass.intro.modifiers do set.add m.to_cmangle
-               for m in modifiers do set.add m.to_cmangle
-               return set.to_a
-       end
-
-
-       # List of all modifiers like redef, private etc.
-       var modifiers: Array[String] is lazy do
-               var res = new Array[String]
-               if not is_intro then
-                       res.add "redef"
-               else
-                       res.add mclass.visibility.to_s
-               end
-               res.add mclass.kind.to_s
-               return res
-       end
-end
-
-redef class MProperty
-       redef fun html_modifiers do return intro.html_modifiers
-       redef fun html_declaration do return intro.html_declaration
-
-       # Returns `mclass::self`.
-       redef fun html_namespace do
-               var tpl = new Template
-               tpl.add intro_mclassdef.mclass.html_namespace
-               tpl.add "::<span>"
-               tpl.add intro.html_link
-               tpl.add "</span>"
-               return tpl
-       end
-
-       # Returns `intro.html_short_signature`.
-       fun html_short_signature: Template do return intro.html_short_signature
-
-       # Returns `intro.html_signature`.
-       fun html_signature: Template do return intro.html_signature
-
-       redef fun css_classes do return intro.css_classes
-end
-
-redef class MPropDef
-       # Depends if `self` is an intro or not.
-       #
-       # * If intro contains the visibility and kind.
-       # * If redef contains the `redef` keyword and kind.
-       redef fun html_modifiers do
-               var res = new Array[String]
-               if not is_intro then
-                       res.add "redef"
-               else
-                       if mproperty.visibility != public_visibility then
-                               res.add mproperty.visibility.to_s
-                       end
-               end
-               return res
-       end
-
-       # Depends if `self` is an intro or not.
-       #
-       # For intro: `private fun foo(e: Object): Bar is abstract`
-       # For redef: `redef fun foo(e) is cached`
-       redef fun html_declaration do
-               var tpl = new Template
-               tpl.add "<span>"
-               tpl.add html_modifiers.join(" ")
-               tpl.add " "
-               if is_intro then
-                       tpl.add html_link
-                       tpl.add html_signature
-               else
-                       tpl.add mproperty.intro.html_link
-                       tpl.add html_short_signature
-               end
-               tpl.add "</span>"
-               return tpl
-       end
-
-       # Returns `mclassdef::self`
-       redef fun html_namespace do
-               var tpl = new Template
-               tpl.add mclassdef.html_namespace
-               tpl.add "::"
-               tpl.add html_link
-               return tpl
-       end
-
-       # Returns the MPropdDef signature without static types.
-       fun html_short_signature: Template is abstract
-
-       # Returns the MPropDef signature with static types.
-       fun html_signature: Template is abstract
-
-       redef fun css_classes do
-               var set = new HashSet[String]
-               if is_intro then set.add "intro"
-               for m in mproperty.intro.modifiers do set.add m.to_cmangle
-               for m in modifiers do set.add m.to_cmangle
-               return set.to_a
-       end
-
-       # List of all modifiers like redef, private, abstract, intern, fun etc.
-       var modifiers: Array[String] is lazy do
-               var res = new Array[String]
-               if not is_intro then
-                       res.add "redef"
-               else
-                       res.add mproperty.visibility.to_s
-               end
-               var mprop = self
-               if mprop isa MVirtualTypeDef then
-                       res.add "type"
-               else if mprop isa MMethodDef then
-                       if mprop.is_abstract then
-                               res.add "abstract"
-                       else if mprop.is_intern then
-                               res.add "intern"
-                       end
-                       if mprop.mproperty.is_init then
-                               res.add "init"
-                       else
-                               res.add "fun"
-                       end
-               end
-               return res
-       end
-end
-
-redef class MAttributeDef
-
-       redef fun html_modifiers do
-               var res = super
-               res.add "var"
-               return res
-       end
-
-       redef fun html_short_signature do return new Template
-
-       redef fun html_signature do
-               var static_mtype = self.static_mtype
-               var tpl = new Template
-               if static_mtype != null then
-                       tpl.add ": "
-                       tpl.add static_mtype.html_signature
-               end
-               return tpl
-       end
-end
-
-redef class MMethodDef
-
-       # FIXME annotation should be handled in their own way
-       redef fun html_modifiers do
-               if mproperty.is_init then
-                       var res = new Array[String]
-                       if mproperty.visibility != public_visibility then
-                               res.add mproperty.visibility.to_s
-                       end
-                       return res
-               end
-               var res = super
-               if is_abstract then
-                       res.add "abstract"
-               else if is_intern then
-                       res.add "intern"
-               end
-               res.add "fun"
-               return res
-       end
-
-       redef fun html_declaration do
-               if mproperty.is_init then
-                       var tpl = new Template
-                       tpl.add "<span>"
-                       tpl.add html_modifiers.join(" ")
-                       tpl.add " "
-                       tpl.add html_link
-                       tpl.add html_signature
-                       tpl.add "</span>"
-                       return tpl
-               end
-               return super
-       end
-
-       redef fun html_short_signature do
-               var new_msignature = self.new_msignature
-               if mproperty.is_root_init and new_msignature != null then
-                       return new_msignature.html_short_signature
-               end
-               return msignature.as(not null).html_short_signature
-       end
-
-       redef fun html_signature do
-               var new_msignature = self.new_msignature
-               if mproperty.is_root_init and new_msignature != null then
-                       return new_msignature.html_signature
-               end
-               return msignature.as(not null).html_signature
-       end
-end
-
-redef class MVirtualTypeProp
-       redef fun html_link do return mvirtualtype.html_link
-end
-
-redef class MVirtualTypeDef
-
-       redef fun html_modifiers do
-               var res = super
-               res.add "type"
-               return res
-       end
-
-       redef fun html_short_signature do return new Template
-
-       redef fun html_signature do
-               var bound = self.bound
-               var tpl = new Template
-               if bound == null then return tpl
-               tpl.add ": "
-               tpl.add bound.html_signature
-               return tpl
-       end
-end
-
-redef class MType
-       # Returns the signature of this type whithout bounds.
-       fun html_short_signature: Template is abstract
-
-       # Returns the signature of this type.
-       fun html_signature: Template is abstract
-end
-
-redef class MClassType
-       redef fun html_link do return mclass.html_link
-       redef fun html_short_signature do return html_link
-       redef fun html_signature do return html_link
-end
-
-redef class MNullableType
-       redef fun html_short_signature do
-               var tpl = new Template
-               tpl.add "nullable "
-               tpl.add mtype.html_short_signature
-               return tpl
-       end
-
-       redef fun html_signature do
-               var tpl = new Template
-               tpl.add "nullable "
-               tpl.add mtype.html_signature
-               return tpl
-       end
-end
-
-redef class MGenericType
-       redef fun html_short_signature do
-               var lnk = html_link
-               var tpl = new Template
-               tpl.add new Link(lnk.href, mclass.name.html_escape, lnk.title)
-               tpl.add "["
-               for i in [0..arguments.length[ do
-                       tpl.add arguments[i].html_short_signature
-                       if i < arguments.length - 1 then tpl.add ", "
-               end
-               tpl.add "]"
-               return tpl
-       end
-
-       redef fun html_signature do
-               var lnk = html_link
-               var tpl = new Template
-               tpl.add new Link(lnk.href, mclass.name.html_escape, lnk.title)
-               tpl.add "["
-               for i in [0..arguments.length[ do
-                       tpl.add arguments[i].html_signature
-                       if i < arguments.length - 1 then tpl.add ", "
-               end
-               tpl.add "]"
-               return tpl
-       end
-end
-
-redef class MParameterType
-       redef fun html_short_signature do return html_link
-       redef fun html_signature do return html_link
-end
-
-redef class MVirtualType
-       redef fun html_signature do return html_link
-end
-
-redef class MSignature
-       redef fun html_short_signature do
-               var tpl = new Template
-               if not mparameters.is_empty then
-                       tpl.add "("
-                       for i in [0..mparameters.length[ do
-                               tpl.add mparameters[i].html_short_signature
-                               if i < mparameters.length - 1 then tpl.add ", "
-                       end
-                       tpl.add ")"
-               end
-               return tpl
-       end
-
-       redef fun html_signature do
-               var tpl = new Template
-               if not mparameters.is_empty then
-                       tpl.add "("
-                       for i in [0..mparameters.length[ do
-                               tpl.add mparameters[i].html_signature
-                               if i < mparameters.length - 1 then tpl.add ", "
-                       end
-                       tpl.add ")"
-               end
-               var return_mtype = self.return_mtype
-               if return_mtype != null then
-                       tpl.add ": "
-                       tpl.add return_mtype.html_signature
-               end
-               return tpl
-       end
-end
-
-redef class MParameter
-
-       # Returns `self` name and ellipsys if any.
-       fun html_short_signature: Template do
-               var tpl = new Template
-               tpl.add name
-               if is_vararg then tpl.add "..."
-               return tpl
-       end
-
-       # Returns `self` name with it's static type and ellipsys if any.
-       fun html_signature: Template do
-               var tpl = new Template
-               tpl.add "{name}: "
-               tpl.add mtype.html_signature
-               if is_vararg then tpl.add "..."
-               return tpl
-       end
-end
-
-redef class MEntityTree
-       # Render `self` as a hierarchical UnorderedList.
-       fun html_list: UnorderedList do
-               var lst = new_unordered_list
-               for r in roots do
-                       var li = new_mentity_item(r)
-                       lst.add_li li
-                       build_html_list(r, li)
-               end
-               return lst
-       end
-
-       # Build the html list recursively.
-       private fun build_html_list(e: MEntity, li: ListItem) do
-               if not sub.has_key(e) then return
-               var subs = sub[e]
-               var lst = new_unordered_list
-               for e2 in subs do
-                       if e2 isa MGroup and e2.is_root then
-                               build_html_list(e2, li)
-                       else
-                               var sli = new_mentity_item(e2)
-                               lst.add_li sli
-                               build_html_list(e2, sli)
-                       end
-               end
-               var text = new Template
-               text.add li.text
-               if not lst.is_empty then text.add lst
-               li.text = text
-       end
-
-       # HTML unordered List used to compose the tree.
-       #
-       # Redefine this method to add custom CSS classes or other html attributes.
-       protected fun new_unordered_list: UnorderedList do return new UnorderedList
-
-       # Return a li element for `mconcern` that can be displayed in a concern list
-       protected fun new_mentity_item(mentity: MEntity): ListItem do
-               var tpl = new Template
-               tpl.add mentity.html_link
-               var comment = mentity.html_synopsis
-               if comment != null then
-                       tpl.add ": "
-                       tpl.add comment
-               end
-               return new ListItem(tpl)
-       end
-end
similarity index 85%
rename from src/doc/doc.nit
rename to src/doc/static/static.nit
index a6fb971..c1a51f5 100644 (file)
@@ -12,8 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Nitdoc generation framework.
-module doc
+# Nitdoc generation framework
+module static
 
-import doc_base
-import doc_phases
+import static::static_html
+import static::static_index
diff --git a/src/doc/static/static_base.nit b/src/doc/static/static_base.nit
new file mode 100644 (file)
index 0000000..a7ae6bb
--- /dev/null
@@ -0,0 +1,352 @@
+# 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.
+
+# Base entities shared by all the nitdoc code
+module static_base
+
+import static_cards
+import modelize
+
+intrude import markdown::wikilinks
+
+# The model of a Nitdoc documentation
+class DocModel
+
+       # Model used to select entities
+       var model: Model
+
+       # Mainmodule to resolve linearization
+       var mainmodule: MModule
+
+       # ModelBuilder used to retrieve AST nodes
+       var modelbuilder: ModelBuilder
+
+       # Catalog for building the homepage
+       var catalog: Catalog
+
+       # Model filters applied to the whole documentation
+       var filter: ModelFilter
+
+       # Specific Markdown processor to use within Nitdoc
+       var md_processor: MarkdownProcessor is lazy do
+               var parser = new CommandParser(model, mainmodule, modelbuilder, catalog)
+               var proc = new CmdMarkdownProcessor(parser)
+               proc.decorator = new CmdDecorator(model)
+               return proc
+       end
+
+       # Specific Markdown processor to use within Nitdoc
+       var inline_processor: MarkdownProcessor is lazy do
+               var parser = new CommandParser(model, mainmodule, modelbuilder, catalog)
+               var proc = new CmdMarkdownProcessor(parser)
+               proc.decorator = new CmdInlineDecorator(model)
+               return proc
+       end
+
+       # Do not generate dot graphs
+       var no_dot = false is writable
+
+       # Do not generate higlighted code
+       var no_code = false is writable
+
+       # Url to code when `no_code` is true
+       var code_url: nullable String = null is writable
+
+       # Url to assets
+       var share_url: nullable String = null is writable
+
+       # Custom menu brand
+       var custom_brand: nullable String = null is writable
+
+       # Custom homepage title
+       var custom_title: nullable String = null is writable
+
+       # Custom page footer
+       var custom_footer: nullable String = null is writable
+
+       # Custom homepage intro text
+       var custom_intro: nullable String = null is writable
+
+       # Optional tracker url
+       var tracker_url: nullable String = null is writable
+
+       # Optional tracker site id
+       var piwik_site_id: nullable String = null is writable
+
+       # Used to sort sidebar elements by name.
+       var name_sorter = new MEntityNameSorter
+end
+
+# Documentation pages
+
+# A documentation page abstraction
+class DocPage
+
+       # Title of this page
+       var title: String is writable
+
+       # Page tab panels
+       #
+       # Nitdoc pages are tabulated.
+       # If a page has only one tab, it is presented as a single page.
+       # With more than one tab, the HTML rendering process adds tab headers and
+       # links.
+       var tabs: Array[DocTab] = [main_tab] is lazy
+
+       # The page main tab
+       #
+       # For most pages this tab is suffisent.
+       # Subclasses can add more tabs.
+       var main_tab = new DocTab("main", "Main")
+
+       redef fun to_s do return title
+end
+
+# The Nitdoc overview page that displays the nit packages catalog
+class PageHome
+       super DocPage
+end
+
+# A DocPage documenting a MEntity
+abstract class PageMEntity
+       super DocPage
+       autoinit mentity
+
+       new(mentity: MEntity) do
+               if mentity isa MPackage then
+                       return new PageMPackage(mentity)
+               else if mentity isa MGroup then
+                       return new PageMGroup(mentity)
+               else if mentity isa MModule then
+                       return new PageMModule(mentity)
+               else if mentity isa MClass then
+                       return new PageMClass(mentity)
+               else if mentity isa MProperty then
+                       return new PageMProperty(mentity)
+               else
+                       print "Not yet implemented: Page for {mentity.full_name} ({mentity.class_name})"
+                       abort
+               end
+       end
+
+       # Type of MEntity documented by this page
+       type MENTITY: MEntity
+
+       # MEntity documented by this page
+       var mentity: MENTITY
+
+       # For mentities the main tab is the doc tab
+       redef var main_tab = new DocTab("doc", "Doc", true, "book")
+
+       # API tab
+       #
+       # Where the MEntity API (groups, modules, classes, props) is displayed
+       var api_tab = new DocTab("api", "API", false, "list")
+
+       # Dependencies tab
+       #
+       # Where the MEntity importation or inheritance is displayed
+       var dep_tab = new DocTab("inh", "Dependencies", false, "object-align-vertical")
+
+       # Code tab
+       #
+       # Since all mentities does not have code, this tab in not in the `tabs` list
+       # by default.
+       var code_tab = new DocTab("code", "Code", false, "console")
+
+       # Lienarization tab
+       #
+       # Since all mentities does not have a linearization, this tab in not in the
+       # `tabs` list by default.
+       var lin_tab = new DocTab("lin", "Linearization", false, "arrow-down")
+
+       redef var tabs = [main_tab, api_tab, dep_tab] is lazy
+       redef var title is lazy do return mentity.name
+end
+
+# A documentation page for a MPackage
+class PageMPackage
+       super PageMEntity
+
+       redef type MENTITY: MPackage
+       redef var api_tab = new DocTab("api", "Groups & Modules", false, "list")
+end
+
+# A documentation page about a MGroup
+class PageMGroup
+       super PageMEntity
+
+       redef type MENTITY: MGroup
+       redef var api_tab = new DocTab("api", "Subgroups & Modules", false, "list")
+end
+
+# A documentation page about a MModule
+class PageMModule
+       super PageMEntity
+
+       redef type MENTITY: MModule
+       redef var api_tab = new DocTab("api", "Classes", false, "list")
+       redef var dep_tab = new DocTab("inh", "Importation", false, "object-align-vertical")
+       redef var tabs = [main_tab, api_tab, dep_tab, code_tab] is lazy
+end
+
+# A documentation page about a MClass
+class PageMClass
+       super PageMEntity
+
+       redef type MENTITY: MClass
+       redef var api_tab = new DocTab("api", "All properties", false, "list")
+       redef var dep_tab = new DocTab("inh", "Inheritance", false, "object-align-vertical")
+       redef var tabs = [main_tab, api_tab, dep_tab, lin_tab] is lazy
+end
+
+# A documentation page about a MProperty
+class PageMProperty
+       super PageMEntity
+
+       redef type MENTITY: MProperty
+       redef var tabs = [main_tab, lin_tab] is lazy
+end
+
+# A page that lists the packages maintained and contributed by a person
+class PagePerson
+       super DocPage
+       autoinit person
+
+       # Person displayed in this page
+       var person: Person
+
+       redef var title is lazy do return person.name
+end
+
+# A page that lists the packages related to a tab
+class PageTag
+       super DocPage
+       autoinit tag
+
+       # Tag displayed in this page
+       var tag: String
+
+       redef var title is lazy do return tag
+end
+
+# Breadcrumbs
+
+redef class MEntity
+       # MEntities composing the breadcrumbs of a nitdoc page
+       fun nitdoc_breadcrumbs: Array[MEntity] is abstract
+end
+
+redef class MPackage
+       redef var nitdoc_breadcrumbs = [self: MEntity] is lazy
+end
+
+redef class MGroup
+       redef var nitdoc_breadcrumbs is lazy do
+               var parent = self.parent
+               if parent != null then
+                       return parent.nitdoc_breadcrumbs + [self]
+               end
+               return mpackage.nitdoc_breadcrumbs
+       end
+end
+
+redef class MModule
+       redef var nitdoc_breadcrumbs is lazy do
+               var mgroup = self.mgroup
+               if mgroup != null then
+                       return mgroup.nitdoc_breadcrumbs + [self]
+               end
+               return [self]
+       end
+end
+
+redef class MClass
+       redef var nitdoc_breadcrumbs is lazy do
+               return intro_mmodule.nitdoc_breadcrumbs + [self]
+       end
+end
+
+redef class MClassDef
+       redef var nitdoc_breadcrumbs is lazy do
+               var res = new Array[MEntity].from(mmodule.nitdoc_breadcrumbs)
+               res.add self
+               return res
+       end
+end
+
+redef class MProperty
+       redef var nitdoc_breadcrumbs is lazy do
+               var res = new Array[MEntity].from(intro_mclassdef.mclass.nitdoc_breadcrumbs)
+               res.add self
+               return res
+       end
+end
+
+redef class MPropDef
+       redef var nitdoc_breadcrumbs is lazy do
+               var res = new Array[MEntity].from(mclassdef.nitdoc_breadcrumbs)
+               res.add self
+               return res
+       end
+end
+
+# Documentation base elements
+
+# A documentation tabulated view
+class DocTab
+
+       # Tab uniq id in the page
+       var id: String is writable
+
+       # Table title
+       var title: String is writable
+
+       # Is this tab displayed by default?
+       var is_active = false is optional, writable
+
+       # Tab header icon
+       var icon: nullable String = null is optional, writable
+
+       # Tab content
+       var content = new Array[StaticCard]
+
+       # Tab sidebar
+       var sidebar = new DocSidebar
+
+       # Tab metadata sidebar
+       var metadata = new DocSidebar
+
+       # Is this tab empty?
+       fun is_empty: Bool do return content.is_empty
+end
+
+# A fictive tab used to display a link
+class DocTabLink
+       super DocTab
+       autoinit(id, title, icon, url)
+
+       # Link to open when the tab is clicked
+       var url: String
+end
+
+# Nitdoc sidebar abstraction
+class DocSidebar
+
+       # A sidebar contains `StaticCard`
+       var cards = new Array[StaticCard]
+
+       # Is this sidebar empty?
+       fun is_empty: Bool do return cards.is_empty
+end
diff --git a/src/doc/static/static_cards.nit b/src/doc/static/static_cards.nit
new file mode 100644 (file)
index 0000000..e589ca6
--- /dev/null
@@ -0,0 +1,667 @@
+# 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.
+
+# Cards templates for the static documentation
+module static_cards
+
+import doc::commands::commands_graph
+import doc::commands::commands_catalog
+import doc::commands::commands_docdown
+import templates_html
+
+# A card that can be rendered to HTML
+#
+# Basically, these cards are templates with additionnal data and behavior.
+abstract class StaticCard
+       super Template
+
+       # Card title
+       var title: String is writable
+
+       # Card id
+       var id: String is writable
+end
+
+# A list of cards
+class CardList
+       super StaticCard
+
+       # Cards contained in this list
+       var cards = new Array[StaticCard] is writable
+
+       redef fun rendering do
+               addn "<div id='{id}' class='card-list'>"
+               for card in cards do
+                       addn card
+               end
+               addn "</div>"
+       end
+end
+
+# Doc elements
+
+# A card that display custom text data
+class CardText
+       super StaticCard
+       autoinit(content)
+
+       # Custom content from options
+       var content: nullable String is writable
+
+       redef var id = "home"
+       redef var title = "Home"
+
+       redef fun rendering do
+               var content = self.content
+               if content == null then return
+               addn "<div>"
+               addn content
+               addn "</div>"
+               addn "<hr/>"
+       end
+end
+
+# A heading section
+#
+# It displays an heading at a specific level from 1 to 6.
+class CardSection
+       super StaticCard
+       autoinit(level, title, subtitle)
+
+       # Section heading level
+       var level: Int is writable
+
+       # Section subtitle
+       var subtitle: nullable String is writable
+
+       redef var id = title.to_cmangle is lazy
+
+       redef fun rendering do
+               addn "<h{level} id='{id}'>{title}</h{level}>"
+       end
+end
+
+# A page header
+class CardPageHeader
+       super CardSection
+       autoinit(title, subtitle)
+
+       redef var level = 2
+
+       redef fun rendering do
+               addn "<div class='page-header'>"
+               super
+               var subtitle = self.subtitle
+               if subtitle != null then
+                       addn "<p class='text-muted'>"
+                       addn subtitle
+                       addn "</p>"
+               end
+               addn "</div>"
+       end
+end
+
+# A card that displays a summary of a list of cards
+class CardSummary
+       super CardList
+       autoinit(no_title)
+
+       redef var id = "summary"
+       redef var title = "Summary"
+
+       # Show the summary title
+       var no_title: Bool = false is optional, writable
+
+       redef fun rendering do
+               if not no_title then
+                       addn "<h4>Summary</h4>"
+               end
+               addn "<div class='summary'>"
+               addn " <ul class='list-unstyled'>"
+               var sections = new Array[CardSection]
+               for card in cards do
+                       if card isa CardSection then
+                               while sections.not_empty and sections.last.level >= card.level do
+                                       sections.pop
+                               end
+                               sections.add card
+                       end
+                       var level = if sections.is_empty then 1 else sections.last.level
+                       if not card isa CardSection then level += 1
+                       addn "<li><a href='#{card.id}'><h{level}>{card.title}</h{level}></a></li>"
+               end
+               addn " </ul>"
+               addn "</div>"
+       end
+end
+
+# A card that displays the summary of a Markdown document
+class CardMdSummary
+       super CardMDoc
+       autoinit(md_processor, headlines)
+
+       # Markdown processor used to extract and render the content
+       var md_processor: MarkdownProcessor is writable
+
+       # Headlines found in the document
+       var headlines: ArrayMap[String, HeadLine] is writable
+
+       redef var id = "summary"
+       redef var title = "Summary"
+
+       redef fun rendering do
+               addn "<h4>Summary</h4>"
+               addn "<div class='summary'>"
+               addn " <ul class='list-unstyled'>"
+               for id, headline in headlines do
+                       var level = headline.level
+                       var title = md_processor.process(headline.title)
+                       addn "<li><a href='#{id}'><h{level}>{title}</h{level}></a></li>"
+               end
+               addn " </ul>"
+               addn "</div>"
+       end
+end
+
+# MEntity related cards
+
+# A card about a mentity
+#
+# It displays the documentation about the model entity.
+class CardMEntity
+       super StaticCard
+       autoinit(mentity, full_doc)
+
+       # MEntity displayed in this card
+       var mentity: MEntity is writable
+
+       # Render the mentity full documentation?
+       var full_doc = false is optional, writable
+
+       redef var id = mentity.html_id is lazy
+       redef var title = mentity.html_name is lazy
+
+       redef fun rendering do
+               addn """
+               <div id='{{{id}}}' class='card'>
+                       <div class='card-left text-center'>
+                       {{{mentity.html_icon.write_to_string}}}
+                       </div>
+                       <div class='card-body'>
+                               <h5 class='card-heading'>
+                                       {{{mentity.html_declaration.write_to_string}}}
+                               </h5>
+                               <p><small>{{{mentity.html_namespace.write_to_string}}}</small></p>"""
+               var mdoc = mentity.mdoc_or_fallback
+               if mdoc != null then
+                       if full_doc then
+                               addn mdoc.html_documentation
+                       else
+                               addn mdoc.html_synopsis
+                       end
+               end
+               addn """
+                       </div>
+               </div>"""
+       end
+end
+
+# A card that displays the content of a MDoc
+class CardMDoc
+       super CardMEntity
+       autoinit(mentity, mdoc, full_doc)
+
+       # MDoc to display in this card
+       var mdoc: nullable MDoc is writable
+
+       redef fun rendering do
+               var mdoc = self.mdoc
+               if mdoc == null then return
+               addn "<div id='{id}' class='card'>"
+               addn " <div class='card-body nitdoc'>"
+               addn mdoc.html_documentation
+               addn " </div>"
+               addn "</div>"
+       end
+end
+
+# A card about the inheritance of a MEntity
+class CardInheritance
+       super CardMEntity
+
+       # Ancestors list
+       var ancestors: nullable Array[MEntity] is writable
+
+       # Parents list
+       var parents: nullable Array[MEntity] is writable
+
+       # Children list
+       var children: nullable Array[MEntity] is writable
+
+       # Descendants list
+       var descendants: nullable Array[MEntity] is writable
+
+       redef var id = "inh_{super}" is lazy
+       redef var title = "Inheritance" is lazy
+
+       redef fun rendering do
+               var ancestors = self.ancestors
+               var descendants = self.descendants
+               if ancestors == null and parents == null and
+                       children == null and descendants == null then return
+
+               addn "<div id='{id}' class='card'>"
+               addn " <div class='card-body'>"
+               if ancestors != null and ancestors.length <= 10 then
+                       render_list("Ancestors", ancestors)
+               else
+                       render_list("Parents", parents)
+               end
+               if descendants != null and descendants.length <= 10 then
+                       render_list("Descendants", descendants)
+               else
+                       render_list("Children", children)
+               end
+               addn " </div>"
+               addn "</div>"
+       end
+
+       private fun render_list(title: String, mentities: nullable Array[MEntity]) do
+               if mentities == null or mentities.is_empty then return
+               addn "<h4 id='{id}'>{title}</h4>"
+               addn "<ul class='list-unstyled'>"
+               for mentity in mentities do
+                       addn mentity.html_list_item
+               end
+               addn "</ul>"
+       end
+end
+
+# A card about the linearization of a MEntity
+class CardLinearizationList
+       super CardMEntity
+
+       # Linearization cards contained in this list
+       var cards = new Array[CardLinearizationDef] is writable
+
+       redef var id = "lin_{super}" is lazy
+       redef var title = "Linearization" is lazy
+
+       redef fun rendering do
+               if cards.is_empty then return
+
+               addn "<div id='{id}'>"
+               for card in cards do
+                       addn card
+                       if card == cards.last then break
+                       addn "<h4 class='text-muted text-center'>"
+                       addn " <span class='glyphicon glyphicon-chevron-up'></span>"
+                       addn "</h4>"
+               end
+               addn "</div>"
+       end
+end
+
+# A card about a definition in a linearization list
+class CardLinearizationDef
+       super CardCode
+
+       # Is this card displayed by default?
+       var is_active: Bool = false is optional, writable
+
+       # Link to external code repository
+       #
+       # Used if `node` is null
+       var url: nullable String = null is optional, writable
+
+       redef var id = "def_{super}" is lazy
+       redef var title = mentity.full_name is lazy
+
+       redef fun rendering do
+               var url = self.url
+
+               var cin = if is_active then "in" else ""
+               var active = if is_active then "active" else ""
+               addn """
+               <div class='card {{{active}}}' id='{{{id}}}'>
+                       <div class='card-body'>
+                               <h5>
+                                       {{{mentity.html_icon.write_to_string}}}
+                                       {{{mentity.html_namespace.write_to_string}}}"""
+               if node != null then
+                       addn """
+                                       <div class='btn-bar'>
+                                               <button class='btn btn-link' data-toggle='collapse'
+                                                 data-target='#{{{mentity.html_id}}}'>
+                                                       <span class='glyphicon glyphicon-console' title='Show code' />
+                                               </button>
+                                       </div>"""
+               else if url != null then
+                       addn """
+                                       <div class='btn-bar'>
+                                               <a class='btn btn-link' href='{{{url}}}'>
+                                                       <span class='glyphicon glyphicon-console' title='Show code' />
+                                               </a>
+                                       </div>"""
+                       var mdoc = mentity.mdoc
+                       if mdoc != null then
+                               addn "<br/><br/>"
+                               addn mdoc.html_documentation
+                       end
+               end
+               addn "</h5>"
+               if node != null then
+                       addn """
+                               <div id='{{{mentity.html_id}}}' class='collapse {{{cin}}}'>
+                                       <pre>"""
+                       render_code
+                       addn """</pre>
+                                       <span class='text-muted'>{{{mentity.location.to_s}}}</span>
+                               </div>"""
+               end
+               addn """
+                       </div>
+               </div>"""
+       end
+end
+
+# A card that displays the code of a MEntity
+class CardCode
+       super CardMEntity
+       autoinit(mentity, node)
+
+       # AST node to display in this card
+       var node: nullable ANode is writable
+
+       redef var id = "code_{super}" is lazy
+       redef var title = "Code"
+
+       redef fun rendering do
+               addn "<div id='{id}' class='card'>"
+               addn " <div class='card-body'>"
+
+               if node != null then
+                       addn "<pre>"
+                       render_code
+                       addn "</pre>"
+               end
+               addn "<span class='text-muted'>{mentity.location}</span>"
+
+               addn " </div>"
+               addn "</div>"
+       end
+
+       private fun render_code do
+               var node = self.node
+               if node == null then return
+               var hl = new HtmlightVisitor
+               hl.show_infobox = false
+               hl.highlight_node node
+               addn hl.html
+       end
+end
+
+# A card that displays a graph
+class CardGraph
+       super CardMEntity
+       autoinit(mentity, graph)
+
+       # Graph to display in this card
+       var graph: InheritanceGraph is writable
+
+       redef var id = "graph_{super}" is lazy
+       redef var title = "Graph"
+
+       redef fun rendering do
+               addn "<div id='{id}' class='card'>"
+               addn " <div class='card-body'>"
+               addn "  <div class='text-center'>"
+               addn graph.graph.to_svg
+               addn "  </div>"
+               addn " </div>"
+               addn "</div>"
+       end
+end
+
+# Catalog related cards
+
+# A card that displays Nit catalog related data
+abstract class CardCatalog
+       super StaticCard
+       autoinit(catalog)
+
+       # Catalog used to extract the data
+       var catalog: Catalog is writable
+end
+
+# A card that displays statistics about a Nit catalog
+class CardCatalogStats
+       super CardCatalog
+
+       redef var id = "catalog_stats"
+       redef var title = "Stats"
+
+       redef fun rendering do
+               addn "<div id='{id}' class='container-fluid'>"
+               for key, value in catalog.catalog_stats.to_map do
+                       addn "<span class='text-muted small'>"
+                       addn " <strong>{value}</strong>&nbsp;<span>{key}</span>&nbsp;"
+                       addn "</span>"
+               end
+               addn "</div>"
+               addn "<hr/>"
+       end
+end
+
+# A card that displays a list of tags
+class CardCatalogTags
+       super CardCatalog
+
+       redef var id = "catalog_tags"
+       redef var title = "Tags"
+
+       # Sorter to sort tags alphabetically
+       var tags_sorter = new CatalogTagsSorter is writable
+
+       redef fun rendering do
+               var tags = catalog.tag2proj.keys.to_a
+               if tags.is_empty then return
+               tags_sorter.sort(tags)
+
+               addn "<h2 id='{id}'>Tags</h2>"
+               addn "<div class='container-fluid'>"
+               for tag in tags do
+                       addn "<div class='col-xs-6 col-sm-3 col-md-2'>"
+                       addn " <span class='badge'>{catalog.tag2proj[tag].length}</span>"
+                       addn " <a href='tag_{tag.to_cmangle}.html'>{tag}</a>"
+                       addn "</div>"
+               end
+               addn "</div>"
+               addn "<hr/>"
+       end
+end
+
+# A card that displays a package from a Nit catalog
+class CardCatalogPackage
+       super CardCatalog
+       super CardMEntity
+       autoinit(catalog, mentity)
+
+       redef var id = "package_{super}" is lazy
+
+       redef fun rendering do
+               var mpackage = self.mentity
+               if not mpackage isa MPackage then return
+
+               addn """
+                       <div id='{{{id}}}' class='card'>
+                        <div class='card-left text-center'>{{{mpackage.html_icon.write_to_string}}}</div>
+                        <div class='card-body' style='width: 75%'>
+                         <h5 class='card-heading'>
+                               {{{mentity.html_declaration.write_to_string}}}
+                               <small>&nbsp;"""
+               for tag in mpackage.metadata.tags do
+                       add "<span>"
+                       add "<a href='tag_{tag.to_cmangle}.html' class='text-muted'>{tag}</a>"
+                       if tag != mpackage.metadata.tags.last then addn ", "
+                       add "</span>"
+               end
+               addn """</small>
+                               </h5>"""
+               var mdoc = mentity.mdoc_or_fallback
+               if mdoc != null then
+                       if full_doc then
+                               addn mdoc.html_documentation
+                       else
+                               addn mdoc.html_synopsis
+                       end
+               end
+               addn " </div>"
+               addn " <div class='card-right' style='width: 25%'>"
+               for maintainer in mpackage.metadata.maintainers do
+                       addn maintainer.to_html
+               end
+               addn " <br>"
+               var license = mpackage.metadata.license
+               if license != null then
+                       addn """
+                                <span class='text-muted'>
+                                 <a href='http://opensource.org/licenses/{{{license}}}' class='text-muted'>
+                                  {{{license}}}
+                                 </a>
+                               </span>"""
+               end
+               addn " </div>"
+               addn "</div>"
+       end
+end
+
+# A card that displays the metadata about a package in the Nit catalog
+class CardMetadata
+       super CardMEntity
+       autoinit(mentity, metadata, stats, deps, clients)
+
+       # Package metadata to display
+       var metadata: MPackageMetadata is writable
+
+       # Package stats
+       var stats: MPackageStats is writable
+
+       # Package dependencies
+       var deps: Array[MPackage] is writable
+
+       # Package clients
+       var clients: Array[MPackage] is writable
+
+       redef var id = "metadata_{super}" is lazy
+       redef var title = "Metadata"
+
+       redef fun rendering do
+               for maintainer in metadata.maintainers do
+                       addn """
+                               <p class='lead'>
+                                       {{{maintainer.to_html}}}
+                               </p>"""
+               end
+               var license = metadata.license
+               if license != null then
+                       addn """
+                               <span class='text-muted'>
+                                       <a href='http://opensource.org/licenses/{{{license}}}'>{{{license}}}</a>
+                                       license
+                               </span>"""
+               end
+
+               var homepage = metadata.homepage
+               var browse = metadata.browse
+               var issues = metadata.issues
+               if homepage != null or browse != null or issues != null then
+                       addn """
+                               <h4>Links</h4>
+                               <ul class='list-unstyled'>"""
+                       if homepage != null then addn "<li><a href='{homepage}'>Homepage</a></li>"
+                       if browse != null then addn "<li><a href='{browse}'>Source Code</a></li>"
+                       if issues != null then addn "<li><a href='{issues}'>Issues</a></li>"
+                       addn "</ul>"
+               end
+
+               var git = metadata.git
+               var last_date = metadata.last_date
+               var first_date = metadata.first_date
+               if git != null then
+                       addn """
+                               <h4>Git</h4>
+                               <ul class='list-unstyled'>
+                                       <li><a href='{{{git}}}'>{{{git}}}</a></li>
+                               </ul>
+                               <span class='text-muted'><b>{{{stats.commits}}}</b> commits</span>
+                               <br>"""
+                       if last_date != null then
+                               addn """<b class=text-muted>Last:</b> {{{last_date}}}<br>"""
+                       end
+                       if first_date != null then
+                               addn """<b class=text-muted>First:</b> {{{first_date}}}"""
+                       end
+               end
+
+               addn """
+                       <h4>Quality</h4>
+                       <ul class='list-unstyled'>
+                               <li>{{{stats.documentation_score}}}% documented</li>
+                       </ul>"""
+
+               if metadata.tags.not_empty then
+                       addn "<h4>Tags</h4>"
+                       for tag in metadata.tags do
+                               addn " <a href='tag_{tag.to_cmangle}.html'>{tag}</a>"
+                               if tag != metadata.tags.last then add ", "
+                       end
+               end
+
+               if deps.not_empty then
+                       addn "<h4>Dependencies</h4>"
+                       for dep in deps do
+                               add dep.html_link
+                               if dep != deps.last then add ", "
+                       end
+               end
+
+               if clients.not_empty then
+                       addn "<h4>Clients</h4>"
+                       for client in clients do
+                               add client.html_link
+                               if client != clients.last then add ", "
+                       end
+               end
+
+               if metadata.contributors.not_empty then
+                       addn """
+                               <h4>Contributors</h4>
+                               <ul class='list-unstyled'>"""
+                       for contrib in metadata.contributors do
+                               addn """<li>{{{contrib.to_html}}}</li>"""
+                       end
+                       addn "</ul>"
+               end
+
+               addn """
+                       <h4>Stats</h4>
+                       <ul class='list-unstyled'>
+                               <li>{{{stats.mmodules}}} modules</li>
+                               <li>{{{stats.mclasses}}} classes</li>
+                               <li>{{{stats.mmethods}}} methods</li>
+                               <li>{{{stats.loc}}} loc</li>
+                       </ul>"""
+       end
+end
diff --git a/src/doc/static/static_html.nit b/src/doc/static/static_html.nit
new file mode 100644 (file)
index 0000000..eb2834f
--- /dev/null
@@ -0,0 +1,412 @@
+# 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.
+
+# Render documentation pages as HTML
+module static_html
+
+import static::static_structure
+import json
+
+redef class DocPage
+       super Template
+
+       # Page url
+       var html_url: String is writable, noinit
+
+       # Directory where css, js and other assets can be found
+       var shareurl: String is writable, noinit
+
+       # Top menu template if any
+       var topmenu: DocTopMenu is writable, noinit
+
+       # Footer content if any
+       var footer: nullable Writable = null is writable
+
+       # Render the page as a html template
+       fun render(doc: DocModel): Writable do
+               # init page options
+               self.shareurl = doc.share_url or else "."
+               self.footer = doc.custom_footer
+
+               # build page
+               init_title(doc)
+               init_topmenu(doc)
+
+               # piwik tracking
+               var tracker_url = doc.tracker_url
+               var site_id = doc.piwik_site_id
+               if tracker_url != null and site_id != null then
+                       piwik_script = new PiwikScript(tracker_url, site_id)
+               end
+               return self
+       end
+
+       # Build page title string
+       fun init_title(doc: DocModel) do end
+
+       # Build top menu template if any
+       fun init_topmenu(doc: DocModel) do
+               topmenu = new DocTopMenu
+
+               var home = new Link("index.html", "Nitdoc")
+
+               var custom_brand = doc.custom_brand
+               if custom_brand != null then
+                       topmenu.brand = new Link("index.html", custom_brand)
+                       topmenu.items.add new ListItem(home)
+               else
+                       topmenu.brand = home
+               end
+       end
+
+       # Renders the html `<head>`
+       private fun render_head do
+               var css = (self.shareurl / "css").html_escape
+               var vendors = (self.shareurl / "vendors").html_escape
+
+               addn "<!DOCTYPE html>"
+               addn "<head>"
+               addn " <meta charset='utf-8'/>"
+               addn " <link rel='stylesheet' href='{vendors}/bootstrap/css/bootstrap.min.css'/>"
+               addn " <link rel='stylesheet' href='{css}/nitdoc.bootstrap.css'/>"
+               addn " <link rel='stylesheet' href='{css}/nitdoc.cards.css'/>"
+               addn " <link rel='stylesheet' href='{css}/nitdoc.code.css'/>"
+               addn " <link rel='stylesheet' href='{css}/nitdoc.css'/>"
+               addn " <link rel='stylesheet' href='{css}/nitdoc.quicksearch.css'/>"
+               addn " <title>{title.html_escape}</title>"
+               addn "</head>"
+               add "<body>"
+       end
+
+       # Renders the footer and content
+       private fun render_content do
+               if tabs.is_empty then return
+               if tabs.length == 1 then
+                       addn tabs.first
+                       return
+               end
+               addn "<ul class='nav nav-tabs'>"
+               for tab in tabs do
+                       if tab.is_empty and not tab isa DocTabLink then continue
+                       addn tab.tab_link
+               end
+               addn "</ul>"
+               addn "<div class='tab-content'>"
+               for tab in tabs do
+                       if tab.is_empty then continue
+                       addn tab
+               end
+               addn "</div>"
+       end
+
+       # Piwik script to append in the page scripts
+       var piwik_script: nullable PiwikScript = null is writable
+
+       # Render JS scripts
+       private fun render_footer do
+               if footer != null then
+                       addn "<div class='footer'>"
+                       add footer.as(not null)
+                       addn "</div>"
+               end
+               var vendors = (self.shareurl / "vendors").html_escape
+               var js = (self.shareurl / "js").html_escape
+
+               addn "<script src='quicksearch-list.js'></script>"
+               addn "<script src='{vendors}/jquery/jquery-1.11.1.min.js'></script>"
+               addn "<script src='{vendors}/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
+               addn "<script src='{vendors}/bootstrap/js/bootstrap.min.js'></script>"
+               addn "<script src='{js}/nitdoc.utils.js'></script>"
+               addn "<script src='{js}/nitdoc.quicksearch.js'></script>"
+
+               var piwik_script = self.piwik_script
+               if piwik_script != null then
+                       add piwik_script
+               end
+               addn "</body>"
+               addn "</html>"
+       end
+
+       # Render the whole page
+       redef fun rendering do
+               render_head
+               add topmenu
+               addn "<div class='container-fluid'>"
+               render_content
+               addn "</div>"
+               render_footer
+       end
+end
+
+redef class PageHome
+       redef var html_url = "index.html"
+
+       redef fun render(doc) do
+               main_tab.show_sidebar = false
+               return super
+       end
+
+       redef fun init_title(doc) do
+               title = doc.custom_title or else "Nitdoc"
+       end
+
+       redef fun render_content do
+               addn "<div class='container'>"
+               if tabs.not_empty then
+                       addn tabs.first
+               end
+               addn "</div>"
+       end
+end
+
+redef class PageMEntity
+       redef var html_url is lazy do return mentity.html_url
+       redef fun init_title(doc) do title = mentity.html_name
+
+       redef fun render_content do
+               addn new CardPageHeader(
+                       mentity.html_declaration.write_to_string,
+                       mentity.html_namespace.write_to_string)
+               super
+       end
+
+       redef fun init_topmenu(doc) do
+               super
+               for m in mentity.nitdoc_breadcrumbs do
+                       topmenu.add_li new ListItem(new Link(m.html_url, m.html_name))
+               end
+               topmenu.active_item = topmenu.items.last
+       end
+end
+
+redef class PagePerson
+       redef var html_url is lazy do return person.html_url
+end
+
+redef class PageTag
+       redef var html_url is lazy do return "tag_{tag.to_cmangle}.html"
+end
+
+redef class HtmlightVisitor
+       redef fun hrefto(mentity) do return mentity.html_url
+end
+
+redef class DocTab
+       super Template
+
+       # Show sidebar for this page?
+       var show_sidebar = true is writable
+
+       # Tab link for tab headers
+       fun tab_link: Template do
+               var tpl = new Template
+               tpl.addn "<li class='{if is_active then "active" else ""}'>"
+               tpl.addn " <a data-toggle='tab' href='#{id}'>"
+
+               var icon = self.icon
+               if icon != null then
+                       tpl.addn "  <span class='glyphicon glyphicon-{icon}'></span>"
+               end
+               tpl.addn " {title}"
+               tpl.addn " </a>"
+               tpl.addn "</li>"
+               return tpl
+       end
+
+       redef fun rendering do
+               var has_left = show_sidebar and sidebar.cards.not_empty
+               var has_right = metadata.cards.not_empty
+
+               addn "<div class='tab-pane {if is_active then "active" else ""}' id='{id}'>"
+               if has_left then
+                       addn " <div class='col-sm-3'>"
+                       addn sidebar
+                       addn " </div>"
+               end
+               var cols = 12
+               if has_left then cols -= 3
+               if has_right then cols -= 3
+               addn " <div class='col-sm-{cols}'>"
+               for card in content do addn card
+               addn " </div>"
+               if has_right then
+                       addn " <div class='col-sm-3'>"
+                       addn metadata
+                       addn " </div>"
+               end
+               addn "</div>"
+       end
+end
+
+redef class DocTabLink
+
+       redef fun tab_link do
+               var tpl = new Template
+               tpl.addn "<li class='{if is_active then "active" else ""}'>"
+               tpl.addn " <a href='{url.html_escape}'>"
+
+               var icon = self.icon
+               if icon != null then
+                       tpl.addn "  <span class='glyphicon glyphicon-{icon}'></span>"
+               end
+               tpl.addn " {title}"
+               tpl.addn " </a>"
+               tpl.addn "</li>"
+               return tpl
+       end
+
+       redef fun rendering do end
+end
+
+# Top menu bar template
+class DocTopMenu
+       super UnorderedList
+
+       # Brand link to display in first position of the top menu
+       #
+       # This is where you want to put your logo.
+       var brand: nullable Link is noinit, writable
+
+       # Active menu item
+       #
+       # Depends on the current page, this allows to hilighted the current item.
+       var active_item: nullable ListItem is noinit, writable
+
+       redef fun rendering do
+               addn "<nav class='navbar navbar-default navbar-fixed-top'>"
+               addn " <div class='container-fluid'>"
+               addn "  <div class='navbar-header'>"
+               add  "   <button type='button' class='navbar-toggle' "
+               addn "       data-toggle='collapse' data-target='#topmenu-collapse'>"
+               addn "    <span class='sr-only'>Toggle menu</span>"
+               addn "    <span class='icon-bar'></span>"
+               addn "    <span class='icon-bar'></span>"
+               addn "    <span class='icon-bar'></span>"
+               addn "   </button>"
+               var brand = self.brand
+               if brand != null then
+                       add "<span class='navbar-brand'>"
+                       add brand
+                       add "</span>"
+               end
+               addn "  </div>"
+               addn "  <div class='collapse navbar-collapse' id='topmenu-collapse'>"
+               addn "   <ul class='nav navbar-nav'>"
+               for item in items do
+                       if item == active_item then item.css_classes.add "active"
+                       add item.write_to_string
+               end
+               addn "   </ul>"
+               addn "   <div id='search-placeholder'>"
+               addn "   </div>"
+               addn "  </div>"
+               addn " </div>"
+               addn "</nav>"
+       end
+end
+
+redef class DocSidebar
+       super Template
+
+       redef fun rendering do
+               if cards.is_empty then return
+               addn "<div id='sidebar'>"
+               for card in cards do addn card
+               addn "</div>"
+       end
+end
+
+# JS script for Piwik Tracker
+class PiwikScript
+       super Template
+
+       # Piwik URL to use for this tracker
+       var tracker_url: String
+
+       # Site ID used on Piwik system
+       var site_id: String
+
+       redef fun rendering do
+               addn "<script>"
+
+               var site_id = self.site_id.to_json
+               var tracker_url = self.tracker_url.trim
+               if tracker_url.chars.last != '/' then tracker_url += "/"
+               tracker_url = "://{tracker_url}".to_json
+
+               addn "<!-- Piwik -->"
+               addn "var _paq = _paq || [];"
+               addn " _paq.push([\"trackPageView\"]);"
+               addn " _paq.push([\"enableLinkTracking\"]);"
+               addn "(function() \{"
+               addn " var u=((\"https:\" == document.location.protocol) ? \"https\" : \"http\") + {tracker_url};"
+               addn " _paq.push([\"setTrackerUrl\", u+\"piwik.php\"]);"
+               addn " _paq.push([\"setSiteId\", {site_id}]);"
+               addn " var d=document, g=d.createElement(\"script\"), s=d.getElementsByTagName(\"script\")[0]; g.type=\"text/javascript\";"
+               addn " g.defer=true; g.async=true; g.src=u+\"piwik.js\"; s.parentNode.insertBefore(g,s);"
+               addn "\})();"
+
+               addn "</script>"
+       end
+end
+
+# Model redefs
+
+redef class MEntity
+       redef fun to_dot_node do
+               var node = super
+               node["URL"] = html_url
+               return node
+       end
+
+       redef var html_url = "{html_id}.html" is lazy
+end
+
+redef class MPackage
+       redef var html_url is lazy do return "package_{super}"
+end
+
+redef class MGroup
+       redef var html_url is lazy do return "group_{super}"
+end
+
+redef class MModule
+       redef var html_url is lazy do return "module_{super}"
+end
+
+redef class MClass
+       redef var html_url is lazy do return "class_{super}"
+end
+
+redef class MClassDef
+       redef var html_url is lazy do
+               if is_intro then return mclass.html_url
+               return "{mclass.html_url}?def=def_code_{html_id}#lin"
+       end
+end
+
+redef class MProperty
+       redef var html_url is lazy do return "property_{super}"
+end
+
+redef class MPropDef
+       redef var html_url is lazy do
+               if is_intro then return mproperty.html_url
+               return "{mproperty.html_url}?def=def_code_{html_id}#lin"
+       end
+end
+
+redef class Person
+       redef var html_url = "person_{html_id}.html" is lazy
+end
diff --git a/src/doc/static/static_index.nit b/src/doc/static/static_index.nit
new file mode 100644 (file)
index 0000000..699a480
--- /dev/null
@@ -0,0 +1,82 @@
+# 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.
+
+# Manage indexing of Nit model for Nitdoc QuickSearch.
+module static_index
+
+import static::static_html
+import json
+
+# Generate the index for then Nitdoc QuickSearch field.
+#
+# Create a JSON object containing links to:
+#  * mpackages
+#  * modules
+#  * mclasses
+#  * mpropdefs
+# All entities are grouped by name to make the research easier.
+#
+# TODO Merge with model_index
+redef class DocModel
+
+       # Build the nitdoc quick search index
+       fun create_index_file(file: String) do
+               var table = new QuickSearchTable(self)
+               var tpl = new Template
+               tpl.add "var nitdocQuickSearchRawList="
+               tpl.add table.to_json
+               tpl.add ";"
+               tpl.write_to_file(file)
+       end
+end
+
+# The result map for QuickSearch.
+private class QuickSearchTable
+       super HashMap[String, Array[QuickSearchResult]]
+
+       var doc: DocModel
+
+       init do
+               var model = doc.model
+               var filter = doc.filter
+
+               index_mentities model.collect_mpackages(filter)
+               index_mentities model.collect_mmodules(filter)
+               index_mentities model.collect_mclasses(filter)
+               index_mentities model.collect_mproperties(filter)
+       end
+
+       fun index_mentities(mentities: Collection[MEntity]) do
+               for mentity in mentities do index_mentity mentity
+       end
+
+       fun index_mentity(mentity: MEntity) do
+               var key = mentity.name
+               if not has_key(key) then
+                       self[key] = new Array[QuickSearchResult]
+               end
+               self[key].add new QuickSearchResult(mentity.full_name, mentity.html_url)
+       end
+end
+
+# A QuickSearch result.
+private class QuickSearchResult
+       serialize
+
+       # The text of the link.
+       var txt: String
+
+       # The destination of the link.
+       var url: String
+end
diff --git a/src/doc/static/static_structure.nit b/src/doc/static/static_structure.nit
new file mode 100644 (file)
index 0000000..8afe591
--- /dev/null
@@ -0,0 +1,439 @@
+# 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 pages of the static documentation
+module static_structure
+
+import static::static_base
+
+redef class DocPage
+
+       # Create the structure of this page
+       fun apply_structure(doc: DocModel) do end
+end
+
+redef class PageHome
+       redef fun apply_structure(doc) do
+               var title = doc.custom_title or else "Welcome to Nitdoc!"
+               var intro = doc.custom_intro
+
+               if intro != null then
+                       main_tab.content.add new CardPageHeader(title)
+                       main_tab.content.add new CardText(intro)
+               else
+                       main_tab.content.add new CardPageHeader(title, "The Nit API documentation.")
+               end
+
+               main_tab.content.add new CardCatalogStats(doc.catalog)
+               main_tab.content.add new CardCatalogTags(doc.catalog)
+
+               main_tab.content.add new CardSection(2, "Packages")
+               var mpackages_sorter = new CatalogScoreSorter(doc.catalog)
+
+               var mpackages = doc.catalog.mpackages.values.to_a
+               mpackages_sorter.sort mpackages
+               var list = new CardList("packages", "Packages")
+               for mpackage in mpackages do
+                       list.cards.add new CardCatalogPackage(doc.catalog, mpackage)
+               end
+               # TODO pagination?
+               main_tab.content.add list
+       end
+end
+
+redef class PageMEntity
+       # Concerns to display in this page.
+       var concerns: nullable ConcernsTree = null
+
+       redef fun apply_structure(doc) do
+               build_main(doc)
+               build_api(doc)
+               build_dependencies(doc)
+       end
+
+       # Build the main tab (the one that contains the MDoc)
+       fun build_main(doc: DocModel) do
+               var mentity = self.mentity
+
+               var sq = new CmdSummary(doc.model, doc.filter, mentity,
+                       markdown_processor = doc.inline_processor)
+               sq.init_command
+
+               main_tab.content.add new CardMDoc(mentity, mentity.mdoc_or_fallback)
+
+               var summary = sq.summary
+               if summary != null then
+                       main_tab.sidebar.cards.add new CardMdSummary(headlines = summary, md_processor = doc.inline_processor)
+               end
+       end
+
+       # Build the API tab
+       fun build_api(doc: DocModel) do
+               var summary = new CardSummary
+
+               var title = "All definitions"
+               if mentity isa MPackage then title = "All groups and modules"
+               if mentity isa MGroup then title = "All subgroups and modules"
+               if mentity isa MModule then title = "All class definitions"
+               if mentity isa MClass or mentity isa MClassDef then title = "All properties"
+
+               var section = new CardSection(2, title)
+               api_tab.content.add section
+               summary.cards.add section
+
+               var dq = new CmdFeatures(doc.model, doc.filter, mentity)
+               dq.init_command
+               var mentities = dq.results
+               if mentities == null then return
+
+               var list = new CardList("api", "API")
+               for m in mentities do
+                       var card = new CardMEntity(m)
+                       card.id = "api_{card.id}" # avoid id conflicts with main tab
+                       list.cards.add card
+                       summary.cards.add card
+               end
+               api_tab.content.add list
+
+               if summary.cards.not_empty then
+                       api_tab.sidebar.cards.add summary
+               end
+       end
+
+       # Build the dependencies tab
+       fun build_dependencies(doc: DocModel) do
+               var summary = new CardSummary
+
+               var model = doc.model
+               var mainmodule = doc.mainmodule
+               var filter = doc.filter
+
+               if not doc.no_dot then
+                       var gq = new CmdInheritanceGraph(model, mainmodule, filter, mentity)
+                       gq.init_command
+                       var graph = gq.graph
+                       if graph != null then
+                               graph.draw(2, 2)
+                               dep_tab.content.add new CardGraph(mentity, graph)
+                       end
+               end
+
+               # No inheritance lists for `Object`
+               if mentity isa MClass and mentity.name == "Object" then return
+
+               var inh = new HashMap[String, CmdEntityList]
+               inh["Ancestors"] = new CmdAncestors(model, mainmodule, filter, mentity, parents = false)
+               inh["Parents"] = new CmdParents(model, mainmodule, filter, mentity)
+               inh["Children"] = new CmdChildren(model, mainmodule, filter, mentity)
+               inh["Descendants"] = new CmdDescendants(model, mainmodule, filter, mentity, children = false)
+
+               for title, cmd in inh do
+                       cmd.init_command
+                       var results = cmd.results
+                       if results == null or results.is_empty then continue
+                       var section = new CardSection(3, title)
+                       dep_tab.content.add section
+                       summary.cards.add section
+
+                       var list = new CardList("inh", "Inheritance")
+                       for mentity in results do
+                               var card = new CardMEntity(mentity)
+                               list.cards.add card
+                               summary.cards.add card
+                       end
+                       dep_tab.content.add list
+               end
+
+               if summary.cards.not_empty then
+                       dep_tab.sidebar.cards.add summary
+               end
+       end
+
+       # Build the code panel
+       fun build_code(doc: DocModel) do
+               var code_url = doc.code_url
+
+               if not doc.no_code then
+                       var cq = new CmdEntityCode(doc.model, doc.modelbuilder, doc.filter, mentity)
+                       cq.init_command
+
+                       var code = cq.node
+                       if code == null then return
+                       code_tab.content.add new CardCode(mentity, code)
+               else if doc.code_url != null then
+                       code_tab = new DocTabLink("code", "Code", "console", mentity.source_url(code_url))
+               end
+       end
+
+       # Build the linearization panel
+       fun build_linearization(doc: DocModel) do
+               var summary = new CardSummary
+
+               var lq = new CmdLinearization(doc.model, doc.mainmodule, doc.filter, mentity)
+               lq.init_command
+
+               var mentities = lq.results
+               if mentities == null then return
+
+               if mentity isa MClass or mentity isa MClassDef then
+                       if mentity.name == "Object" then return # No linearization for `Object`
+                       if mentity.name == "Sys" then return # No linearization for `Sys`
+                       var section = new CardSection(2, "Class definitions")
+                       lin_tab.content.add section
+                       summary.cards.add section
+               else if mentity isa MProperty or mentity isa MPropDef then
+                       if mentity.name == "init" then return # No linearization for `init`
+                       if mentity.name == "SELF" then return # No linearization for `SELF`
+                       if mentity.name == "to_s" then return # No linearization for `to_s`
+                       var section = new CardSection(2, "Property definitions")
+                       lin_tab.content.add section
+                       summary.cards.add section
+               end
+
+               var list = new CardLinearizationList(mentity)
+               for m in mentities do
+                       var url = mentity.source_url(doc.code_url)
+                       var node = doc.modelbuilder.mentity2node(m)
+                       if node == null then continue
+                       if doc.no_code then node = null
+                       if m == mentity or
+                         (m isa MClassDef and m.is_intro) or
+                         (m isa MPropDef and m.is_intro) then
+                               var card = new CardLinearizationDef(m, node, is_active = true, url)
+                               list.cards.add card
+                               summary.cards.add card
+                       else
+                               var card = new CardLinearizationDef(m, node, is_active = false, url)
+                               list.cards.add card
+                               summary.cards.add card
+                       end
+               end
+               lin_tab.content.add list
+
+               if summary.cards.not_empty then
+                       lin_tab.sidebar.cards.add summary
+               end
+       end
+end
+
+redef class PageMPackage
+       redef fun build_main(doc) do
+               super
+               main_tab.metadata.cards.add new CardMetadata(mentity, mentity.metadata,
+                       doc.catalog.mpackages_stats[mentity],
+                       doc.catalog.deps[mentity].direct_greaters.to_a,
+                       doc.catalog.deps[mentity].direct_smallers.to_a)
+       end
+end
+
+redef class PageMModule
+       redef fun apply_structure(doc) do
+               super
+               build_code(doc)
+       end
+
+       redef fun build_main(doc) do
+               super
+
+               var summary = new CardSummary(no_title = true)
+
+               # Intros
+               var cmd: CmdEntities = new CmdIntros(doc.model, doc.mainmodule, doc.filter, mentity)
+               cmd.init_command
+               var intros = cmd.results
+               if intros != null and intros.not_empty then
+                       var section = new CardSection(3, "Introduced classes")
+                       main_tab.content.add section
+                       summary.cards.add section
+                       var cards = new CardList("intros", "Intros")
+                       for intro in intros do
+                               var card = new CardMEntity(intro)
+                               summary.cards.add card
+                               cards.cards.add card
+                       end
+                       main_tab.content.add cards
+               end
+
+               # Redefs
+               cmd = new CmdRedefs(doc.model, doc.mainmodule, doc.filter, mentity)
+               cmd.init_command
+               var redefs = cmd.results
+               if redefs != null and redefs.not_empty then
+                       var section = new CardSection(3, "Redefined classes")
+                       main_tab.content.add section
+                       summary.cards.add section
+                       var cards = new CardList("redefs", "Redefs")
+                       for prop in redefs do
+                               var card = new CardMEntity(prop)
+                               summary.cards.add card
+                               cards.cards.add card
+                       end
+                       main_tab.content.add cards
+               end
+
+               main_tab.sidebar.cards.add summary
+       end
+end
+
+redef class PageMClass
+       redef fun apply_structure(doc) do
+               super
+               build_code(doc)
+               build_linearization(doc)
+       end
+
+       redef fun build_main(doc) do
+               super
+
+               var summary = new CardSummary(no_title = true)
+
+               # Intros
+               var cmd: CmdEntities = new CmdIntros(doc.model, doc.mainmodule, doc.filter, mentity)
+               cmd.init_command
+               var intros = cmd.results
+               if intros != null and intros.not_empty then
+                       var section = new CardSection(3, "Introduced properties")
+                       main_tab.content.add section
+                       summary.cards.add section
+                       var cards = new CardList("intros", "Intros")
+                       for intro in intros do
+                               var card = new CardMEntity(intro)
+                               summary.cards.add card
+                               cards.cards.add card
+                       end
+                       main_tab.content.add cards
+               end
+
+               # Redefs
+               cmd = new CmdRedefs(doc.model, doc.mainmodule, doc.filter, mentity)
+               cmd.init_command
+               var redefs = cmd.results
+               if redefs != null and redefs.not_empty then
+                       var section = new CardSection(3, "Redefined properties")
+                       main_tab.content.add section
+                       summary.cards.add section
+                       var cards = new CardList("redefs", "Redefs")
+                       for prop in redefs do
+                               var card = new CardMEntity(prop)
+                               summary.cards.add card
+                               cards.cards.add card
+                       end
+                       main_tab.content.add cards
+               end
+
+               # Expand summary
+               main_tab.sidebar.cards.add summary
+       end
+
+       redef fun build_api(doc) do
+               var summary = new CardSummary
+
+               var section = new CardSection(2, "All properties")
+               api_tab.content.add section
+               summary.cards.add section
+
+               var dq = new CmdAllProps(doc.model, doc.mainmodule, doc.filter, mentity)
+               dq.init_command
+               var mentities = dq.results
+               if mentities == null then return
+
+               var list = new CardList("api", "API")
+               for m in mentities do
+                       var card = new CardMEntity(m)
+                       list.cards.add card
+                       summary.cards.add card
+               end
+               api_tab.content.add list
+
+               if summary.cards.not_empty then
+                       api_tab.sidebar.cards.add summary
+               end
+       end
+end
+
+redef class PageMProperty
+       redef fun apply_structure(doc) do
+               super
+               build_code(doc)
+               build_linearization(doc)
+       end
+end
+
+redef class PagePerson
+       redef fun apply_structure(doc) do
+               var mpackages_sorter = new CatalogScoreSorter(doc.catalog)
+               main_tab.content.add new CardPageHeader(person.name, person.email)
+
+               var maint = doc.catalog.maint2proj[person]
+               mpackages_sorter.sort maint
+               var mlist = new CardList("maintained", "Maintained")
+               for mpackage in maint do
+                       mlist.cards.add new CardCatalogPackage(doc.catalog, mpackage)
+               end
+
+               # TODO pagination?
+               if maint.not_empty then
+                       main_tab.content.add new CardSection(3, "{maint.length} maintained packages")
+                       main_tab.content.add mlist
+               end
+
+               var contrib = doc.catalog.contrib2proj[person]
+               mpackages_sorter.sort contrib
+               var clist = new CardList("contribs", "Contributed")
+               for mpackage in contrib do
+                       clist.cards.add new CardCatalogPackage(doc.catalog, mpackage)
+               end
+
+               # TODO pagination?
+               if contrib.not_empty then
+                       main_tab.content.add new CardSection(3, "{contrib.length} contributed packages")
+                       main_tab.content.add clist
+               end
+       end
+end
+
+redef class PageTag
+       redef fun apply_structure(doc) do
+               var mpackages_sorter = new CatalogScoreSorter(doc.catalog)
+               main_tab.content.add new CardPageHeader(tag)
+
+               var mpackages = doc.catalog.tag2proj[tag]
+               mpackages_sorter.sort mpackages
+               var list = new CardList("packages", "Packages")
+               for mpackage in mpackages do
+                       list.cards.add new CardCatalogPackage(doc.catalog, mpackage)
+               end
+
+               # TODO pagination?
+               main_tab.content.add new CardSection(3, "{mpackages.length} packages")
+               main_tab.content.add list
+       end
+end
+
+redef class MEntity
+       # Render a HTML link for the MEntity location
+       private fun source_url(url_pattern: nullable String): String do
+               var location = self.location
+               var file = location.file
+
+               if file == null then return location.to_s
+               if url_pattern == null then return file.filename.simplify_path
+
+               var url = url_pattern
+               url = url.replace("%f", file.filename.simplify_path)
+               url = url.replace("%l", location.line_start.to_s)
+               url = url.replace("%L", location.line_end.to_s)
+               return url.simplify_path
+       end
+end
index f74ac84..4faf0a6 100644 (file)
@@ -18,6 +18,7 @@ module templates_html
 import model::model_collect
 import doc::doc_down
 import html::bootstrap
+import catalog
 
 redef class MEntity
 
@@ -263,7 +264,9 @@ redef class MMethodDef
                if mproperty.is_root_init and new_msignature != null then
                        return new_msignature.html_signature(short)
                end
-               return msignature.as(not null).html_signature(short)
+               var msignature = self.msignature
+               if msignature == null then return new Template
+               return msignature.html_signature(short)
        end
 end
 
@@ -360,3 +363,29 @@ redef class MParameter
                return tpl
        end
 end
+
+redef class Person
+
+       # HTML uniq id
+       fun html_id: String do return name.to_cmangle
+
+       # HTML default URL
+       #
+       # Should be redefined in clients.
+       fun html_url: String do return "person_{html_id}.html"
+
+       # Link to this person `html_url`
+       fun html_link: Link do return new Link(html_url, name)
+
+       redef fun to_html do
+               var tpl = new Template
+               tpl.addn "<span>"
+               var gravatar = self.gravatar
+               if gravatar != null then
+                       tpl.addn "<img class='avatar' src='https://secure.gravatar.com/avatar/{gravatar}?size=14&amp;default=retro' />"
+               end
+               tpl.addn html_link
+               tpl.addn "</span>"
+               return tpl.write_to_string
+       end
+end
diff --git a/src/doc/test_doc_commands.nit b/src/doc/test_doc_commands.nit
deleted file mode 100644 (file)
index 82f5e7c..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-# 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.
-
-module test_doc_commands is test
-
-import doc_commands
-
-class TestDocCommandParser
-       test
-
-       var parser: DocCommandParser
-
-       fun init_parser is before do
-               parser = new DocCommandParser
-       end
-
-       fun test_empty_string is test do
-               var command = parser.parse("")
-               assert command == null
-               assert parser.errors.length == 1
-               assert parser.errors.first.to_s == "Error: empty command name (col: 0)"
-       end
-
-       fun test_bad_string is test do
-               var command = parser.parse(":")
-               assert command == null
-               assert parser.errors.length == 1
-               assert parser.errors.first.to_s == "Error: empty command name (col: 0)"
-       end
-
-       fun test_unknown_command is test do
-               var command = parser.parse("foo: foo")
-               assert command == null
-               assert parser.errors.length == 1
-               assert parser.errors.first.to_s == "Error: unknown command name (col: 0)"
-       end
-
-       fun test_unallowed_command is test do
-               parser.allowed_commands.clear
-               var command = parser.parse("comment: core::Array")
-               assert command == null
-               assert parser.errors.length == 1
-               assert parser.errors.first.to_s == "Error: unknown command name (col: 0)"
-       end
-
-       fun test_no_arg is test do
-               var command = parser.parse("doc:")
-               assert command == null
-               assert parser.errors.length == 1
-               print parser.errors.first
-               assert parser.errors.first.to_s == "Error: empty command arg (col: 4)"
-       end
-
-       fun test_no_opts is test do
-               var command = parser.parse("doc: core::Array")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert parser.errors.is_empty
-       end
-
-       fun test_opts_empty is test do
-               var command = parser.parse("doc: core::Array | ")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert parser.errors.is_empty
-       end
-
-       fun test_1_opt is test do
-               var command = parser.parse("doc: core::Array | opt1: val1 ")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert command.opts.length == 1
-               assert command.opts["opt1"] == "val1"
-               assert parser.errors.is_empty
-       end
-
-       fun test_2_opts is test do
-               var command = parser.parse("doc: core::Array | opt1: val1 , opt2: val2,  ")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert command.opts.length == 2
-               assert command.opts["opt1"] == "val1"
-               assert command.opts["opt2"] == "val2"
-               assert parser.errors.is_empty
-       end
-
-       fun test_empty_opt_name is test do
-               var command = parser.parse("doc: core::Array | opt1: val1  , :")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert command.opts.length == 1
-               assert command.opts["opt1"] == "val1"
-               assert parser.errors.is_empty
-       end
-
-       fun test_empty_opt_value is test do
-               var command = parser.parse("doc: core::Array | opt1:  , opt2: val2,  ")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert command.opts.length == 2
-               assert command.opts["opt1"] == ""
-               assert command.opts["opt2"] == "val2"
-               assert parser.errors.is_empty
-       end
-
-       fun test_empty_opt_value2 is test do
-               var command = parser.parse("doc: core::Array | opt1")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert command.opts.length == 1
-               assert command.opts["opt1"] == ""
-               assert parser.errors.is_empty
-       end
-
-       fun test_empty_opt_value3 is test do
-               var command = parser.parse("doc: core::Array | opt1, opt2: val2")
-               assert command isa CommentCommand
-               assert command.name == "doc"
-               assert command.arg == "core::Array"
-               assert command.opts.length == 2
-               assert command.opts["opt1"] == ""
-               assert command.opts["opt2"] == "val2"
-               assert parser.errors.is_empty
-       end
-end
diff --git a/src/indexing/code_index.nit b/src/indexing/code_index.nit
new file mode 100644 (file)
index 0000000..765fad0
--- /dev/null
@@ -0,0 +1,204 @@
+# 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.
+
+# An index that contains Nit code
+#
+# Model entities are indexed by their ANode.
+#
+# Vectorization is based on model usage such as:
+# * modules importation
+# * classes spcialization and refinement
+# * methods calls and refinements
+#
+# Example:
+# ~~~nitish
+# # Create the index
+# var index = new CodeIndex(toolcontext)
+# for mentity in mentities do
+#      index.index_mentity(mentity)
+# end
+#
+# # Match a piece of code
+# var matches = index.match_code("print \"Hello, World!\"")
+# for match in matches do
+#      print match
+# end
+# ~~~
+module code_index
+
+import vsm
+import semantize
+import parser_util
+
+# Index for Nit doc
+class CodeIndex
+       super VSMIndex
+
+       redef type DOC: CodeDocument
+
+       # ToolContext used to parse pieces of code
+       var toolcontext: ToolContext
+
+       # Index `mentity`
+       fun index_mentity(mentity: MEntity) do
+               var terms = vectorize_mentity(mentity)
+               var doc = new CodeDocument(mentity, terms)
+               index_document(doc, false)
+       end
+
+       # Match `code` with the index
+       fun match_code(code: String): Array[IndexMatch[DOC]] do
+               var node = parse_code(code)
+               if node == null then return new Array[IndexMatch[DOC]]
+               return match_node(node)
+       end
+
+       # Match `node` with the index
+       fun match_node(node: ANode): Array[IndexMatch[DOC]] do
+               var vector = vectorize_node(node)
+               return match_vector(vector)
+       end
+
+       # Parse a piece of code
+       private fun parse_code(code: String): nullable AModule do
+               # Try to parse code
+               var node = toolcontext.parse_something(code)
+               if not node isa AModule then return null
+
+               # Load code into model
+               var mbuilder = toolcontext.modelbuilder
+               mbuilder.load_rt_module(null, node, "tmp")
+               mbuilder.run_phases
+               return node
+       end
+
+       # Transform `node` in a Vector
+       private fun vectorize_node(node: ANode): Vector do
+               var visitor = new CodeIndexVisitor
+               visitor.enter_visit(node)
+               return visitor.vector
+       end
+
+       # Transform `mentity` in a Vector
+       private fun vectorize_mentity(mentity: MEntity): Vector do
+               var node = toolcontext.modelbuilder.mentity2node(mentity)
+               if node == null then return new Vector
+               return vectorize_node(node)
+       end
+end
+
+# A specific document for mentities code
+class CodeDocument
+       super Document
+       autoinit(mentity, terms_count)
+
+       # MEntity related to this document
+       var mentity: MEntity
+
+       redef var title = mentity.full_name is lazy
+
+       redef var uri = mentity.location.to_s is lazy
+end
+
+# Code index visitor
+#
+# Used to build a VSM Vector from a Nit ANode.
+private class CodeIndexVisitor
+       super Visitor
+
+       var vector = new Vector
+
+       redef fun visit(node) do
+               node.accept_code_index_visitor(self)
+       end
+end
+
+redef class ANode
+       private fun accept_code_index_visitor(v: CodeIndexVisitor) do
+               visit_all(v)
+       end
+end
+
+redef class AStdImport
+       redef fun accept_code_index_visitor(v) do
+               var mmodule = self.mmodule
+               if mmodule != null then
+                       v.vector.inc "import#{mmodule.full_name}"
+               end
+       end
+end
+
+redef class AStdClassdef
+       redef fun accept_code_index_visitor(v) do
+               var mclassdef = self.mclassdef
+               if mclassdef != null then
+                       if not mclassdef.is_intro then
+                               v.vector.inc "redef#{mclassdef.full_name}"
+                               v.vector.inc "redef#{mclassdef.mclass.full_name}"
+                       end
+               end
+               visit_all(v)
+       end
+end
+
+redef class ASuperPropdef
+       redef fun accept_code_index_visitor(v) do
+               var mtype = self.n_type.mtype
+               if mtype isa MClassType then
+                       v.vector.inc "super#{mtype.mclass.intro.full_name}"
+                       v.vector.inc "super#{mtype.mclass.full_name}"
+               end
+       end
+end
+
+redef class APropdef
+       redef fun accept_code_index_visitor(v) do
+               var mpropdef = self.mpropdef
+               if mpropdef != null then
+                       if not mpropdef.is_intro then
+                               v.vector.inc "redef#{mpropdef.mproperty.intro.full_name}"
+                               v.vector.inc "redef#{mpropdef.mproperty.full_name}"
+                       end
+               end
+               visit_all(v)
+       end
+end
+
+redef class ASendExpr
+       redef fun accept_code_index_visitor(v) do
+               var callsite = self.callsite
+               if callsite != null then
+                       var args = callsite.signaturemap.as(not null).map.length
+                       v.vector.inc "call#{callsite.mpropdef.full_name}({args})"
+                       v.vector.inc "call#{callsite.mpropdef.mproperty.full_name}({args})"
+                       v.vector.inc "call#{callsite.mpropdef.mclassdef.full_name}({args})"
+                       v.vector.inc "call#{callsite.mpropdef.mclassdef.mclass.full_name}({args})"
+               end
+               visit_all(v)
+       end
+end
+
+redef class ANewExpr
+       redef fun accept_code_index_visitor(v) do
+               var callsite = self.callsite
+               if callsite != null then
+                       var args = callsite.signaturemap.as(not null).map.length
+                       v.vector.inc "call#{callsite.mpropdef.full_name}({args})"
+                       v.vector.inc "call#{callsite.mpropdef.mproperty.full_name}({args})"
+                       v.vector.inc "new#{callsite.mpropdef.mclassdef.full_name}({args})"
+                       v.vector.inc "new#{callsite.mpropdef.mclassdef.mclass.full_name}({args})"
+               end
+               visit_all(v)
+       end
+end
diff --git a/src/indexing/tests/test_code_index.nit b/src/indexing/tests/test_code_index.nit
new file mode 100644 (file)
index 0000000..b2a8f2e
--- /dev/null
@@ -0,0 +1,74 @@
+# 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.
+
+module test_code_index is test
+
+import code_index
+import frontend
+
+class TestCodeIndex
+       test
+
+       # CodeIndex used in tests
+       var test_index: CodeIndex is noinit
+
+       # Initialize test variables
+       #
+       # Must be called before test execution.
+       # FIXME should be before_all
+       fun build_test_env is before do
+               var test_path = "NIT_TESTING_PATH".environ.dirname
+               var test_src = test_path / "../../../tests/test_prog"
+
+               # build model
+               var toolcontext = new ToolContext
+               var model = new Model
+               var modelbuilder = new ModelBuilder(model, toolcontext)
+               var mmodules = modelbuilder.parse_full([test_src])
+               modelbuilder.run_phases
+               toolcontext.run_global_phases(mmodules)
+
+               # create index
+               var index = new CodeIndex(toolcontext)
+               for mmodule in mmodules do
+                       index.index_mentity(mmodule)
+               end
+               test_index = index
+               modelbuilder.paths.add test_src
+       end
+
+       fun test_find1 is test do
+               var query = "import game\n"
+               var matches = test_index.match_code(query)
+               assert matches.first.document.mentity.full_name == "test_prog::test_prog"
+       end
+
+       fun test_find2 is test do
+               var query = "import game\nimport rpg\n"
+               var matches = test_index.match_code(query)
+               assert matches.first.document.mentity.full_name == "test_prog::game"
+       end
+
+       fun test_find3 is test do
+               var query = "import game\nclass MyGame\nsuper Game\nredef fun start_game do end\nend\n"
+               var matches = test_index.match_code(query)
+               assert matches.first.document.mentity.full_name == "test_prog::game_examples"
+       end
+
+       fun test_find_error is test do
+               var query = "error"
+               var matches = test_index.match_code(query)
+               assert matches.is_empty
+       end
+end
index 94132ff..65227b3 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Documentation generator for the nit language.
+# Generator of static API documentation for the Nit language
 #
-# Generate API documentation in HTML format from nit source code.
+# Generate API documentation in HTML format from Nit source code.
 module nitdoc
 
-import modelbuilder
-import doc
+import doc::static
 
 redef class ToolContext
-       # Nitdoc generation phase.
+
+       # Nitdoc generation phase
        var docphase: Phase = new Nitdoc(self, null)
 
-       # Do not generate documentation for attributes.
+       # Directory where the Nitdoc is rendered
+       var opt_dir = new OptionString("Output directory", "-d", "--dir")
+
+       # Do not generate documentation for attributes
        var opt_no_attributes = new OptionBool("Ignore the attributes", "--no-attributes")
 
-       # Do not generate documentation for private properties.
+       # Do not generate documentation for private properties
        var opt_private = new OptionBool("Also generate private API", "--private")
 
+       # Use a shareurl instead of copy shared files
+       #
+       # This is usefull if you don't want to store the Nitdoc templates with your
+       # documentation.
+       var opt_shareurl = new OptionString("Use shareurl instead of copy shared files", "--shareurl")
+
+       # Use a custom title for the homepage
+       var opt_custom_title = new OptionString("Custom title for homepage", "--custom-title")
+
+       # Display a custom brand or logo in the documentation top menu
+       var opt_custom_brand = new OptionString("Custom link to external site", "--custom-brand")
+
+       # Display a custom introduction text before the packages overview
+       var opt_custom_intro = new OptionString("Custom intro text for homepage", "--custom-overview-text")
+
+       # Display a custom footer on each documentation page
+       #
+       # Generally used to display the documentation or product version.
+       var opt_custom_footer = new OptionString("Custom footer text", "--custom-footer-text")
+
+       # Piwik tracker URL
+       #
+       # If you want to monitor your visitors.
+       var opt_piwik_tracker = new OptionString("Piwik tracker URL (ex: `nitlanguage.org/piwik/`)", "--piwik-tracker")
+
+       # Piwik tracker site id
+       var opt_piwik_site_id = new OptionString("Piwik site ID", "--piwik-site-id")
+
+       # Do not generate dot/graphviz diagrams
+       var opt_nodot = new OptionBool("Do not generate graphs with graphviz", "--no-dot")
+
+       # Do not include highlighted code
+       var opt_nocode = new OptionBool("Do not generate code with nitlight", "--no-code")
+
+       # File pattern used to link documentation to source code.
+       var opt_source = new OptionString("Format to link source code (%f for filename, " +
+               "%l for first line, %L for last line) only works with option --no-code", "--source")
+
+       # Disable HTML rendering
+       var opt_norender = new OptionBool("DO not render any HTML", "--no-render")
+
+       # Test mode
+       #
+       # Display test data and remove the progress bar
+       var opt_test = new OptionBool("Output test data", "--test")
+
        redef init do
                super
-               option_context.add_option(opt_no_attributes, opt_private)
+               option_context.add_option(
+                       opt_dir, opt_no_attributes, opt_private,
+                       opt_share_dir, opt_shareurl, opt_custom_title,
+                       opt_custom_footer, opt_custom_intro, opt_custom_brand,
+                       opt_piwik_tracker, opt_piwik_site_id,
+                       opt_nodot, opt_nocode, opt_source, opt_norender, opt_test)
+       end
+end
+
+redef class DocModel
+
+       # Generate a documentation page
+       fun gen_page(page: DocPage, output_dir: String) do
+               page.apply_structure(self)
+               page.render(self).write_to_file("{output_dir}/{page.html_url}")
        end
 end
 
-# Nitdoc phase explores the model and generate pages for each mentities found
+# Nitdoc phase explores the model and generate pages for each mentity found
 private class Nitdoc
        super Phase
+
        redef fun process_mainmodule(mainmodule, mmodules)
        do
+               var modelbuilder = toolcontext.modelbuilder
+               var model = modelbuilder.model
+
                var min_visibility = private_visibility
                if not toolcontext.opt_private.value then min_visibility = protected_visibility
                var accept_attribute = true
                if toolcontext.opt_no_attributes.value then accept_attribute = false
 
-               var filters = new ModelFilter(
+               var catalog = new Catalog(toolcontext.modelbuilder)
+               catalog.build_catalog(mainmodule.model.mpackages)
+
+               var filter = new ModelFilter(
                        min_visibility,
                        accept_attribute = accept_attribute,
-                       accept_fictive = false)
-               var doc = new DocModel(toolcontext.modelbuilder.model, mainmodule, filters)
-
-               var phases = [
-                       new IndexingPhase(toolcontext, doc),
-                       new MakePagePhase(toolcontext, doc),
-                       new POSetPhase(toolcontext, doc),
-                       new ConcernsPhase(toolcontext, doc),
-                       new StructurePhase(toolcontext, doc),
-                       new InheritanceListsPhase(toolcontext, doc),
-                       new IntroRedefListPhase(toolcontext, doc),
-                       new LinListPhase(toolcontext, doc),
-                       new GraphPhase(toolcontext, doc),
-                       new ReadmePhase(toolcontext, doc),
-                       new RenderHTMLPhase(toolcontext, doc),
-                       new DocTestPhase(toolcontext, doc): DocPhase]
-
-               for phase in phases do
-                       toolcontext.info("# {phase.class_name}", 1)
-                       phase.apply
+                       accept_fictive = true,
+                       accept_generated = true,
+                       accept_test = false,
+                       accept_redef = true,
+                       accept_extern = true,
+                       accept_empty_doc = true,
+                       accept_example = true,
+                       accept_broken = false)
+
+               var doc = new DocModel(model, mainmodule, modelbuilder, catalog, filter)
+
+               model.nitdoc_md_processor = doc.md_processor
+               doc.no_dot = toolcontext.opt_nodot.value
+               doc.no_code = toolcontext.opt_nocode.value
+               doc.code_url = toolcontext.opt_source.value
+               doc.share_url = toolcontext.opt_shareurl.value
+               doc.custom_brand = toolcontext.opt_custom_brand.value
+               doc.custom_title = toolcontext.opt_custom_title.value
+               doc.custom_footer = toolcontext.opt_custom_footer.value
+               doc.custom_intro = toolcontext.opt_custom_intro.value
+               doc.tracker_url = toolcontext.opt_piwik_tracker.value
+               doc.piwik_site_id = toolcontext.opt_piwik_site_id.value
+
+               # Prepare output dir
+               var test_mode = toolcontext.opt_test.value
+               var no_render = toolcontext.opt_norender.value
+               var output_dir = toolcontext.opt_dir.value or else "doc"
+
+               if not no_render then
+                       output_dir.mkdir
+
+                       # Copy assets
+                       var share_dir = toolcontext.opt_share_dir.value or else "{toolcontext.share_dir}/nitdoc"
+                       sys.system("cp -r -- {share_dir.escape_to_sh}/* {output_dir.escape_to_sh}/")
+               end
+
+               # Collect model to document
+               var mpackages = model.collect_mpackages(filter)
+               var mgroups = model.collect_mgroups(filter)
+               var nmodules = model.collect_mmodules(filter)
+               var mclasses = model.collect_mclasses(filter)
+               var mprops = model.collect_mproperties(filter)
+
+               var mentities = new Array[MEntity]
+               mentities.add_all mpackages
+               mentities.add_all mgroups
+               mentities.add_all nmodules
+               mentities.add_all mclasses
+               mentities.add_all mprops
+
+               var persons = doc.catalog.persons
+               var tags = doc.catalog.tag2proj.keys
+
+               # Prepare progress bar
+               var count = 0
+               var pages = 1 # count homepage
+               pages += mentities.length
+               pages += persons.length
+               pages += tags.length
+
+               print "Generating documentation pages..."
+               var progress = new TermProgress(pages, 0)
+               if not test_mode then progress.display
+
+               # Make pages
+               count += 1
+               if not test_mode then progress.update(count, "homepage")
+               if not no_render then doc.gen_page(new PageHome("Overview"), output_dir)
+
+               for mentity in mentities do
+                       count += 1
+                       if not test_mode then progress.update(count, "page {count}/{pages}")
+                       if not no_render then doc.gen_page(new PageMEntity(mentity), output_dir)
+               end
+               for name, person in persons do
+                       count += 1
+                       if not test_mode then progress.update(count, "page {count}/{pages}")
+                       if not no_render then doc.gen_page(new PagePerson(person), output_dir)
+               end
+               for tag in tags do
+                       count += 1
+                       if not test_mode then progress.update(count, "page {count}/{pages}")
+                       if not no_render then doc.gen_page(new PageTag(tag), output_dir)
+               end
+
+               if not test_mode then  print "" # finalise progress
+               if not no_render then
+                       doc.create_index_file("{output_dir}/quicksearch-list.js")
+                       print "Documentation produced in `{output_dir}`"
+               end
+
+               if test_mode then
+                       print "Generated {count}/{pages} pages"
+                       print " PageHome: 1"
+                       print " PageMPackage: {mpackages.length}"
+                       print " PageMGroup: {mgroups.length}"
+                       print " PageMModule: {nmodules.length}"
+                       print " PageMClass: {mclasses.length}"
+                       print " PageMProperty: {mprops.length}"
+                       print " PagePerson: {persons.length}"
+                       print " PageTag: {tags.length}"
+               end
+       end
+end
+
+redef class Catalog
+
+       # Build the catalog from `mpackages`
+       fun build_catalog(mpackages: Array[MPackage]) do
+               # Compute the poset
+               for p in mpackages do
+                       var g = p.root
+                       assert g != null
+                       modelbuilder.scan_group(g)
+
+                       deps.add_node(p)
+                       for gg in p.mgroups do for m in gg.mmodules do
+                               for im in m.in_importation.direct_greaters do
+                                       var ip = im.mpackage
+                                       if ip == null or ip == p then continue
+                                       deps.add_edge(p, ip)
+                               end
+                       end
+               end
+               # Build the catalog
+               for mpackage in mpackages do
+                       package_page(mpackage)
+                       git_info(mpackage)
+                       mpackage_stats(mpackage)
                end
        end
 end
@@ -91,5 +270,6 @@ var mmodules = mbuilder.parse_full(arguments)
 
 # process
 if mmodules.is_empty then return
+print "Parsing code..."
 mbuilder.run_phases
 toolcontext.run_global_phases(mmodules)
index e08c0ad..7b99224 100644 (file)
@@ -3,6 +3,7 @@ cocoa_message_box
 hello_cocoa
 hello_ios
 test_platform_ios
+test_platform_android
 mpi
 emscripten
 neo_doxygen
@@ -10,3 +11,69 @@ neo4j
 mongo
 pernicious_numbers
 frankuchredux
+base_autocast
+base_covar_int_alt5
+base_div_by_zero
+shootout_mandelbrot_args1
+test_binary
+test_curl
+test_ffi_java
+test_ffi_objc_types_and_callbacks
+test_fix_int
+test_glsl_validation
+test_json_static
+test_jvm
+test_kill_process
+test_msgpack_deserialization
+test_nitcorn
+test_path_args1
+test_postgres
+test_read_all_args1
+test_regex_check
+test_signals
+test_stream_poll
+nitc
+nitls_args3
+nitmetrics_args3
+nitpm_args
+nitsmells_args
+nitunit_args
+nitvm
+nitweb
+test_highlight_args1
+test_neo
+test_loader_args2
+test_loader_args5
+montecarlo
+catalan_numbers
+count_the_coins
+fibonacci_word
+first_letter_last_letter
+curl_http
+nlp_index
+drop_privileges
+concurrent_array_and_barrier
+jointask_example
+socket_client
+socket_server
+socket_simple_server
+fannkuchredux
+mandelbrot
+thread_ring
+htcpcp_server
+simple_file_server
+test_restful_annot
+nitin
+nitiwiki_args1
+nitiwiki_args2
+test_annot_pkgconfig_alt
+test_gtk
+nitlight_as_a_service
+curl_rest
+lang_annot
+opengles2_hello_triangle
+nlp_server
+ui_test
+restful_annot
+langannot
+simple_simulation
index c643d3d..e18f76f 100644 (file)
@@ -1,4 +1,4 @@
-module_1.nit -d $WRITE
-base_attr_nullable.nit -d $WRITE
---private base_attr_nullable.nit --no-attributes -d $WRITE
---no-render --test test_prog -d $WRITE
+--test module_1.nit -d $WRITE
+--test base_attr_nullable.nit -d $WRITE
+--test --private base_attr_nullable.nit --no-attributes -d $WRITE
+--test --no-render test_prog -d $WRITE
index 7a451c4..0d24e60 100644 (file)
@@ -44,3 +44,4 @@ test_rubix_visual
 test_csv
 repeating_key_xor_solve
 nitpm
+nitdoc
index d346e2c..697b17e 100644 (file)
@@ -47,3 +47,4 @@ test_explain_assert
 base_notnull_lit_alt2
 assertions
 nitpm
+nitdoc
index 3d90f09..a7326d6 100644 (file)
@@ -1,39 +1,39 @@
-Empty README for group `module_1` (readme-warning)
-Empty README for group `module_0` (readme-warning)
-Errors: 0. Warnings: 2.
-class_module_95d0-__Int.html
-class_module_95d0-__Object.html
-class_module_95d0-__Sys.html
-class_module_95d1-__A.html
-class_module_95d1-__B.html
+Parsing code...
+Generating documentation pages...
+Documentation produced in `out/nitdoc_args1.write`
+Generated 22/22 pages
+ PageHome: 1
+ PageMPackage: 2
+ PageMGroup: 2
+ PageMModule: 2
+ PageMClass: 5
+ PageMProperty: 10
+ PagePerson: 0
+ PageTag: 0
+class_module_95d0_58d_58dInt.html
+class_module_95d0_58d_58dObject.html
+class_module_95d0_58d_58dSys.html
+class_module_95d1_58d_58dA.html
+class_module_95d1_58d_58dB.html
 css/
-dep_class_module_95d0-__Int.dot
-dep_class_module_95d0-__Object.dot
-dep_class_module_95d0-__Sys.dot
-dep_class_module_95d1-__A.dot
-dep_class_module_95d1-__B.dot
-dep_module_module_95d0-.dot
-dep_module_module_95d1-.dot
-dep_module_module_95d1_45dm.dot
-group_module_95d0.html
-group_module_95d1.html
+group_module_95d0_62d.html
+group_module_95d1_62d.html
 index.html
 js/
 less/
-module_module_95d0-.html
-module_module_95d1-.html
-module_module_95d1_45dm.html
-property_module_95d0-__Object__init.html
-property_module_95d0-__Object__output.html
-property_module_95d0-__Object__print.html
-property_module_95d0-__Sys__main.html
-property_module_95d1-__A__a1.html
-property_module_95d1-__A__a12.html
-property_module_95d1-__A__a123.html
-property_module_95d1-__A__a13.html
-property_module_95d1-__B__all2.html
-property_module_95d1-__B__all25.html
+module_module_95d0_58d_58dmodule_95d0.html
+module_module_95d1_58d_58dmodule_95d1.html
+package_module_95d0.html
+package_module_95d1.html
+property_module_95d0_58d_58dObject_58d_58dinit.html
+property_module_95d0_58d_58dObject_58d_58doutput.html
+property_module_95d0_58d_58dObject_58d_58dprint.html
+property_module_95d0_58d_58dSys_58d_58dmain.html
+property_module_95d1_58d_58dA_58d_58da1.html
+property_module_95d1_58d_58dA_58d_58da12.html
+property_module_95d1_58d_58dA_58d_58da123.html
+property_module_95d1_58d_58dA_58d_58da13.html
+property_module_95d1_58d_58dB_58d_58dall2.html
+property_module_95d1_58d_58dB_58d_58dall25.html
 quicksearch-list.js
-resources/
-search.html
 vendors/
index 047c766..268190c 100644 (file)
@@ -1,50 +1,45 @@
-Empty README for group `base_attr_nullable` (readme-warning)
-Errors: 0. Warnings: 1.
-class_base_attr_nullable-__Bar.html
-class_base_attr_nullable-__Bool.html
-class_base_attr_nullable-__Foo.html
-class_base_attr_nullable-__Int.html
-class_base_attr_nullable-__Integer.html
-class_base_attr_nullable-__Object.html
-class_base_attr_nullable-__Sys.html
+Parsing code...
+Generating documentation pages...
+Documentation produced in `out/nitdoc_args2.write`
+Generated 28/28 pages
+ PageHome: 1
+ PageMPackage: 1
+ PageMGroup: 1
+ PageMModule: 1
+ PageMClass: 7
+ PageMProperty: 17
+ PagePerson: 0
+ PageTag: 0
+class_base_attr_nullable_58d_58dBar.html
+class_base_attr_nullable_58d_58dBool.html
+class_base_attr_nullable_58d_58dFoo.html
+class_base_attr_nullable_58d_58dInt.html
+class_base_attr_nullable_58d_58dInteger.html
+class_base_attr_nullable_58d_58dObject.html
+class_base_attr_nullable_58d_58dSys.html
 css/
-dep_class_base_attr_nullable-__Bar.dot
-dep_class_base_attr_nullable-__Bool.dot
-dep_class_base_attr_nullable-__Foo.dot
-dep_class_base_attr_nullable-__Int.dot
-dep_class_base_attr_nullable-__Integer.dot
-dep_class_base_attr_nullable-__Object.dot
-dep_class_base_attr_nullable-__Sys.dot
-dep_module_base_attr_nullable-.dot
-dep_module_base_attr_nullable_45dm.dot
-group_base_attr_nullable.html
+group_base_attr_nullable_62d.html
 index.html
 js/
 less/
-module_base_attr_nullable-.html
-module_base_attr_nullable_45dm.html
-property_base_attr_nullable-__Bar___a3.html
-property_base_attr_nullable-__Bar__a3.html
-property_base_attr_nullable-__Bar__a3_61d.html
-property_base_attr_nullable-__Foo___a1.html
-property_base_attr_nullable-__Foo___a2.html
-property_base_attr_nullable-__Foo__a1.html
-property_base_attr_nullable-__Foo__a1_61d.html
-property_base_attr_nullable-__Foo__a2.html
-property_base_attr_nullable-__Foo__a2_61d.html
-property_base_attr_nullable-__Foo__nop.html
-property_base_attr_nullable-__Foo__run.html
-property_base_attr_nullable-__Foo__run_other.html
-property_base_attr_nullable-__Int___43d.html
-property_base_attr_nullable-__Int__output.html
-property_base_attr_nullable-__Integer___val.html
-property_base_attr_nullable-__Integer__init.html
-property_base_attr_nullable-__Integer__output.html
-property_base_attr_nullable-__Integer__val.html
-property_base_attr_nullable-__Integer__val_61d.html
-property_base_attr_nullable-__Object__init.html
-property_base_attr_nullable-__Sys__main.html
+module_base_attr_nullable_58d_58dbase_attr_nullable.html
+package_base_attr_nullable.html
+property_base_attr_nullable_58d_58dBar_58d_58da3.html
+property_base_attr_nullable_58d_58dBar_58d_58da3_61d.html
+property_base_attr_nullable_58d_58dFoo_58d_58da1.html
+property_base_attr_nullable_58d_58dFoo_58d_58da1_61d.html
+property_base_attr_nullable_58d_58dFoo_58d_58da2.html
+property_base_attr_nullable_58d_58dFoo_58d_58da2_61d.html
+property_base_attr_nullable_58d_58dFoo_58d_58dnop.html
+property_base_attr_nullable_58d_58dFoo_58d_58drun.html
+property_base_attr_nullable_58d_58dFoo_58d_58drun_other.html
+property_base_attr_nullable_58d_58dInt_58d_58d_43d.html
+property_base_attr_nullable_58d_58dInt_58d_58doutput.html
+property_base_attr_nullable_58d_58dInteger_58d_58dinit.html
+property_base_attr_nullable_58d_58dInteger_58d_58doutput.html
+property_base_attr_nullable_58d_58dInteger_58d_58dval.html
+property_base_attr_nullable_58d_58dInteger_58d_58dval_61d.html
+property_base_attr_nullable_58d_58dObject_58d_58dinit.html
+property_base_attr_nullable_58d_58dSys_58d_58dmain.html
 quicksearch-list.js
-resources/
-search.html
 vendors/
index 047c766..105d27c 100644 (file)
@@ -1,50 +1,45 @@
-Empty README for group `base_attr_nullable` (readme-warning)
-Errors: 0. Warnings: 1.
-class_base_attr_nullable-__Bar.html
-class_base_attr_nullable-__Bool.html
-class_base_attr_nullable-__Foo.html
-class_base_attr_nullable-__Int.html
-class_base_attr_nullable-__Integer.html
-class_base_attr_nullable-__Object.html
-class_base_attr_nullable-__Sys.html
+Parsing code...
+Generating documentation pages...
+Documentation produced in `out/nitdoc_args3.write`
+Generated 28/28 pages
+ PageHome: 1
+ PageMPackage: 1
+ PageMGroup: 1
+ PageMModule: 1
+ PageMClass: 7
+ PageMProperty: 17
+ PagePerson: 0
+ PageTag: 0
+class_base_attr_nullable_58d_58dBar.html
+class_base_attr_nullable_58d_58dBool.html
+class_base_attr_nullable_58d_58dFoo.html
+class_base_attr_nullable_58d_58dInt.html
+class_base_attr_nullable_58d_58dInteger.html
+class_base_attr_nullable_58d_58dObject.html
+class_base_attr_nullable_58d_58dSys.html
 css/
-dep_class_base_attr_nullable-__Bar.dot
-dep_class_base_attr_nullable-__Bool.dot
-dep_class_base_attr_nullable-__Foo.dot
-dep_class_base_attr_nullable-__Int.dot
-dep_class_base_attr_nullable-__Integer.dot
-dep_class_base_attr_nullable-__Object.dot
-dep_class_base_attr_nullable-__Sys.dot
-dep_module_base_attr_nullable-.dot
-dep_module_base_attr_nullable_45dm.dot
-group_base_attr_nullable.html
+group_base_attr_nullable_62d.html
 index.html
 js/
 less/
-module_base_attr_nullable-.html
-module_base_attr_nullable_45dm.html
-property_base_attr_nullable-__Bar___a3.html
-property_base_attr_nullable-__Bar__a3.html
-property_base_attr_nullable-__Bar__a3_61d.html
-property_base_attr_nullable-__Foo___a1.html
-property_base_attr_nullable-__Foo___a2.html
-property_base_attr_nullable-__Foo__a1.html
-property_base_attr_nullable-__Foo__a1_61d.html
-property_base_attr_nullable-__Foo__a2.html
-property_base_attr_nullable-__Foo__a2_61d.html
-property_base_attr_nullable-__Foo__nop.html
-property_base_attr_nullable-__Foo__run.html
-property_base_attr_nullable-__Foo__run_other.html
-property_base_attr_nullable-__Int___43d.html
-property_base_attr_nullable-__Int__output.html
-property_base_attr_nullable-__Integer___val.html
-property_base_attr_nullable-__Integer__init.html
-property_base_attr_nullable-__Integer__output.html
-property_base_attr_nullable-__Integer__val.html
-property_base_attr_nullable-__Integer__val_61d.html
-property_base_attr_nullable-__Object__init.html
-property_base_attr_nullable-__Sys__main.html
+module_base_attr_nullable_58d_58dbase_attr_nullable.html
+package_base_attr_nullable.html
+property_base_attr_nullable_58d_58dBar_58d_58da3.html
+property_base_attr_nullable_58d_58dBar_58d_58da3_61d.html
+property_base_attr_nullable_58d_58dFoo_58d_58da1.html
+property_base_attr_nullable_58d_58dFoo_58d_58da1_61d.html
+property_base_attr_nullable_58d_58dFoo_58d_58da2.html
+property_base_attr_nullable_58d_58dFoo_58d_58da2_61d.html
+property_base_attr_nullable_58d_58dFoo_58d_58dnop.html
+property_base_attr_nullable_58d_58dFoo_58d_58drun.html
+property_base_attr_nullable_58d_58dFoo_58d_58drun_other.html
+property_base_attr_nullable_58d_58dInt_58d_58d_43d.html
+property_base_attr_nullable_58d_58dInt_58d_58doutput.html
+property_base_attr_nullable_58d_58dInteger_58d_58dinit.html
+property_base_attr_nullable_58d_58dInteger_58d_58doutput.html
+property_base_attr_nullable_58d_58dInteger_58d_58dval.html
+property_base_attr_nullable_58d_58dInteger_58d_58dval_61d.html
+property_base_attr_nullable_58d_58dObject_58d_58dinit.html
+property_base_attr_nullable_58d_58dSys_58d_58dmain.html
 quicksearch-list.js
-resources/
-search.html
 vendors/
index 8fee501..3be4a55 100644 (file)
-Empty README for group `examples` (readme-warning)
-Empty README for group `man` (readme-warning)
-Empty README for group `tests` (readme-warning)
-Empty README for group `excluded` (readme-warning)
-Errors: 0. Warnings: 4.
-MGroupPage excluded
-       # excluded.section
-               ## excluded.intro
-               ## excluded.concerns
-               ## excluded.concern
-               ## excluded.concern
-               ## excluded-.concern
-                       ### excluded-.definition
-                               #### excluded-.intros_redefs
-                                       ##### list.group
-                                               ###### excluded-.intros
-                                               ###### excluded-.redefs
-
-MModulePage excluded
-       # excluded.section
-               ## excluded-.intro
-               ## excluded-.importation
-                       ### excluded-.graph
-                       ### list.group
-                               #### excluded-.imports
-                               #### excluded-.clients
-
-OverviewPage Overview
-       # home.article
-               ## packages.section
-                       ### excluded.definition
-                       ### test_prog.definition
-
-ReadmePage excluded
-
-ReadmePage test_prog
-       # mdarticle-0
-
-ReadmePage examples
-
-ReadmePage game
-       # mdarticle-0
-
-ReadmePage man
-
-ReadmePage platform
-       # mdarticle-0
-
-ReadmePage rpg
-       # mdarticle-0
-
-ReadmePage tests
-
-SearchPage Index
-       # index.article
-
-MGroupPage test_prog
-       # test_prog.section
-               ## test_prog.intro
-               ## test_prog.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog-.concern
-                       ### test_prog-.definition
-                               #### test_prog-.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog-.intros
-                                               ###### test_prog-.redefs
-
-MModulePage test_prog
-       # test_prog.section
-               ## test_prog-.intro
-               ## test_prog-.importation
-                       ### test_prog-.graph
-                       ### list.group
-                               #### test_prog-.imports
-                               #### test_prog-.clients
-               ## test_prog-.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog-.concern
-                       ### test_prog-__Starter.definition-list
-                               #### test_prog-__Starter.definition
-                                       ##### test_prog-__Starter.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog-__Starter.intros
-                                                       ####### test_prog-__Starter.redefs
-               ## test_prog__platform.concern
-               ## test_prog__platform-.concern
-                       ### test_prog__platform-__Sys.definition-list
-                               #### test_prog__platform-__Sys.definition
-                               #### test_prog-__Sys.definition
-                                       ##### test_prog-__Sys.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog-__Sys.intros
-                                                       ####### test_prog-__Sys.redefs
-
-MClassPage Starter
-       # Starter.section
-               ## test_prog-__Starter.intro
-               ## test_prog-__Starter.inheritance
-                       ### test_prog-__Starter.graph
-                       ### list.group
-                               #### test_prog-__Starter.parents
-                               #### test_prog-__Starter.ancestors
-                               #### test_prog-__Starter.children
-                               #### test_prog-__Starter.descendants
-               ## test_prog-__Starter.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog-__Starter.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog-.concern
-                       ### test_prog-__Starter__start.definition
-
-MPropertyPage start
-       # start.section
-               ## test_prog-__Starter__start.intro
-
-MModulePage test_prog-m
-       # test_prog-m.section
-               ## test_prog_45dm.intro
-               ## test_prog_45dm.importation
-                       ### test_prog_45dm.graph
-                       ### list.group
-                               #### test_prog_45dm.imports
-                               #### test_prog_45dm.clients
-
-MGroupPage examples
-       # examples.section
-               ## test_prog__examples.intro
-               ## test_prog__examples.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-.definition
-                               #### test_prog__examples-.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__examples-.intros
-                                               ###### test_prog__examples-.redefs
-
-MModulePage game_examples
-       # game_examples.section
-               ## test_prog__examples-.intro
-               ## test_prog__examples-.importation
-                       ### test_prog__examples-.graph
-                       ### list.group
-                               #### test_prog__examples-.imports
-                               #### test_prog__examples-.clients
-               ## test_prog__examples-.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-__MyGame.definition-list
-                               #### test_prog__examples-__MyGame.definition
-                                       ##### test_prog__examples-__MyGame.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__examples-__MyGame.intros
-                                                       ####### test_prog__examples-__MyGame.redefs
-
-MClassPage MyGame
-       # MyGame.section
-               ## test_prog__examples-__MyGame.intro
-               ## test_prog__examples-__MyGame.inheritance
-                       ### test_prog__examples-__MyGame.graph
-                       ### list.group
-                               #### test_prog__examples-__MyGame.parents
-                               #### test_prog__examples-__MyGame.ancestors
-                               #### test_prog__examples-__MyGame.children
-                               #### test_prog__examples-__MyGame.descendants
-               ## test_prog__examples-__MyGame.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__examples-__MyGame.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-__MyGame__computer_characters.definition
-                               #### test_prog__examples-__MyGame__computer_characters.lin
-                       ### test_prog__examples-__MyGame__computer_characters_61d.definition
-                       ### test_prog__examples-__MyGame__pause_game.definition
-                               #### test_prog__examples-__MyGame__pause_game.lin
-                       ### test_prog__examples-__MyGame__player_characters.definition
-                               #### test_prog__examples-__MyGame__player_characters.lin
-                       ### test_prog__examples-__MyGame__player_characters_61d.definition
-                       ### test_prog__examples-__MyGame__start_game.definition
-                               #### test_prog__examples-__MyGame__start_game.lin
-                       ### test_prog__examples-__MyGame__stop_game.definition
-                               #### test_prog__examples-__MyGame__stop_game.lin
-
-MPropertyPage _computer_characters
-       # _computer_characters.section
-               ## test_prog__examples-__MyGame___computer_characters.intro
-
-MPropertyPage _player_characters
-       # _player_characters.section
-               ## test_prog__examples-__MyGame___player_characters.intro
-
-MPropertyPage computer_characters=
-       # computer_characters=.section
-               ## test_prog__examples-__MyGame__computer_characters_61d.intro
-
-MPropertyPage player_characters=
-       # player_characters=.section
-               ## test_prog__examples-__MyGame__player_characters_61d.intro
-
-MGroupPage game
-       # game.section
-               ## test_prog__game.intro
-               ## test_prog__game.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__game.concern
-               ## test_prog__game-.concern
-                       ### test_prog__game-.definition
-                               #### test_prog__game-.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__game-.intros
-                                               ###### test_prog__game-.redefs
-
-MModulePage game
-       # game.section
-               ## test_prog__game-.intro
-               ## test_prog__game-.importation
-                       ### test_prog__game-.graph
-                       ### list.group
-                               #### test_prog__game-.imports
-                               #### test_prog__game-.clients
-               ## test_prog__game-.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__game.concern
-               ## test_prog__game-.concern
-                       ### test_prog__game-__Game.definition-list
-                               #### test_prog__game-__Game.definition
-                                       ##### test_prog__game-__Game.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__game-__Game.intros
-                                                       ####### test_prog__game-__Game.redefs
-
-MClassPage Game
-       # Game.section
-               ## test_prog__game-__Game.intro
-               ## test_prog__game-__Game.inheritance
-                       ### test_prog__game-__Game.graph
-                       ### list.group
-                               #### test_prog__game-__Game.parents
-                               #### test_prog__game-__Game.ancestors
-                               #### test_prog__game-__Game.children
-                               #### test_prog__game-__Game.descendants
-               ## test_prog__game-__Game.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__game-__Game.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__game.concern
-               ## test_prog__game-.concern
-                       ### test_prog__game-__Game__computer_characters.definition
-                       ### test_prog__game-__Game__pause_game.definition
-                       ### test_prog__game-__Game__player_characters.definition
-                       ### test_prog__game-__Game__start_game.definition
-                       ### test_prog__game-__Game__stop_game.definition
-
-MPropertyPage computer_characters
-       # computer_characters.section
-               ## test_prog__game-__Game__computer_characters.intro
-               ## test_prog__game-__Game__computer_characters.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-__MyGame__computer_characters.definition
-
-MPropertyPage pause_game
-       # pause_game.section
-               ## test_prog__game-__Game__pause_game.intro
-               ## test_prog__game-__Game__pause_game.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-__MyGame__pause_game.definition
-
-MPropertyPage player_characters
-       # player_characters.section
-               ## test_prog__game-__Game__player_characters.intro
-               ## test_prog__game-__Game__player_characters.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-__MyGame__player_characters.definition
-               ## test_prog__tests.concern
-               ## test_prog__tests-.concern
-                       ### test_prog__tests-__TestGame__player_characters.definition
-
-MPropertyPage start_game
-       # start_game.section
-               ## test_prog__game-__Game__start_game.intro
-               ## test_prog__game-__Game__start_game.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-__MyGame__start_game.definition
-
-MPropertyPage stop_game
-       # stop_game.section
-               ## test_prog__game-__Game__stop_game.intro
-               ## test_prog__game-__Game__stop_game.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__examples.concern
-               ## test_prog__examples-.concern
-                       ### test_prog__examples-__MyGame__stop_game.definition
-
-MGroupPage man
-       # man.section
-               ## test_prog__man.intro
-
-MGroupPage platform
-       # platform.section
-               ## test_prog__platform.intro
-               ## test_prog__platform.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__platform.concern
-               ## test_prog__platform-.concern
-                       ### test_prog__platform-.definition
-                               #### test_prog__platform-.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__platform-.intros
-                                               ###### test_prog__platform-.redefs
-
-MModulePage platform
-       # platform.section
-               ## test_prog__platform-.intro
-               ## test_prog__platform-.importation
-                       ### test_prog__platform-.graph
-                       ### list.group
-                               #### test_prog__platform-.imports
-                               #### test_prog__platform-.clients
-               ## test_prog__platform-.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__platform.concern
-               ## test_prog__platform-.concern
-                       ### test_prog__platform-__Bool.definition-list
-                               #### test_prog__platform-__Bool.definition
-                                       ##### test_prog__platform-__Bool.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__platform-__Bool.intros
-                                                       ####### test_prog__platform-__Bool.redefs
-                       ### test_prog__platform-__Float.definition-list
-                               #### test_prog__platform-__Float.definition
-                                       ##### test_prog__platform-__Float.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__platform-__Float.intros
-                                                       ####### test_prog__platform-__Float.redefs
-                       ### test_prog__platform-__Int.definition-list
-                               #### test_prog__platform-__Int.definition
-                                       ##### test_prog__platform-__Int.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__platform-__Int.intros
-                                                       ####### test_prog__platform-__Int.redefs
-                       ### test_prog__platform-__List.definition-list
-                               #### test_prog__platform-__List.definition
-                                       ##### test_prog__platform-__List.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__platform-__List.intros
-                                                       ####### test_prog__platform-__List.redefs
-                       ### test_prog__platform-__Object.definition-list
-                               #### test_prog__platform-__Object.definition
-                                       ##### test_prog__platform-__Object.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__platform-__Object.intros
-                                                       ####### test_prog__platform-__Object.redefs
-                       ### test_prog__platform-__String.definition-list
-                               #### test_prog__platform-__String.definition
-                                       ##### test_prog__platform-__String.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__platform-__String.intros
-                                                       ####### test_prog__platform-__String.redefs
-                       ### test_prog__platform-__Sys.definition-list
-                               #### test_prog__platform-__Sys.definition
-                                       ##### test_prog__platform-__Sys.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__platform-__Sys.intros
-                                                       ####### test_prog__platform-__Sys.redefs
-
-MClassPage Bool
-       # Bool.section
-               ## test_prog__platform-__Bool.intro
-               ## test_prog__platform-__Bool.inheritance
-                       ### test_prog__platform-__Bool.graph
-                       ### list.group
-                               #### test_prog__platform-__Bool.parents
-                               #### test_prog__platform-__Bool.ancestors
-                               #### test_prog__platform-__Bool.children
-                               #### test_prog__platform-__Bool.descendants
-
-MClassPage Float
-       # Float.section
-               ## test_prog__platform-__Float.intro
-               ## test_prog__platform-__Float.inheritance
-                       ### test_prog__platform-__Float.graph
-                       ### list.group
-                               #### test_prog__platform-__Float.parents
-                               #### test_prog__platform-__Float.ancestors
-                               #### test_prog__platform-__Float.children
-                               #### test_prog__platform-__Float.descendants
-               ## test_prog__platform-__Float.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__platform-__Float.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__platform.concern
-               ## test_prog__platform-.concern
-                       ### test_prog__platform-__Float___42d.definition
-                       ### test_prog__platform-__Float___43d.definition
-                       ### test_prog__platform-__Float___45d.definition
-                       ### test_prog__platform-__Float___47d.definition
-                       ### test_prog__platform-__Float___62d.definition
-
-MPropertyPage *
-       # *.section
-               ## test_prog__platform-__Float___42d.intro
-
-MPropertyPage +
-       # +.section
-               ## test_prog__platform-__Float___43d.intro
-
-MPropertyPage -
-       # -.section
-               ## test_prog__platform-__Float___45d.intro
-
-MPropertyPage &#47;
-       # &#47;.section
-               ## test_prog__platform-__Float___47d.intro
-
-MPropertyPage &gt;
-       # &gt;.section
-               ## test_prog__platform-__Float___62d.intro
-
-MClassPage Int
-       # Int.section
-               ## test_prog__platform-__Int.intro
-               ## test_prog__platform-__Int.inheritance
-                       ### test_prog__platform-__Int.graph
-                       ### list.group
-                               #### test_prog__platform-__Int.parents
-                               #### test_prog__platform-__Int.ancestors
-                               #### test_prog__platform-__Int.children
-                               #### test_prog__platform-__Int.descendants
-               ## test_prog__platform-__Int.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__platform-__Int.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__platform.concern
-               ## test_prog__platform-.concern
-                       ### test_prog__platform-__Int___42d.definition
-                       ### test_prog__platform-__Int___43d.definition
-                       ### test_prog__platform-__Int___45d.definition
-                       ### test_prog__platform-__Int___47d.definition
-                       ### test_prog__platform-__Int___62d.definition
-                       ### test_prog__platform-__Int__to_f.definition
-                       ### test_prog__platform-__Int__unary_32d_45d.definition
-
-MPropertyPage *
-       # *.section
-               ## test_prog__platform-__Int___42d.intro
-
-MPropertyPage +
-       # +.section
-               ## test_prog__platform-__Int___43d.intro
-
-MPropertyPage -
-       # -.section
-               ## test_prog__platform-__Int___45d.intro
-
-MPropertyPage &#47;
-       # &#47;.section
-               ## test_prog__platform-__Int___47d.intro
-
-MPropertyPage &gt;
-       # &gt;.section
-               ## test_prog__platform-__Int___62d.intro
-
-MPropertyPage to_f
-       # to_f.section
-               ## test_prog__platform-__Int__to_f.intro
-
-MPropertyPage unary -
-       # unary -.section
-               ## test_prog__platform-__Int__unary_32d_45d.intro
-
-MClassPage List
-       # List.section
-               ## test_prog__platform-__List.intro
-               ## test_prog__platform-__List.inheritance
-                       ### test_prog__platform-__List.graph
-                       ### list.group
-                               #### test_prog__platform-__List.parents
-                               #### test_prog__platform-__List.ancestors
-                               #### test_prog__platform-__List.children
-                               #### test_prog__platform-__List.descendants
-
-MClassPage Object
-       # Object.section
-               ## test_prog__platform-__Object.intro
-               ## test_prog__platform-__Object.inheritance
-                       ### test_prog__platform-__Object.graph
-                       ### list.group
-                               #### test_prog__platform-__Object.parents
-                               #### test_prog__platform-__Object.ancestors
-                               #### test_prog__platform-__Object.children
-                               #### test_prog__platform-__Object.descendants
-               ## test_prog__platform-__Object.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__platform-__Object.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__platform.concern
-               ## test_prog__platform-.concern
-                       ### test_prog__platform-__Object__OTHER.definition
-                       ### test_prog__platform-__Object___33d_61d.definition
-                       ### test_prog__platform-__Object___61d_61d.definition
-
-MPropertyPage OTHER
-       # OTHER.section
-               ## test_prog__platform-__Object__OTHER.intro
-
-MPropertyPage !=
-       # !=.section
-               ## test_prog__platform-__Object___33d_61d.intro
-
-MPropertyPage ==
-       # ==.section
-               ## test_prog__platform-__Object___61d_61d.intro
-
-MPropertyPage init
-       # init.section
-               ## test_prog__platform-__Object__init.intro
-               ## test_prog__platform-__Object__init.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__careers.concern
-                       ### test_prog__rpg__careers__Career__init.definition
-                       ### test_prog__rpg__careers__Warrior__init.definition
-                       ### test_prog__rpg__careers__Magician__init.definition
-                       ### test_prog__rpg__careers__Alcoholic__init.definition
-               ## test_prog__rpg__races.concern
-                       ### test_prog__rpg__races__Race__init.definition
-                       ### test_prog__rpg__races__Human__init.definition
-                       ### test_prog__rpg__races__Dwarf__init.definition
-                       ### test_prog__rpg__races__Elf__init.definition
-               ## test_prog__rpg__character.concern
-                       ### test_prog__rpg__character__Character__init.definition
-
-MClassPage String
-       # String.section
-               ## test_prog__platform-__String.intro
-               ## test_prog__platform-__String.inheritance
-                       ### test_prog__platform-__String.graph
-                       ### list.group
-                               #### test_prog__platform-__String.parents
-                               #### test_prog__platform-__String.ancestors
-                               #### test_prog__platform-__String.children
-                               #### test_prog__platform-__String.descendants
-
-MClassPage Sys
-       # Sys.section
-               ## test_prog__platform-__Sys.intro
-               ## test_prog__platform-__Sys.inheritance
-                       ### test_prog__platform-__Sys.graph
-                       ### list.group
-                               #### test_prog__platform-__Sys.parents
-                               #### test_prog__platform-__Sys.ancestors
-                               #### test_prog__platform-__Sys.children
-                               #### test_prog__platform-__Sys.descendants
-               ## test_prog__platform-__Sys.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__platform-__Sys.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__platform.concern
-               ## test_prog__platform-.concern
-                       ### test_prog__platform-__Sys__main.definition
-                               #### test_prog__platform-__Sys__main.lin
-               ## test_prog-.concern
-                       ### test_prog-__Sys__main.definition
-                               #### test_prog-__Sys__main.lin
-
-MPropertyPage main
-       # main.section
-               ## test_prog__platform-__Sys__main.intro
-               ## test_prog__platform-__Sys__main.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog-.concern
-                       ### test_prog-__Sys__main.definition
-
-MGroupPage rpg
-       # rpg.section
-               ## test_prog__rpg.intro
-               ## test_prog__rpg.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__careers.concern
-                       ### test_prog__rpg__careers.definition
-                               #### test_prog__rpg__careers.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__rpg__careers.intros
-                                               ###### test_prog__rpg__careers.redefs
-               ## test_prog__rpg__races.concern
-                       ### test_prog__rpg__races.definition
-                               #### test_prog__rpg__races.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__rpg__races.intros
-                                               ###### test_prog__rpg__races.redefs
-               ## test_prog__rpg__character.concern
-                       ### test_prog__rpg__character.definition
-                               #### test_prog__rpg__character.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__rpg__character.intros
-                                               ###### test_prog__rpg__character.redefs
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat.definition
-                               #### test_prog__rpg__combat.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__rpg__combat.intros
-                                               ###### test_prog__rpg__combat.redefs
-               ## test_prog__rpg__rpg.concern
-                       ### test_prog__rpg__rpg.definition
-                               #### test_prog__rpg__rpg.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__rpg__rpg.intros
-                                               ###### test_prog__rpg__rpg.redefs
-
-MModulePage careers
-       # careers.section
-               ## test_prog__rpg__careers.intro
-               ## test_prog__rpg__careers.importation
-                       ### test_prog__rpg__careers.graph
-                       ### list.group
-                               #### test_prog__rpg__careers.imports
-                               #### test_prog__rpg__careers.clients
-               ## test_prog__rpg__careers.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__careers.concern
-                       ### test_prog__rpg__careers__Alcoholic.definition-list
-                               #### test_prog__rpg__careers__Alcoholic.definition
-                                       ##### test_prog__rpg__careers__Alcoholic.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__careers__Alcoholic.intros
-                                                       ####### test_prog__rpg__careers__Alcoholic.redefs
-                       ### test_prog__rpg__careers__Career.definition-list
-                               #### test_prog__rpg__careers__Career.definition
-                                       ##### test_prog__rpg__careers__Career.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__careers__Career.intros
-                                                       ####### test_prog__rpg__careers__Career.redefs
-                       ### test_prog__rpg__careers__Magician.definition-list
-                               #### test_prog__rpg__careers__Magician.definition
-                                       ##### test_prog__rpg__careers__Magician.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__careers__Magician.intros
-                                                       ####### test_prog__rpg__careers__Magician.redefs
-                       ### test_prog__rpg__careers__Warrior.definition-list
-                               #### test_prog__rpg__careers__Warrior.definition
-                                       ##### test_prog__rpg__careers__Warrior.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__careers__Warrior.intros
-                                                       ####### test_prog__rpg__careers__Warrior.redefs
-
-MClassPage Alcoholic
-       # Alcoholic.section
-               ## test_prog__rpg__careers__Alcoholic.intro
-               ## test_prog__rpg__careers__Alcoholic.inheritance
-                       ### test_prog__rpg__careers__Alcoholic.graph
-                       ### list.group
-                               #### test_prog__rpg__careers__Alcoholic.parents
-                               #### test_prog__rpg__careers__Alcoholic.ancestors
-                               #### test_prog__rpg__careers__Alcoholic.children
-                               #### test_prog__rpg__careers__Alcoholic.descendants
-               ## test_prog__rpg__careers__Alcoholic.constructors
-                       ### test_prog__rpg__careers__Alcoholic__init.definition
-                               #### test_prog__rpg__careers__Alcoholic__init.lin
-               ## test_prog__rpg__careers__Alcoholic.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__careers.concern
-
-MClassPage Career
-       # Career.section
-               ## test_prog__rpg__careers__Career.intro
-               ## test_prog__rpg__careers__Career.inheritance
-                       ### test_prog__rpg__careers__Career.graph
-                       ### list.group
-                               #### test_prog__rpg__careers__Career.parents
-                               #### test_prog__rpg__careers__Career.ancestors
-                               #### test_prog__rpg__careers__Career.children
-                               #### test_prog__rpg__careers__Career.descendants
-               ## test_prog__rpg__careers__Career.constructors
-                       ### test_prog__rpg__careers__Career__init.definition
-                               #### test_prog__rpg__careers__Career__init.lin
-               ## test_prog__rpg__careers__Career.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__careers.concern
-                       ### test_prog__rpg__careers__Career__endurance_bonus.definition
-                       ### test_prog__rpg__careers__Career__endurance_bonus_61d.definition
-                       ### test_prog__rpg__careers__Career__intelligence_bonus.definition
-                       ### test_prog__rpg__careers__Career__intelligence_bonus_61d.definition
-                       ### test_prog__rpg__careers__Career__strength_bonus.definition
-                       ### test_prog__rpg__careers__Career__strength_bonus_61d.definition
-
-MPropertyPage _endurance_bonus
-       # _endurance_bonus.section
-               ## test_prog__rpg__careers__Career___endurance_bonus.intro
-
-MPropertyPage _intelligence_bonus
-       # _intelligence_bonus.section
-               ## test_prog__rpg__careers__Career___intelligence_bonus.intro
-
-MPropertyPage _strength_bonus
-       # _strength_bonus.section
-               ## test_prog__rpg__careers__Career___strength_bonus.intro
-
-MPropertyPage endurance_bonus
-       # endurance_bonus.section
-               ## test_prog__rpg__careers__Career__endurance_bonus.intro
-
-MPropertyPage endurance_bonus=
-       # endurance_bonus=.section
-               ## test_prog__rpg__careers__Career__endurance_bonus_61d.intro
-
-MPropertyPage intelligence_bonus
-       # intelligence_bonus.section
-               ## test_prog__rpg__careers__Career__intelligence_bonus.intro
-
-MPropertyPage intelligence_bonus=
-       # intelligence_bonus=.section
-               ## test_prog__rpg__careers__Career__intelligence_bonus_61d.intro
-
-MPropertyPage strength_bonus
-       # strength_bonus.section
-               ## test_prog__rpg__careers__Career__strength_bonus.intro
-
-MPropertyPage strength_bonus=
-       # strength_bonus=.section
-               ## test_prog__rpg__careers__Career__strength_bonus_61d.intro
-
-MClassPage Magician
-       # Magician.section
-               ## test_prog__rpg__careers__Magician.intro
-               ## test_prog__rpg__careers__Magician.inheritance
-                       ### test_prog__rpg__careers__Magician.graph
-                       ### list.group
-                               #### test_prog__rpg__careers__Magician.parents
-                               #### test_prog__rpg__careers__Magician.ancestors
-                               #### test_prog__rpg__careers__Magician.children
-                               #### test_prog__rpg__careers__Magician.descendants
-               ## test_prog__rpg__careers__Magician.constructors
-                       ### test_prog__rpg__careers__Magician__init.definition
-                               #### test_prog__rpg__careers__Magician__init.lin
-               ## test_prog__rpg__careers__Magician.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__careers.concern
-
-MClassPage Warrior
-       # Warrior.section
-               ## test_prog__rpg__careers__Warrior.intro
-               ## test_prog__rpg__careers__Warrior.inheritance
-                       ### test_prog__rpg__careers__Warrior.graph
-                       ### list.group
-                               #### test_prog__rpg__careers__Warrior.parents
-                               #### test_prog__rpg__careers__Warrior.ancestors
-                               #### test_prog__rpg__careers__Warrior.children
-                               #### test_prog__rpg__careers__Warrior.descendants
-               ## test_prog__rpg__careers__Warrior.constructors
-                       ### test_prog__rpg__careers__Warrior__init.definition
-                               #### test_prog__rpg__careers__Warrior__init.lin
-               ## test_prog__rpg__careers__Warrior.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__careers.concern
-
-MModulePage character
-       # character.section
-               ## test_prog__rpg__character.intro
-               ## test_prog__rpg__character.importation
-                       ### test_prog__rpg__character.graph
-                       ### list.group
-                               #### test_prog__rpg__character.imports
-                               #### test_prog__rpg__character.clients
-               ## test_prog__rpg__character.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__character.concern
-                       ### test_prog__rpg__character__Character.definition-list
-                               #### test_prog__rpg__character__Character.definition
-                                       ##### test_prog__rpg__character__Character.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__character__Character.intros
-                                                       ####### test_prog__rpg__character__Character.redefs
-
-MClassPage Character
-       # Character.section
-               ## test_prog__rpg__character__Character.intro
-               ## test_prog__rpg__character__Character.inheritance
-                       ### test_prog__rpg__character__Character.graph
-                       ### list.group
-                               #### test_prog__rpg__character__Character.parents
-                               #### test_prog__rpg__character__Character.ancestors
-                               #### test_prog__rpg__character__Character.children
-                               #### test_prog__rpg__character__Character.descendants
-               ## test_prog__rpg__character__Character.constructors
-                       ### test_prog__rpg__character__Character__init.definition
-                               #### test_prog__rpg__character__Character__init.lin
-               ## test_prog__rpg__character__Character.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__character.concern
-                       ### test_prog__rpg__character__Character__age.definition
-                       ### test_prog__rpg__character__Character__age_61d.definition
-                       ### test_prog__rpg__character__Character__career.definition
-                       ### test_prog__rpg__character__Character__career_61d.definition
-                       ### test_prog__rpg__character__Character__health.definition
-                       ### test_prog__rpg__character__Character__health_61d.definition
-                       ### test_prog__rpg__character__Character__max_health.definition
-                       ### test_prog__rpg__character__Character__name.definition
-                       ### test_prog__rpg__character__Character__name_61d.definition
-                       ### test_prog__rpg__character__Character__quit.definition
-                       ### test_prog__rpg__character__Character__race.definition
-                       ### test_prog__rpg__character__Character__race_61d.definition
-                       ### test_prog__rpg__character__Character__sex.definition
-                       ### test_prog__rpg__character__Character__sex_61d.definition
-                       ### test_prog__rpg__character__Character__total_endurance.definition
-                       ### test_prog__rpg__character__Character__total_intelligence.definition
-                       ### test_prog__rpg__character__Character__total_strengh.definition
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat__Character__hit_points.definition
-                               #### test_prog__rpg__combat__Character__hit_points.lin
-
-MPropertyPage _age
-       # _age.section
-               ## test_prog__rpg__character__Character___age.intro
-
-MPropertyPage _career
-       # _career.section
-               ## test_prog__rpg__character__Character___career.intro
-
-MPropertyPage _health
-       # _health.section
-               ## test_prog__rpg__character__Character___health.intro
-
-MPropertyPage _name
-       # _name.section
-               ## test_prog__rpg__character__Character___name.intro
-
-MPropertyPage _race
-       # _race.section
-               ## test_prog__rpg__character__Character___race.intro
-
-MPropertyPage _sex
-       # _sex.section
-               ## test_prog__rpg__character__Character___sex.intro
-
-MPropertyPage age
-       # age.section
-               ## test_prog__rpg__character__Character__age.intro
-
-MPropertyPage age=
-       # age=.section
-               ## test_prog__rpg__character__Character__age_61d.intro
-
-MPropertyPage career
-       # career.section
-               ## test_prog__rpg__character__Character__career.intro
-
-MPropertyPage career=
-       # career=.section
-               ## test_prog__rpg__character__Character__career_61d.intro
-
-MPropertyPage health
-       # health.section
-               ## test_prog__rpg__character__Character__health.intro
-
-MPropertyPage health=
-       # health=.section
-               ## test_prog__rpg__character__Character__health_61d.intro
-
-MPropertyPage max_health
-       # max_health.section
-               ## test_prog__rpg__character__Character__max_health.intro
-
-MPropertyPage name
-       # name.section
-               ## test_prog__rpg__character__Character__name.intro
-
-MPropertyPage name=
-       # name=.section
-               ## test_prog__rpg__character__Character__name_61d.intro
-
-MPropertyPage quit
-       # quit.section
-               ## test_prog__rpg__character__Character__quit.intro
-
-MPropertyPage race
-       # race.section
-               ## test_prog__rpg__character__Character__race.intro
-
-MPropertyPage race=
-       # race=.section
-               ## test_prog__rpg__character__Character__race_61d.intro
-
-MPropertyPage sex
-       # sex.section
-               ## test_prog__rpg__character__Character__sex.intro
-
-MPropertyPage sex=
-       # sex=.section
-               ## test_prog__rpg__character__Character__sex_61d.intro
-
-MPropertyPage total_endurance
-       # total_endurance.section
-               ## test_prog__rpg__character__Character__total_endurance.intro
-
-MPropertyPage total_intelligence
-       # total_intelligence.section
-               ## test_prog__rpg__character__Character__total_intelligence.intro
-
-MPropertyPage total_strengh
-       # total_strengh.section
-               ## test_prog__rpg__character__Character__total_strengh.intro
-
-MModulePage combat
-       # combat.section
-               ## test_prog__rpg__combat.intro
-               ## test_prog__rpg__combat.importation
-                       ### test_prog__rpg__combat.graph
-                       ### list.group
-                               #### test_prog__rpg__combat.imports
-                               #### test_prog__rpg__combat.clients
-               ## test_prog__rpg__combat.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat__Combatable.definition-list
-                               #### test_prog__rpg__combat__Combatable.definition
-                                       ##### test_prog__rpg__combat__Combatable.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__combat__Combatable.intros
-                                                       ####### test_prog__rpg__combat__Combatable.redefs
-                       ### test_prog__rpg__combat__Weapon.definition-list
-                               #### test_prog__rpg__combat__Weapon.definition
-                                       ##### test_prog__rpg__combat__Weapon.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__combat__Weapon.intros
-                                                       ####### test_prog__rpg__combat__Weapon.redefs
-               ## test_prog__rpg__races.concern
-                       ### test_prog__rpg__races__Dwarf.definition-list
-                               #### test_prog__rpg__races__Dwarf.definition
-                               #### test_prog__rpg__combat__Dwarf.definition
-                                       ##### test_prog__rpg__combat__Dwarf.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__combat__Dwarf.intros
-                                                       ####### test_prog__rpg__combat__Dwarf.redefs
-               ## test_prog__rpg__character.concern
-                       ### test_prog__rpg__character__Character.definition-list
-                               #### test_prog__rpg__character__Character.definition
-                               #### test_prog__rpg__combat__Character.definition
-                                       ##### test_prog__rpg__combat__Character.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__combat__Character.intros
-                                                       ####### test_prog__rpg__combat__Character.redefs
-
-MClassPage Combatable
-       # Combatable.section
-               ## test_prog__rpg__combat__Combatable.intro
-               ## test_prog__rpg__combat__Combatable.inheritance
-                       ### test_prog__rpg__combat__Combatable.graph
-                       ### list.group
-                               #### test_prog__rpg__combat__Combatable.parents
-                               #### test_prog__rpg__combat__Combatable.ancestors
-                               #### test_prog__rpg__combat__Combatable.children
-                               #### test_prog__rpg__combat__Combatable.descendants
-               ## test_prog__rpg__combat__Combatable.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__rpg__combat__Combatable.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat__Combatable__attack.definition
-                       ### test_prog__rpg__combat__Combatable__defend.definition
-                       ### test_prog__rpg__combat__Combatable__direct_attack.definition
-                       ### test_prog__rpg__combat__Combatable__hit_points.definition
-                       ### test_prog__rpg__combat__Combatable__is_dead.definition
-
-MPropertyPage attack
-       # attack.section
-               ## test_prog__rpg__combat__Combatable__attack.intro
-
-MPropertyPage defend
-       # defend.section
-               ## test_prog__rpg__combat__Combatable__defend.intro
-
-MPropertyPage direct_attack
-       # direct_attack.section
-               ## test_prog__rpg__combat__Combatable__direct_attack.intro
-
-MPropertyPage hit_points
-       # hit_points.section
-               ## test_prog__rpg__combat__Combatable__hit_points.intro
-               ## test_prog__rpg__combat__Combatable__hit_points.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat__Character__hit_points.definition
-
-MPropertyPage is_dead
-       # is_dead.section
-               ## test_prog__rpg__combat__Combatable__is_dead.intro
-
-MClassPage Weapon
-       # Weapon.section
-               ## test_prog__rpg__combat__Weapon.intro
-               ## test_prog__rpg__combat__Weapon.inheritance
-                       ### test_prog__rpg__combat__Weapon.graph
-                       ### list.group
-                               #### test_prog__rpg__combat__Weapon.parents
-                               #### test_prog__rpg__combat__Weapon.ancestors
-                               #### test_prog__rpg__combat__Weapon.children
-                               #### test_prog__rpg__combat__Weapon.descendants
-               ## test_prog__rpg__combat__Weapon.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__rpg__combat__Weapon.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat__Weapon__dps.definition
-
-MPropertyPage dps
-       # dps.section
-               ## test_prog__rpg__combat__Weapon__dps.intro
-               ## test_prog__rpg__combat__Weapon__dps.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat__Dwarf__dps.definition
-
-MModulePage races
-       # races.section
-               ## test_prog__rpg__races.intro
-               ## test_prog__rpg__races.importation
-                       ### test_prog__rpg__races.graph
-                       ### list.group
-                               #### test_prog__rpg__races.imports
-                               #### test_prog__rpg__races.clients
-               ## test_prog__rpg__races.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__races.concern
-                       ### test_prog__rpg__races__Dwarf.definition-list
-                               #### test_prog__rpg__races__Dwarf.definition
-                                       ##### test_prog__rpg__races__Dwarf.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__races__Dwarf.intros
-                                                       ####### test_prog__rpg__races__Dwarf.redefs
-                       ### test_prog__rpg__races__Elf.definition-list
-                               #### test_prog__rpg__races__Elf.definition
-                                       ##### test_prog__rpg__races__Elf.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__races__Elf.intros
-                                                       ####### test_prog__rpg__races__Elf.redefs
-                       ### test_prog__rpg__races__Human.definition-list
-                               #### test_prog__rpg__races__Human.definition
-                                       ##### test_prog__rpg__races__Human.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__races__Human.intros
-                                                       ####### test_prog__rpg__races__Human.redefs
-                       ### test_prog__rpg__races__Race.definition-list
-                               #### test_prog__rpg__races__Race.definition
-                                       ##### test_prog__rpg__races__Race.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__rpg__races__Race.intros
-                                                       ####### test_prog__rpg__races__Race.redefs
-
-MClassPage Dwarf
-       # Dwarf.section
-               ## test_prog__rpg__races__Dwarf.intro
-               ## test_prog__rpg__races__Dwarf.inheritance
-                       ### test_prog__rpg__races__Dwarf.graph
-                       ### list.group
-                               #### test_prog__rpg__races__Dwarf.parents
-                               #### test_prog__rpg__races__Dwarf.ancestors
-                               #### test_prog__rpg__races__Dwarf.children
-                               #### test_prog__rpg__races__Dwarf.descendants
-               ## test_prog__rpg__races__Dwarf.constructors
-                       ### test_prog__rpg__races__Dwarf__init.definition
-                               #### test_prog__rpg__races__Dwarf__init.lin
-               ## test_prog__rpg__races__Dwarf.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__races.concern
-               ## test_prog__rpg__combat.concern
-                       ### test_prog__rpg__combat__Dwarf__dps.definition
-                               #### test_prog__rpg__combat__Dwarf__dps.lin
-
-MClassPage Elf
-       # Elf.section
-               ## test_prog__rpg__races__Elf.intro
-               ## test_prog__rpg__races__Elf.inheritance
-                       ### test_prog__rpg__races__Elf.graph
-                       ### list.group
-                               #### test_prog__rpg__races__Elf.parents
-                               #### test_prog__rpg__races__Elf.ancestors
-                               #### test_prog__rpg__races__Elf.children
-                               #### test_prog__rpg__races__Elf.descendants
-               ## test_prog__rpg__races__Elf.constructors
-                       ### test_prog__rpg__races__Elf__init.definition
-                               #### test_prog__rpg__races__Elf__init.lin
-               ## test_prog__rpg__races__Elf.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__races.concern
-
-MClassPage Human
-       # Human.section
-               ## test_prog__rpg__races__Human.intro
-               ## test_prog__rpg__races__Human.inheritance
-                       ### test_prog__rpg__races__Human.graph
-                       ### list.group
-                               #### test_prog__rpg__races__Human.parents
-                               #### test_prog__rpg__races__Human.ancestors
-                               #### test_prog__rpg__races__Human.children
-                               #### test_prog__rpg__races__Human.descendants
-               ## test_prog__rpg__races__Human.constructors
-                       ### test_prog__rpg__races__Human__init.definition
-                               #### test_prog__rpg__races__Human__init.lin
-               ## test_prog__rpg__races__Human.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__races.concern
-
-MClassPage Race
-       # Race.section
-               ## test_prog__rpg__races__Race.intro
-               ## test_prog__rpg__races__Race.inheritance
-                       ### test_prog__rpg__races__Race.graph
-                       ### list.group
-                               #### test_prog__rpg__races__Race.parents
-                               #### test_prog__rpg__races__Race.ancestors
-                               #### test_prog__rpg__races__Race.children
-                               #### test_prog__rpg__races__Race.descendants
-               ## test_prog__rpg__races__Race.constructors
-                       ### test_prog__rpg__races__Race__init.definition
-                               #### test_prog__rpg__races__Race__init.lin
-               ## test_prog__rpg__races__Race.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__rpg.concern
-               ## test_prog__rpg__races.concern
-                       ### test_prog__rpg__races__Race__base_endurance.definition
-                       ### test_prog__rpg__races__Race__base_endurance_61d.definition
-                       ### test_prog__rpg__races__Race__base_intelligence.definition
-                       ### test_prog__rpg__races__Race__base_intelligence_61d.definition
-                       ### test_prog__rpg__races__Race__base_strength.definition
-                       ### test_prog__rpg__races__Race__base_strength_61d.definition
-
-MPropertyPage _base_endurance
-       # _base_endurance.section
-               ## test_prog__rpg__races__Race___base_endurance.intro
-
-MPropertyPage _base_intelligence
-       # _base_intelligence.section
-               ## test_prog__rpg__races__Race___base_intelligence.intro
-
-MPropertyPage _base_strength
-       # _base_strength.section
-               ## test_prog__rpg__races__Race___base_strength.intro
-
-MPropertyPage base_endurance
-       # base_endurance.section
-               ## test_prog__rpg__races__Race__base_endurance.intro
-
-MPropertyPage base_endurance=
-       # base_endurance=.section
-               ## test_prog__rpg__races__Race__base_endurance_61d.intro
-
-MPropertyPage base_intelligence
-       # base_intelligence.section
-               ## test_prog__rpg__races__Race__base_intelligence.intro
-
-MPropertyPage base_intelligence=
-       # base_intelligence=.section
-               ## test_prog__rpg__races__Race__base_intelligence_61d.intro
-
-MPropertyPage base_strength
-       # base_strength.section
-               ## test_prog__rpg__races__Race__base_strength.intro
-
-MPropertyPage base_strength=
-       # base_strength=.section
-               ## test_prog__rpg__races__Race__base_strength_61d.intro
-
-MModulePage rpg
-       # rpg.section
-               ## test_prog__rpg__rpg.intro
-               ## test_prog__rpg__rpg.importation
-                       ### test_prog__rpg__rpg.graph
-                       ### list.group
-                               #### test_prog__rpg__rpg.imports
-                               #### test_prog__rpg__rpg.clients
-
-MGroupPage tests
-       # tests.section
-               ## test_prog__tests.intro
-               ## test_prog__tests.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__tests.concern
-               ## test_prog__tests-.concern
-                       ### test_prog__tests-.definition
-                               #### test_prog__tests-.intros_redefs
-                                       ##### list.group
-                                               ###### test_prog__tests-.intros
-                                               ###### test_prog__tests-.redefs
-
-MModulePage test_game
-       # test_game.section
-               ## test_prog__tests-.intro
-               ## test_prog__tests-.importation
-                       ### test_prog__tests-.graph
-                       ### list.group
-                               #### test_prog__tests-.imports
-                               #### test_prog__tests-.clients
-               ## test_prog__tests-.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__tests.concern
-               ## test_prog__tests-.concern
-                       ### test_prog__tests-__GameTest.definition-list
-                               #### test_prog__tests-__GameTest.definition
-                                       ##### test_prog__tests-__GameTest.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__tests-__GameTest.intros
-                                                       ####### test_prog__tests-__GameTest.redefs
-                       ### test_prog__tests-__TestGame.definition-list
-                               #### test_prog__tests-__TestGame.definition
-                                       ##### test_prog__tests-__TestGame.intros_redefs
-                                               ###### list.group
-                                                       ####### test_prog__tests-__TestGame.intros
-                                                       ####### test_prog__tests-__TestGame.redefs
-
-MClassPage GameTest
-       # GameTest.section
-               ## test_prog__tests-__GameTest.intro
-               ## test_prog__tests-__GameTest.inheritance
-                       ### test_prog__tests-__GameTest.graph
-                       ### list.group
-                               #### test_prog__tests-__GameTest.parents
-                               #### test_prog__tests-__GameTest.ancestors
-                               #### test_prog__tests-__GameTest.children
-                               #### test_prog__tests-__GameTest.descendants
-               ## test_prog__tests-__GameTest.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__tests-__GameTest.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__tests.concern
-               ## test_prog__tests-.concern
-                       ### test_prog__tests-__GameTest__test_game.definition
-
-MPropertyPage test_game
-       # test_game.section
-               ## test_prog__tests-__GameTest__test_game.intro
-
-MClassPage TestGame
-       # TestGame.section
-               ## test_prog__tests-__TestGame.intro
-               ## test_prog__tests-__TestGame.inheritance
-                       ### test_prog__tests-__TestGame.graph
-                       ### list.group
-                               #### test_prog__tests-__TestGame.parents
-                               #### test_prog__tests-__TestGame.ancestors
-                               #### test_prog__tests-__TestGame.children
-                               #### test_prog__tests-__TestGame.descendants
-               ## test_prog__tests-__TestGame.constructors
-                       ### test_prog__platform-__Object__init.definition
-               ## test_prog__tests-__TestGame.concerns
-               ## test_prog.concern
-               ## test_prog.concern
-               ## test_prog__tests.concern
-               ## test_prog__tests-.concern
-                       ### test_prog__tests-__TestGame__player_characters.definition
-                               #### test_prog__tests-__TestGame__player_characters.lin
-                       ### test_prog__tests-__TestGame__player_characters_61d.definition
-
-MPropertyPage _player_characters
-       # _player_characters.section
-               ## test_prog__tests-__TestGame___player_characters.intro
-
-MPropertyPage player_characters=
-       # player_characters=.section
-               ## test_prog__tests-__TestGame__player_characters_61d.intro
-
-Generated 130 pages
- list:
-  MPropertyPage: 77 (59.23%)
-  MClassPage: 23 (17.69%)
-  MModulePage: 12 (9.23%)
-  ReadmePage: 8 (6.15%)
-  MGroupPage: 8 (6.15%)
-  SearchPage: 1 (0.76%)
-  OverviewPage: 1 (0.76%)
-Found 212 mentities
- list:
-  MMethodDef: 79 (37.26%)
-  MMethod: 61 (28.77%)
-  MClassDef: 26 (12.26%)
-  MClass: 23 (10.84%)
-  MModule: 11 (5.18%)
-  MGroup: 8 (3.77%)
-  MPackage: 2 (0.94%)
-  MVirtualTypeDef: 1 (0.47%)
-  MVirtualTypeProp: 1 (0.47%)
-quicksearch-list.js
+Parsing code...
+Generating documentation pages...
+Generated 111/111 pages
+ PageHome: 1
+ PageMPackage: 2
+ PageMGroup: 7
+ PageMModule: 10
+ PageMClass: 22
+ PageMProperty: 61
+ PagePerson: 6
+ PageTag: 2
index 61b00e9..7740b5f 100755 (executable)
 # limitations under the License.
 
 # Run some tests on each engine
-for x in nitcg nitcs nitcsg nitce niti nitvm; do
+
+engine=(nitcg nitcg nitcs nitcsg nitce niti nitvm)
+if uname | grep MINGW64 1>/dev/null 2>&1; then
+       engine=(nitcg nitcg nitcs nitcsg nitce)
+fi
+
+for x in "${engine[@]}"; do
        echo "--engine $x"
        ./tests.sh --engine $x "$@"
 done