")
+ .addClass("form-group has-icon")
+ .append(searchField)
+ .append(
+ $("
")
+ .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
index 0000000000..ac19c29cf0
--- /dev/null
+++ b/share/nitdoc/js/nitdoc.utils.js
@@ -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
index fa0f12ec01..0000000000
--- a/share/nitdoc/js/plugins/filtering.js
+++ /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
index c77c0d0eae..0000000000
--- a/share/nitdoc/js/plugins/github.js
+++ /dev/null
@@ -1,593 +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.Github comment edition module
- *
- * Allows user to modify source code comments directly from the Nitdoc
- */
-define([
- "jquery",
- "github-api",
- "highlight",
- "marked",
- "nit",
- "plugins/modalbox",
- "plugins/github/loginbox",
- "plugins/github/commentbox",
- "utils"
-], function($, GithubAPI, hljs, marked) {
- var GithubUser = function(login, password, repo, branch) {
- this.login = login;
- this.password = password;
- this.repo = repo;
- this.auth = "Basic " + (login + ':' + password).base64Encode();
- this.branch = branch;
- }
-
- var GithubUI = {
- init: function(upstream, basesha1) {
- console.info("Github plugin: init GitHub module (upstream: "+ upstream +", base: " + basesha1 + ")");
- this.origin = this._parseUpstream(upstream);
- this._initMarked();
- // Add github menu
- $("#topmenu>.container-fluid").append(
- $("")
- .attr({
- "id": "nitdoc-github-li",
- "type": "button",
- "class": "navbar-btn navbar-right btn-link",
- "href": "#",
- "data-container": "body",
- "data-toggle": "popover",
- "data-placement": "bottom",
- "data-content": "bottom",
- "data-html": "true",
- })
- .loginbox()
- //.loginbox("displayLogin")
- .bind("loginbox_logoff", function() {
- GithubUI.disactivate();
- })
- .bind("loginbox_login", function(event, infos) {
- GithubUI._tryLoginFromCredentials(infos);
- })
- );
- // check local session
- this._tryLoginFromLocalSession();
- },
-
- activate: function(user, origin) {
- this.openedComments = 0;
- this._saveSession(user);
- $("#nitdoc-github-li").loginbox("displayLogout", origin, user);
- this._attachCommentBoxes();
- this._reloadComments();
-
- // Prevent page unload if there is comments in editing mode
- $(window).on('beforeunload', function() {
- if(GithubUI.openedComments > 0){
- return "There is uncommited modified comments. Are you sure you want to leave this page?";
- }
- });
- },
-
- disactivate: function() {
- if(this.openedComments > 0){
- if(!confirm('There is uncommited modified comments. Are you sure you want to leave this page?')) {
- return false;
- }
- }
-
- localStorage.clear();
- $("#nitdoc-github-li").loginbox("toggle");
- $("#nitdoc-github-li").loginbox("displayLogin");
- $(window).unbind('beforeunload');
- //window.location.reload();
- },
-
- /* login */
-
- _checkLoginInfos: function(infos) {
- if(!infos.login || !infos.password || !infos.repo || !infos.branch) {
- $("")
- .text("Please enter your GitHub username, password, repository and branch.")
- .modalbox({
- title: "Sign in error",
- isError: true
- })
- .modalbox("open");
- return false;
- } else {
- return true;
- }
- },
-
- _tryLoginFromCredentials: function(infos) {
- if(this._checkLoginInfos(infos)) {
- var isok = this._tryLogin(infos.login, infos.password, infos.repo, infos.branch);
- if(isok === true) {
- this.activate(this.user, this.origin);
- } else {
- if(isok == "error:login") {
- $("")
- .text("The username, password, repo or branch you entered is incorrect.")
- .modalbox({
- title: "Github sign in error",
- isError: true
- })
- .modalbox("open");
- } else if(isok == "error:sha") {
- $("")
- .text("The provided Github repository must contain the base commit '" + this.origin.sha + "'.")
- .modalbox({
- title: "Github base commit error",
- isError: true
- })
- .modalbox("open");
- } else if(isok == "error:profile") {
- $("")
- .text("Please set your public name and email in your " +
- "GitHub profile." +
- "
Your public profile informations are used to sign-off your commits.")
- .modalbox({
- title: "Github profile error",
- isError: true
- })
- .modalbox("open");
- }
- }
- }
- },
-
- _tryLoginFromLocalSession: function() {
- if(localStorage.user) {
- var session = JSON.parse(localStorage.user);
- var isok = this._tryLogin(
- session.login,
- session.password.base64Decode(),
- session.repo,
- session.branch
- );
- if(isok === true) {
- this.activate(this.user, this.origin);
- } else {
- console.debug("Github plugin: Session found but authentification failed");
- localStorage.clear();
- }
- } else {
- console.debug("Github plugin: No session found");
- }
- },
-
- _tryLogin: function(login, password, repo, branch) {
- var tmpUser = new GithubUser(login, password, repo, branch);
- if(!GithubAPI.login(tmpUser)) {
- return "error:login";
- }
- if(!tmpUser.infos.name || !tmpUser.infos.email) {
- return "error:profile";
- }
- var commit = GithubAPI.getCommit(tmpUser, this.origin.sha);
- if(!commit || !commit.sha) {
- return "error:sha";
- }
- this.user = tmpUser;
- return true;
- },
-
- _saveSession: function(user) {
- localStorage.user = JSON.stringify({
- login: user.login,
- password: user.password.base64Encode(),
- repo: user.repo,
- branch: user.branch,
- });
- // check local storage synchro with branch
- if(localStorage.base != this.origin.sha) {
- console.log("Base changed: cleaned cache");
- localStorage.requests = "[]";
- localStorage.base = this.origin.sha;
- }
- },
-
- /* html decoration */
-
- // Attach edit button on each comment
- _attachCommentBoxes: function() {
- $("textarea.baseComment").each(function() {
- $(this).commentbox();
-
- var isNew = false;
- if(!$(this).val()) {
- isNew = true;
- $(this).nextAll(".info:first").find(".noComment").hide()
- $(this).nextAll(".info:first").before(
- $("")
- .hide()
- .addClass("comment")
- .append(
- $("").addClass("nitdoc")
- )
- )
- }
-
- $(this).nextAll(".info:first").prepend(
- $("")
- .addClass("nitdoc-github-editComment")
- .css("cursor", "pointer")
- .text((isNew ? "add" : "edit") + " comment")
- .click($.proxy(GithubUI._openCommentBox, GithubUI, null, $(this)))
- .after(" for ")
- )
-
- $(this).bind("commentbox_commit", function(event, data) {
- GithubUI._saveChanges(data);
- $(this).commentbox("close");
- GithubUI._reloadComments();
- })
- .bind("commentbox_preview", function(event, data) {
- $("")
- .append($("").text("Comment:"))
- .append(
- $("")
- .addClass("description")
- .append(
- $("")
- .addClass("comment")
- .append(
- $("")
- .addClass("nitdoc")
- .html(marked(data.value))
- )
- )
- )
- .append($("").text("Message:"))
- .append(
- $("")
- .addClass("description")
- .append(
- $("")
- .addClass("comment")
- .append(
- $("").html(marked(data.message))
- )
- )
- )
- .modalbox({
- title: "Preview comment",
- css: {"min-width": "500px"}
- })
- .modalbox("open");
- })
- .bind("commentbox_open", function(event, data) {
- GithubUI.openedComments++;
- $(this).nextAll(".comment").hide();
- })
- .bind("commentbox_close", function(event, data) {
- GithubUI.openedComments--;
- $(this).nextAll(".comment").show();
- });
- });
- },
-
- // reload comments from saved pull request
- _reloadComments: function() {
- if(!localStorage.requests){ return; }
- $("p.pullRequest").remove();
- var requests = JSON.parse(localStorage.requests);
- // Look for modified comments in page
- for(i in requests) {
- if(!requests[i]) { continue; }
- var request = requests[i];
- $("textarea[data-comment-location=\"" + request.location + "\"]").each(function () {
- if(request.isClosed) {
- var oldComment = request.oldComment.base64Decode();
- var htmlComment = marked(oldComment);
- $(this).val(oldComment);
- if(!$(this).val()) {
- $(this).nextAll("div.comment:first").hide();
- } else {
- $(this).nextAll("div.comment:first").show();
- }
- $(this).nextAll("div.comment").find("div.nitdoc").empty().html(htmlComment);
- $(this).nextAll("p.info").find("a.nitdoc-github-editComment").show();
- } else {
- var newComment = request.comment.base64Decode();
- var htmlComment = marked(newComment);
- $(this).val(newComment);
- if(!$(this).val()) {
- $(this).nextAll("div.comment:first").hide();
- } else {
- $(this).nextAll("div.comment:first").show();
- }
- $(this).nextAll("div.comment").find("div.nitdoc").empty().html(htmlComment);
- GithubUI._addPullRequestLink($(this), request);
- $(this).nextAll("p.info").find("a.nitdoc-github-editComment").hide();
- }
- });
- }
- },
-
- _addPullRequestLink: function(baseArea, request) {
- baseArea.nextAll("p.info").before(
- $("")
- .addClass("pullRequest inheritance")
- .text("comment modified in ")
- .append(
- $("")
- .attr({
- href: request.request.html_url,
- title: "Review on GitHub"
- })
- .text("pull request #" + request.request.number)
- )
- .append(" ")
- .append(
- $("")
- .data("pullrequest-number", request.request.number)
- .addClass("nitdoc-github-update")
- .text("update")
- .click($.proxy(GithubUI._doUpdateRequest, GithubUI, null, baseArea, request))
- )
- .append(" ")
- .append(
- $("")
- .data("pullrequest-number", request.request.number)
- .addClass("nitdoc-github-cancel")
- .text("cancel")
- .click($.proxy(GithubUI._doCancelRequest, GithubUI, null, baseArea, request))
- )
- );
- },
-
- /* github calls */
-
- _saveChanges: function(edit) {
- // if pull request update close existing pull request for the comment
- if(edit.requestID) {
- this._closePullRequest(edit.requestID);
- }
- edit.oldContent = this._getFileContent(edit.location.path);
- edit.newContent = this._mergeComment(edit.oldContent, edit.newComment, edit.location);
- edit.request = this._pushChanges(edit)
- if(!edit.request) {
- $("")
- .text("Unable to commit changes.
" + response)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return;
- }
- this._saveRequest(edit);
- },
-
- // save pull request in local storage
- _saveRequest: function(edit) {
- var requests = {};
- if(localStorage.requests) {requests = JSON.parse(localStorage.requests)}
- requests[edit.request.number] = {
- request: edit.request,
- location: edit.location.origin,
- comment: edit.newComment.base64Encode(),
- oldComment: edit.oldComment.base64Encode()
- };
- localStorage.requests = JSON.stringify(requests);
- },
-
- /*
- Creating a new pull request with the new comment take 5 steps:
- 1. get the base tree from latest commit
-
- 2. create a new blob with updated file content
- 3. post a new tree from base tree and blob
- 4. post the new commit with new tree
- 5. create the pull request
- */
- _pushChanges: function(edit) {
- var baseTree = GithubAPI.getTree(this.user, this.origin.sha);
- if(!baseTree.sha) {
- $("")
- .text("Unable to locate base tree.
" + baseTree.status + ": " + baseTree.statusText)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return false;
- }
- console.log("Base tree: " + baseTree.url);
- var newBlob = GithubAPI.createBlob(this.user, edit.newContent);
- if(!newBlob.sha) {
- $("")
- .text("Unable to create new blob.
" + newBlob.status + ": " + newBlob.statusText)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return false;
- }
- console.log("New blob: " + newBlob.url);
- var newTree = GithubAPI.createTree(this.user, baseTree, edit.location.path, newBlob);
- if(!newTree.sha) {
- $("")
- .text("Unable to create new tree.
" + newTree.status + ": " + newTree.statusText)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return false;
- }
- console.log("New tree: " + newTree.url);
- var newCommit = GithubAPI.createCommit(this.user, edit.message, baseTree.sha, newTree);
- if(!newCommit.sha) {
- $("")
- .text("Unable to create new commit.
" + newCommit.status + ": " + newCommit.statusText)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return false;
- }
- console.log("New commit: " + newCommit.url);
- var pullRequest = GithubAPI.createPullRequest(this.user, edit.title, "Pull request from Nitdoc", this.origin, newCommit.sha);
- if(!pullRequest.number) {
- $("")
- .text("Unable to create pull request.
" + pullRequest.status + ": " + pullRequest.statusText)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return false;
- }
- console.log("New pull request: " + pullRequest.url);
- return pullRequest;
- },
-
- // close previously opened pull request
- _closePullRequest: function(number) {
- var requests = JSON.parse(localStorage.requests);
- if(!requests[number]) {
- $("")
- .text("Unable to close pull request.
" + "Pull request " + number + "not found")
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return false;
- }
- // close pull request
- var res = GithubAPI.updatePullRequest(this.user, "Closed from Nitdoc", "", "closed", requests[number].request);
- if(!res.id) {
- $("")
- .text("Unable to close pull request.
" + res.status + ": " + res.statusText)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return false;
- }
- // update in localstorage
- requests[number].isClosed = true;
- localStorage.requests = JSON.stringify(requests);
- },
-
- /* internals */
-
- _initMarked: function() {
- var renderer = new marked.Renderer();
- renderer.code = function(code) {
- return '' + hljs.highlight('nit', code).value + '
';
- }
- renderer.codespan = function(code) {
- return '' + hljs.highlight('nit', code).value + '
';
- }
- marked.setOptions({
- renderer: renderer,
- gfm: true,
- tables: true,
- breaks: true,
- pedantic: false,
- sanitize: true,
- smartLists: true,
- smartypants: false
- });
- },
-
- _parseUpstream: function(upstream) {
- var parts = upstream.split(":");
- return {
- user: parts[0],
- repo: parts[1],
- branch: parts[2],
- sha: basesha1
- };
- },
-
- _getFileContent: function(githubUrl) {
- var origFile = GithubAPI.getFile(this.user, githubUrl);
- if(!origFile.content) {
- $("")
- .text("Unable to locate source file.
" + origFile.status + ": " + origFile.statusText)
- .modalbox({
- title: "Github commit error",
- isError: true
- })
- .modalbox("open");
- return;
- }
- var base64Content = origFile.content.substring(0, origFile.content.length - 1)
- return base64Content.base64Decode();
- },
-
- _mergeComment: function(fileContent, comment, location) {
- // replace comment in file content
- var res = new String();
- var lines = fileContent.split("\n");
- // copy lines fron 0 to lstart
- for(var i = 0; i < location.lstart - 1; i++) {
- res += lines[i] + "\n";
- }
- // set comment
- if(comment && comment != "") {
- var commentLines = comment.split("\n");
- for(var i = 0; i < commentLines.length; i++) {
- var line = commentLines[i];
- var tab = location.tabpos > 1 ? "\t" : "";
- res += tab + (line.length > 0 ? "# " : "#") + line + "\n";
- }
- }
- // copy lines fron lend to end
- for(var i = location.lend - 1; i < lines.length; i++) {
- res += lines[i];
- if(i < lines.length - 1) { res += "\n"; }
- }
- return res;
- },
-
- /* events */
-
- _openCommentBox: function(event, baseArea) {
- baseArea.commentbox("open", this.user);
- },
-
- _doCancelRequest: function(event, baseArea, request) {
- this._closePullRequest(request.request.number);
- this._reloadComments();
- },
-
- _doUpdateRequest: function(event, baseArea, request) {
- baseArea.commentbox("open", this.user, request.request.number);
- },
- }
-
- // Get github plugin data
- var upstream = $("body").attr("data-github-upstream");
- var basesha1 = $("body").attr("data-github-base-sha1");
- if(upstream && basesha1) {
- GithubUI.init(upstream, basesha1);
- }
-});
diff --git a/share/nitdoc/js/plugins/github/commentbox.js b/share/nitdoc/js/plugins/github/commentbox.js
deleted file mode 100644
index 2bb6a182fe..0000000000
--- a/share/nitdoc/js/plugins/github/commentbox.js
+++ /dev/null
@@ -1,231 +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.
-*/
-
-/*
- * CommentBox allows user to edit comments then preview, commit or cancel the changes
- */
-define([
- "jquery",
- "jQueryUI"
-], function($) {
- var Location = function(location) {
- var parts = location.split(":");
- this.origin = location;
- this.path = parts[0];
- this.lstart = parseInt(parts[1].split("--")[0].split(",")[0]);
- this.tabpos = parseInt(parts[1].split("--")[0].split(",")[1]);
- this.lend = parseInt(parts[1].split("--")[1].split(",")[0]);
- this.toString = function() {
- return this.path + ":" + this.lstart + "," + this.tabpos + "--" + this.lend + ",0";
- }
- }
-
- $.widget("nitdoc.commentbox", {
-
- options: {
- previewTxt: "preview",
- commitTxt: "Commit",
- cancelTxt: "Cancel",
- commentboxTitle: "Edit comment",
- messageTxt: "Commit message"
- },
-
- _create: function() {
- this._id = $(".nitdoc-github-commentbox").length
- this._oldComment = this.element.val();
- this._namespace = this.element.data("comment-namespace");
- this._location = new Location(this.element.data("comment-location"));
- this.commentBox = $("")
- .hide()
- .addClass("nitdoc-github-commentbox")
- .append(
- $("")
- .text(this.options.commentboxTitle)
- )
- .append(
- $("
")
- .addClass("nitdoc-github-commentbox-fields")
- .append(
- $("")
- .append(
- $("")
- .attr("id", "nitdoc-github-commentbox-comment" + this._id)
- .addClass("nitdoc-github-commentarea")
- .keyup($.proxy(this._doKeyUp, this))
- .keydown($.proxy(this._doKeyDown, this))
- )
- )
- .append(
- $("")
- .append(
- $("")
- .attr("for", "nitdoc-github-commentbox-message" + this._id)
- .text(this.options.messageTxt + ":")
- )
- )
- .append(
- $("")
- .append(
- $("")
- .attr("id", "nitdoc-github-commentbox-message" + this._id)
- .keyup($.proxy(this._doKeyUp, this))
- .keydown($.proxy(this._doKeyDown, this))
- )
- )
- .append(
- $("")
- .append(
- $("")
- .attr({
- id: "nitdoc-github-commentbox-signedoff" + this._id,
- type: "checkbox"
- })
- .change($.proxy(this._doSignedChange, this))
- )
- .append(
- $("")
- .attr({
- "id": "nitdoc-github-commentbox-signedoff-label" + this._id,
- "for": "nitdoc-github-commentbox-signedoff" + this._id
- })
- )
- )
- )
- this._buildButtonBar();
- this.element.after(this.commentBox);
- },
-
- _buildButtonBar: function() {
- this.commentBox.append(
- $("")
- .addClass("nitdoc-github-commentbox-buttons")
- .append(
- $("")
- .addClass("nitdoc-github-preview")
- .html(this.options.previewTxt)
- .click($.proxy(this._doPreviewClick, this))
- )
- .append(
- $("")
- .addClass("nitdoc-github-button")
- .addClass("nitdoc-github-commit")
- .attr("disabled", "disabled")
- .html(this.options.commitTxt)
- .click($.proxy(this._doCommitClick, this))
- )
- .append(
- $("")
- .addClass("nitdoc-github-button")
- .addClass("nitdoc-github-cancel")
- .html(this.options.cancelTxt)
- .click($.proxy(this._doCancelClick, this))
- )
- );
- },
-
- /* public actions */
-
- open: function(user, requestID) {
- this._requestID = requestID;
- var value = this.element.val();
- var isNew = !value;
- var message = "doc: " + (isNew ? "added" : "modified") + " comment for " + this._namespace;
- this._setMessage(message);
- this._setSignedOff("Signed-off-by: " + user.signedOff);
- this._setComment(value);
- this.commentBox.show();
- this.commentBox.find("textarea").width(this.commentBox.innerWidth() - 45)
- $("#nitdoc-github-commentbox-comment" + this._id).focus();
- $("#nitdoc-github-commentbox-comment" + this._id).trigger("keyup");
- $("#nitdoc-github-commentbox-message" + this._id).trigger("keyup");
- this._trigger("_open", null, {commentBox: this});
- },
-
- close: function() {
- this.commentBox.hide();
- this._trigger("_close", null, {commentBox: this});
- },
-
- /* internals */
-
- _setComment: function(value) {
- $("#nitdoc-github-commentbox-comment" + this._id).val(value);
- },
-
- _getComment: function() {
- return $("#nitdoc-github-commentbox-comment" + this._id).val();
- },
-
- _getMessage: function() {
- return $("#nitdoc-github-commentbox-message" + this._id).val();
- },
-
- _setMessage: function(message) {
- $("#nitdoc-github-commentbox-message" + this._id).val(message);
- },
-
- _getSignedOff: function() {
- return $("#nitdoc-github-commentbox-signedoff" + this._id).val();
- },
-
- _setSignedOff: function(signedoff) {
- $("#nitdoc-github-commentbox-signedoff" + this._id).val(signedoff);
- $("#nitdoc-github-commentbox-signedoff-label" + this._id).text(signedoff);
- },
-
- /* events */
-
- _doKeyUp: function(event) {
- $(event.target).height($(event.target).val().split(/\r|\n/).length * 16);
- },
-
- _doKeyDown: function(event) {
- if(event.keyCode == 13){
- $(event.target).css("height", ($(event.target).outerHeight() + 6) + "px");
- }
- },
-
- _doSignedChange: function(event) {
- if ($(event.currentTarget).is(':checked')) {
- this.commentBox.find("button.nitdoc-github-commit").removeAttr("disabled");
- } else {
- this.commentBox.find("button.nitdoc-github-commit").attr("disabled", "disabled");
- }
- },
-
- _doPreviewClick: function(event) {
- this._trigger("_preview", event, {
- value: this._getComment(),
- message: this._getMessage() + "\n\n" + this._getSignedOff()
- });
- },
-
- _doCommitClick: function() {
- this._trigger("_commit", event, {
- requestID: this._requestID,
- location: this._location,
- namespace: this._namespace,
- oldComment: this._oldComment,
- newComment: this._getComment(),
- title: this._getMessage(),
- message: this._getMessage() + "\n\n" + this._getSignedOff()
- });
- },
-
- _doCancelClick: function() {
- this.close();
- }
- });
-});
diff --git a/share/nitdoc/js/plugins/github/loginbox.js b/share/nitdoc/js/plugins/github/loginbox.js
deleted file mode 100644
index 55fbffe472..0000000000
--- a/share/nitdoc/js/plugins/github/loginbox.js
+++ /dev/null
@@ -1,255 +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.
-*/
-
-/*
- * LoginBox allows user to login and logoff from GitHub API
- */
-define([
- "jquery",
- "jQueryUI"
-], function($) {
- $.widget("nitdoc.loginbox", {
- options: {
- icon: "resources/icons/github-icon.png",
- iconActive: "resources/icons/github-icon-green.png",
- iconAlt: "GitHub",
- signedinTxt: "Signed in Github",
- signedoutTxt: "Sign in Github",
- welcomeTxt: "Hello",
- upstreamTxt: "Upstream branch",
- baseTxt: "Base",
- signoffTxt: "Sign Off",
- usernameTxt: "Username",
- passwordTxt: "Password",
- repoTxt: "Repository",
- branchTxt: "Branch",
- signinTxt: "Sign In"
- },
-
- _create: function() {
- this.element.append(
- $("")
- .addClass("glyphicon glyphicon-off")
- //.click($.proxy(this.toggle, this))
- .attr({
- "data-container": "body",
- "data-toggle": "popover",
- "data-placement": "bottom",
- "data-content": "bottom",
- "data-html": "true",
- })
- );
-
- this.content = $("");
- this.loginBox = $("")
- .attr("id", "nitdoc-github-loginbox")
- .css("display", "none")
- .append(
- $(document.createElement("div"))
- .addClass("nitdoc-github-loginbox-arrow")
- .append(" ")
- )
- .append(this.content);
- this.element.append(this.loginBox);
- },
-
- /* public actions */
-
- displayLogout: function(origin, user) {
- this.content.empty();
- this.content.append(
- $("").text(this.options.signedinTxt)
- )
- this.content.append(
- $("")
- .append(
- $("")
- .append(this.options.welcomeTxt + " ")
- .append(
- $("")
- .attr("href", "https://github.com/" + user.login)
- .append(user.login)
- ).append(",")
- )
- .append(
- $("")
- .text("Upstream Branch")
- )
- .append(
- $("")
- .text(origin.user + ":" + origin.repo + ":" + origin.branch)
- .addClass("nitdoc-github-loginbox-githublink")
- .attr({
- title: "Open branch in GitHub",
- href: "https://github.com/" + origin.user + "/" + origin.repo + "/tree/" + origin.branch
- })
- )
- .append(
- $("")
- .attr("for", "github-base")
- .append("Your branch")
- )
- .append(
- $("")
- .text(user.login + ":" + user.repo + ":" + user.branch)
- .addClass("nitdoc-github-loginbox-githublink")
- .attr({
- title: "Open branch in GitHub",
- href: "https://github.com/" + user.login + "/" + user.repo + "/tree/" + user.branch
- })
- )
- .append(
- $("")
- .addClass("nitdoc-github-button")
- .addClass("nitdoc-github-cancel")
- .append(
- $("")
- .attr("src", this.options.icon)
- ).text(this.options.signoffTxt)
- .click($.proxy(this._doClickLogoff, this))
- )
- );
- $(".nitdoc-github-li-img").attr("src", this.options.iconActive);
- },
-
- displayLogin: function() {
- this.content.empty();
- this.content.append(
- $("").text(this.options.signedoutTxt)
- )
- this.content.append(
- $("")
- .keyup($.proxy(this._doFormChange, this))
- .append(
- $("")
- .addClass("form-group")
- .append(
- $("")
- .attr("for", "nitdoc-github-login-field")
- .append(this.options.usernameTxt)
- )
- .addClass("form-group")
- .append(
- $("")
- .attr({
- id: "nitdoc-github-login-field",
- type: "text",
- "class": "form-control"
- })
- )
- )
- .append(
- $("")
- .addClass("form-group")
- .append(
- $("")
- .attr("for", "nitdoc-github-password-field")
- .append(this.options.passwordTxt)
- )
- .append(
- $("")
- .attr({
- id: "nitdoc-github-password-field",
- type: "password",
- "class": "form-control"
- })
- )
- )
- .append(
- $("")
- .addClass("form-group")
- .append(
- $("")
- .attr("for", "nitdoc-github-repo-field")
- .append(this.options.repoTxt)
- )
- .append(
- $("")
- .attr({
- id: "nitdoc-github-repo-field",
- type: "text",
- "class": "form-control"
- })
- )
- )
- .append(
- $("")
- .addClass("form-group")
- .append(
- $("")
- .attr("for", "nitdoc-github-branch-field")
- .append(this.options.branchTxt)
- )
- .append(
- $("")
- .attr({
- id: "nitdoc-github-branch-field",
- type: "text",
- "class": "form-control"
- })
- )
- )
- .append(
- $("")
- .addClass("nitdoc-github-button btn btn-primary btn-lg pull-right")
- .attr("disabled", "disabled")
- .append(
- $("")
- .attr("src", this.options.icon)
- ).text(this.options.signinTxt)
- .click($.proxy(this._doClickLogin, this))
- )
- );
- $(".nitdoc-github-li-img").attr("src", this.options.icon);
- },
-
- toggle: function() {
- if(this.loginBox.is(':hidden')) {
- this.loginBox.show();
- if ($('#nitdoc-github-login-field').is(':visible')) { $('#nitdoc-github-login-field').focus(); }
- } else {
- this.loginBox.hide();
- }
- },
-
- /* events */
-
- _doClickLogoff: function(event) {
- this._trigger("_logoff", event);
- },
-
- _doClickLogin: function(event) {
- this._trigger("_login", event, {
- login: $('#nitdoc-github-login-field').val(),
- password: $('#nitdoc-github-password-field').val(),
- repo: $('#nitdoc-github-repo-field').val(),
- branch: $('#nitdoc-github-branch-field').val()
- });
- return false;
- },
-
- _doFormChange: function(event) {
- login = $('#nitdoc-github-login-field').val();
- password = $('#nitdoc-github-password-field').val();
- repo = $('#nitdoc-github-repo-field').val();
- branch = $('#nitdoc-github-branch-field').val();
- if(login && password && repo && branch) {
- this.loginBox.find("form .nitdoc-github-button").removeAttr("disabled");
- } else {
- this.loginBox.find("form .nitdoc-github-button").attr("disabled", "disabled");
- }
- }
- });
-});
diff --git a/share/nitdoc/js/plugins/modalbox.js b/share/nitdoc/js/plugins/modalbox.js
deleted file mode 100644
index 71bbbade09..0000000000
--- a/share/nitdoc/js/plugins/modalbox.js
+++ /dev/null
@@ -1,104 +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.
-*/
-
-define([
- "jquery",
- "jQueryUI"
-], function($) {
- $.widget("nitdoc.modalbox", {
- options: {
- id: "nitdoc-dialog",
- classes: "nitdoc-dialog",
- css: {},
- title: "Title",
- isError: false,
- },
-
- _create: function() {
- this._addFade();
- this._makeDialog();
- },
-
- open: function() {
- this._dialog
- .show()
- .css({
- top: "50%",
- marginTop: -(this._dialog.outerHeight() / 2) + "px",
- left: "50%",
- marginLeft: -(this._dialog.outerWidth() / 2) + "px"
- })
- .find(".nitdoc-dialog-buttons button:first").focus();
-
- this._fade.show();
- },
-
- close: function() {
- this._fade.hide();
- this._dialog.hide();
- },
-
- _addFade: function() {
- this._fade = $("")
- .hide()
- .attr("id", "nitdoc-dialog-fade-" + this.options.id)
- .addClass("nitdoc-dialog-fade");
- $("body").append(this._fade);
- },
-
- _makeDialog: function() {
- this._dialog = $("")
- .hide()
- .attr("id", this.options.id)
- .addClass(this.options.classes)
- .css(this.options.css)
- .append(
- $("")
- .addClass("nitdoc-dialog-header")
- .append(
- $("")
- .text(this.options.title)
- )
- .append(
- $("")
- .addClass("nitdoc-dialog-close")
- .append("x")
- .click($.proxy(this.close, this))
- )
- )
- .append(
- $("")
- .addClass("nitdoc-dialog-content")
- .html(this.element)
- )
- .append(
- $("")
- .addClass("nitdoc-dialog-buttons")
- .append(
- $("")
- .append("Ok")
- .click($.proxy(this.close, this))
- )
- );
- if(this.options.isError) {
- this._dialog.addClass("nitdoc-dialog-error");
- }
- $("body").append(this._dialog);
- }
- });
-});
diff --git a/share/nitdoc/js/plugins/quicksearch.js b/share/nitdoc/js/plugins/quicksearch.js
deleted file mode 100644
index f8cd5202af..0000000000
--- a/share/nitdoc/js/plugins/quicksearch.js
+++ /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: "▲",
- overflowDownHtml: "▼",
- 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 = $("")
- .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 = $("
")
- .addClass(this.options.rowClass)
- .data("searchDetails", {name: name, url: url})
- .data("index", this._rows.length)
- .append(
- $(" | ")
- .html(name)
- .addClass(cls)
- )
- .append(
- $("
| ")
- .html(txt + " »")
- .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(
- $("
|
")
- .addClass(this.options.rowOverflowClass)
- .append(
- $("
| ")
- .attr("colspan", 2)
- .html(this.options.overflowUpHtml)
- )
- .click($.proxy(this._clickPrev, this))
- );
- },
-
- addOverflowDown: function() {
- this._table.append(
- $("
|
")
- .addClass(this.options.rowOverflowClass)
- .addClass(this.options.rowOverflowActive)
- .append(
- $("
| ")
- .attr("colspan", 2)
- .html(this.options.overflowDownHtml)
- )
- .click($.proxy(this._clickNext, this))
- );
- },
-
- addNoResultRow: function() {
- this._table.prepend(
- $("
|
")
- .addClass(this.options.rowNoResultClass)
- .append(
- $("
| ")
- .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 = $("
")
-.addClass("form-control input-sm")
-.attr({
- id: "nitdoc-qs-field",
- type: "text",
- placeholder: "Search..."
-})
-
-$("#topmenu-collapse").append(
- $("
")
- .addClass("navbar-form navbar-right")
- .append(
- $("
")
- .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
index d291056e87..0000000000
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
index 98ae072c55..0000000000
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
index 8b25551a97..0000000000
Binary files a/share/nitdoc/resources/icons/github-icon.png and /dev/null differ
diff --git a/src/catalog/catalog.nit b/src/catalog/catalog.nit
index dd891ace11..6a12238d53 100644
--- a/src/catalog/catalog.nit
+++ b/src/catalog/catalog.nit
@@ -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
diff --git a/src/doc/api/api_base.nit b/src/doc/api/api_base.nit
index 9b84a35159..4c3db90912 100644
--- a/src/doc/api/api_base.nit
+++ b/src/doc/api/api_base.nit
@@ -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
diff --git a/src/doc/commands/commands_model.nit b/src/doc/commands/commands_model.nit
index ffb530dbfb..abf5d7d04f 100644
--- a/src/doc/commands/commands_model.nit
+++ b/src/doc/commands/commands_model.nit
@@ -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
index 98362ce6de..0000000000
--- a/src/doc/doc_base.nit
+++ /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 = "
"
- redef var title = ""
-
- # 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
index 208738b8f4..0000000000
--- a/src/doc/doc_commands.nit
+++ /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: `.
-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
diff --git a/src/doc/doc_down.nit b/src/doc/doc_down.nit
index 7bb330b519..f02b1fdf3c 100644
--- a/src/doc/doc_down.nit
+++ b/src/doc/doc_down.nit
@@ -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
index a61233f206..0000000000
--- a/src/doc/doc_phases/doc_concerns.nit
+++ /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
index c559e80d63..0000000000
--- a/src/doc/doc_phases/doc_graphs.nit
+++ /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
index fa9de2db10..0000000000
--- a/src/doc/doc_phases/doc_hierarchies.nit
+++ /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
index 3f1a3e72ed..0000000000
--- a/src/doc/doc_phases/doc_html.nit
+++ /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 "View Source"
- end
- # THIS IS JUST UGLY ! (but there is no replace yet)
- var x = source.split_with("%f")
- source = x.join(location.file.filename.simplify_path)
- 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 "View Source"
- 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 = """Go to API"""
- 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 = """Go to README"""
- 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
index 87190114f6..0000000000
--- a/src/doc/doc_phases/doc_indexing.nit
+++ /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
index 829a9ef827..0000000000
--- a/src/doc/doc_phases/doc_intros_redefs.nit
+++ /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
index 7864b279dc..0000000000
--- a/src/doc/doc_phases/doc_lin.nit
+++ /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
index ec06f6af13..0000000000
--- a/src/doc/doc_phases/doc_pages.nit
+++ /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
index 24969e4ce1..0000000000
--- a/src/doc/doc_phases/doc_phases.nit
+++ /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
index 9f665b9c8c..0000000000
--- a/src/doc/doc_phases/doc_poset.nit
+++ /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
index 1dbd50e26d..0000000000
--- a/src/doc/doc_phases/doc_readme.nit
+++ /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
index b328fb9c2f..0000000000
--- a/src/doc/doc_phases/doc_structure.nit
+++ /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
index 46ea9d1d05..0000000000
--- a/src/doc/doc_phases/doc_test.nit
+++ /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
index fa3bd693ce..0000000000
--- a/src/doc/html_templates/html_components.nit
+++ /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 ""
- if drop_list.items.length > 1 then add drop_list
- add "
"
- for panel in panels do
- add panel
- end
- add "
"
- add "
"
- 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 """"
- 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 ""
- add html_content
- add "
"
- 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 ""
- add " "
- add text
- add " "
- add ""
- end
-end
-
-# A HTML tag attribute
-# ``
-#
-# ~~~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<>\""
-# ~~~
-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 ""
- 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 ""
- 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
index 820a9a3811..0000000000
--- a/src/doc/html_templates/html_model.nit
+++ /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: `html_short_name
- 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: `html_short_name
- 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
index 9f8390e6ae..0000000000
--- a/src/doc/html_templates/html_templates.nit
+++ /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 ``.
- private fun render_head do
- var css = (self.shareurl / "css").html_escape
- var vendors = (self.shareurl / "vendors").html_escape
-
- addn ""
- addn ""
- addn " "
- addn " "
- addn " "
- addn " "
- addn " "
- addn " "
- addn " "
- addn " "
- addn " {title.html_escape}"
- addn ""
- add ""
- end
-
- # Renders the footer and content.
- private fun render_content do
- add root
- if footer != null then
- addn ""
- 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 ""
- addn ""
- addn ""
- addn ""
- addn ""
- addn ""
- addn ""
- for script in scripts do add script
- addn """"""
- addn ""
- addn ""
- end
-
- # Render the whole page
- redef fun rendering do
- render_head
- addn ""
- addn "
"
- add topmenu
- addn "
"
- addn "
"
- var sidebar = self.sidebar
- if sidebar != null then
- addn "
"
- add sidebar
- addn "
"
- addn "
"
- render_content
- addn "
"
- else
- addn "
"
- render_content
- addn "
"
- end
- addn "
"
- addn "
"
- 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 ""
- 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 ""
- 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 ""
- addn "
"
- addn "
"
- add content
- addn "
"
- addn "
"
- 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 ""
- addn html_subtitle.write_to_string
- addn "
"
- 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 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 ""
- return
- end
- addn ""
- render_title
- render_body
- addn ""
- 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 ""
- render_title
- render_body
- addn ""
- 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 ""
- addn "
"
- render_list("Modules", mmodules)
- render_list("Classes", mclasses)
- render_list("Properties", mprops)
- addn "
"
- addn "
"
- 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 ""
- 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 "
"
- 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 ""
- var svg = self.svg
- if svg != null then add svg
- addn "
"
- 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} – {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
index 8e89dd4758..0000000000
--- a/src/doc/html_templates/model_html.nit
+++ /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 ""
- tpl.add html_modifiers.join(" ")
- tpl.add " "
- tpl.add html_link
- tpl.add ""
- 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 ""
- tpl.add html_link
- tpl.add ""
- 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 ""
- 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 ""
- return tpl
- end
-
- # Returns `mmodule::self`
- redef fun html_namespace do
- var tpl = new Template
- tpl.add mmodule.html_namespace
- tpl.add "::"
- tpl.add mclass.html_link
- tpl.add ""
- 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 "::"
- tpl.add intro.html_link
- tpl.add ""
- 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 ""
- 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 ""
- 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 ""
- tpl.add html_modifiers.join(" ")
- tpl.add " "
- tpl.add html_link
- tpl.add html_signature
- tpl.add ""
- 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
diff --git a/src/doc/doc.nit b/src/doc/static/static.nit
similarity index 85%
rename from src/doc/doc.nit
rename to src/doc/static/static.nit
index a6fb971dcf..c1a51f5917 100644
--- a/src/doc/doc.nit
+++ b/src/doc/static/static.nit
@@ -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
index 0000000000..a7ae6bbe49
--- /dev/null
+++ b/src/doc/static/static_base.nit
@@ -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
index 0000000000..e589ca6ef8
--- /dev/null
+++ b/src/doc/static/static_cards.nit
@@ -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 ""
+ for card in cards do
+ addn card
+ end
+ addn "
"
+ 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 ""
+ addn content
+ addn "
"
+ addn "
"
+ 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 "{title}"
+ end
+end
+
+# A page header
+class CardPageHeader
+ super CardSection
+ autoinit(title, subtitle)
+
+ redef var level = 2
+
+ redef fun rendering do
+ addn ""
+ 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 "Summary
"
+ end
+ addn ""
+ addn "
"
+ 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 "- {card.title}
"
+ end
+ addn "
"
+ addn "
"
+ 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 "Summary
"
+ addn ""
+ addn "
"
+ for id, headline in headlines do
+ var level = headline.level
+ var title = md_processor.process(headline.title)
+ addn "- {title}
"
+ end
+ addn "
"
+ addn "
"
+ 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 """
+
+
+ {{{mentity.html_icon.write_to_string}}}
+
+
+
+ {{{mentity.html_declaration.write_to_string}}}
+
+
{{{mentity.html_namespace.write_to_string}}}
"""
+ 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 """
+
+
"""
+ 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 ""
+ addn "
"
+ addn mdoc.html_documentation
+ addn "
"
+ addn "
"
+ 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 ""
+ addn "
"
+ 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 "
"
+ addn "
"
+ end
+
+ private fun render_list(title: String, mentities: nullable Array[MEntity]) do
+ if mentities == null or mentities.is_empty then return
+ addn "{title}
"
+ addn ""
+ for mentity in mentities do
+ addn mentity.html_list_item
+ end
+ addn "
"
+ 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 ""
+ for card in cards do
+ addn card
+ if card == cards.last then break
+ addn "
"
+ addn " "
+ addn "
"
+ end
+ addn ""
+ 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 """
+
+
+
+ {{{mentity.html_icon.write_to_string}}}
+ {{{mentity.html_namespace.write_to_string}}}"""
+ if node != null then
+ addn """
+
+
+
"""
+ else if url != null then
+ addn """
+ """
+ var mdoc = mentity.mdoc
+ if mdoc != null then
+ addn "
"
+ addn mdoc.html_documentation
+ end
+ end
+ addn ""
+ if node != null then
+ addn """
+
+
"""
+ render_code
+ addn """
+
{{{mentity.location.to_s}}}
+
"""
+ end
+ addn """
+
+
"""
+ 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 ""
+ addn "
"
+
+ if node != null then
+ addn "
"
+ render_code
+ addn "
"
+ end
+ addn "
{mentity.location}"
+
+ addn "
"
+ addn "
"
+ 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 ""
+ addn "
"
+ addn "
"
+ addn graph.graph.to_svg
+ addn "
"
+ addn "
"
+ addn "
"
+ 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 ""
+ for key, value in catalog.catalog_stats.to_map do
+ addn ""
+ addn " {value} {key} "
+ addn ""
+ end
+ addn "
"
+ addn "
"
+ 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 "Tags
"
+ addn ""
+ for tag in tags do
+ addn "
"
+ addn "
{catalog.tag2proj[tag].length}"
+ addn "
{tag}"
+ addn "
"
+ end
+ addn "
"
+ addn "
"
+ 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 """
+
+
{{{mpackage.html_icon.write_to_string}}}
+
+
+ {{{mentity.html_declaration.write_to_string}}}
+ """
+ for tag in mpackage.metadata.tags do
+ add ""
+ add "{tag}"
+ if tag != mpackage.metadata.tags.last then addn ", "
+ add ""
+ end
+ addn """
+
"""
+ 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 "
"
+ addn "
"
+ for maintainer in mpackage.metadata.maintainers do
+ addn maintainer.to_html
+ end
+ addn "
"
+ var license = mpackage.metadata.license
+ if license != null then
+ addn """
+
+
+ {{{license}}}
+
+ """
+ end
+ addn "
"
+ addn "
"
+ 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 """
+
+ {{{maintainer.to_html}}}
+
"""
+ end
+ var license = metadata.license
+ if license != null then
+ addn """
+
+ {{{license}}}
+ license
+ """
+ end
+
+ var homepage = metadata.homepage
+ var browse = metadata.browse
+ var issues = metadata.issues
+ if homepage != null or browse != null or issues != null then
+ addn """
+ Links
+ """
+ if homepage != null then addn "- Homepage
"
+ if browse != null then addn "- Source Code
"
+ if issues != null then addn "- Issues
"
+ addn "
"
+ end
+
+ var git = metadata.git
+ var last_date = metadata.last_date
+ var first_date = metadata.first_date
+ if git != null then
+ addn """
+ Git
+
+ {{{stats.commits}}} commits
+
"""
+ if last_date != null then
+ addn """Last: {{{last_date}}}
"""
+ end
+ if first_date != null then
+ addn """First: {{{first_date}}}"""
+ end
+ end
+
+ addn """
+ Quality
+
+ - {{{stats.documentation_score}}}% documented
+
"""
+
+ if metadata.tags.not_empty then
+ addn "Tags
"
+ for tag in metadata.tags do
+ addn " {tag}"
+ if tag != metadata.tags.last then add ", "
+ end
+ end
+
+ if deps.not_empty then
+ addn "Dependencies
"
+ for dep in deps do
+ add dep.html_link
+ if dep != deps.last then add ", "
+ end
+ end
+
+ if clients.not_empty then
+ addn "Clients
"
+ for client in clients do
+ add client.html_link
+ if client != clients.last then add ", "
+ end
+ end
+
+ if metadata.contributors.not_empty then
+ addn """
+ Contributors
+ """
+ for contrib in metadata.contributors do
+ addn """- {{{contrib.to_html}}}
"""
+ end
+ addn "
"
+ end
+
+ addn """
+ Stats
+
+ - {{{stats.mmodules}}} modules
+ - {{{stats.mclasses}}} classes
+ - {{{stats.mmethods}}} methods
+ - {{{stats.loc}}} loc
+
"""
+ end
+end
diff --git a/src/doc/static/static_html.nit b/src/doc/static/static_html.nit
new file mode 100644
index 0000000000..eb2834f401
--- /dev/null
+++ b/src/doc/static/static_html.nit
@@ -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 ``
+ private fun render_head do
+ var css = (self.shareurl / "css").html_escape
+ var vendors = (self.shareurl / "vendors").html_escape
+
+ addn ""
+ addn ""
+ addn " "
+ addn " "
+ addn " "
+ addn " "
+ addn " "
+ addn " "
+ addn " "
+ addn " {title.html_escape}"
+ addn ""
+ add ""
+ 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 ""
+ for tab in tabs do
+ if tab.is_empty and not tab isa DocTabLink then continue
+ addn tab.tab_link
+ end
+ addn "
"
+ addn ""
+ for tab in tabs do
+ if tab.is_empty then continue
+ addn tab
+ end
+ addn "
"
+ 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 ""
+ end
+ var vendors = (self.shareurl / "vendors").html_escape
+ var js = (self.shareurl / "js").html_escape
+
+ addn ""
+ addn ""
+ addn ""
+ addn ""
+ addn ""
+ addn ""
+
+ var piwik_script = self.piwik_script
+ if piwik_script != null then
+ add piwik_script
+ end
+ addn ""
+ addn ""
+ end
+
+ # Render the whole page
+ redef fun rendering do
+ render_head
+ add topmenu
+ addn ""
+ render_content
+ addn "
"
+ 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 ""
+ if tabs.not_empty then
+ addn tabs.first
+ end
+ addn "
"
+ 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 ""
+ tpl.addn " "
+
+ var icon = self.icon
+ if icon != null then
+ tpl.addn " "
+ end
+ tpl.addn " {title}"
+ tpl.addn " "
+ tpl.addn ""
+ 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 ""
+ if has_left then
+ addn "
"
+ addn sidebar
+ addn "
"
+ end
+ var cols = 12
+ if has_left then cols -= 3
+ if has_right then cols -= 3
+ addn "
"
+ for card in content do addn card
+ addn "
"
+ if has_right then
+ addn "
"
+ addn metadata
+ addn "
"
+ end
+ addn "
"
+ end
+end
+
+redef class DocTabLink
+
+ redef fun tab_link do
+ var tpl = new Template
+ tpl.addn ""
+ tpl.addn " "
+
+ var icon = self.icon
+ if icon != null then
+ tpl.addn " "
+ end
+ tpl.addn " {title}"
+ tpl.addn " "
+ tpl.addn ""
+ 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 ""
+ end
+end
+
+redef class DocSidebar
+ super Template
+
+ redef fun rendering do
+ if cards.is_empty then return
+ addn ""
+ 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 ""
+ 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
index 0000000000..699a48032c
--- /dev/null
+++ b/src/doc/static/static_index.nit
@@ -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
index 0000000000..8afe591f41
--- /dev/null
+++ b/src/doc/static/static_structure.nit
@@ -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
diff --git a/src/doc/templates/templates_html.nit b/src/doc/templates/templates_html.nit
index f74ac8464e..4faf0a6570 100644
--- a/src/doc/templates/templates_html.nit
+++ b/src/doc/templates/templates_html.nit
@@ -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 ""
+ var gravatar = self.gravatar
+ if gravatar != null then
+ tpl.addn ""
+ end
+ tpl.addn html_link
+ tpl.addn ""
+ 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
index 82f5e7c1f6..0000000000
--- a/src/doc/test_doc_commands.nit
+++ /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/nitdoc.nit b/src/nitdoc.nit
index 94132ffb9c..65227b3811 100644
--- a/src/nitdoc.nit
+++ b/src/nitdoc.nit
@@ -12,63 +12,242 @@
# 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)
diff --git a/tests/nitdoc.args b/tests/nitdoc.args
index c643d3df81..e18f76fff0 100644
--- a/tests/nitdoc.args
+++ b/tests/nitdoc.args
@@ -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
diff --git a/tests/niti.skip b/tests/niti.skip
index 7a451c4067..0d24e60d3b 100644
--- a/tests/niti.skip
+++ b/tests/niti.skip
@@ -44,3 +44,4 @@ test_rubix_visual
test_csv
repeating_key_xor_solve
nitpm
+nitdoc
diff --git a/tests/nitvm.skip b/tests/nitvm.skip
index d346e2c4bf..697b17ebf2 100644
--- a/tests/nitvm.skip
+++ b/tests/nitvm.skip
@@ -47,3 +47,4 @@ test_explain_assert
base_notnull_lit_alt2
assertions
nitpm
+nitdoc
diff --git a/tests/sav/nitdoc_args1.res b/tests/sav/nitdoc_args1.res
index 3d90f09482..a7326d61c2 100644
--- a/tests/sav/nitdoc_args1.res
+++ b/tests/sav/nitdoc_args1.res
@@ -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/
diff --git a/tests/sav/nitdoc_args2.res b/tests/sav/nitdoc_args2.res
index 047c766628..268190ca73 100644
--- a/tests/sav/nitdoc_args2.res
+++ b/tests/sav/nitdoc_args2.res
@@ -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/
diff --git a/tests/sav/nitdoc_args3.res b/tests/sav/nitdoc_args3.res
index 047c766628..105d27ca74 100644
--- a/tests/sav/nitdoc_args3.res
+++ b/tests/sav/nitdoc_args3.res
@@ -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/
diff --git a/tests/sav/nitdoc_args4.res b/tests/sav/nitdoc_args4.res
index 8fee501249..3be4a55d94 100644
--- a/tests/sav/nitdoc_args4.res
+++ b/tests/sav/nitdoc_args4.res
@@ -1,1352 +1,11 @@
-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 /
- # /.section
- ## test_prog__platform-__Float___47d.intro
-
-MPropertyPage >
- # >.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 /
- # /.section
- ## test_prog__platform-__Int___47d.intro
-
-MPropertyPage >
- # >.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