+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc Github Login Box\r
- */\r
-\r
-#nitdoc-github-li.current {\r
- color: #999;\r
-}\r
-\r
-#nitdoc-github-li .glyphicon {\r
- cursor: pointer;\r
-}\r
-\r
-#nitdoc-github-loginbox {\r
- cursor: default;\r
- position: absolute;\r
- width : 220px;\r
- margin-top: 2px;\r
- margin-left: -10px;\r
- display: block;\r
- padding: 10px;\r
- text-align: left;\r
- white-space: normal;\r
- background-color: #ffffff;\r
- border: 1px solid #ccc;\r
- border: 1px solid rgba(0, 0, 0, 0.2);\r
- -webkit-border-radius: 2px;\r
- -moz-border-radius: 2px;\r
- border-radius: 2px;\r
- -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
- -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
- -webkit-background-clip: padding-box;\r
- -moz-background-clip: padding;\r
- background-clip: padding-box;\r
-}\r
-\r
-#nitdoc-github-loginbox .nitdoc-github-loginbox-arrow {\r
- position: absolute;\r
- display: block;\r
- width: 0;\r
- height: 0;\r
- border-color: transparent;\r
- border-style: solid;\r
- border-width: 7px;\r
- top: -7px;\r
- margin-left: 2px;\r
- border-bottom-color: #999;\r
- border-bottom-color: rgba(0, 0, 0, 0.25);\r
- border-top-width: 0;\r
-}\r
-\r
-#nitdoc-github-loginbox .nitdoc-github-loginbox-arrow:after {\r
- position: absolute;\r
- display: block;\r
- width: 0;\r
- height: 0;\r
- border-color: transparent;\r
- border-style: solid;\r
- border-width: 10px;\r
- content: "";\r
- top: 1px;\r
- margin-left: -10px;\r
- border-bottom-color: #ffffff;\r
- border-top-width: 0;\r
-}\r
-\r
-#nitdoc-github-loginbox h3 {\r
- text-align:center;\r
-}\r
-\r
-#nitdoc-github-loginbox h4 {\r
- display: block;\r
- width: 100%;\r
- color: #6C6C6C;\r
- font-style: normal;\r
- text-align: center;\r
- margin-bottom: 20px;\r
-}\r
-\r
-\r
-#nitdoc-github-loginbox a.nitdoc-github-loginbox-githublink {\r
- display: block;\r
- margin: 10px;\r
- color: #0D8921;\r
-}\r
-\r
-/* Comment editing */\r
-\r
-.nitdoc-github-commentbox {\r
- margin: 1em 5px;\r
- border: 1px solid #eee;\r
- padding: 1em;\r
- background: #fff;\r
- -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\r
- -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\r
- box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);\r
-}\r
-\r
-.nitdoc-github-commentbox h3 {\r
- margin: 0;\r
-}\r
-\r
-.nitdoc-github-commentbox-buttons {\r
- text-align: right;\r
-}\r
-\r
-.nitdoc-github-commentbox dl {\r
- margin-bottom: 0;\r
-}\r
-\r
-.nitdoc-github-commentbox dt {\r
- margin-bottom: 0.5em;\r
-}\r
-\r
-.nitdoc-github-commentbox dd {\r
- margin: 0 0 1em 0;\r
-}\r
-\r
-.nitdoc-github-commentbox textarea {\r
- display: block;\r
- font-family: monospace;\r
- font-size: 1em;\r
- width: 100%;\r
- padding: 4px;\r
- padding-left: 11px;\r
- overflow-y: hidden;\r
- border: 1px solid #CCC;\r
-}\r
-\r
-.nitdoc-github-preview {\r
- margin: 0 15px;\r
- cursor: pointer;\r
-}\r
-\r
-.nitdoc-github-button.nitdoc-github-cancel {\r
- background-color: #b33630;\r
- background-image: -webkit-gradient(linear, left top, left bottom, from(#E97A74), to(#9f312c)); /* Saf4+, Chrome */\r
- background-image: -webkit-linear-gradient(top, #E97A74, #9f312c); /* Chrome 10+, Saf5.1+ */\r
- background-image: -moz-linear-gradient(top, #E97A74, #9f312c); /* FF3.6 */\r
- background-image: -ms-linear-gradient(top, #E97A74, #9f312c); /* IE10 */\r
- background-image: -o-linear-gradient(top, #E97A74, #9f312c); /* Opera 11.10+ */\r
- background-image: linear-gradient(top, #E97A74, #9f312c);\r
- filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#E97A74', EndColorStr='#9f312c'); /* IE6–IE9 */\r
- border: 1px solid #9f312c;\r
-}\r
-\r
-div.comment.locked {\r
- color: gray;\r
-}\r
-p.locked {\r
- color: black;\r
-}\r
-\r
-a.nitdoc-github-cancel {\r
- color: #b33630;\r
- cursor: pointer;\r
-}\r
-\r
-a.nitdoc-github-update {\r
- color: orange;\r
- cursor: pointer;\r
-}\r
-\r
-.nitdoc-dialog h4 {\r
- font-weight: bold;\r
-}\r
-\r
-/* hljs */\r
-\r
-.hljs.nitcode {\r
- padding-left: 10px;\r
-}\r
-\r
-.hljs-comment, .hljs-comment-block {\r
- color: #777;\r
-}\r
-\r
-.hljs-keyword {\r
- color: #000;\r
- font-weight: bold;\r
-}\r
-\r
-.hljs-title {\r
- font-weight: bold;\r
-}\r
-\r
-.hljs-module {\r
- color: #3762E4;\r
-}\r
-\r
-.hljs-class .hljs-title {\r
- color: #3762E4;\r
-}\r
-\r
-.hljs-type {\r
- color: #3762E4;\r
-}\r
-\r
-.hljs-string {\r
- color: #8F1546;\r
-}\r
-\r
-.hljs-subst {\r
- color: #9E6BEB;\r
-}\r
-\r
-.hljs-fun .hljs-title {\r
- color: #3762E4;\r
-}\r
-\r
-.hljs-char, .hljs-number {\r
- color: #009999;\r
-}\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc ModalBox style\r
- */\r
-\r
-.nitdoc-dialog-fade {\r
- background: #000;\r
- position: fixed; left: 0; top: 0;\r
- width: 100%; height: 100%;\r
- opacity: .80;\r
- filter: alpha(opacity=80);\r
- z-index: 9999;\r
-}\r
-\r
-.nitdoc-dialog {\r
- background: #fff;\r
- border: 1px solid #ddd;\r
- float: left;\r
- position: fixed;\r
- z-index: 99999;\r
- -webkit-box-shadow: 0px 0px 20px #000;\r
- -moz-box-shadow: 0px 0px 20px #000;\r
- box-shadow: 0px 0px 20px #000;\r
- -webkit-border-radius: 2px;\r
- -moz-border-radius: 2px;\r
- border-radius: 2px;\r
- text-align: left;\r
- min-width: 300px;\r
-}\r
-\r
-.nitdoc-dialog-header {\r
- padding: 10px 10px 10px 20px;\r
- background: #f1f1f1;\r
- border-bottom: 1px solid #ddd;\r
-}\r
-\r
-.nitdoc-dialog-error .nitdoc-dialog-header {\r
- background: #C92020;\r
-}\r
-.nitdoc-dialog-error .nitdoc-dialog-header h3 {\r
- color: white;\r
-}\r
-\r
-.nitdoc-dialog h3 {\r
- display: inline;\r
- margin: 0;\r
-}\r
-\r
-.nitdoc-dialog-content {\r
- max-height: 450px;\r
- overflow-y: scroll;\r
- padding: 10px;\r
-}\r
-\r
-.nitdoc-dialog-buttons {\r
- text-align: right;\r
- padding: 5px;\r
- border-top: 1px solid #ddd;\r
-}\r
-\r
-.nitdoc-dialog textarea {\r
- min-width: 300px;\r
- width: 100%;\r
-}\r
-\r
-.nitdoc-dialog button {\r
- cursor: pointer;\r
- border-radius: 2px;\r
- -moz-border-radius: 2px;\r
- -webkit-border-radius: 2px;\r
- font-size: 14px;\r
- padding: 5px 7px 5px 7px;\r
- text-align: center;\r
- background: #eee;\r
- color: #333;\r
- border: 1px solid #ddd;\r
- font-weight: bold;\r
-}\r
-\r
-.nitdoc-dialog button:hover {\r
- background: #0D8921;\r
- color: #fff;\r
- border: 1px solid #1d7900;\r
-}\r
-\r
-.nitdoc-dialog-close {\r
- float: right;\r
- padding: 5px;\r
- margin: 0px;\r
- line-height: 10px;\r
- text-transform: lowercase;\r
-}\r
-\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc Quick Search JS module \r
- */\r
-\r
-#nitdoc-qs-field {\r
- width: 300px;\r
- margin-top: 3px;\r
-}\r
-\r
-#nitdoc-qs-table {\r
- background-color: #FFFFFF;\r
- border: 1px solid #E0E0E0;\r
- border-spacing: 0px;\r
- z-index: 1000;\r
- -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
- -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\r
-}\r
-\r
-#nitdoc-qs-table .nitdoc-qs-active {\r
- cursor: pointer;\r
- background: #EEE;\r
-}\r
-\r
-#nitdoc-qs-table td, th {\r
- white-space: nowrap;\r
- overflow: hidden;\r
- line-height: 22px;\r
- padding: 2px;\r
-}\r
-\r
-#nitdoc-qs-table td.nitdoc-qs-sub {\r
- color: #6C6C6C;\r
- padding-left: 12px;\r
-}\r
-\r
-#nitdoc-qs-table td.nitdoc-qs-info {\r
- color: #0D8921;\r
- font-size: smaller;\r
- text-align: right;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-noresult td {\r
- color: #6C6C6C;\r
- font-size: small;\r
- line-height: 15px;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-overflow td {\r
- text-align: center;\r
- font-size: x-small;\r
- line-height: 10px;\r
- color: #FFF;\r
- -webkit-touch-callout: none;\r
- -webkit-user-select: none;\r
- -khtml-user-select: none;\r
- -moz-user-select: none;\r
- -ms-user-select: none;\r
- user-select: none;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-overflow-active td {\r
- color: #0D8921;\r
- cursor: pointer;\r
-}\r
-\r
-#nitdoc-qs-table tr.nitdoc-qs-overflow-active td:hover {\r
- background-color: #E0E0E0;\r
-}\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * Nitdoc UI JS module \r
- */\r
-\r
-\r
-/* Folding */\r
-\r
-a.nitdoc-ui-fold {\r
- margin: 0 5px;\r
- color: #999;\r
- font-family: monospace;\r
- font-weight: bold;\r
- font-size: 120%;\r
-}\r
-\r
-/* Search page field */\r
-\r
-.nitdoc-ui-searchpage-field {\r
- width: 750px;\r
-}\r
-\r
-/* Side bar boxes text filtering */\r
-\r
-.nitdoc-ui-filter {\r
- text-align: center;\r
- padding: 5px;\r
-}\r
-\r
-.nitdoc-ui-filter-field {\r
- width: 150px;\r
- margin-right: 5px;\r
-}\r
-\r
-.nitdoc-ui-filter-field-notused {\r
- color: #999;\r
- font-style: italic;\r
-}\r
-\r
-/* Side bar boxes type filtering */\r
-\r
-a.nitdoc-ui-filter-link {\r
- color: #0D8921;\r
- cursor: pointer;\r
- font-family: monospace;\r
- margin-right: 5px;\r
- font-weight: bold;\r
-}\r
-\r
-a.nitdoc-ui-filter-link:hover {\r
- text-decoration: underline;\r
-}\r
-\r
-a.nitdoc-ui-filter-hidden {\r
- color: #999;\r
- font-weight: normal;\r
-}\r
-\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/* \r
- * GitHub API wrapper for github plugin\r
- */\r
-define([\r
- "jquery",\r
- "utils"\r
-], function($, Utils) {\r
- return {\r
-\r
- // try to login the user to github API\r
- login: function(user) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo,\r
- async: false,\r
- dataType: 'json',\r
- success: function() {\r
- res = true;\r
- }\r
- });\r
- user.infos = this.getUserInfos(user);\r
- user.signedOff = this.getSignedOff(user)\r
- return res;\r
- },\r
-\r
- // request for user github account infos\r
- getUserInfos: function(user) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/users/" + user.login,\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- // build signedoff user default signature\r
- getSignedOff: function(user) {\r
- return user.infos.name + " <" + user.infos.email + ">";\r
- },\r
-\r
- // get the branches list from a repo\r
- getBranches: function(user) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/branches",\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- /* GitHub commits */\r
-\r
- // get the latest commit on `branchName`\r
- getCommit: function(user, sha) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits/" + sha,\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- // get the base tree for a commit sha\r
- getTree: function(user, sha) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees/" + sha + "?recursive=1",\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- // create a new blob\r
- createBlob: function(user, content) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/blobs",\r
- async: false,\r
- dataType: 'json',\r
- data: JSON.stringify({\r
- content: content.base64Encode(),\r
- encoding: "base64"\r
- }),\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- // create a new tree from a base tree\r
- createTree: function(user, baseTree, path, blob) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/trees",\r
- data: JSON.stringify({\r
- base_tree: baseTree.sha,\r
- tree: [{\r
- path: path,\r
- mode: "100644", // file (blob)\r
- type: "blob",\r
- sha: blob.sha\r
- }]\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- // create a new commit\r
- createCommit: function(user, message, parentCommit, tree) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/git/commits",\r
- data: JSON.stringify({\r
- message: message,\r
- parents: parentCommit,\r
- tree: tree.sha,\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- // create a pull request\r
- createPullRequest: function(user, title, body, origin, head) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "POST",\r
- url: "https://api.github.com/repos/" + origin.user + "/" + origin.repo + "/pulls",\r
- data: JSON.stringify({\r
- title: title,\r
- body: body,\r
- base: origin.branch,\r
- head: user.login + ":" + head\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- // update a pull request\r
- updatePullRequest: function(user, title, body, state, request) {\r
- var res = false;\r
- $.ajax({\r
- beforeSend: function (xhr) {\r
- xhr.setRequestHeader ("Authorization", user.auth);\r
- },\r
- type: "PATCH",\r
- url: request.url,\r
- data: JSON.stringify({\r
- title: title,\r
- body: body,\r
- state: state\r
- }),\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- },\r
-\r
- /* Files */\r
-\r
- getFile: function(user, path, branch) {\r
- var res = false;\r
- $.ajax({\r
- type: "GET",\r
- url: "https://api.github.com/repos/" + user.login + "/" + user.repo + "/contents/" + path,\r
- data: {\r
- ref: branch\r
- },\r
- async: false,\r
- dataType: 'json',\r
- success: function(response) {\r
- res = response;\r
- },\r
- error: function(response) {\r
- res = response;\r
- }\r
- });\r
- return res;\r
- }\r
- }\r
-});\r
+++ /dev/null
-/* Copyright (c) 2006, Ivan Sagalaev
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of highlight.js nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-var hljs = new function() {
-
- /* Utility functions */
-
- function escape(value) {
- return value.replace(/&/gm, '&').replace(/</gm, '<').replace(/>/gm, '>');
- }
-
- function tag(node) {
- return node.nodeName.toLowerCase();
- }
-
- function testRe(re, lexeme) {
- var match = re && re.exec(lexeme);
- return match && match.index == 0;
- }
-
- function blockLanguage(block) {
- var classes = (block.className + ' ' + (block.parentNode ? block.parentNode.className : '')).split(/\s+/);
- classes = classes.map(function(c) {return c.replace(/^lang(uage)?-/, '');});
- return classes.filter(function(c) {return getLanguage(c) || c == 'no-highlight';})[0];
- }
-
- function inherit(parent, obj) {
- var result = {};
- for (var key in parent)
- result[key] = parent[key];
- if (obj)
- for (var key in obj)
- result[key] = obj[key];
- return result;
- };
-
- /* Stream merging */
-
- function nodeStream(node) {
- var result = [];
- (function _nodeStream(node, offset) {
- for (var child = node.firstChild; child; child = child.nextSibling) {
- if (child.nodeType == 3)
- offset += child.nodeValue.length;
- else if (tag(child) == 'br')
- offset += 1;
- else if (child.nodeType == 1) {
- result.push({
- event: 'start',
- offset: offset,
- node: child
- });
- offset = _nodeStream(child, offset);
- result.push({
- event: 'stop',
- offset: offset,
- node: child
- });
- }
- }
- return offset;
- })(node, 0);
- return result;
- }
-
- function mergeStreams(original, highlighted, value) {
- var processed = 0;
- var result = '';
- var nodeStack = [];
-
- function selectStream() {
- if (!original.length || !highlighted.length) {
- return original.length ? original : highlighted;
- }
- if (original[0].offset != highlighted[0].offset) {
- return (original[0].offset < highlighted[0].offset) ? original : highlighted;
- }
-
- /*
- To avoid starting the stream just before it should stop the order is
- ensured that original always starts first and closes last:
-
- if (event1 == 'start' && event2 == 'start')
- return original;
- if (event1 == 'start' && event2 == 'stop')
- return highlighted;
- if (event1 == 'stop' && event2 == 'start')
- return original;
- if (event1 == 'stop' && event2 == 'stop')
- return highlighted;
-
- ... which is collapsed to:
- */
- return highlighted[0].event == 'start' ? original : highlighted;
- }
-
- function open(node) {
- function attr_str(a) {return ' ' + a.nodeName + '="' + escape(a.value) + '"';}
- result += '<' + tag(node) + Array.prototype.map.call(node.attributes, attr_str).join('') + '>';
- }
-
- function close(node) {
- result += '</' + tag(node) + '>';
- }
-
- function render(event) {
- (event.event == 'start' ? open : close)(event.node);
- }
-
- while (original.length || highlighted.length) {
- var stream = selectStream();
- result += escape(value.substr(processed, stream[0].offset - processed));
- processed = stream[0].offset;
- if (stream == original) {
- /*
- On any opening or closing tag of the original markup we first close
- the entire highlighted node stack, then render the original tag along
- with all the following original tags at the same offset and then
- reopen all the tags on the highlighted stack.
- */
- nodeStack.reverse().forEach(close);
- do {
- render(stream.splice(0, 1)[0]);
- stream = selectStream();
- } while (stream == original && stream.length && stream[0].offset == processed);
- nodeStack.reverse().forEach(open);
- } else {
- if (stream[0].event == 'start') {
- nodeStack.push(stream[0].node);
- } else {
- nodeStack.pop();
- }
- render(stream.splice(0, 1)[0]);
- }
- }
- return result + escape(value.substr(processed));
- }
-
- /* Initialization */
-
- function compileLanguage(language) {
-
- function reStr(re) {
- return (re && re.source) || re;
- }
-
- function langRe(value, global) {
- return RegExp(
- reStr(value),
- 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')
- );
- }
-
- function compileMode(mode, parent) {
- if (mode.compiled)
- return;
- mode.compiled = true;
-
- mode.keywords = mode.keywords || mode.beginKeywords;
- if (mode.keywords) {
- var compiled_keywords = {};
-
- function flatten(className, str) {
- if (language.case_insensitive) {
- str = str.toLowerCase();
- }
- str.split(' ').forEach(function(kw) {
- var pair = kw.split('|');
- compiled_keywords[pair[0]] = [className, pair[1] ? Number(pair[1]) : 1];
- });
- }
-
- if (typeof mode.keywords == 'string') { // string
- flatten('keyword', mode.keywords);
- } else {
- Object.keys(mode.keywords).forEach(function (className) {
- flatten(className, mode.keywords[className]);
- });
- }
- mode.keywords = compiled_keywords;
- }
- mode.lexemesRe = langRe(mode.lexemes || /\b[A-Za-z0-9_]+\b/, true);
-
- if (parent) {
- if (mode.beginKeywords) {
- mode.begin = '\\b(' + mode.beginKeywords.split(' ').join('|') + ')\\b';
- }
- if (!mode.begin)
- mode.begin = /\B|\b/;
- mode.beginRe = langRe(mode.begin);
- if (!mode.end && !mode.endsWithParent)
- mode.end = /\B|\b/;
- if (mode.end)
- mode.endRe = langRe(mode.end);
- mode.terminator_end = reStr(mode.end) || '';
- if (mode.endsWithParent && parent.terminator_end)
- mode.terminator_end += (mode.end ? '|' : '') + parent.terminator_end;
- }
- if (mode.illegal)
- mode.illegalRe = langRe(mode.illegal);
- if (mode.relevance === undefined)
- mode.relevance = 1;
- if (!mode.contains) {
- mode.contains = [];
- }
- var expanded_contains = [];
- mode.contains.forEach(function(c) {
- if (c.variants) {
- c.variants.forEach(function(v) {expanded_contains.push(inherit(c, v));});
- } else {
- expanded_contains.push(c == 'self' ? mode : c);
- }
- });
- mode.contains = expanded_contains;
- mode.contains.forEach(function(c) {compileMode(c, mode);});
-
- if (mode.starts) {
- compileMode(mode.starts, parent);
- }
-
- var terminators =
- mode.contains.map(function(c) {
- return c.beginKeywords ? '\\.?(' + c.begin + ')\\.?' : c.begin;
- })
- .concat([mode.terminator_end, mode.illegal])
- .map(reStr)
- .filter(Boolean);
- mode.terminators = terminators.length ? langRe(terminators.join('|'), true) : {exec: function(s) {return null;}};
-
- mode.continuation = {};
- }
-
- compileMode(language);
- }
-
- /*
- Core highlighting function. Accepts a language name, or an alias, and a
- string with the code to highlight. Returns an object with the following
- properties:
-
- - relevance (int)
- - value (an HTML string with highlighting markup)
-
- */
- function highlight(name, value, ignore_illegals, continuation) {
-
- function subMode(lexeme, mode) {
- for (var i = 0; i < mode.contains.length; i++) {
- if (testRe(mode.contains[i].beginRe, lexeme)) {
- return mode.contains[i];
- }
- }
- }
-
- function endOfMode(mode, lexeme) {
- if (testRe(mode.endRe, lexeme)) {
- return mode;
- }
- if (mode.endsWithParent) {
- return endOfMode(mode.parent, lexeme);
- }
- }
-
- function isIllegal(lexeme, mode) {
- return !ignore_illegals && testRe(mode.illegalRe, lexeme);
- }
-
- function keywordMatch(mode, match) {
- var match_str = language.case_insensitive ? match[0].toLowerCase() : match[0];
- return mode.keywords.hasOwnProperty(match_str) && mode.keywords[match_str];
- }
-
- function buildSpan(classname, insideSpan, leaveOpen, noPrefix) {
- var classPrefix = noPrefix ? '' : options.classPrefix,
- openSpan = '<span class="' + classPrefix,
- closeSpan = leaveOpen ? '' : '</span>';
-
- openSpan += classname + '">';
-
- return openSpan + insideSpan + closeSpan;
- }
-
- function processKeywords() {
- if (!top.keywords)
- return escape(mode_buffer);
- var result = '';
- var last_index = 0;
- top.lexemesRe.lastIndex = 0;
- var match = top.lexemesRe.exec(mode_buffer);
- while (match) {
- result += escape(mode_buffer.substr(last_index, match.index - last_index));
- var keyword_match = keywordMatch(top, match);
- if (keyword_match) {
- relevance += keyword_match[1];
- result += buildSpan(keyword_match[0], escape(match[0]));
- } else {
- result += escape(match[0]);
- }
- last_index = top.lexemesRe.lastIndex;
- match = top.lexemesRe.exec(mode_buffer);
- }
- return result + escape(mode_buffer.substr(last_index));
- }
-
- function processSubLanguage() {
- if (top.subLanguage && !languages[top.subLanguage]) {
- return escape(mode_buffer);
- }
- var result = top.subLanguage ? highlight(top.subLanguage, mode_buffer, true, top.continuation.top) : highlightAuto(mode_buffer);
- // Counting embedded language score towards the host language may be disabled
- // with zeroing the containing mode relevance. Usecase in point is Markdown that
- // allows XML everywhere and makes every XML snippet to have a much larger Markdown
- // score.
- if (top.relevance > 0) {
- relevance += result.relevance;
- }
- if (top.subLanguageMode == 'continuous') {
- top.continuation.top = result.top;
- }
- return buildSpan(result.language, result.value, false, true);
- }
-
- function processBuffer() {
- return top.subLanguage !== undefined ? processSubLanguage() : processKeywords();
- }
-
- function startNewMode(mode, lexeme) {
- var markup = mode.className? buildSpan(mode.className, '', true): '';
- if (mode.returnBegin) {
- result += markup;
- mode_buffer = '';
- } else if (mode.excludeBegin) {
- result += escape(lexeme) + markup;
- mode_buffer = '';
- } else {
- result += markup;
- mode_buffer = lexeme;
- }
- top = Object.create(mode, {parent: {value: top}});
- }
-
- function processLexeme(buffer, lexeme) {
-
- mode_buffer += buffer;
- if (lexeme === undefined) {
- result += processBuffer();
- return 0;
- }
-
- var new_mode = subMode(lexeme, top);
- if (new_mode) {
- result += processBuffer();
- startNewMode(new_mode, lexeme);
- return new_mode.returnBegin ? 0 : lexeme.length;
- }
-
- var end_mode = endOfMode(top, lexeme);
- if (end_mode) {
- var origin = top;
- if (!(origin.returnEnd || origin.excludeEnd)) {
- mode_buffer += lexeme;
- }
- result += processBuffer();
- do {
- if (top.className) {
- result += '</span>';
- }
- relevance += top.relevance;
- top = top.parent;
- } while (top != end_mode.parent);
- if (origin.excludeEnd) {
- result += escape(lexeme);
- }
- mode_buffer = '';
- if (end_mode.starts) {
- startNewMode(end_mode.starts, '');
- }
- return origin.returnEnd ? 0 : lexeme.length;
- }
-
- if (isIllegal(lexeme, top))
- throw new Error('Illegal lexeme "' + lexeme + '" for mode "' + (top.className || '<unnamed>') + '"');
-
- /*
- Parser should not reach this point as all types of lexemes should be caught
- earlier, but if it does due to some bug make sure it advances at least one
- character forward to prevent infinite looping.
- */
- mode_buffer += lexeme;
- return lexeme.length || 1;
- }
-
- var language = getLanguage(name);
- if (!language) {
- throw new Error('Unknown language: "' + name + '"');
- }
-
- compileLanguage(language);
- var top = continuation || language;
- var result = '';
- for(var current = top; current != language; current = current.parent) {
- if (current.className) {
- result += buildSpan(current.className, result, true);
- }
- }
- var mode_buffer = '';
- var relevance = 0;
- try {
- var match, count, index = 0;
- while (true) {
- top.terminators.lastIndex = index;
- match = top.terminators.exec(value);
- if (!match)
- break;
- count = processLexeme(value.substr(index, match.index - index), match[0]);
- index = match.index + count;
- }
- processLexeme(value.substr(index));
- for(var current = top; current.parent; current = current.parent) { // close dangling modes
- if (current.className) {
- result += '</span>';
- }
- };
- return {
- relevance: relevance,
- value: result,
- language: name,
- top: top
- };
- } catch (e) {
- if (e.message.indexOf('Illegal') != -1) {
- return {
- relevance: 0,
- value: escape(value)
- };
- } else {
- throw e;
- }
- }
- }
-
- /*
- Highlighting with language detection. Accepts a string with the code to
- highlight. Returns an object with the following properties:
-
- - language (detected language)
- - relevance (int)
- - value (an HTML string with highlighting markup)
- - second_best (object with the same structure for second-best heuristically
- detected language, may be absent)
-
- */
- function highlightAuto(text, languageSubset) {
- languageSubset = languageSubset || options.languages || Object.keys(languages);
- var result = {
- relevance: 0,
- value: escape(text)
- };
- var second_best = result;
- languageSubset.forEach(function(name) {
- if (!getLanguage(name)) {
- return;
- }
- var current = highlight(name, text, false);
- current.language = name;
- if (current.relevance > second_best.relevance) {
- second_best = current;
- }
- if (current.relevance > result.relevance) {
- second_best = result;
- result = current;
- }
- });
- if (second_best.language) {
- result.second_best = second_best;
- }
- return result;
- }
-
- /*
- Post-processing of the highlighted markup:
-
- - replace TABs with something more useful
- - replace real line-breaks with '<br>' for non-pre containers
-
- */
- function fixMarkup(value) {
- if (options.tabReplace) {
- value = value.replace(/^((<[^>]+>|\t)+)/gm, function(match, p1, offset, s) {
- return p1.replace(/\t/g, options.tabReplace);
- });
- }
- if (options.useBR) {
- value = value.replace(/\n/g, '<br>');
- }
- return value;
- }
-
- /*
- Applies highlighting to a DOM node containing code. Accepts a DOM node and
- two optional parameters for fixMarkup.
- */
- function highlightBlock(block) {
- var text = options.useBR ? block.innerHTML
- .replace(/\n/g,'').replace(/<br>|<br [^>]*>/g, '\n').replace(/<[^>]*>/g,'')
- : block.textContent;
- var language = blockLanguage(block);
- if (language == 'no-highlight')
- return;
- var result = language ? highlight(language, text, true) : highlightAuto(text);
- var original = nodeStream(block);
- if (original.length) {
- var pre = document.createElementNS('http://www.w3.org/1999/xhtml', 'pre');
- pre.innerHTML = result.value;
- result.value = mergeStreams(original, nodeStream(pre), text);
- }
- result.value = fixMarkup(result.value);
-
- block.innerHTML = result.value;
- block.className += ' hljs ' + (!language && result.language || '');
- block.result = {
- language: result.language,
- re: result.relevance
- };
- if (result.second_best) {
- block.second_best = {
- language: result.second_best.language,
- re: result.second_best.relevance
- };
- }
- }
-
- var options = {
- classPrefix: 'hljs-',
- tabReplace: null,
- useBR: false,
- languages: undefined
- };
-
- /*
- Updates highlight.js global options with values passed in the form of an object
- */
- function configure(user_options) {
- options = inherit(options, user_options);
- }
-
- /*
- Applies highlighting to all <pre><code>..</code></pre> blocks on a page.
- */
- function initHighlighting() {
- if (initHighlighting.called)
- return;
- initHighlighting.called = true;
-
- var blocks = document.querySelectorAll('pre code');
- Array.prototype.forEach.call(blocks, highlightBlock);
- }
-
- /*
- Attaches highlighting to the page load event.
- */
- function initHighlightingOnLoad() {
- addEventListener('DOMContentLoaded', initHighlighting, false);
- addEventListener('load', initHighlighting, false);
- }
-
- var languages = {};
- var aliases = {};
-
- function registerLanguage(name, language) {
- var lang = languages[name] = language(this);
- if (lang.aliases) {
- lang.aliases.forEach(function(alias) {aliases[alias] = name;});
- }
- }
-
- function listLanguages() {
- return Object.keys(languages);
- }
-
- function getLanguage(name) {
- return languages[name] || languages[aliases[name]];
- }
-
- /* Interface definition */
-
- this.highlight = highlight;
- this.highlightAuto = highlightAuto;
- this.fixMarkup = fixMarkup;
- this.highlightBlock = highlightBlock;
- this.configure = configure;
- this.initHighlighting = initHighlighting;
- this.initHighlightingOnLoad = initHighlightingOnLoad;
- this.registerLanguage = registerLanguage;
- this.listLanguages = listLanguages;
- this.getLanguage = getLanguage;
- this.inherit = inherit;
-
- // Common regexps
- this.IDENT_RE = '[a-zA-Z][a-zA-Z0-9_]*';
- this.UNDERSCORE_IDENT_RE = '[a-zA-Z_][a-zA-Z0-9_]*';
- this.NUMBER_RE = '\\b\\d+(\\.\\d+)?';
- this.C_NUMBER_RE = '(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)'; // 0x..., 0..., decimal, float
- this.BINARY_NUMBER_RE = '\\b(0b[01]+)'; // 0b...
- this.RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~';
-
- // Common modes
- this.BACKSLASH_ESCAPE = {
- begin: '\\\\[\\s\\S]', relevance: 0
- };
- this.APOS_STRING_MODE = {
- className: 'string',
- begin: '\'', end: '\'',
- illegal: '\\n',
- contains: [this.BACKSLASH_ESCAPE]
- };
- this.QUOTE_STRING_MODE = {
- className: 'string',
- begin: '"', end: '"',
- illegal: '\\n',
- contains: [this.BACKSLASH_ESCAPE]
- };
- this.PHRASAL_WORDS_MODE = {
- begin: /\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/
- };
- this.C_LINE_COMMENT_MODE = {
- className: 'comment',
- begin: '//', end: '$',
- contains: [this.PHRASAL_WORDS_MODE]
- };
- this.C_BLOCK_COMMENT_MODE = {
- className: 'comment',
- begin: '/\\*', end: '\\*/',
- contains: [this.PHRASAL_WORDS_MODE]
- };
- this.HASH_COMMENT_MODE = {
- className: 'comment',
- begin: '#', end: '$',
- contains: [this.PHRASAL_WORDS_MODE]
- };
- this.NUMBER_MODE = {
- className: 'number',
- begin: this.NUMBER_RE,
- relevance: 0
- };
- this.C_NUMBER_MODE = {
- className: 'number',
- begin: this.C_NUMBER_RE,
- relevance: 0
- };
- this.BINARY_NUMBER_MODE = {
- className: 'number',
- begin: this.BINARY_NUMBER_RE,
- relevance: 0
- };
- this.CSS_NUMBER_MODE = {
- className: 'number',
- begin: this.NUMBER_RE + '(' +
- '%|em|ex|ch|rem' +
- '|vw|vh|vmin|vmax' +
- '|cm|mm|in|pt|pc|px' +
- '|deg|grad|rad|turn' +
- '|s|ms' +
- '|Hz|kHz' +
- '|dpi|dpcm|dppx' +
- ')?',
- relevance: 0
- };
- this.REGEXP_MODE = {
- className: 'regexp',
- begin: /\//, end: /\/[gim]*/,
- illegal: /\n/,
- contains: [
- this.BACKSLASH_ESCAPE,
- {
- begin: /\[/, end: /\]/,
- relevance: 0,
- contains: [this.BACKSLASH_ESCAPE]
- }
- ]
- };
- this.TITLE_MODE = {
- className: 'title',
- begin: this.IDENT_RE,
- relevance: 0
- };
- this.UNDERSCORE_TITLE_MODE = {
- className: 'title',
- begin: this.UNDERSCORE_IDENT_RE,
- relevance: 0
- };
-};
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- Documentation generator for the nit language.
- Generate API documentation in HTML format from nit source code.
-*/
-
-hljs.registerLanguage('nit', function(hljs) {
- var METHOD_RE = '[a-z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?';
- var KEYWORDS = {
- keyword: 'abort abstract and as assert break class continue do else end enum extern for fun ' +
- 'if import in init interface intern intrude is isa isset label loop module new nullable not ' +
- 'once or protected private redef return self super then type universal var ' +
- 'when while writable',
- literal: "true false null"
- };
- var COMMENT = {
- className: 'comment',
- begin: '#', end: '$',
- };
- var SUBST = {
- className: 'subst',
- begin: '{', end: '}',
- keywords: KEYWORDS
- };
- var STRING = {
- className: 'string',
- contains: [hljs.BACKSLASH_ESCAPE, SUBST],
- variants: [
- {begin: /"/, end: /"/},
- ]
- };
- var CHAR = {
- className: 'char',
- contains: [hljs.BACKSLASH_ESCAPE, SUBST],
- begin: /'/, end: /'/,
- };
- var TYPE = {
- className: 'type',
- begin: '[A-Z]\\w*'
- }
- var PARAMS = {
- className: 'params',
- begin: '\\(', end: '\\)',
- keywords: KEYWORDS,
- contains: [TYPE]
- };
- var RET_TYPE = {
- className: 'rettype',
- begin: ':', end: '$|do|is|=',
- keywords: 'nullable',
- returnEnd: true,
- contains: [TYPE]
- }
- var DO_BLOCK = {
- className: 'block',
- begin: 'do', end: '$|end',
- keywords: KEYWORDS
- }
- var IS_BLOCK = {
- className: 'modifiers',
- begin: 'is', end: '$',
- keywords: KEYWORDS
- }
- var CONTAINS = [
- STRING,
- CHAR,
- COMMENT,
- TYPE,
- {
- className: 'module',
- beginKeywords: 'module', end: '$',
- contains: [
- hljs.inherit(hljs.TITLE_MODE, {begin: '[a-z_]\\w*'}),
- COMMENT
- ]
- },
- {
- className: 'import',
- begin: '(intrude )?import', end: '$',
- keywords: 'intrude import',
- contains: [
- {
- className: 'module',
- begin: '[a-z_]\\w*'
- },
- COMMENT
- ]
- },
- {
- className: 'class',
- begin: '(redef |private |protected )?(abstract )?(class|interface)', end: '$',
- keywords: 'redef private protected abstract class interface',
- contains: [
- hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Z]\\w*'}),
- {
- className: 'super',
- begin: '\\bsuper', end: '$',
- keywords: 'super',
- contains: [TYPE]
- },
- COMMENT
- ]
- },
- {
- className: 'fun',
- begin: '(redef |private |protected )?(fun|init|type)\\b', end: '$',
- keywords: KEYWORDS,
- contains: [
- PARAMS,
- RET_TYPE,
- DO_BLOCK,
- IS_BLOCK,
- {
- className: 'title',
- begin: '\\b[a-zA-Z_][a-zA-Z_]*\\b'
- },
- COMMENT
- ]
- },
- {
- className: 'number',
- begin: '(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b',
- relevance: 0
- }
- ];
- SUBST.contains = CONTAINS;
-
- return {
- keywords: KEYWORDS,
- contains: CONTAINS
- };
-});
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- Documentation generator for the nit language.
- Generate API documentation in HTML format from nit source code.
-*/
-
-/*
- * Utils module
- */
-String.prototype.startsWith = function(prefix, caseSensitive) {
- if(caseSensitive) {
- return this.toUpperCase().indexOf(prefix.toUpperCase()) === 0;
- }
- return this.indexOf(prefix) === 0;
-}
-
-// Compare two strings using Sorensen-Dice Coefficient
-// see: http://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient
-String.prototype.dice = function(other) {
- var length1 = this.length - 1;
- var length2 = other.length - 1;
- if(length1 < 1 || length2 < 1) return 0;
-
- var bigrams2 = [];
- for(var i = 0; i < length2; i++) {
- bigrams2.push(other.substr(i, 2));
- }
-
- var intersection = 0;
- for(var i = 0; i < length1; i++) {
- var bigram1 = this.substr(i, 2);
- for(var j = 0; j < length2; j++) {
- if(bigram1 == bigrams2[j]) {
- intersection++;
- bigrams2[j] = null;
- break;
- }
- }
- }
- return (2.0 * intersection) / (length1 + length2);
-}
-
-/* base64 */
-
-String.prototype._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
-// public method for encoding
-String.prototype.base64Encode = function () {
- var output = "";
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
- var i = 0;
-
- input = this._utf8_encode();
-
- while (i < input.length) {
-
- chr1 = input.charCodeAt(i++);
- chr2 = input.charCodeAt(i++);
- chr3 = input.charCodeAt(i++);
-
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
-
- if (isNaN(chr2)) {
- enc3 = enc4 = 64;
- } else if (isNaN(chr3)) {
- enc4 = 64;
- }
-
- output = output +
- this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
- this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
-
- }
- return output;
-};
-
-// public method for decoding
-String.prototype.base64Decode = function () {
- var output = "";
- var chr1, chr2, chr3;
- var enc1, enc2, enc3, enc4;
- var i = 0;
-
- input = this.replace(/[^A-Za-z0-9\+\/\=]/g, "");
-
- while (i < input.length) {
-
- enc1 = this._keyStr.indexOf(input.charAt(i++));
- enc2 = this._keyStr.indexOf(input.charAt(i++));
- enc3 = this._keyStr.indexOf(input.charAt(i++));
- enc4 = this._keyStr.indexOf(input.charAt(i++));
-
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
-
- output = output + String.fromCharCode(chr1);
-
- if (enc3 != 64) {
- output = output + String.fromCharCode(chr2);
- }
- if (enc4 != 64) {
- output = output + String.fromCharCode(chr3);
- }
-
- }
- return output._utf8_decode();;
-};
-
-// private method for UTF-8 encoding
-String.prototype._utf8_encode = function () {
- string = this.replace(/\r\n/g,"\n");
- var utftext = "";
-
- for (var n = 0; n < string.length; n++) {
-
- var c = string.charCodeAt(n);
-
- if (c < 128) {
- utftext += String.fromCharCode(c);
- }
- else if((c > 127) && (c < 2048)) {
- utftext += String.fromCharCode((c >> 6) | 192);
- utftext += String.fromCharCode((c & 63) | 128);
- }
- else {
- utftext += String.fromCharCode((c >> 12) | 224);
- utftext += String.fromCharCode(((c >> 6) & 63) | 128);
- utftext += String.fromCharCode((c & 63) | 128);
- }
-
- }
- return utftext;
-};
-
-// private method for UTF-8 decoding
-String.prototype._utf8_decode = function () {
- var string = "";
- var i = 0;
- var c = c1 = c2 = 0;
-
- while ( i < this.length ) {
-
- c = this.charCodeAt(i);
-
- if (c < 128) {
- string += String.fromCharCode(c);
- i++;
- }
- else if((c > 191) && (c < 224)) {
- c2 = this.charCodeAt(i+1);
- string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
- i += 2;
- }
- else {
- c2 = this.charCodeAt(i+1);
- c3 = this.charCodeAt(i+2);
- string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
- i += 3;
- }
-
- }
- return string;
-};
-
-// JQuery Case Insensitive :icontains selector
-$.expr[':'].icontains = function(obj, index, meta, stack){
- return (obj.textContent.replace(/\[[0-9]+\]/g, "") || obj.innerText.replace(/\[[0-9]+\]/g, "") || jQuery(obj).text().replace(/\[[0-9]+\]/g, "") || '').toLowerCase().indexOf(meta[3].toLowerCase()) >= 0;
-};
-
-var Utils = {
- // Extract anchor part (after #) from URL string
- extractAnchor: function(url) {
- var index = url.indexOf("#");
- if (index >= 0) {
- return url.substring(index + 1);
- }
- return null;
- },
-
- delayEvent: function(handler, event) {
- if(this.delayEvent.timeout) {
- clearTimeout(this.delayEvent.timeout);
- }
- this.delayEvent.timeout = setTimeout(function() {
- handler.call(event);
- }, 50);
- }
-};
+++ /dev/null
-/* 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')");
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-/*\r
- * Nitdoc.Github comment edition module\r
- *\r
- * Allows user to modify source code comments directly from the Nitdoc\r
- */\r
-define([\r
- "jquery",\r
- "github-api",\r
- "highlight",\r
- "marked",\r
- "nit",\r
- "plugins/modalbox",\r
- "plugins/github/loginbox",\r
- "plugins/github/commentbox",\r
- "utils"\r
-], function($, GithubAPI, hljs, marked) {\r
- var GithubUser = function(login, password, repo, branch) {\r
- this.login = login;\r
- this.password = password;\r
- this.repo = repo;\r
- this.auth = "Basic " + (login + ':' + password).base64Encode();\r
- this.branch = branch;\r
- }\r
-\r
- var GithubUI = {\r
- init: function(upstream, basesha1) {\r
- console.info("Github plugin: init GitHub module (upstream: "+ upstream +", base: " + basesha1 + ")");\r
- this.origin = this._parseUpstream(upstream);\r
- this._initMarked();\r
- // Add github menu\r
- $("#topmenu>.container-fluid").append(\r
- $("<a/>")\r
- .attr({\r
- "id": "nitdoc-github-li",\r
- "type": "button",\r
- "class": "navbar-btn navbar-right btn-link",\r
- "href": "#",\r
- "data-container": "body",\r
- "data-toggle": "popover",\r
- "data-placement": "bottom",\r
- "data-content": "bottom",\r
- "data-html": "true",\r
- })\r
- .loginbox()\r
- //.loginbox("displayLogin")\r
- .bind("loginbox_logoff", function() {\r
- GithubUI.disactivate();\r
- })\r
- .bind("loginbox_login", function(event, infos) {\r
- GithubUI._tryLoginFromCredentials(infos);\r
- })\r
- );\r
- // check local session\r
- this._tryLoginFromLocalSession();\r
- },\r
-\r
- activate: function(user, origin) {\r
- this.openedComments = 0;\r
- this._saveSession(user);\r
- $("#nitdoc-github-li").loginbox("displayLogout", origin, user);\r
- this._attachCommentBoxes();\r
- this._reloadComments();\r
-\r
- // Prevent page unload if there is comments in editing mode\r
- $(window).on('beforeunload', function() {\r
- if(GithubUI.openedComments > 0){\r
- return "There is uncommited modified comments. Are you sure you want to leave this page?";\r
- }\r
- });\r
- },\r
-\r
- disactivate: function() {\r
- if(this.openedComments > 0){\r
- if(!confirm('There is uncommited modified comments. Are you sure you want to leave this page?')) {\r
- return false;\r
- }\r
- }\r
-\r
- localStorage.clear();\r
- $("#nitdoc-github-li").loginbox("toggle");\r
- $("#nitdoc-github-li").loginbox("displayLogin");\r
- $(window).unbind('beforeunload');\r
- //window.location.reload();\r
- },\r
-\r
- /* login */\r
-\r
- _checkLoginInfos: function(infos) {\r
- if(!infos.login || !infos.password || !infos.repo || !infos.branch) {\r
- $("<p/>")\r
- .text("Please enter your GitHub username, password, repository and branch.")\r
- .modalbox({\r
- title: "Sign in error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- } else {\r
- return true;\r
- }\r
- },\r
-\r
- _tryLoginFromCredentials: function(infos) {\r
- if(this._checkLoginInfos(infos)) {\r
- var isok = this._tryLogin(infos.login, infos.password, infos.repo, infos.branch);\r
- if(isok === true) {\r
- this.activate(this.user, this.origin);\r
- } else {\r
- if(isok == "error:login") {\r
- $("<p/>")\r
- .text("The username, password, repo or branch you entered is incorrect.")\r
- .modalbox({\r
- title: "Github sign in error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- } else if(isok == "error:sha") {\r
- $("<p/>")\r
- .text("The provided Github repository must contain the base commit '" + this.origin.sha + "'.")\r
- .modalbox({\r
- title: "Github base commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- } else if(isok == "error:profile") {\r
- $("<p/>")\r
- .text("Please set your public name and email in your " +\r
- "<a href='https://github.com/settings/profile'>GitHub profile</a>." +\r
- "<br/><br/>Your public profile informations are used to sign-off your commits.")\r
- .modalbox({\r
- title: "Github profile error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- }\r
- }\r
- }\r
- },\r
-\r
- _tryLoginFromLocalSession: function() {\r
- if(localStorage.user) {\r
- var session = JSON.parse(localStorage.user);\r
- var isok = this._tryLogin(\r
- session.login,\r
- session.password.base64Decode(),\r
- session.repo,\r
- session.branch\r
- );\r
- if(isok === true) {\r
- this.activate(this.user, this.origin);\r
- } else {\r
- console.debug("Github plugin: Session found but authentification failed");\r
- localStorage.clear();\r
- }\r
- } else {\r
- console.debug("Github plugin: No session found");\r
- }\r
- },\r
-\r
- _tryLogin: function(login, password, repo, branch) {\r
- var tmpUser = new GithubUser(login, password, repo, branch);\r
- if(!GithubAPI.login(tmpUser)) {\r
- return "error:login";\r
- }\r
- if(!tmpUser.infos.name || !tmpUser.infos.email) {\r
- return "error:profile";\r
- }\r
- var commit = GithubAPI.getCommit(tmpUser, this.origin.sha);\r
- if(!commit || !commit.sha) {\r
- return "error:sha";\r
- }\r
- this.user = tmpUser;\r
- return true;\r
- },\r
-\r
- _saveSession: function(user) {\r
- localStorage.user = JSON.stringify({\r
- login: user.login,\r
- password: user.password.base64Encode(),\r
- repo: user.repo,\r
- branch: user.branch,\r
- });\r
- // check local storage synchro with branch\r
- if(localStorage.base != this.origin.sha) {\r
- console.log("Base changed: cleaned cache");\r
- localStorage.requests = "[]";\r
- localStorage.base = this.origin.sha;\r
- }\r
- },\r
-\r
- /* html decoration */\r
-\r
- // Attach edit button on each comment\r
- _attachCommentBoxes: function() {\r
- $("textarea.baseComment").each(function() {\r
- $(this).commentbox();\r
-\r
- var isNew = false;\r
- if(!$(this).val()) {\r
- isNew = true;\r
- $(this).nextAll(".info:first").find(".noComment").hide()\r
- $(this).nextAll(".info:first").before(\r
- $("<div/>")\r
- .hide()\r
- .addClass("comment")\r
- .append(\r
- $("<div/>").addClass("nitdoc")\r
- )\r
- )\r
- }\r
-\r
- $(this).nextAll(".info:first").prepend(\r
- $("<a/>")\r
- .addClass("nitdoc-github-editComment")\r
- .css("cursor", "pointer")\r
- .text((isNew ? "add" : "edit") + " comment")\r
- .click($.proxy(GithubUI._openCommentBox, GithubUI, null, $(this)))\r
- .after(" for ")\r
- )\r
-\r
- $(this).bind("commentbox_commit", function(event, data) {\r
- GithubUI._saveChanges(data);\r
- $(this).commentbox("close");\r
- GithubUI._reloadComments();\r
- })\r
- .bind("commentbox_preview", function(event, data) {\r
- $("<div/>")\r
- .append($("<h4/>").text("Comment:"))\r
- .append(\r
- $("<div/>")\r
- .addClass("description")\r
- .append(\r
- $("<div/>")\r
- .addClass("comment")\r
- .append(\r
- $("<div/>")\r
- .addClass("nitdoc")\r
- .html(marked(data.value))\r
- )\r
- )\r
- )\r
- .append($("<h4/>").text("Message:"))\r
- .append(\r
- $("<div/>")\r
- .addClass("description")\r
- .append(\r
- $("<div/>")\r
- .addClass("comment")\r
- .append(\r
- $("<div/>").html(marked(data.message))\r
- )\r
- )\r
- )\r
- .modalbox({\r
- title: "Preview comment",\r
- css: {"min-width": "500px"}\r
- })\r
- .modalbox("open");\r
- })\r
- .bind("commentbox_open", function(event, data) {\r
- GithubUI.openedComments++;\r
- $(this).nextAll(".comment").hide();\r
- })\r
- .bind("commentbox_close", function(event, data) {\r
- GithubUI.openedComments--;\r
- $(this).nextAll(".comment").show();\r
- });\r
- });\r
- },\r
-\r
- // reload comments from saved pull request\r
- _reloadComments: function() {\r
- if(!localStorage.requests){ return; }\r
- $("p.pullRequest").remove();\r
- var requests = JSON.parse(localStorage.requests);\r
- // Look for modified comments in page\r
- for(i in requests) {\r
- if(!requests[i]) { continue; }\r
- var request = requests[i];\r
- $("textarea[data-comment-location=\"" + request.location + "\"]").each(function () {\r
- if(request.isClosed) {\r
- var oldComment = request.oldComment.base64Decode();\r
- var htmlComment = marked(oldComment);\r
- $(this).val(oldComment);\r
- if(!$(this).val()) {\r
- $(this).nextAll("div.comment:first").hide();\r
- } else {\r
- $(this).nextAll("div.comment:first").show();\r
- }\r
- $(this).nextAll("div.comment").find("div.nitdoc").empty().html(htmlComment);\r
- $(this).nextAll("p.info").find("a.nitdoc-github-editComment").show();\r
- } else {\r
- var newComment = request.comment.base64Decode();\r
- var htmlComment = marked(newComment);\r
- $(this).val(newComment);\r
- if(!$(this).val()) {\r
- $(this).nextAll("div.comment:first").hide();\r
- } else {\r
- $(this).nextAll("div.comment:first").show();\r
- }\r
- $(this).nextAll("div.comment").find("div.nitdoc").empty().html(htmlComment);\r
- GithubUI._addPullRequestLink($(this), request);\r
- $(this).nextAll("p.info").find("a.nitdoc-github-editComment").hide();\r
- }\r
- });\r
- }\r
- },\r
-\r
- _addPullRequestLink: function(baseArea, request) {\r
- baseArea.nextAll("p.info").before(\r
- $("<p/>")\r
- .addClass("pullRequest inheritance")\r
- .text("comment modified in ")\r
- .append(\r
- $("<a/>")\r
- .attr({\r
- href: request.request.html_url,\r
- title: "Review on GitHub"\r
- })\r
- .text("pull request #" + request.request.number)\r
- )\r
- .append(" ")\r
- .append(\r
- $("<a/>")\r
- .data("pullrequest-number", request.request.number)\r
- .addClass("nitdoc-github-update")\r
- .text("update")\r
- .click($.proxy(GithubUI._doUpdateRequest, GithubUI, null, baseArea, request))\r
- )\r
- .append(" ")\r
- .append(\r
- $("<a/>")\r
- .data("pullrequest-number", request.request.number)\r
- .addClass("nitdoc-github-cancel")\r
- .text("cancel")\r
- .click($.proxy(GithubUI._doCancelRequest, GithubUI, null, baseArea, request))\r
- )\r
- );\r
- },\r
-\r
- /* github calls */\r
-\r
- _saveChanges: function(edit) {\r
- // if pull request update close existing pull request for the comment\r
- if(edit.requestID) {\r
- this._closePullRequest(edit.requestID);\r
- }\r
- edit.oldContent = this._getFileContent(edit.location.path);\r
- edit.newContent = this._mergeComment(edit.oldContent, edit.newComment, edit.location);\r
- edit.request = this._pushChanges(edit)\r
- if(!edit.request) {\r
- $("<p/>")\r
- .text("Unable to commit changes.<br/>" + response)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return;\r
- }\r
- this._saveRequest(edit);\r
- },\r
-\r
- // save pull request in local storage\r
- _saveRequest: function(edit) {\r
- var requests = {};\r
- if(localStorage.requests) {requests = JSON.parse(localStorage.requests)}\r
- requests[edit.request.number] = {\r
- request: edit.request,\r
- location: edit.location.origin,\r
- comment: edit.newComment.base64Encode(),\r
- oldComment: edit.oldComment.base64Encode()\r
- };\r
- localStorage.requests = JSON.stringify(requests);\r
- },\r
-\r
- /*\r
- Creating a new pull request with the new comment take 5 steps:\r
- 1. get the base tree from latest commit\r
-\r
- 2. create a new blob with updated file content\r
- 3. post a new tree from base tree and blob\r
- 4. post the new commit with new tree\r
- 5. create the pull request\r
- */\r
- _pushChanges: function(edit) {\r
- var baseTree = GithubAPI.getTree(this.user, this.origin.sha);\r
- if(!baseTree.sha) {\r
- $("<p/>")\r
- .text("Unable to locate base tree.<br/>" + baseTree.status + ": " + baseTree.statusText)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- }\r
- console.log("Base tree: " + baseTree.url);\r
- var newBlob = GithubAPI.createBlob(this.user, edit.newContent);\r
- if(!newBlob.sha) {\r
- $("<p/>")\r
- .text("Unable to create new blob.<br/>" + newBlob.status + ": " + newBlob.statusText)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- }\r
- console.log("New blob: " + newBlob.url);\r
- var newTree = GithubAPI.createTree(this.user, baseTree, edit.location.path, newBlob);\r
- if(!newTree.sha) {\r
- $("<p/>")\r
- .text("Unable to create new tree.<br/>" + newTree.status + ": " + newTree.statusText)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- }\r
- console.log("New tree: " + newTree.url);\r
- var newCommit = GithubAPI.createCommit(this.user, edit.message, baseTree.sha, newTree);\r
- if(!newCommit.sha) {\r
- $("<p/>")\r
- .text("Unable to create new commit.<br/>" + newCommit.status + ": " + newCommit.statusText)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- }\r
- console.log("New commit: " + newCommit.url);\r
- var pullRequest = GithubAPI.createPullRequest(this.user, edit.title, "Pull request from Nitdoc", this.origin, newCommit.sha);\r
- if(!pullRequest.number) {\r
- $("<p/>")\r
- .text("Unable to create pull request.<br/>" + pullRequest.status + ": " + pullRequest.statusText)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- }\r
- console.log("New pull request: " + pullRequest.url);\r
- return pullRequest;\r
- },\r
-\r
- // close previously opened pull request\r
- _closePullRequest: function(number) {\r
- var requests = JSON.parse(localStorage.requests);\r
- if(!requests[number]) {\r
- $("<p/>")\r
- .text("Unable to close pull request.<br/>" + "Pull request " + number + "not found")\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- }\r
- // close pull request\r
- var res = GithubAPI.updatePullRequest(this.user, "Closed from Nitdoc", "", "closed", requests[number].request);\r
- if(!res.id) {\r
- $("<p/>")\r
- .text("Unable to close pull request.<br/>" + res.status + ": " + res.statusText)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return false;\r
- }\r
- // update in localstorage\r
- requests[number].isClosed = true;\r
- localStorage.requests = JSON.stringify(requests);\r
- },\r
-\r
- /* internals */\r
-\r
- _initMarked: function() {\r
- var renderer = new marked.Renderer();\r
- renderer.code = function(code) {\r
- return '<pre class="nitcode hljs">' + hljs.highlight('nit', code).value + '</pre>';\r
- }\r
- renderer.codespan = function(code) {\r
- return '<code class="nitcode hljs">' + hljs.highlight('nit', code).value + '</code>';\r
- }\r
- marked.setOptions({\r
- renderer: renderer,\r
- gfm: true,\r
- tables: true,\r
- breaks: true,\r
- pedantic: false,\r
- sanitize: true,\r
- smartLists: true,\r
- smartypants: false\r
- });\r
- },\r
-\r
- _parseUpstream: function(upstream) {\r
- var parts = upstream.split(":");\r
- return {\r
- user: parts[0],\r
- repo: parts[1],\r
- branch: parts[2],\r
- sha: basesha1\r
- };\r
- },\r
-\r
- _getFileContent: function(githubUrl) {\r
- var origFile = GithubAPI.getFile(this.user, githubUrl);\r
- if(!origFile.content) {\r
- $("<p/>")\r
- .text("Unable to locate source file.<br/>" + origFile.status + ": " + origFile.statusText)\r
- .modalbox({\r
- title: "Github commit error",\r
- isError: true\r
- })\r
- .modalbox("open");\r
- return;\r
- }\r
- var base64Content = origFile.content.substring(0, origFile.content.length - 1)\r
- return base64Content.base64Decode();\r
- },\r
-\r
- _mergeComment: function(fileContent, comment, location) {\r
- // replace comment in file content\r
- var res = new String();\r
- var lines = fileContent.split("\n");\r
- // copy lines fron 0 to lstart\r
- for(var i = 0; i < location.lstart - 1; i++) {\r
- res += lines[i] + "\n";\r
- }\r
- // set comment\r
- if(comment && comment != "") {\r
- var commentLines = comment.split("\n");\r
- for(var i = 0; i < commentLines.length; i++) {\r
- var line = commentLines[i];\r
- var tab = location.tabpos > 1 ? "\t" : "";\r
- res += tab + (line.length > 0 ? "# " : "#") + line + "\n";\r
- }\r
- }\r
- // copy lines fron lend to end\r
- for(var i = location.lend - 1; i < lines.length; i++) {\r
- res += lines[i];\r
- if(i < lines.length - 1) { res += "\n"; }\r
- }\r
- return res;\r
- },\r
-\r
- /* events */\r
-\r
- _openCommentBox: function(event, baseArea) {\r
- baseArea.commentbox("open", this.user);\r
- },\r
-\r
- _doCancelRequest: function(event, baseArea, request) {\r
- this._closePullRequest(request.request.number);\r
- this._reloadComments();\r
- },\r
-\r
- _doUpdateRequest: function(event, baseArea, request) {\r
- baseArea.commentbox("open", this.user, request.request.number);\r
- },\r
- }\r
-\r
- // Get github plugin data\r
- var upstream = $("body").attr("data-github-upstream");\r
- var basesha1 = $("body").attr("data-github-base-sha1");\r
- if(upstream && basesha1) {\r
- GithubUI.init(upstream, basesha1);\r
- }\r
-});\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-*/\r
-\r
-/*\r
- * CommentBox allows user to edit comments then preview, commit or cancel the changes\r
- */\r
-define([\r
- "jquery",\r
- "jQueryUI"\r
-], function($) {\r
- var Location = function(location) {\r
- var parts = location.split(":");\r
- this.origin = location;\r
- this.path = parts[0];\r
- this.lstart = parseInt(parts[1].split("--")[0].split(",")[0]);\r
- this.tabpos = parseInt(parts[1].split("--")[0].split(",")[1]);\r
- this.lend = parseInt(parts[1].split("--")[1].split(",")[0]);\r
- this.toString = function() {\r
- return this.path + ":" + this.lstart + "," + this.tabpos + "--" + this.lend + ",0";\r
- }\r
- }\r
-\r
- $.widget("nitdoc.commentbox", {\r
-\r
- options: {\r
- previewTxt: "preview",\r
- commitTxt: "Commit",\r
- cancelTxt: "Cancel",\r
- commentboxTitle: "Edit comment",\r
- messageTxt: "Commit message"\r
- },\r
-\r
- _create: function() {\r
- this._id = $(".nitdoc-github-commentbox").length\r
- this._oldComment = this.element.val();\r
- this._namespace = this.element.data("comment-namespace");\r
- this._location = new Location(this.element.data("comment-location"));\r
- this.commentBox = $("<div/>")\r
- .hide()\r
- .addClass("nitdoc-github-commentbox")\r
- .append(\r
- $("<h3/>")\r
- .text(this.options.commentboxTitle)\r
- )\r
- .append(\r
- $("<dl/>")\r
- .addClass("nitdoc-github-commentbox-fields")\r
- .append(\r
- $("<dd/>")\r
- .append(\r
- $("<textarea/>")\r
- .attr("id", "nitdoc-github-commentbox-comment" + this._id)\r
- .addClass("nitdoc-github-commentarea")\r
- .keyup($.proxy(this._doKeyUp, this))\r
- .keydown($.proxy(this._doKeyDown, this))\r
- )\r
- )\r
- .append(\r
- $("<dt/>")\r
- .append(\r
- $("<label/>")\r
- .attr("for", "nitdoc-github-commentbox-message" + this._id)\r
- .text(this.options.messageTxt + ":")\r
- )\r
- )\r
- .append(\r
- $("<dd/>")\r
- .append(\r
- $("<textarea/>")\r
- .attr("id", "nitdoc-github-commentbox-message" + this._id)\r
- .keyup($.proxy(this._doKeyUp, this))\r
- .keydown($.proxy(this._doKeyDown, this))\r
- )\r
- )\r
- .append(\r
- $("<dt/>")\r
- .append(\r
- $("<input/>")\r
- .attr({\r
- id: "nitdoc-github-commentbox-signedoff" + this._id,\r
- type: "checkbox"\r
- })\r
- .change($.proxy(this._doSignedChange, this))\r
- )\r
- .append(\r
- $("<label/>")\r
- .attr({\r
- "id": "nitdoc-github-commentbox-signedoff-label" + this._id,\r
- "for": "nitdoc-github-commentbox-signedoff" + this._id\r
- })\r
- )\r
- )\r
- )\r
- this._buildButtonBar();\r
- this.element.after(this.commentBox);\r
- },\r
-\r
- _buildButtonBar: function() {\r
- this.commentBox.append(\r
- $("<div/>")\r
- .addClass("nitdoc-github-commentbox-buttons")\r
- .append(\r
- $("<a/>")\r
- .addClass("nitdoc-github-preview")\r
- .html(this.options.previewTxt)\r
- .click($.proxy(this._doPreviewClick, this))\r
- )\r
- .append(\r
- $("<button/>")\r
- .addClass("nitdoc-github-button")\r
- .addClass("nitdoc-github-commit")\r
- .attr("disabled", "disabled")\r
- .html(this.options.commitTxt)\r
- .click($.proxy(this._doCommitClick, this))\r
- )\r
- .append(\r
- $("<button/>")\r
- .addClass("nitdoc-github-button")\r
- .addClass("nitdoc-github-cancel")\r
- .html(this.options.cancelTxt)\r
- .click($.proxy(this._doCancelClick, this))\r
- )\r
- );\r
- },\r
-\r
- /* public actions */\r
-\r
- open: function(user, requestID) {\r
- this._requestID = requestID;\r
- var value = this.element.val();\r
- var isNew = !value;\r
- var message = "doc: " + (isNew ? "added" : "modified") + " comment for " + this._namespace;\r
- this._setMessage(message);\r
- this._setSignedOff("Signed-off-by: " + user.signedOff);\r
- this._setComment(value);\r
- this.commentBox.show();\r
- this.commentBox.find("textarea").width(this.commentBox.innerWidth() - 45)\r
- $("#nitdoc-github-commentbox-comment" + this._id).focus();\r
- $("#nitdoc-github-commentbox-comment" + this._id).trigger("keyup");\r
- $("#nitdoc-github-commentbox-message" + this._id).trigger("keyup");\r
- this._trigger("_open", null, {commentBox: this});\r
- },\r
-\r
- close: function() {\r
- this.commentBox.hide();\r
- this._trigger("_close", null, {commentBox: this});\r
- },\r
-\r
- /* internals */\r
-\r
- _setComment: function(value) {\r
- $("#nitdoc-github-commentbox-comment" + this._id).val(value);\r
- },\r
-\r
- _getComment: function() {\r
- return $("#nitdoc-github-commentbox-comment" + this._id).val();\r
- },\r
-\r
- _getMessage: function() {\r
- return $("#nitdoc-github-commentbox-message" + this._id).val();\r
- },\r
-\r
- _setMessage: function(message) {\r
- $("#nitdoc-github-commentbox-message" + this._id).val(message);\r
- },\r
-\r
- _getSignedOff: function() {\r
- return $("#nitdoc-github-commentbox-signedoff" + this._id).val();\r
- },\r
-\r
- _setSignedOff: function(signedoff) {\r
- $("#nitdoc-github-commentbox-signedoff" + this._id).val(signedoff);\r
- $("#nitdoc-github-commentbox-signedoff-label" + this._id).text(signedoff);\r
- },\r
-\r
- /* events */\r
-\r
- _doKeyUp: function(event) {\r
- $(event.target).height($(event.target).val().split(/\r|\n/).length * 16);\r
- },\r
-\r
- _doKeyDown: function(event) {\r
- if(event.keyCode == 13){\r
- $(event.target).css("height", ($(event.target).outerHeight() + 6) + "px");\r
- }\r
- },\r
-\r
- _doSignedChange: function(event) {\r
- if ($(event.currentTarget).is(':checked')) {\r
- this.commentBox.find("button.nitdoc-github-commit").removeAttr("disabled");\r
- } else {\r
- this.commentBox.find("button.nitdoc-github-commit").attr("disabled", "disabled");\r
- }\r
- },\r
-\r
- _doPreviewClick: function(event) {\r
- this._trigger("_preview", event, {\r
- value: this._getComment(),\r
- message: this._getMessage() + "\n\n" + this._getSignedOff()\r
- });\r
- },\r
-\r
- _doCommitClick: function() {\r
- this._trigger("_commit", event, {\r
- requestID: this._requestID,\r
- location: this._location,\r
- namespace: this._namespace,\r
- oldComment: this._oldComment,\r
- newComment: this._getComment(),\r
- title: this._getMessage(),\r
- message: this._getMessage() + "\n\n" + this._getSignedOff()\r
- });\r
- },\r
-\r
- _doCancelClick: function() {\r
- this.close();\r
- }\r
- });\r
-});\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-*/\r
-\r
-/*\r
- * LoginBox allows user to login and logoff from GitHub API\r
- */\r
-define([\r
- "jquery",\r
- "jQueryUI"\r
-], function($) {\r
- $.widget("nitdoc.loginbox", {\r
- options: {\r
- icon: "resources/icons/github-icon.png",\r
- iconActive: "resources/icons/github-icon-green.png",\r
- iconAlt: "GitHub",\r
- signedinTxt: "Signed in Github",\r
- signedoutTxt: "Sign in Github",\r
- welcomeTxt: "Hello",\r
- upstreamTxt: "Upstream branch",\r
- baseTxt: "Base",\r
- signoffTxt: "Sign Off",\r
- usernameTxt: "Username",\r
- passwordTxt: "Password",\r
- repoTxt: "Repository",\r
- branchTxt: "Branch",\r
- signinTxt: "Sign In"\r
- },\r
-\r
- _create: function() {\r
- this.element.append(\r
- $("<span/>")\r
- .addClass("glyphicon glyphicon-off")\r
- //.click($.proxy(this.toggle, this))\r
- .attr({\r
- "data-container": "body",\r
- "data-toggle": "popover",\r
- "data-placement": "bottom",\r
- "data-content": "bottom",\r
- "data-html": "true",\r
- })\r
- );\r
-\r
- this.content = $("<div/>");\r
- this.loginBox = $("<div/>")\r
- .attr("id", "nitdoc-github-loginbox")\r
- .css("display", "none")\r
- .append(\r
- $(document.createElement("div"))\r
- .addClass("nitdoc-github-loginbox-arrow")\r
- .append(" ")\r
- )\r
- .append(this.content);\r
- this.element.append(this.loginBox);\r
- },\r
-\r
- /* public actions */\r
-\r
- displayLogout: function(origin, user) {\r
- this.content.empty();\r
- this.content.append(\r
- $("<h3/>").text(this.options.signedinTxt)\r
- )\r
- this.content.append(\r
- $("<div/>")\r
- .append(\r
- $("<h4/>")\r
- .append(this.options.welcomeTxt + " ")\r
- .append(\r
- $("<a/>")\r
- .attr("href", "https://github.com/" + user.login)\r
- .append(user.login)\r
- ).append(",")\r
- )\r
- .append(\r
- $("<label/>")\r
- .text("Upstream Branch")\r
- )\r
- .append(\r
- $("<a/>")\r
- .text(origin.user + ":" + origin.repo + ":" + origin.branch)\r
- .addClass("nitdoc-github-loginbox-githublink")\r
- .attr({\r
- title: "Open branch in GitHub",\r
- href: "https://github.com/" + origin.user + "/" + origin.repo + "/tree/" + origin.branch\r
- })\r
- )\r
- .append(\r
- $("<label/>")\r
- .attr("for", "github-base")\r
- .append("Your branch")\r
- )\r
- .append(\r
- $("<a/>")\r
- .text(user.login + ":" + user.repo + ":" + user.branch)\r
- .addClass("nitdoc-github-loginbox-githublink")\r
- .attr({\r
- title: "Open branch in GitHub",\r
- href: "https://github.com/" + user.login + "/" + user.repo + "/tree/" + user.branch\r
- })\r
- )\r
- .append(\r
- $("<button/>")\r
- .addClass("nitdoc-github-button")\r
- .addClass("nitdoc-github-cancel")\r
- .append(\r
- $("<img/>")\r
- .attr("src", this.options.icon)\r
- ).text(this.options.signoffTxt)\r
- .click($.proxy(this._doClickLogoff, this))\r
- )\r
- );\r
- $(".nitdoc-github-li-img").attr("src", this.options.iconActive);\r
- },\r
-\r
- displayLogin: function() {\r
- this.content.empty();\r
- this.content.append(\r
- $("<h3/>").text(this.options.signedoutTxt)\r
- )\r
- this.content.append(\r
- $("<form/>")\r
- .keyup($.proxy(this._doFormChange, this))\r
- .append(\r
- $("<div/>")\r
- .addClass("form-group")\r
- .append(\r
- $("<label/>")\r
- .attr("for", "nitdoc-github-login-field")\r
- .append(this.options.usernameTxt)\r
- )\r
- .addClass("form-group")\r
- .append(\r
- $("<input/>")\r
- .attr({\r
- id: "nitdoc-github-login-field",\r
- type: "text",\r
- "class": "form-control"\r
- })\r
- )\r
- )\r
- .append(\r
- $("<div/>")\r
- .addClass("form-group")\r
- .append(\r
- $("<label/>")\r
- .attr("for", "nitdoc-github-password-field")\r
- .append(this.options.passwordTxt)\r
- )\r
- .append(\r
- $("<input/>")\r
- .attr({\r
- id: "nitdoc-github-password-field",\r
- type: "password",\r
- "class": "form-control"\r
- })\r
- )\r
- )\r
- .append(\r
- $("<div/>")\r
- .addClass("form-group")\r
- .append(\r
- $("<label/>")\r
- .attr("for", "nitdoc-github-repo-field")\r
- .append(this.options.repoTxt)\r
- )\r
- .append(\r
- $("<input/>")\r
- .attr({\r
- id: "nitdoc-github-repo-field",\r
- type: "text",\r
- "class": "form-control"\r
- })\r
- )\r
- )\r
- .append(\r
- $("<div/>")\r
- .addClass("form-group")\r
- .append(\r
- $("<label/>")\r
- .attr("for", "nitdoc-github-branch-field")\r
- .append(this.options.branchTxt)\r
- )\r
- .append(\r
- $("<input/>")\r
- .attr({\r
- id: "nitdoc-github-branch-field",\r
- type: "text",\r
- "class": "form-control"\r
- })\r
- )\r
- )\r
- .append(\r
- $("<button/>")\r
- .addClass("nitdoc-github-button btn btn-primary btn-lg pull-right")\r
- .attr("disabled", "disabled")\r
- .append(\r
- $("<img/>")\r
- .attr("src", this.options.icon)\r
- ).text(this.options.signinTxt)\r
- .click($.proxy(this._doClickLogin, this))\r
- )\r
- );\r
- $(".nitdoc-github-li-img").attr("src", this.options.icon);\r
- },\r
-\r
- toggle: function() {\r
- if(this.loginBox.is(':hidden')) {\r
- this.loginBox.show();\r
- if ($('#nitdoc-github-login-field').is(':visible')) { $('#nitdoc-github-login-field').focus(); }\r
- } else {\r
- this.loginBox.hide();\r
- }\r
- },\r
-\r
- /* events */\r
-\r
- _doClickLogoff: function(event) {\r
- this._trigger("_logoff", event);\r
- },\r
-\r
- _doClickLogin: function(event) {\r
- this._trigger("_login", event, {\r
- login: $('#nitdoc-github-login-field').val(),\r
- password: $('#nitdoc-github-password-field').val(),\r
- repo: $('#nitdoc-github-repo-field').val(),\r
- branch: $('#nitdoc-github-branch-field').val()\r
- });\r
- return false;\r
- },\r
-\r
- _doFormChange: function(event) {\r
- login = $('#nitdoc-github-login-field').val();\r
- password = $('#nitdoc-github-password-field').val();\r
- repo = $('#nitdoc-github-repo-field').val();\r
- branch = $('#nitdoc-github-branch-field').val();\r
- if(login && password && repo && branch) {\r
- this.loginBox.find("form .nitdoc-github-button").removeAttr("disabled");\r
- } else {\r
- this.loginBox.find("form .nitdoc-github-button").attr("disabled", "disabled");\r
- }\r
- }\r
- });\r
-});\r
+++ /dev/null
-/* This file is part of NIT ( http://www.nitlanguage.org ).\r
-\r
- Licensed under the Apache License, Version 2.0 (the "License");\r
- you may not use this file except in compliance with the License.\r
- You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
- Documentation generator for the nit language.\r
- Generate API documentation in HTML format from nit source code.\r
-*/\r
-\r
-define([\r
- "jquery",\r
- "jQueryUI"\r
-], function($) {\r
- $.widget("nitdoc.modalbox", {\r
- options: {\r
- id: "nitdoc-dialog",\r
- classes: "nitdoc-dialog",\r
- css: {},\r
- title: "Title",\r
- isError: false,\r
- },\r
-\r
- _create: function() {\r
- this._addFade();\r
- this._makeDialog();\r
- },\r
-\r
- open: function() {\r
- this._dialog\r
- .show()\r
- .css({\r
- top: "50%",\r
- marginTop: -(this._dialog.outerHeight() / 2) + "px",\r
- left: "50%",\r
- marginLeft: -(this._dialog.outerWidth() / 2) + "px"\r
- })\r
- .find(".nitdoc-dialog-buttons button:first").focus();\r
-\r
- this._fade.show();\r
- },\r
-\r
- close: function() {\r
- this._fade.hide();\r
- this._dialog.hide();\r
- },\r
-\r
- _addFade: function() {\r
- this._fade = $("<div/>")\r
- .hide()\r
- .attr("id", "nitdoc-dialog-fade-" + this.options.id)\r
- .addClass("nitdoc-dialog-fade");\r
- $("body").append(this._fade);\r
- },\r
-\r
- _makeDialog: function() {\r
- this._dialog = $("<div/>")\r
- .hide()\r
- .attr("id", this.options.id)\r
- .addClass(this.options.classes)\r
- .css(this.options.css)\r
- .append(\r
- $("<div/>")\r
- .addClass("nitdoc-dialog-header")\r
- .append(\r
- $("<h3/>")\r
- .text(this.options.title)\r
- )\r
- .append(\r
- $("<button/>")\r
- .addClass("nitdoc-dialog-close")\r
- .append("x")\r
- .click($.proxy(this.close, this))\r
- )\r
- )\r
- .append(\r
- $("<div/>")\r
- .addClass("nitdoc-dialog-content")\r
- .html(this.element)\r
- )\r
- .append(\r
- $("<div/>")\r
- .addClass("nitdoc-dialog-buttons")\r
- .append(\r
- $("<button/>")\r
- .append("Ok")\r
- .click($.proxy(this.close, this))\r
- )\r
- );\r
- if(this.options.isError) {\r
- this._dialog.addClass("nitdoc-dialog-error");\r
- }\r
- $("body").append(this._dialog);\r
- }\r
- });\r
-});\r
+++ /dev/null
-/* 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 = $("<table/>")
- .attr("id", this.options.tableID)
- .css(this.options.tableCSS)
- .css("min-width", this.element.outerWidth());
- $("body").append(this._table);
- // make table disappear when a click occurs outside
- $(document).click($.proxy(this.closeTable, this));
- },
-
- /* events */
-
- _doKeyDown: function(event) {
- switch(event.keyCode) {
- case 38: // Up
- this._selectPrev();
- return false;
- case 40: // Down
- this._selectNext();
- return false;
- default:
- return true;
- }
- },
-
- _doKeyUp: function(event) {
- switch(event.keyCode) {
- case 38: // Up
- case 40: // Down
- break;
- case 13: // Enter
- this._loadResult();
- return false;
- case 27: // Escape
- this.element.blur();
- this.closeTable();
- return true;
- default: // Other keys
- return true;
- }
- },
-
- _doInput: function(event) {
- Utils.delayEvent($.proxy(this.search, this));
- },
-
- /* Result lookup */
-
- _getResults: function(query) {
- var results = {};
- results.matches = [];
- for(var entry in this.options.list) {
- if(!entry.startsWith(query, true)) {
- continue;
- }
- var cat = {
- name: entry,
- entries: this.options.list[entry]
- };
- results.matches[results.matches.length] = cat;
-
- if(entry == query) {
- cat.rank = 3;
- } else if(entry.toUpperCase() == query.toUpperCase()) {
- cat.rank = 2;
- } else {
- cat.rank = 1 + query.dice(entry);
- }
- }
- results.matches.sort(this._rankSorter);
- results.partials = new Array();
- if(results.matches.length == 0) {
- for(var entry in this.options.list) {
- var cat = {
- name: entry,
- entries: this.options.list[entry]
- }
- cat.rank = query.dice(entry);
- if(cat.rank > 0) {
- results.partials[results.partials.length] = cat;
- }
- }
- results.partials.sort(this._rankSorter);
- }
- return results;
- },
-
- _rankSorter: function(a, b){
- if(a.rank < b.rank) {
- return 1;
- } else if(a.rank > b.rank) {
- return -1;
- }
- return 0;
- },
-
- /* Results table */
-
- search: function() {
- var query = this.element.val();
- if(query) {
- var results = this._getResults(query);
- this.openTable(query, results);
- }
- },
-
- openTable: function(query, results) {
- this._table.empty();
- this._rows = [];
- this._index = -1;
-
- var resultSet = results.matches;
- if(resultSet.length == 0) {
- resultSet = results.partials
- }
-
- for(var i in resultSet) {
- var cat = resultSet[i];
- var result = cat.entries[0];
- this.addRow(cat.name, result.txt, result.url, this.options.rowCatClass)
- for(var j = 1; j < cat.entries.length; j++) {
- var result = cat.entries[j];
- this.addRow(cat.name, result.txt, result.url, this.options.rowSubClass)
- }
- }
-
- if(this._rows.length >= this.options.maxSize) {
- this.addOverflowUp();
- this.addOverflowDown();
- }
- if(results.matches.length == 0) {
- this.addNoResultRow();
- }
-
- if(resultSet.length > 0) {
- this._setIndex(0);
- }
- this._table.show();
- this._autosizeTable();
- },
-
- closeTable: function(target) {
- if(target != this.element && target != this._table) {
- this._table.hide();
- }
- },
-
- addRow: function(name, txt, url, cls) {
- var row = $("<tr/>")
- .addClass(this.options.rowClass)
- .data("searchDetails", {name: name, url: url})
- .data("index", this._rows.length)
- .append(
- $("<td/>")
- .html(name)
- .addClass(cls)
- )
- .append(
- $("<td/>")
- .html(txt + " »")
- .addClass(this.options.infoClass)
- )
- .mouseover($.proxy(this._mouseOverRow, this))
- .click($.proxy(this._clickRow, this))
- this._rows.push(row);
- if(this._rows.length >= this.options.maxSize) {
- row.hide();
- }
- this._table.append(row);
- },
-
- addOverflowUp: function() {
- this._table.prepend(
- $("<tr/>")
- .addClass(this.options.rowOverflowClass)
- .append(
- $("<td/>")
- .attr("colspan", 2)
- .html(this.options.overflowUpHtml)
- )
- .click($.proxy(this._clickPrev, this))
- );
- },
-
- addOverflowDown: function() {
- this._table.append(
- $("<tr/>")
- .addClass(this.options.rowOverflowClass)
- .addClass(this.options.rowOverflowActive)
- .append(
- $("<td/>")
- .attr("colspan", 2)
- .html(this.options.overflowDownHtml)
- )
- .click($.proxy(this._clickNext, this))
- );
- },
-
- addNoResultRow: function() {
- this._table.prepend(
- $("<tr/>")
- .addClass(this.options.rowNoResultClass)
- .append(
- $("<td/>")
- .attr("colspan", "2")
- .text(this.options.noresultText)
- )
- );
- },
-
- _autosizeTable: function() {
- this._table.position({
- my: "right top",
- at: "right bottom",
- of: this.element
- });
- },
-
- _hasIndex: function(index) {
- return index >= 0 && index < this._rows.length;
- },
-
- _hasPrev: function(index) {
- return index - 1 >= 0;
- },
-
- _hasNext: function(index) {
- return index + 1 < this._rows.length;
- },
-
- _setIndex: function(index) {
- if(this._hasIndex(this._index)) {
- this._rows[this._index].removeClass(this.options.rowActiveClass);
- }
- this._index = index;
- if(this._hasIndex(this._index)) {
- this._rows[this._index].addClass(this.options.rowActiveClass);
- }
- },
-
- _selectPrev: function() {
- if(this._hasPrev(this._index)) {
- this._setIndex(this._index - 1);
- if(!this._rows[this._index].is(":visible")) {
- this._table.find("tr." + this.options.rowClass + ":visible").last().hide();
- this._table.find("tr." + this.options.rowOverflowClass).addClass(this.options.rowOverflowActive);
- this._rows[this._index].show();
- if(!this._hasPrev(this._index)) {
- this._table.find("tr." + this.options.rowOverflowClass).removeClass(this.options.rowOverflowActive);
- }
- this._autosizeTable();
- }
- }
- },
-
- _selectNext: function() {
- if(this._hasNext(this._index)) {
- this._setIndex(this._index + 1);
- if(!this._rows[this._index].is(":visible")) {
- this._table.find("tr." + this.options.rowClass + ":visible").first().hide();
- this._table.find("tr." + this.options.rowOverflowClass).addClass(this.options.rowOverflowActive);
- this._rows[this._index].show();
- if(!this._hasNext(this._index)) {
- this._table.find("tr." + this.options.rowOverflowClass).removeClass(this.options.rowOverflowActive);
- }
- this._autosizeTable();
- }
- }
- },
-
- // Load selected search result page
- _loadResult: function() {
- if(this._index > -1) {
- window.location = this._rows[this._index].data("searchDetails").url;
- return;
- }
- if(this.element.val().length == 0) { return; }
-
- window.location = this.options.gotoPage + "#q=" + this.element.val();
- if(window.location.href.indexOf(this.options.gotoPage) > -1) {
- location.reload();
- }
- },
-
- /* table events */
-
- _clickNext: function(event) {
- event.stopPropagation();
- this._selectNext();
- },
-
- _clickPrev: function(event) {
- event.stopPropagation();
- this._selectPrev();
- },
-
- _clickRow: function(event) {
- window.location = $(event.currentTarget).data("searchDetails")["url"];
- },
-
- _mouseOverRow: function(event) {
- this._setIndex($(event.currentTarget).data("index"));
- }
-});
-
-var searchField = $("<input/>")
-.addClass("form-control input-sm")
-.attr({
- id: "nitdoc-qs-field",
- type: "text",
- placeholder: "Search..."
-})
-
-$("#topmenu-collapse").append(
- $("<div>")
- .addClass("navbar-form navbar-right")
- .append(
- $("<div>")
- .addClass("form-group")
- .append(searchField)
- )
-);
-
-searchField.quicksearch({
- list: this.nitdocQuickSearchRawList
-});
+++ /dev/null
-# 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.
-
-# Nitdoc generation framework.
-module doc
-
-import doc_base
-import doc_phases
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Base entities shared by all the nitdoc code.
-module doc_base
-
-import toolcontext
-import model_ext
-import model::model_collect
-
-# The model of a Nitdoc documentation.
-#
-# `DocModel` contains the list of the `DocPage` to be generated.
-#
-# The model is populated through `DocPhase` to be constructed.
-# It is a placeholder to share data between each phase.
-class DocModel
-
- # Model to generate the documentation for
- var model: Model
-
- # Main module of the sources behing documented
- var mainmodule: MModule
-
- # Model filters to apply
- var filter: ModelFilter
-
- # `DocPage` composing the documentation associated to their ids.
- #
- # This is where `DocPhase` store and access pages to produce documentation.
- #
- # See `add_page`.
- var pages: Map[String, DocPage] = new HashMap[String, DocPage]
-
- # Add a `page` to this documentation.
- fun add_page(page: DocPage) do
- if pages.has_key(page.id) then
- print "Warning: multiple page with the same id `{page.id}`"
- end
- pages[page.id] = page
- end
-end
-
-# A documentation page abstraction.
-#
-# The page contains a link to the `root` of the `DocComposite` that compose the
-# the page.
-class DocPage
-
- # Page uniq id.
- #
- # The `id` is used as name for the generated file corresponding to the page
- # (if any).
- # Because multiple pages can be generated in the same directory it should be
- # uniq.
- #
- # The `id` can also be used to establish links between pages (HTML links,
- # HTML anchors, vim links, etc.).
- var id: String is writable
-
- # Title of this page.
- var title: String is writable
-
- # Root element of the page.
- #
- # `DocPhase` access the structure of the page from the `DocRoot`.
- var root = new DocRoot
-
- redef fun to_s do return title
-
- # Pretty prints the content of this page.
- fun pretty_print: Writable do
- var res = new Template
- res.addn "{class_name} {title}"
- for child in root.children do
- child.pretty_print_in(res)
- end
- return res
- end
-end
-
-# `DocPage` elements that can be nested in another.
-#
-# `DocComposite` is an abstraction for everything that go in a `DocPage` like
-# sections, articles, images, lists, graphs...
-#
-# It provides base services for nesting mechanisms following the
-# *Composite pattern*.
-# The composed structure is a tree from a `DocRoot` that can be manipulated
-# recursively.
-abstract class DocComposite
-
- # Parent element.
- var parent: nullable DocComposite = null is writable
-
- # Element uniq id.
- #
- # The `id` is used as name for the generated element (if any).
- # Because multiple elements can be generated in the same container
- # it should be uniq.
- #
- # The `id` can also be used to establish links between elements
- # (HTML links, HTML anchors, vim links, etc.).
- var id: String is writable
-
- # Item title if any.
- var title: nullable String is writable
-
- # Does `self` have a `parent`?
- fun is_root: Bool do return parent == null
-
- # Children elements contained in `self`.
- #
- # Children are ordered, this order can be changed by the `DocPhase`.
- var children = new Array[DocComposite]
-
- # Is `self` not displayed in the page.
- #
- # By default, empty elements are hidden.
- fun is_hidden: Bool do return children.is_empty
-
- # Title used in table of content if any.
- var toc_title: nullable String is writable, lazy do return title
-
- # Is `self` hidden in the table of content?
- var is_toc_hidden: Bool is writable, lazy do
- return toc_title == null or is_hidden
- end
-
- # Add a `child` to `self`.
- #
- # Shortcut for `children.add`.
- fun add_child(child: DocComposite) do
- child.parent = self
- children.add child
- end
-
- # Depth of `self` in the composite tree.
- fun depth: Int do
- var parent = self.parent
- if parent == null then return 0
- return parent.depth + 1
- end
-
- # Pretty prints this composite recursively.
- fun pretty_print: Writable do
- var res = new Template
- pretty_print_in(res)
- return res
- end
-
- # Appends the Pretty print of this composite in `res`.
- private fun pretty_print_in(res: Template) do
- res.add "\t" * depth
- res.add "#" * depth
- res.addn " {id}"
- for child in children do child.pretty_print_in(res)
- end
-end
-
-# The `DocComposite` element that contains all the other.
-#
-# The root uses a specific subclass to provide different a different behavior
-# than other `DocComposite` elements.
-class DocRoot
- noautoinit
- super DocComposite
-
- redef var id = "<root>"
- redef var title = "<root>"
-
- # No op for `RootSection`.
- redef fun parent=(p) do end
-end
-
-# Base page elements.
-
-# `DocSection` are used to break the documentation page into meaningfull parts.
-#
-# The content of the documentation summary is based on the section structure
-# contained in the DocComposite tree.
-class DocSection
- super DocComposite
-end
-
-# `DocArticle` are pieces of documentation.
-#
-# They maintains the content (text, list, image...) of a documentation page.
-class DocArticle
- super DocComposite
-end
-
-# A DocPhase is a step in the production of a Nitdoc documentation.
-#
-# Phases work from a `DocModel`.
-# Specific phases are used to populate, organize, enhance and render the content
-# of the documentation pages.
-#
-# See `doc_phases` for available DocPhase.
-class DocPhase
-
- # Link to the ToolContext to access Nitdoc tool options.
- var ctx: ToolContext
-
- # `DocModel` used by this phase to work.
- var doc: DocModel
-
- # Starting point of a `DocPhase`.
- #
- # This is where the behavior of the phase is implemented.
- # Phases can populate, edit or render the `doc` from here.
- fun apply is abstract
-end
-
-redef class ToolContext
-
- # Directory where the Nitdoc is rendered.
- var opt_dir = new OptionString("Output directory", "-d", "--dir")
-
- # Shortcut for `opt_dir.value` with default "doc".
- var output_dir: String is lazy do return opt_dir.value or else "doc"
-
- redef init do
- super
- option_context.add_option(opt_dir)
- end
-end
-
-# Catalog properties by kind.
-class PropertiesByKind
- # The virtual types.
- var virtual_types = new PropertyGroup[MVirtualTypeProp]("Virtual types")
-
- # The constructors.
- var constructors = new PropertyGroup[MMethod]("Contructors")
-
- # The attributes.
- var attributes = new PropertyGroup[MAttribute]("Attributes")
-
- # The methods.
- var methods = new PropertyGroup[MMethod]("Methods")
-
- # The inner classes.
- var inner_classes = new PropertyGroup[MInnerClass]("Inner classes")
-
- # All the groups.
- #
- # Sorted in the order they are displayed to the user.
- var groups: SequenceRead[PropertyGroup[MProperty]] = [
- virtual_types,
- constructors,
- attributes,
- methods,
- inner_classes: PropertyGroup[MProperty]]
-
- # Add each the specified property to the appropriate list.
- init with_elements(properties: Collection[MProperty]) do add_all(properties)
-
- # Add the specified property to the appropriate list.
- fun add(property: MProperty) do
- if property isa MMethod then
- if property.is_init then
- constructors.add property
- else
- methods.add property
- end
- else if property isa MVirtualTypeProp then
- virtual_types.add property
- else if property isa MAttribute then
- attributes.add property
- else if property isa MInnerClass then
- inner_classes.add property
- else
- abort
- end
- end
-
- # Add each the specified property to the appropriate list.
- fun add_all(properties: Collection[MProperty]) do
- for p in properties do add(p)
- end
-
- # Sort each group with the specified comparator.
- fun sort_groups(comparator: Comparator) do
- for g in groups do comparator.sort(g)
- end
-end
-
-# An ordered list of properties of the same kind.
-class PropertyGroup[E: MProperty]
- super Array[E]
-
- # The title of the group, as displayed to the user.
- var title: String
-end
-
-redef class MEntity
- # ID used as a unique ID and in file names.
- #
- # **Must** match the following (POSIX ERE) regular expression:
- #
- # ~~~POSIX ERE
- # ^[A-Za-z_][A-Za-z0-9._-]*$
- # ~~~
- #
- # That way, the ID is always a valid URI component and a valid XML name.
- fun nitdoc_id: String do return full_name.to_cmangle
-
- # Name displayed in console for debug and tests.
- fun nitdoc_name: String do return name.html_escape
-end
-
-redef class MModule
-
- # Avoid id conflict with group
- redef fun nitdoc_id do
- var mgroup = self.mgroup
- if mgroup == null then return super
- return "{mgroup.full_name}::{full_name}".to_cmangle
- end
-end
-
-redef class MClassDef
- redef fun nitdoc_name do return mclass.nitdoc_name
-end
-
-redef class MPropDef
- redef fun nitdoc_name do return mproperty.nitdoc_name
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Parsing of commands understood by documentation tools.
-#
-# This can be through:
-# * `nitx` commands like `code: MEntity::name`
-# * `nitdoc` wikilinks like `[[doc: MEntity::name]]`
-module doc_commands
-
-#
-class DocCommandParser
-
- # List of allowed command names for this parser
- var allowed_commands: Array[String] = [ "doc", "list", "param", "return",
- "new", "call", "code", "graph"] is writable
-
- # Parse `string` as a DocCommand
- #
- # Returns `null` if the string cannot be parsed.
- #
- # ~~~
- # var parser = new DocCommandParser
- #
- # var command = parser.parse("doc: core::Array")
- # assert command isa CommentCommand
- # assert command.arg == "core::Array"
- #
- # command = parser.parse(":") # syntax error
- # assert command == null
- # assert parser.errors.not_empty
- # ~~~
- fun parse(string: String): nullable DocCommand do
- var pos = 0
- var tmp = new FlatBuffer
- errors.clear
-
- # Parse command name
- pos = string.read_until(tmp, pos, ':')
- var name = tmp.write_to_string.trim
-
- # Check allowed commands
- if name.is_empty then
- error("empty command name", 0)
- return null
- end
- if not allowed_commands.has(name) then
- error("unknown command name", 0)
- return null
- end
-
- # Build the command
- var command = new_command(name, string)
- if command == null then
- error("unknown command name", 0)
- return null
- end
-
- # Parse the argument
- tmp.clear
- pos = string.read_until(tmp, pos + 1, '|')
- var arg = tmp.write_to_string.trim
- if arg.is_empty then
- error("empty command arg", pos)
- return null
- end
- command.arg = arg
-
- # Parse command options
- while pos < string.length do
- # Parse option name
- tmp.clear
- pos = string.read_until(tmp, pos + 1, ':', ',')
- var oname = tmp.write_to_string.trim
- var oval = ""
- if oname.is_empty then break
- # Parse option value
- if pos < string.length and string[pos] == ':' then
- tmp.clear
- pos = string.read_until(tmp, pos + 1, ',')
- oval = tmp.write_to_string.trim
- end
- command.opts[oname] = oval
- # TODO Check options
- end
-
- return command
- end
-
- # Init a new DocCommand from its `name`
- #
- # You must redefine this method to add new custom commands.
- fun new_command(name, string: String): nullable DocCommand do
- if name == "doc" then return new CommentCommand(string)
- if name == "list" then return new ListCommand(string)
- if name == "param" then return new ParamCommand(string)
- if name == "return" then return new ReturnCommand(string)
- if name == "new" then return new NewCommand(string)
- if name == "call" then return new CallCommand(string)
- if name == "code" then return new CodeCommand(string)
- if name == "graph" then return new GraphCommand(string)
- return null
- end
-
- # Errors and warnings from last call to `parse`
- var errors = new Array[DocMessage]
-
- # Generate an error
- fun error(message: String, col: nullable Int) do
- errors.add new DocMessage(1, message, col)
- end
-
- # Generate a warning
- fun warning(message: String, col: nullable Int) do
- errors.add new DocMessage(2, message, col)
- end
-end
-
-# A message generated by the DocCommandParser
-class DocMessage
-
- # Message severity
- #
- # 1- Error
- # 2- Warning
- var level: Int
-
- # Message explanatory string
- var message: String
-
- # Related column in original string if any
- var col: nullable Int
-
- redef fun to_s do
- var str = new FlatBuffer
- if level == 1 then
- str.append "Error: "
- else
- str.append "Warning: "
- end
- str.append message
- var col = self.col
- if col != null then
- str.append " (col: {col})"
- end
- return str.write_to_string
- end
-end
-
-redef class Text
- # Read `self` as raw text until `nend` and append it to the `out` buffer.
- private fun read_until(out: FlatBuffer, start: Int, nend: Char...): Int do
- var pos = start
- while pos < length do
- var c = self[pos]
- var end_reached = false
- for n in nend do
- if c == n then
- end_reached = true
- break
- end
- end
- if end_reached then break
- out.add c
- pos += 1
- end
- return pos
- end
-end
-
-# A command aimed at a documentation tool like `nitdoc` or `nitx`.
-#
-# `DocCommand` are generally of the form `command: arg | opt1: val1, opt2: val2`.
-abstract class DocCommand
-
- # Original command string.
- var string: String
-
- # Command name.
- var name: String is noinit
-
- # Command arguments.
- var arg: String is noinit, writable
-
- # Command options.
- var opts = new HashMap[String, String] is writable
-
- redef fun to_s do
- if opts.is_empty then
- return "{name}: {arg}"
- end
- return "{name}: {arg} | {opts.join(", ", ": ")}"
- end
-end
-
-# A `DocCommand` that includes the documentation article of a `MEntity`.
-#
-# Syntax: `doc: MEntity::name`.
-class CommentCommand
- super DocCommand
-
- redef var name = "doc"
-end
-
-# A `DocCommand` that includes a list of something.
-#
-# Syntax: `list:kind: <arg>`.
-class ListCommand
- super DocCommand
-
- redef var name = "list"
-end
-
-# A `DocCommand` that includes the list of methods tanking a `MType` as parameter.
-#
-# Syntax: `param: MType`.
-class ParamCommand
- super DocCommand
-
- redef var name = "param"
-end
-
-# A `DocCommand` that includes the list of methods returning a `MType` as parameter.
-#
-# Syntax: `return: MType`.
-class ReturnCommand
- super DocCommand
-
- redef var name = "return"
-end
-
-# A `DocCommand` that includes the list of methods creating new instances of a specific `MType`
-#
-# Syntax: `new: MType`.
-class NewCommand
- super DocCommand
-
- redef var name = "new"
-end
-
-# A `DocCommand` that includes the list of methods calling a specific `MProperty`.
-#
-# Syntax: `call: MEntity::name`.
-class CallCommand
- super DocCommand
-
- redef var name = "call"
-end
-
-# A `DocCommand` that includes the source code of a `MEntity`.
-#
-# Syntax:
-# * `code: MEntity::name`
-# * `./src/file.nit` to include source code from a file.
-# * `./src/file.nit:1,2--3,4` to select code between positions.
-class CodeCommand
- super DocCommand
-
- redef var name = "code"
-end
-
-# A `DocCommand` that display an graph for a `MEntity`.
-#
-# Syntax:
-# * `graph: MEntity::name`
-class GraphCommand
- super DocCommand
-
- redef var name = "graph"
-end
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Render the DocModel pages as HTML pages.
-#
-# FIXME this module is all f*cked up to maintain compatibility with
-# the original `doc_templates` and `doc_model` modules.
-# This will change in further refactorings.
-module doc_html
-
-import doc_structure
-import doc_hierarchies
-import doc_intros_redefs
-import doc_graphs
-import html_templates
-
-redef class ToolContext
-
- # File pattern used to link documentation to source code.
- var opt_source = new OptionString("Format to link source code (%f for filename, " +
- "%l for first line, %L for last line)", "--source")
-
- # Use a shareurl instead of copy shared files.
- #
- # This is usefull if you don't want to store the Nitdoc templates with your
- # documentation.
- var opt_shareurl = new OptionString("Use shareurl instead of copy shared files", "--shareurl")
-
- # Use a custom title for the homepage.
- var opt_custom_title = new OptionString("Custom title for homepage", "--custom-title")
-
- # Display a custom brand or logo in the documentation top menu.
- var opt_custom_brand = new OptionString("Custom link to external site", "--custom-brand")
-
- # Display a custom introduction text before the packages overview.
- var opt_custom_intro = new OptionString("Custom intro text for homepage", "--custom-overview-text")
- # Display a custom footer on each documentation page.
- #
- # Generally used to display the documentation or product version.
- var opt_custom_footer = new OptionString("Custom footer text", "--custom-footer-text")
-
- # Piwik tracker URL.
- #
- # If you want to monitor your visitors.
- var opt_piwik_tracker = new OptionString("Piwik tracker URL (ex: `nitlanguage.org/piwik/`)", "--piwik-tracker")
-
- # Piwik tracker site id.
- var opt_piwik_site_id = new OptionString("Piwik site ID", "--piwik-site-id")
-
- # These options are not currently used in Nitdoc.
-
- # FIXME redo the plugin
- var opt_github_upstream = new OptionString("Git branch where edited commits will be pulled into (ex: user:repo:branch)", "--github-upstream")
- # FIXME redo the plugin
- var opt_github_base_sha1 = new OptionString("Git sha1 of base commit used to create pull request", "--github-base-sha1")
- # FIXME redo the plugin
- var opt_github_gitdir = new OptionString("Git working directory used to resolve path name (ex: /home/me/mypackage/)", "--github-gitdir")
-
- # Do not produce HTML files
- var opt_no_render = new OptionBool("Do not render HTML files", "--no-render")
-
- redef init do
- super
-
- option_context.add_option(
- opt_source, opt_share_dir, opt_shareurl, opt_custom_title,
- opt_custom_footer, opt_custom_intro, opt_custom_brand,
- opt_github_upstream, opt_github_base_sha1, opt_github_gitdir,
- opt_piwik_tracker, opt_piwik_site_id,
- opt_no_render)
- end
-
- redef fun process_options(args) do
- super
- var upstream = opt_github_upstream
- var base_sha = opt_github_base_sha1
- var git_dir = opt_github_gitdir
- var opts = [upstream.value, base_sha.value, git_dir.value]
- if not opts.has_only(null) and opts.has(null) then
- print "Option Error: options {upstream.names.first}, " +
- "{base_sha.names.first} and {git_dir.names.first} " +
- "are required to enable the GitHub plugin"
- exit 1
- end
- end
-end
-
-# Render the Nitdoc as a HTML website.
-class RenderHTMLPhase
- super DocPhase
-
- # Used to sort sidebar elements by name.
- var name_sorter = new MEntityNameSorter
-
- redef fun apply do
- if ctx.opt_no_render.value then return
- init_output_dir
- for page in doc.pages.values do
- page.render(self, doc).write_to_file("{ctx.output_dir.to_s}/{page.html_url}")
- end
- end
-
- # Creates the output directory and imports assets files form `resources/`.
- fun init_output_dir do
- # create destination dir if it's necessary
- var output_dir = ctx.output_dir
- if not output_dir.file_exists then output_dir.mkdir
- # locate share dir
- var sharedir = ctx.share_dir / "nitdoc"
- # copy shared files
- if ctx.opt_shareurl.value == null then
- sys.system("cp -r -- {sharedir.to_s.escape_to_sh}/* {output_dir.to_s.escape_to_sh}/")
- else
- sys.system("cp -r -- {sharedir.to_s.escape_to_sh}/resources/ {output_dir.to_s.escape_to_sh}/resources/")
- end
-
- end
-
- # Returns a HTML link for a given `location`.
- fun html_source_link(location: nullable Location): nullable String
- do
- if location == null then return null
- var source = ctx.opt_source.value
- if source == null then
- var url = location.file.filename.simplify_path
- return "<a target='_blank' title='Show source' href=\"{url.html_escape}\">View Source</a>"
- end
- # THIS IS JUST UGLY ! (but there is no replace yet)
- var x = source.split_with("%f")
- source = x.join(location.file.filename.simplify_path)
- x = source.split_with("%l")
- source = x.join(location.line_start.to_s)
- x = source.split_with("%L")
- source = x.join(location.line_end.to_s)
- source = source.simplify_path
- return "<a target='_blank' title='Show source' href=\"{source.to_s.html_escape}\">View Source</a>"
- end
-end
-
-redef class DocPage
-
- # Render the page as a html template.
- private fun render(v: RenderHTMLPhase, doc: DocModel): Writable do
- var shareurl = "."
- if v.ctx.opt_shareurl.value != null then
- shareurl = v.ctx.opt_shareurl.value.as(not null)
- end
-
- # init page options
- self.shareurl = shareurl
- self.footer = v.ctx.opt_custom_footer.value
- self.body_attrs.add(new TagAttribute("data-bootstrap-share", shareurl))
-
- # build page
- init_title(v, doc)
- init_topmenu(v, doc)
- init_content(v, doc)
- init_sidebar(v, doc)
-
- # piwik tracking
- var tracker_url = v.ctx.opt_piwik_tracker.value
- var site_id = v.ctx.opt_piwik_site_id.value
- if tracker_url != null and site_id != null then
- self.scripts.add new TplPiwikScript(tracker_url, site_id)
- end
- return self
- end
-
- # FIXME diff hack
- # all properties below are roughly copied from `doc_pages`
-
- # Build page title string
- fun init_title(v: RenderHTMLPhase, doc: DocModel) do end
-
- # Build top menu template if any.
- fun init_topmenu(v: RenderHTMLPhase, doc: DocModel) do
- topmenu = new DocTopMenu
- topmenu.brand = v.ctx.opt_custom_brand.value
- var title = "Overview"
- if v.ctx.opt_custom_title.value != null then
- title = v.ctx.opt_custom_title.value.to_s
- end
- topmenu.add_li new ListItem(new Link("index.html", title))
- topmenu.add_li new ListItem(new Link("search.html", "Index"))
- topmenu.active_item = topmenu.items.first
- end
-
- # Build page sidebar if any.
- fun init_sidebar(v: RenderHTMLPhase, doc: DocModel) do
- sidebar = new DocSideBar
- sidebar.boxes.add new DocSideBox("Summary", html_toc)
- end
-
- # Build page content template.
- fun init_content(v: RenderHTMLPhase, doc: DocModel) do
- root.init_html_render(v, doc, self)
- end
-end
-
-redef class OverviewPage
- redef var html_url = "index.html"
-
- redef fun init_title(v, doc) do
- title = "Overview"
- if v.ctx.opt_custom_title.value != null then
- title = v.ctx.opt_custom_title.value.to_s
- end
- end
-end
-
-redef class SearchPage
- redef var html_url = "search.html"
- redef fun init_title(v, doc) do title = "Index"
-
- redef fun init_topmenu(v, doc) do
- super
- topmenu.active_item = topmenu.items.last
- end
-
- redef fun init_sidebar(v, doc) do end
-end
-
-redef class MEntityPage
- redef var html_url is lazy do
- if mentity isa MGroup and mentity.mdoc != null then
- return "api_{mentity.nitdoc_url}"
- end
- return mentity.nitdoc_url
- end
-
- redef fun init_title(v, doc) do title = mentity.html_name
-end
-
-# FIXME all clases below are roughly copied from `doc_pages` and adapted to new
-# doc phases. This is to preserve the compatibility with the current
-# `doc_templates` module.
-
-redef class ReadmePage
- redef var html_url is lazy do return mentity.nitdoc_url
-
- redef fun init_topmenu(v, doc) do
- super
- var mpackage = mentity.mpackage
- if not mentity.is_root then
- topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
- end
- topmenu.add_li new ListItem(new Link(html_url, mpackage.html_name))
- topmenu.active_item = topmenu.items.last
- end
-
- redef fun init_sidebar(v, doc) do
- super
- var api_lnk = """<a href="api_{{{mentity.nitdoc_url}}}">Go to API</a>"""
- sidebar.boxes.unshift new DocSideBox(api_lnk, "")
- end
-end
-
-redef class MGroupPage
- redef fun init_topmenu(v, doc) do
- super
- var mpackage = mentity.mpackage
- if not mentity.is_root then
- topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
- end
- topmenu.add_li new ListItem(new Link(html_url, mpackage.html_name))
- topmenu.active_item = topmenu.items.last
- end
-
- redef fun init_sidebar(v, doc) do
- super
- # README link
- if mentity.mdoc != null then
- var doc_lnk = """<a href="{{{mentity.nitdoc_url}}}">Go to README</a>"""
- sidebar.boxes.unshift new DocSideBox(doc_lnk, "")
- end
- # MClasses list
- var mclasses = new HashSet[MClass]
- mclasses.add_all intros
- mclasses.add_all redefs
- if mclasses.is_empty then return
- var list = new UnorderedList
- list.css_classes.add "list-unstyled list-labeled"
- var sorted = mclasses.to_a
- v.name_sorter.sort(sorted)
- for mclass in sorted do
- list.add_li tpl_sidebar_item(mclass)
- end
- sidebar.boxes.add new DocSideBox("All classes", list)
- sidebar.boxes.last.is_open = false
- end
-
- private fun tpl_sidebar_item(def: MClass): ListItem do
- var classes = def.intro.css_classes
- if intros.has(def) then
- classes.add "intro"
- else
- classes.add "redef"
- end
- var lnk = new Template
- lnk.add new DocHTMLLabel.with_classes(classes)
- lnk.add def.html_link
- return new ListItem(lnk)
- end
-end
-
-redef class MModulePage
- redef fun init_topmenu(v, doc) do
- super
- var mpackage = mentity.mpackage
- if mpackage != null then
- topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
- end
- topmenu.add_li new ListItem(new Link(mentity.nitdoc_url, mentity.html_name))
- topmenu.active_item = topmenu.items.last
- end
-
- # Class list to display in sidebar
- redef fun init_sidebar(v, doc) do
- # TODO filter here?
- super
- var mclasses = new HashSet[MClass]
- mclasses.add_all mentity.collect_intro_mclasses(v.doc.filter)
- mclasses.add_all mentity.collect_redef_mclasses(v.doc.filter)
- if mclasses.is_empty then return
- var list = new UnorderedList
- list.css_classes.add "list-unstyled list-labeled"
-
- var sorted = mclasses.to_a
- v.name_sorter.sort(sorted)
- for mclass in sorted do
- list.add_li tpl_sidebar_item(mclass)
- end
- sidebar.boxes.add new DocSideBox("All classes", list)
- sidebar.boxes.last.is_open = false
- end
-
- private fun tpl_sidebar_item(def: MClass): ListItem do
- var classes = def.intro.css_classes
- if def.intro_mmodule == self.mentity then
- classes.add "intro"
- else
- classes.add "redef"
- end
- var lnk = new Template
- lnk.add new DocHTMLLabel.with_classes(classes)
- lnk.add def.html_link
- return new ListItem(lnk)
- end
-end
-
-redef class MClassPage
-
- redef fun init_topmenu(v, doc) do
- super
- var mpackage = mentity.intro_mmodule.mgroup.mpackage
- topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
- topmenu.add_li new ListItem(new Link(html_url, mentity.html_name))
- topmenu.active_item = topmenu.items.last
- end
-
- redef fun init_sidebar(v, doc) do
- super
- var by_kind = new PropertiesByKind.with_elements(mclass_inherited_mprops(v, doc))
- var summary = new UnorderedList
- summary.css_classes.add "list-unstyled"
-
- by_kind.sort_groups(v.name_sorter)
- for g in by_kind.groups do tpl_sidebar_list(g, summary)
- sidebar.boxes.add new DocSideBox("All properties", summary)
- sidebar.boxes.last.is_open = false
- end
-
- private fun tpl_sidebar_list(mprops: PropertyGroup[MProperty], summary: UnorderedList) do
- if mprops.is_empty then return
- var list = new UnorderedList
- list.css_classes.add "list-unstyled list-labeled"
- for mprop in mprops do
- list.add_li tpl_sidebar_item(mprop)
- end
- var content = new Template
- content.add mprops.title
- content.add list
- var li = new ListItem(content)
- summary.add_li li
- end
-
- private fun tpl_sidebar_item(mprop: MProperty): ListItem do
- var classes = mprop.intro.css_classes
- if not mprop_is_local(mprop) then
- classes.add "inherit"
- var cls_url = mprop.intro.mclassdef.mclass.nitdoc_url
- var def_url = "{cls_url}#{mprop.nitdoc_id}.definition"
- var lnk = new Link(def_url, mprop.html_name)
- var mdoc = mprop.intro.mdoc_or_fallback
- if mdoc != null then lnk.title = mdoc.synopsis
- var item = new Template
- item.add new DocHTMLLabel.with_classes(classes)
- item.add lnk
- return new ListItem(item)
- end
- if mpropdefs.has(mprop.intro) then
- classes.add "intro"
- else
- classes.add "redef"
- end
- var def = select_mpropdef(mprop)
- var anc = def.html_link_to_anchor
- anc.href = "#{def.nitdoc_id}.definition"
- var lnk = new Template
- lnk.add new DocHTMLLabel.with_classes(classes)
- lnk.add anc
- return new ListItem(lnk)
- end
-
- # Get the mpropdef contained in `self` page for a mprop.
- #
- # FIXME this method is used to translate a mprop into a mpropdefs for
- # section linking. A better page structure should avoid this...
- private fun select_mpropdef(mprop: MProperty): MPropDef do
- for mclassdef in mentity.mclassdefs do
- for mpropdef in mclassdef.mpropdefs do
- if mpropdef.mproperty == mprop then return mpropdef
- end
- end
- abort # FIXME is there a case where the prop is not found?
- end
-
- private fun mclass_inherited_mprops(v: RenderHTMLPhase, doc: DocModel): Set[MProperty] do
- var res = new HashSet[MProperty]
- var local = mentity.collect_local_mproperties(v.doc.filter)
- for mprop in mentity.collect_inherited_mproperties(doc.mainmodule, v.doc.filter) do
- if local.has(mprop) then continue
- #if mprop isa MMethod and mprop.is_init then continue
- if mprop.intro.mclassdef.mclass.name == "Object" and
- (mprop.visibility == protected_visibility or
- mprop.intro.mclassdef.mmodule.name != "kernel") then continue
- res.add mprop
- end
- res.add_all local
- return res
- end
-
- private fun mprop_is_local(mprop: MProperty): Bool do
- for mpropdef in mprop.mpropdefs do
- if self.mpropdefs.has(mpropdef) then return true
- end
- return false
- end
-end
-
-redef class MPropertyPage
- redef fun init_title(v, doc) do
- title = "{mentity.html_name}{mentity.html_short_signature.write_to_string}"
- end
-
- redef fun init_topmenu(v, doc) do
- super
- var mmodule = mentity.intro_mclassdef.mmodule
- var mpackage = mmodule.mgroup.mpackage
- var mclass = mentity.intro_mclassdef.mclass
- topmenu.add_li new ListItem(new Link(mpackage.nitdoc_url, mpackage.html_name))
- topmenu.add_li new ListItem(new Link(mclass.nitdoc_url, mclass.html_name))
- topmenu.add_li new ListItem(new Link(html_url, mentity.html_name))
- topmenu.active_item = topmenu.items.last
- end
-end
-
-redef class DocComposite
- # Prepares the HTML rendering for this element.
- #
- # This visit is mainly used to set template attributes before rendering.
- fun init_html_render(v: RenderHTMLPhase, doc: DocModel, page: DocPage) do
- for child in children do child.init_html_render(v, doc, page)
- end
-end
-
-# FIXME hideous hacks to avoid diff
-redef class MEntitySection
- redef fun init_html_render(v, doc, page) do
- if not page isa MEntityPage then return
- var mentity = self.mentity
- if mentity isa MGroup and mentity.is_root then
- html_title = mentity.mpackage.html_name
- html_subtitle = mentity.mpackage.html_declaration
- else if mentity isa MProperty then
- var title = new Template
- title.add mentity.html_name
- title.add mentity.html_signature
- html_title = title
- html_subtitle = mentity.html_namespace
- html_toc_title = mentity.html_name
- end
- super
- end
-end
-
-# FIXME hideous hacks to avoid diff
-redef class ConcernSection
- redef fun init_html_render(v, doc, page) do
- if not page isa MEntityPage then return
- var mentity = self.mentity
- if page isa MGroupPage then
- html_title = null
- html_toc_title = mentity.html_name
- is_toc_hidden = false
- else if page.mentity isa MModule and mentity isa MModule then
- var title = new Template
- if mentity == page.mentity then
- title.add "in "
- html_toc_title = "in {mentity.html_name}"
- else
- title.add "from "
- html_toc_title = "from {mentity.html_name}"
- end
- title.add mentity.html_namespace
- html_title = title
- else if (page.mentity isa MClass and mentity isa MModule) or
- (page.mentity isa MProperty and mentity isa MModule) then
- var title = new Template
- title.add "in "
- title.add mentity.html_namespace
- html_title = title
- html_toc_title = "in {mentity.html_name}"
- end
- super
- end
-end
-
-# TODO redo showlink
-redef class IntroArticle
- redef fun init_html_render(v, doc, page) do
- var mentity = self.mentity
- if mentity isa MModule then
- html_source_link = v.html_source_link(mentity.location)
- else if mentity isa MClassDef then
- html_source_link = v.html_source_link(mentity.location)
- else if mentity isa MPropDef then
- html_source_link = v.html_source_link(mentity.location)
- end
- end
-end
-
-# FIXME less hideous hacks...
-redef class DefinitionArticle
- redef fun init_html_render(v, doc, page) do
- var mentity = self.mentity
- if mentity isa MPackage or mentity isa MModule then
- var title = new Template
- title.add mentity.html_icon
- title.add mentity.html_namespace
- html_title = title
- html_toc_title = mentity.html_name
- if mentity isa MModule then
- html_source_link = v.html_source_link(mentity.location)
- end
- else if mentity isa MClassDef then
- var title = new Template
- title.add "in "
- title.add mentity.mmodule.html_namespace
- html_title = mentity.html_declaration
- html_subtitle = title
- html_toc_title = "in {mentity.html_name}"
- html_source_link = v.html_source_link(mentity.location)
- if page isa MEntityPage and mentity.is_intro and mentity.mmodule != page.mentity then
- is_short_comment = true
- end
- if page isa MModulePage then is_toc_hidden = true
- else if mentity isa MPropDef then
- if page isa MClassPage then
- var title = new Template
- title.add mentity.html_icon
- title.add mentity.html_declaration
- html_title = title
- html_subtitle = mentity.html_namespace
- html_toc_title = mentity.html_name
- else
- var title = new Template
- title.add "in "
- title.add mentity.mclassdef.html_link
- html_title = title
- html_toc_title = "in {mentity.mclassdef.html_name}"
- end
- html_source_link = v.html_source_link(mentity.location)
- end
- if page isa MGroupPage and mentity isa MModule then
- is_toc_hidden = true
- end
- super
- end
-end
-
-redef class HomeArticle
- redef fun init_html_render(v, doc, page) do
- if v.ctx.opt_custom_title.value != null then
- self.html_title = v.ctx.opt_custom_title.value.to_s
- self.html_toc_title = v.ctx.opt_custom_title.value.to_s
- end
- self.content = v.ctx.opt_custom_intro.value
- super
- end
-end
-
-redef class GraphArticle
- redef fun init_html_render(v, doc, page) do
- var path = v.ctx.output_dir / graph_id
- var file = new FileWriter.open("{path}.dot")
- file.write(dot)
- file.close
- var proc = new ProcessReader("dot", "-Tsvg", "-Tcmapx", "{path}.dot")
- var svg = new Buffer
- var i = 0
- while not proc.eof do
- i += 1
- if i < 6 then continue # skip dot default header
- svg.append proc.read_line
- end
- proc.close
- self.svg = svg.write_to_string
- end
-end
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# HTML templates used by Nitdoc to generate API documentation
-# Pages are assembled using `Template`
-module html_components
-
-import doc_base
-import html::bootstrap
-import json
-
-# A label with a text content.
-class DocHTMLLabel
- super BSLabel
-
- redef init do
- css_classes.clear
- css_classes.add "label"
- end
-
- # Init this label from css classes.
- init with_classes(classes: Array[String]) do
- init("label", "")
- css_classes.add_all classes
- end
-end
-
-# A component that display tabbed data.
-class DocTabs
- super BSComponent
- autoinit(html_id, drop_text, css_classes)
-
- # HTML id of this component.
- var html_id: String
-
- # Text displayed on the tabs dropdown button.
- var drop_text: String
-
- # Panels to display in this tab group.
- var panels = new Array[DocTabPanel]
-
- # Droplist containing links to panels.
- #
- # Can also be used to add external links.
- var drop_list: DocTabsDrop is lazy do return new DocTabsDrop(html_id, drop_text)
-
- # Adds a new `panel` to that tab.
- #
- # You should always use this instead of `panels.add` because it also set the
- # `drop_list` entry.
- fun add_panel(panel: DocTabPanel) do
- drop_list.add_li panel.render_tab
- panels.add panel
- end
-
- redef fun rendering do
- if panels.is_empty then return
- panels.first.is_active = true
- add "<div role=\"tabpanel\">"
- if drop_list.items.length > 1 then add drop_list
- add " <div class=\"tab-content\">"
- for panel in panels do
- add panel
- end
- add " </div>"
- add "</div>"
- end
-end
-
-# A list of tab regrouped in a dropdown
-class DocTabsDrop
- super UnorderedList
- autoinit(html_id, html_title, items, css_classes)
-
- # HTML id used by the tabs group.
- var html_id: String
-
- # Title to display in the tab item.
- var html_title: String
-
- redef fun rendering do
- add """<ul id="{{{html_id}}}-tabs" class="nav pull-right" role="tablist">"""
- add """ <li role="presentation" class="dropdown pull-right">"""
- add """ <a href="#" id="{{{html_id}}}-drop" class="dropdown-toggle"
- data-toggle="dropdown" aria-controls="{{{html_id}}}-contents"
- aria-expanded="false">"""
- add html_title
- add """ <span class="glyphicon glyphicon-menu-hamburger"></span>"""
- add """ </a>"""
- add """ <ul class="dropdown-menu" role="menu"
- aria-labelledby="{{{html_id}}}-drop" id="{{{html_id}}}-contents">"""
- for item in items do add item
- add " </ul>"
- add " </li>"
- add "</ul>"
- end
-end
-
-# A panel that goes in a DocTabs.
-class DocTabPanel
- super BSComponent
- autoinit(html_id, tab_title, html_content, is_active, css_classes)
-
- # HTML id of this panel.
- var html_id: String
-
- # Title of this panel as displayed in the tab label.
- var tab_title: String
-
- # HTML content of this panel.
- var html_content: Writable is writable
-
- # Is this panel visible by default?
- var is_active = false is optional
-
- redef fun rendering do
- var active = ""
- if is_active then active = "active in"
- add "<div role=\"tabpanel\" class=\"tab-pane fade {active}\""
- add " id=\"{html_id}\" aria-labelledby=\"{html_id}-tab\">"
- add html_content
- add "</div>"
- end
-
- private fun render_tab: DocTabItem do return new DocTabItem(tab_title, html_id)
-end
-
-# A ListItem that goes in a DocTabsDrop.
-private class DocTabItem
- super ListItem
- autoinit(text, target_id, css_classes)
-
- # Panel id to trigger when the link is clicked.
- var target_id: String
-
- redef fun rendering do
- add "<li{render_css_classes}>"
- add " <a role=\"tab\" data-toggle=\"tab\" aria-expanded=\"false\" tabindex=\"-1\""
- add " id=\"{target_id}-tab\" href=\"#{target_id}\" aria-controls=\"{target_id}\">"
- add text
- add " </a>"
- add "</li>"
- end
-end
-
-# A HTML tag attribute
-# `<tag attr="value">`
-#
-# ~~~nit
-# var attr: TagAttribute
-#
-# attr = new TagAttribute("foo", null)
-# assert attr.write_to_string == " foo=\"\""
-#
-# attr = new TagAttribute("foo", "bar<>")
-# assert attr.write_to_string == " foo=\"bar<>\""
-# ~~~
-class TagAttribute
- super Template
-
- var name: String
- var value: nullable String
-
- redef fun rendering do
- var value = self.value
- if value == null then
- # SEE: http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes
- add " {name.html_escape}=\"\""
- else
- add " {name.html_escape}=\"{value.html_escape}\""
- end
- end
-end
-
-# Javacript template that can be added into a DocPage.
-class TplScript
- super Template
-
- # HTML attributes to add in this tag.
- var attrs = new Array[TagAttribute]
-
- # Text content of this script tag.
- var content: nullable Writable = null is writable
-
- init do
- attrs.add(new TagAttribute("type", "text/javascript"))
- end
-
- # Render the content of this script.
- protected fun render_content do
- if content != null then add content.as(not null)
- end
-
- redef fun rendering do
- add "<script"
- for attr in attrs do add attr
- addn ">"
- render_content
- addn "</script>"
- end
-end
-
-# JS script for Piwik Tracker
-class TplPiwikScript
- super TplScript
-
- # Piwik URL to use for this tracker.
- var tracker_url: String
-
- # Site ID used on Piwik system.
- var site_id: String
-
- redef fun render_content do
- var site_id = self.site_id.to_json
- var tracker_url = self.tracker_url.trim
- if tracker_url.chars.last != '/' then tracker_url += "/"
- tracker_url = "://{tracker_url}".to_json
-
- addn "<!-- Piwik -->"
- addn "var _paq = _paq || [];"
- addn " _paq.push([\"trackPageView\"]);"
- addn " _paq.push([\"enableLinkTracking\"]);"
- addn "(function() \{"
- addn " var u=((\"https:\" == document.location.protocol) ? \"https\" : \"http\") + {tracker_url};"
- addn " _paq.push([\"setTrackerUrl\", u+\"piwik.php\"]);"
- addn " _paq.push([\"setSiteId\", {site_id}]);"
- addn " var d=document, g=d.createElement(\"script\"), s=d.getElementsByTagName(\"script\")[0]; g.type=\"text/javascript\";"
- addn " g.defer=true; g.async=true; g.src=u+\"piwik.js\"; s.parentNode.insertBefore(g,s);"
- addn "\})();"
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# HTML templates for Nit model MEntities.
-module html_model
-
-import doc_base
-import html_components
-import ordered_tree
-import model_html
-
-redef class MEntity
- # URL of this entity’s Nitdoc page.
- fun nitdoc_url: String is abstract
-
- # Returns a Link to the mentity `html_url`.
- #
- # Example: `<a href="html_url" title="mdoc.short_comment">html_short_name</a>
- redef var html_link is lazy do
- var tpl = new Link(nitdoc_url, html_name)
- var mdoc = mdoc_or_fallback
- if mdoc != null then
- tpl.title = mdoc.synopsis
- end
- return tpl
- end
-
- # Returns a Link to the mentity `nitdoc_id`.
- #
- # Example: `<a href="#nitdoc_id" title="mdoc.short_comment">html_short_name</a>
- fun html_link_to_anchor: Link do
- var tpl = new Link("#{nitdoc_id}", html_name)
- var mdoc = mdoc_or_fallback
- if mdoc != null then
- tpl.title = mdoc.synopsis
- end
- return tpl
- end
-
- # A li element that can go in a `HTMLList`.
- fun html_list_item: ListItem do
- var tpl = new Template
- tpl.add new DocHTMLLabel.with_classes(css_classes)
- tpl.add html_link
- var comment = html_synopsis
- if comment != null then
- tpl.add ": "
- tpl.add comment
- end
- return new ListItem(tpl)
- end
-end
-
-redef class MPackage
- redef var nitdoc_id = name.to_cmangle is lazy
-
- redef fun nitdoc_url do
- var root = self.root
- if root == null then return super
- return root.nitdoc_url
- end
-end
-
-redef class MGroup
- redef var nitdoc_id is lazy do
- var parent = self.parent
- if parent != null then
- return "{parent.nitdoc_id}__{name.to_cmangle}"
- end
- return name.to_cmangle
- end
-
- redef fun nitdoc_url do return "group_{nitdoc_id}.html"
-end
-
-redef class MModule
- redef var nitdoc_id is lazy do
- var mgroup = self.mgroup
- if mgroup != null then
- if mgroup.mmodules.length == 1 then
- return "{mgroup.nitdoc_id}-"
- else
- return "{mgroup.nitdoc_id}__{name.to_cmangle}"
- end
- end
- return name.to_cmangle
- end
-
- redef fun nitdoc_url do return "module_{nitdoc_id}.html"
-end
-
-redef class MClass
- redef var nitdoc_id = "{intro_mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
- redef fun nitdoc_url do return "class_{nitdoc_id}.html"
-end
-
-redef class MClassDef
- redef var nitdoc_id = "{mmodule.nitdoc_id}__{name.to_cmangle}" is lazy
- redef fun nitdoc_url do return "{mclass.nitdoc_url}#{nitdoc_id}"
-end
-
-redef class MProperty
- redef var nitdoc_id = "{intro_mclassdef.mclass.nitdoc_id}__{name.to_cmangle}" is lazy
- redef fun nitdoc_url do return "property_{nitdoc_id}.html"
-end
-
-redef class MPropDef
- redef var nitdoc_id = "{mclassdef.nitdoc_id}__{name.to_cmangle}" is lazy
- redef fun nitdoc_url do return "{mproperty.nitdoc_url}#{nitdoc_id}"
-end
-
-redef class MAttributeDef
-
- redef fun html_modifiers do
- var res = super
- res.add "var"
- return res
- end
-
- redef fun html_short_signature do return new Template
-
- redef fun html_signature do
- var static_mtype = self.static_mtype
- var tpl = new Template
- if static_mtype != null then
- tpl.add ": "
- tpl.add static_mtype.html_signature
- end
- return tpl
- end
-end
-
-redef class MParameterType
- redef fun html_link do
- return new Link("{mclass.nitdoc_url}#FT_{name.to_cmangle}", name, "formal type")
- end
-end
-
-redef class MVirtualType
- redef fun html_link do return mproperty.intro.html_link
-end
-
-redef class ConcernsTree
- # Render `self` as a hierarchical UnorderedList.
- fun html_list: UnorderedList do
- var lst = new UnorderedList
- lst.css_classes.add "list-unstyled list-definition"
- for r in roots do
- var li = r.html_concern_item
- lst.add_li li
- build_html_list(r, li)
- end
- return lst
- end
-
- # Build the html list recursively.
- private fun build_html_list(e: MConcern, li: ListItem) do
- if not sub.has_key(e) then return
- var subs = sub[e]
- var lst = new UnorderedList
- lst.css_classes.add "list-unstyled list-definition"
- for e2 in subs do
- if e2 isa MGroup and e2.is_root then
- build_html_list(e2, li)
- else
- var sli = e2.html_concern_item
- lst.add_li sli
- build_html_list(e2, sli)
- end
- end
- var text = new Template
- text.add li.text
- if not lst.is_empty then text.add lst
- li.text = text
- end
-end
-
-redef class MConcern
- # Return a li element for `self` that can be displayed in a concern list
- private fun html_concern_item: ListItem do
- var lnk = html_link
- var tpl = new Template
- tpl.add new Link("#{nitdoc_id}.concern", lnk.text, lnk.title)
- var comment = html_synopsis
- if comment != null then
- tpl.add ": "
- tpl.add comment
- end
- return new ListItem(tpl)
- end
-end
-
-################################################################################
-# Additions to `model_ext`.
-
-redef class MRawType
- redef fun html_signature do
- var tpl = new Template
-
- for part in parts do
- if part.target != null then
- tpl.add part.target.as(not null).html_link
- else
- tpl.add part.text.html_escape
- end
- end
- return tpl
- end
-end
-
-redef class MInnerClass
- redef fun nitdoc_url do return inner.nitdoc_url
- redef fun html_signature do return inner.html_signature
-end
-
-redef class MInnerClassDef
- redef fun nitdoc_url do return inner.nitdoc_url
-
- redef fun html_link_to_anchor do return inner.html_link_to_anchor
- redef fun html_link do return inner.html_link
- redef fun html_signature do return inner.html_signature
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Introduces templates that compose the documentation HTML rendering.
-module html_templates
-
-import html_model
-import html::bootstrap
-import doc_phases::doc_structure
-import doc_phases::doc_hierarchies
-import doc_phases::doc_graphs
-import doc_phases::doc_intros_redefs
-import doc_phases::doc_lin
-import doc_phases::doc_readme
-intrude import doc_down
-
-# Renders the page as HTML.
-redef class DocPage
- super Template
-
- # Page url.
- var html_url: String is writable, noinit
-
- # Directory where css, js and other assets can be found.
- var shareurl: String is writable, noinit
-
- # Attributes of the body tag element.
- var body_attrs = new Array[TagAttribute]
-
- # Top menu template if any.
- var topmenu: DocTopMenu is writable, noinit
-
- # Sidebar template if any.
- var sidebar: nullable DocSideBar = null is writable
-
- # Footer content if any.
- var footer: nullable Writable = null is writable
-
- # JS scripts to append at the end of the body
- var scripts = new Array[TplScript]
-
- # Renders the html `<head>`.
- private fun render_head do
- var css = (self.shareurl / "css").html_escape
- var vendors = (self.shareurl / "vendors").html_escape
-
- addn "<!DOCTYPE html>"
- addn "<head>"
- addn " <meta charset='utf-8'/>"
- addn " <!--link rel='stylesheet' href='{css}/Nitdoc.UI.css' type='text/css'/-->"
- addn " <link rel='stylesheet' href='{vendors}/bootstrap/css/bootstrap.min.css'/>"
- addn " <link rel='stylesheet' href='{css}/nitdoc.bootstrap.css'/>"
- addn " <link rel='stylesheet' href='{css}/nitdoc.css'/>"
- addn " <link rel='stylesheet' href='{css}/Nitdoc.QuickSearch.css'/>"
- addn " <link rel='stylesheet' href='{css}/Nitdoc.ModalBox.css'/>"
- addn " <link rel='stylesheet' href='{css}/Nitdoc.GitHub.css'/>"
- addn " <title>{title.html_escape}</title>"
- addn "</head>"
- add "<body"
- for attr in body_attrs do add attr
- addn ">"
- end
-
- # Renders the footer and content.
- private fun render_content do
- add root
- if footer != null then
- addn "<div class='well footer'>"
- add footer.as(not null)
- addn "</div>"
- end
- end
-
- # Render JS scripts
- private fun render_footer do
- var vendors = (self.shareurl / "vendors").html_escape
- var js = (self.shareurl / "js").html_escape
-
- addn "<script src='{vendors}/jquery/jquery-1.11.1.min.js'></script>"
- addn "<script src='{vendors}/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
- addn "<script src='{vendors}/bootstrap/js/bootstrap.min.js'></script>"
- addn "<script src='{js}/lib/utils.js'></script>"
- addn "<script src='{js}/plugins/filtering.js'></script>"
- addn "<script src='quicksearch-list.js'></script>"
- addn "<script src='{js}/plugins/quicksearch.js'></script>"
- for script in scripts do add script
- addn """<script>
- $(function () {
- $("[data-toggle='tooltip']").tooltip();
- $("[data-toggle='popover']").popover();
- });
- </script>"""
- addn "</body>"
- addn "</html>"
- end
-
- # Render the whole page
- redef fun rendering do
- render_head
- addn "<div class='container-fluid'>"
- addn " <div class='row'>"
- add topmenu
- addn " </div>"
- addn " <div class='row' id='content'>"
- var sidebar = self.sidebar
- if sidebar != null then
- addn "<div class='col col-xs-3 col-lg-2'>"
- add sidebar
- addn "</div>"
- addn "<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
- render_content
- addn "</div>"
- else
- addn "<div class='col col-xs-12'>"
- render_content
- addn "</div>"
- end
- addn " </div>"
- addn "</div>"
- render_footer
- end
-
- # Render table of content for this page.
- fun html_toc: UnorderedList do
- var lst = new UnorderedList
- lst.css_classes.add "nav"
- for child in root.children do
- child.render_toc_item(lst)
- end
- return lst
- end
-end
-
-# Top menu bar template.
-#
-# FIXME should be a Bootstrap component template
-# At this moment, the topmenu structure stills to specific to Nitdoc to use the
-# generic component.
-class DocTopMenu
- super UnorderedList
-
- # Brand link to display in first position of the top menu.
- #
- # This is where you want to put your logo.
- var brand: nullable Writable is noinit, writable
-
- # Active menu item.
- #
- # Depends on the current page, this allows to hilighted the current item.
- #
- # FIXME should be using Boostrap breadcrumbs component.
- # This will still like this to avoid diff and be changed in further fixes
- # when we will modify the output.
- var active_item: nullable ListItem is noinit, writable
-
- redef fun rendering do
- addn "<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
- addn " <div class='container-fluid'>"
- addn " <div class='navbar-header'>"
- add " <button type='button' class='navbar-toggle' "
- addn " data-toggle='collapse' data-target='#topmenu-collapse'>"
- addn " <span class='sr-only'>Toggle menu</span>"
- addn " <span class='icon-bar'></span>"
- addn " <span class='icon-bar'></span>"
- addn " <span class='icon-bar'></span>"
- addn " </button>"
- if brand != null then
- add "<span class='navbar-brand'>"
- add brand.write_to_string
- add "</span>"
- end
- addn " </div>"
- addn " <div class='collapse navbar-collapse' id='topmenu-collapse'>"
- addn " <ul class='nav navbar-nav'>"
- for item in items do
- if item == active_item then item.css_classes.add "active"
- add item.write_to_string
- end
- addn " </ul>"
- addn " </div>"
- addn " </div>"
- addn "</nav>"
- end
-end
-
-# Nitdoc sidebar template.
-class DocSideBar
- super Template
-
- # Sidebar contains `DocSideBox`.
- var boxes = new Array[DocSideBox]
-
- redef fun rendering do
- if boxes.is_empty then return
- addn "<div id='sidebar'>"
- for box in boxes do add box
- addn "</div>"
- end
-end
-
-# Something that can be put in a DocSideBar.
-class DocSideBox
- super Template
-
- # Box HTML id, used for Bootstrap collapsing feature.
- #
- # Use `html_title.to_cmangle` by default.
- var id: String is lazy do return title.write_to_string.to_cmangle
-
- # Title of the box to display.
- var title: Writable
-
- # Content to display in the box.
- var content: Writable
-
- # Is the box opened by default?
- #
- # Otherwise, the user will have to clic on the title to display the content.
- #
- # Default is `true`.
- var is_open = true is writable
-
- redef fun rendering do
- var open = ""
- if is_open then open = "in"
- addn "<div class='panel'>"
- addn " <div class='panel-heading'>"
- add " <a data-toggle='collapse' data-parent='#sidebar'"
- add " data-target='#box_{id}' href='#'>"
- add title
- addn " </a>"
- addn " </div>"
- addn " <div id='box_{id}' class='summary panel-body collapse {open}'>"
- add content
- addn " </div>"
- addn "</div>"
- end
-end
-
-redef class DocComposite
- super Template
-
- # HTML anchor id
- var html_id: String is writable, lazy do return id
-
- # Title to display if any.
- #
- # This title can be decorated with HTML.
- var html_title: nullable Writable is writable, lazy do return title
-
- # Subtitle to display if any.
- var html_subtitle: nullable Writable is noinit, writable
-
- # Render the element title and subtitle.
- private fun render_title do
- if html_title != null then
- var header = new Header(hlvl, html_title.write_to_string)
- header.css_classes.add "signature"
- addn header
- end
- if html_subtitle != null then
- addn "<div class='info subtitle'>"
- addn html_subtitle.write_to_string
- addn "</div>"
- end
- end
-
- # Render the element body.
- private fun render_body do
- for child in children do addn child.write_to_string
- end
-
- redef fun rendering do
- if is_hidden then return
- render_title
- render_body
- end
-
- # Level <hX> for HTML heading.
- private fun hlvl: Int do return depth
-
- # A short, undecorated title that goes in the table of contents.
- #
- # By default, returns `html_title.to_s`, subclasses should redefine it.
- var html_toc_title: nullable String is lazy, writable do
- if html_title == null then return toc_title
- return html_title.write_to_string
- end
-
- # Render this element in a table of contents.
- private fun render_toc_item(lst: UnorderedList) do
- if is_toc_hidden or html_toc_title == null then return
-
- var content = new Template
- content.add new Link("#{html_id}", html_toc_title.to_s)
- if not children.is_empty then
- var sublst = new UnorderedList
- sublst.css_classes.add "nav"
- for child in children do
- child.render_toc_item(sublst)
- end
- content.add sublst
- end
- lst.add_li new ListItem(content)
- end
-
- # ID used in HTML tab labels.
- #
- # We sanitize it for Boostrap JS panels that do not like ":" and "." in ids.
- var html_tab_id: String is lazy do
- var id = html_id.replace(":", "")
- id = id.replace(".", "")
- return "{id}-tab"
- end
-end
-
-redef class DocRoot
- redef fun rendering do
- for child in children do addn child.write_to_string
- end
-end
-
-redef class DocSection
- super BSComponent
-
- redef fun css_classes do return new Array[String]
-
- redef fun rendering do
- if is_hidden then
- addn "<a id=\"{html_id}\"></a>"
- return
- end
- addn "<section{render_css_classes} id=\"{html_id}\">"
- render_title
- render_body
- addn "</section>"
- end
-end
-
-redef class DocArticle
- super BSComponent
-
- redef fun css_classes do return new Array[String]
-
- redef fun rendering do
- if is_hidden then return
- addn "<article{render_css_classes} id=\"{html_id}\">"
- render_title
- render_body
- addn "</article>"
- end
-end
-
-redef class TabbedGroup
- redef fun render_body do
- var tabs = new DocTabs("{html_id}.tabs", "")
- for child in children do
- if child.is_hidden then continue
- var title = child.html_toc_title or else child.toc_title or else ""
- tabs.add_panel new DocTabPanel(child.html_tab_id, title, child)
- end
- addn tabs
- end
-end
-
-redef class PanelGroup
- redef var html_title = null
- redef var toc_title is lazy do return title or else ""
- redef var is_toc_hidden = true
-end
-
-redef class HomeArticle
- redef var html_title = "Overview"
-
- # HTML content to display on the home page.
- #
- # This attribute is set by the `doc_render` phase who knows the context.
- var content: nullable String is noinit, writable
-
- redef fun render_body do
- var content = self.content
- if content != null then add content
- super
- end
-end
-
-redef class IndexArticle
- redef var html_title = "Index"
-
- redef fun render_body do
- addn "<div class='container-fluid'>"
- addn " <div class='row'>"
- render_list("Modules", mmodules)
- render_list("Classes", mclasses)
- render_list("Properties", mprops)
- addn "</div>"
- addn "</div>"
- end
-
- # Displays a list from the content of `mentities`.
- private fun render_list(title: String, mentities: Array[MEntity]) do
- if mentities.is_empty then return
- addn "<div class='col-xs-4'>"
- addn new Header(3, title)
- var lst = new UnorderedList
- for mentity in mentities do
- if mentity isa MProperty then
- var tpl = new Template
- tpl.add mentity.intro.html_link
- tpl.add " ("
- tpl.add mentity.intro.mclassdef.mclass.html_link
- tpl.add ")"
- lst.add_li new ListItem(tpl)
- else
- lst.add_li new ListItem(mentity.html_link)
- end
- end
- addn lst
- addn "</div>"
- end
-end
-
-redef class MEntityComposite
- redef var html_title is lazy do return mentity.nitdoc_name
-end
-
-redef class MEntitySection
- redef var html_title is lazy do return mentity.html_name
- redef var html_subtitle is lazy do return mentity.html_declaration
-end
-
-redef class ConcernSection
- redef var html_title is lazy do return "in {mentity.nitdoc_name}"
-end
-
-redef class IntroArticle
- redef var html_title = null
-
- # Link to source to display if any.
- var html_source_link: nullable Writable is noinit, writable
-
- redef fun render_body do
- var tabs = new DocTabs("{html_id}.tabs", "")
- var comment = mentity.html_documentation
- if mentity isa MPackage then
- comment = mentity.html_synopsis
- end
- if comment != null then
- tabs.add_panel new DocTabPanel("{html_tab_id}-comment", "Comment", comment)
- end
- for child in children do
- if child.is_hidden then continue
- var title = child.html_toc_title or else child.toc_title or else ""
- tabs.add_panel new DocTabPanel(child.html_tab_id, title, child)
- end
- var lnk = html_source_link
- if lnk != null then
- tabs.drop_list.items.add new ListItem(lnk)
- end
- addn tabs
- end
-end
-
-redef class ConcernsArticle
- redef var html_title = "Concerns"
- redef fun render_body do add concerns.html_list
-end
-
-redef class DefinitionListArticle
- redef var html_title is lazy do
- var title = new Template
- title.add mentity.html_icon
- title.add mentity.html_link
- return title
- end
-
- redef var html_subtitle is lazy do return mentity.html_namespace
- redef var html_toc_title is lazy do return mentity.html_name
-end
-
-redef class DefinitionArticle
- redef var html_title is lazy do return mentity.html_name
- redef var html_subtitle is lazy do return mentity.html_declaration
-
- # Does `self` display only it's title and no body?
- #
- # FIXME diff hack
- var is_no_body: Bool = false is writable
-
- # Does `self` display only the short content as definition?
- #
- # FIXME diff hack
- var is_short_comment: Bool = false is writable
-
- # Link to source to display if any.
- var html_source_link: nullable Writable is noinit, writable
-
- redef fun render_body do
- var tabs = new DocTabs("{html_id}.tabs", "")
- if not is_no_body then
- var comment
- if is_short_comment or mentity isa MPackage then
- comment = mentity.html_synopsis
- else
- comment = mentity.html_documentation
- end
- if comment != null then
- tabs.add_panel new DocTabPanel("{html_tab_id}-comment", "Comment", comment)
- end
- end
- for child in children do
- if child.is_hidden then continue
- var title = child.html_toc_title or else child.toc_title or else ""
- tabs.add_panel new DocTabPanel(child.html_tab_id, title, child)
- end
- var lnk = html_source_link
- if lnk != null then
- tabs.drop_list.items.add new ListItem(lnk)
- end
- addn tabs
- end
-end
-
-redef class MEntitiesListArticle
- redef fun render_body do
- var lst = new UnorderedList
- lst.css_classes.add "list-unstyled list-definition"
- for mentity in mentities do
- lst.add_li mentity.html_list_item
- end
- add lst
- end
-end
-
-redef class DefinitionLinArticle
- redef fun render_body do
- var lst = new UnorderedList
- lst.css_classes.add "list-unstyled list-labeled"
- for mentity in mentities do
- if not mentity isa MPropDef then continue # TODO handle all mentities
- var tpl = new Template
- tpl.add mentity.mclassdef.html_namespace
- var comment = mentity.mclassdef.html_synopsis
- if comment != null then
- tpl.add ": "
- tpl.add comment
- end
- var li = new ListItem(tpl)
- li.css_classes.add "signature"
- lst.add_li li
- end
- add lst
- end
-end
-
-redef class GraphArticle
- redef var html_title = null
-
- # Graph in SVG with clickable map.
- #
- # This attribute is set by the `doc_render` phase who knows the context.
- var svg: nullable String = null is writable
-
- redef fun render_body do
- addn "<div class=\"text-center\">"
- var svg = self.svg
- if svg != null then add svg
- addn "</div>"
- end
-end
-
-redef class ReadmeSection
- redef var html_id is lazy do
- return markdown_processor.decorator.strip_id(html_title.as(not null).to_s)
- end
-
- redef var html_title is lazy do
- return markdown_processor.process(title.as(not null))
- end
-end
-
-redef class ReadmeArticle
- redef var html_id = ""
- redef var html_title = null
- redef var is_toc_hidden = true
-
- redef fun render_body do
- add markdown_processor.process(md.trim.write_to_string)
- end
-end
-
-redef class DocumentationArticle
- redef var html_title is lazy do
- var synopsis = mentity.html_synopsis
- if synopsis == null then return mentity.html_link
- return "{mentity.html_link.write_to_string} – {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
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Translate mentities to html blocks.
-module model_html
-
-import model
-import doc::doc_down
-import html::bootstrap
-
-redef class MEntity
-
- # Returns the MEntity name escaped for html.
- #
- # * MPackage: `foo`
- # * MGroup: `foo`
- # * MModule: `foo`
- # * MClass: `Foo[E]`
- # * MClassDef: `Foo[E]`
- # * MProperty: `foo(e)`
- # * MPropdef: `foo(e)`
- var html_name: String is lazy do return name.html_escape
-
- # Returns the MEntity full_name escaped for html.
- var html_full_name: String is lazy do return full_name.html_escape
-
- # Link to MEntity in the web server.
- # TODO this should be parameterizable... but how?
- fun html_link: Link do return new Link("/doc/{full_name}", html_name)
-
- # Returns the list of keyword used in `self` declaration.
- fun html_modifiers: Array[String] is abstract
-
- # Returns the complete MEntity declaration decorated with HTML.
- #
- # * MPackage: `package foo`
- # * MGroup: `group foo`
- # * MModule: `module foo`
- # * MClass: `private abstract class Foo[E: Object]`
- # * MClassDef: `redef class Foo[E]`
- # * MProperty: `private fun foo(e: Object): Int`
- # * MPropdef: `redef fun foo(e)`
- fun html_declaration: Template do
- var tpl = new Template
- tpl.add "<span>"
- tpl.add html_modifiers.join(" ")
- tpl.add " "
- tpl.add html_link
- tpl.add "</span>"
- return tpl
- end
-
- # Returns `self` namespace decorated with HTML links.
- #
- # * MPackage: `mpackage`
- # * MGroup: `mpackage(::group)`
- # * MModule: `mgroup::mmodule`
- # * MClass: `mpackage::mclass`
- # * MClassDef: `mmodule::mclassdef`
- # * MProperty: `mclass::mprop`
- # * MPropdef: `mclassdef:mpropdef`
- fun html_namespace: Template is abstract
-
- # Returns the synopsis and the comment of this MEntity formatted as HTML.
- var html_documentation: nullable Writable is lazy do
- var mdoc = mdoc_or_fallback
- if mdoc == null then return null
- return mdoc.html_documentation
- end
-
- # Returns the synopsis of this MEntity formatted as HTML.
- var html_synopsis: nullable Writable is lazy do
- var mdoc = mdoc_or_fallback
- if mdoc == null then return null
- return mdoc.html_synopsis
- end
-
- # Returns the the comment without the synopsis formatted as HTML.
- var html_comment: nullable Writable is lazy do
- var mdoc = mdoc_or_fallback
- if mdoc == null then return null
- return mdoc.html_comment
- end
-
- # Icon that will be displayed before the title
- fun html_icon: BSIcon do
- var icon = new BSIcon("tag")
- icon.css_classes.add_all(css_classes)
- return icon
- end
-
- # CSS classes used to decorate `self`.
- #
- # Mainly used for icons.
- var css_classes = new Array[String]
-end
-
-redef class MPackage
- redef var html_modifiers = ["package"]
- redef fun html_namespace do return html_link
- redef var css_classes = ["public"]
-end
-
-redef class MGroup
- redef var html_modifiers = ["group"]
-
- # Depends if `self` is root or not.
- #
- # * If root `mpackage`.
- # * Else `mpackage::self`.
- redef fun html_namespace do
- var tpl = new Template
- tpl.add mpackage.html_namespace
- if mpackage.root != self then
- tpl.add "::"
- tpl.add html_link
- end
- return tpl
- end
-
- redef var css_classes = ["public"]
-end
-
-redef class MModule
-
- redef var html_modifiers = ["module"]
-
- # Depends if `self` belongs to a MGroup.
- #
- # * If mgroup `mgroup::self`.
- # * Else `self`.
- redef fun html_namespace do
- var mgroup = self.mgroup
- var tpl = new Template
- if mgroup != null then
- tpl.add mgroup.html_namespace
- tpl.add "::"
- end
- tpl.add html_link
- return tpl
- end
-
- redef var css_classes = ["public"]
-end
-
-redef class MClass
- # Format: `Foo[E]`
- redef var html_name is lazy do
- var tpl = new Template
- tpl.add name.html_escape
- if arity > 0 then
- tpl.add "["
- var parameter_names = new Array[String]
- for p in mparameters do
- parameter_names.add(p.html_name)
- end
- tpl.add parameter_names.join(", ")
- tpl.add "]"
- end
- return tpl.write_to_string
- end
-
- redef fun html_modifiers do return intro.html_modifiers
- redef fun html_declaration do return intro.html_declaration
-
- # Returns `mpackage::self`.
- redef fun html_namespace do
- var mgroup = intro_mmodule.mgroup
- var tpl = new Template
- if mgroup != null then
- tpl.add mgroup.mpackage.html_namespace
- tpl.add "::"
- end
- tpl.add "<span>"
- tpl.add html_link
- tpl.add "</span>"
- return tpl
- end
-
- # Returns `intro.html_short_signature`.
- fun html_short_signature: Template do return intro.html_short_signature
-
- # Returns `intro.html_signature`.
- fun html_signature: Template do return intro.html_signature
-
- redef fun html_icon do return intro.html_icon
- redef fun css_classes do return intro.css_classes
-end
-
-redef class MClassDef
- # Depends if `self` is an intro or not.
- #
- # * If intro contains the visibility and kind.
- # * If redef contains the `redef` keyword and kind.
- redef fun html_modifiers do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- if mclass.visibility != public_visibility then
- res.add mclass.visibility.to_s
- end
- end
- res.add mclass.kind.to_s
- return res
- end
-
- # Depends if `self` is an intro or not.
- #
- # For intro: `private abstract class Foo[E: Object]`
- # For redef: `redef class Foo[E]`
- redef fun html_declaration do
- var tpl = new Template
- tpl.add "<span>"
- tpl.add html_modifiers.join(" ")
- tpl.add " "
- tpl.add html_link
- if is_intro then
- tpl.add html_signature
- else
- tpl.add html_short_signature
- end
- tpl.add "</span>"
- return tpl
- end
-
- # Returns `mmodule::self`
- redef fun html_namespace do
- var tpl = new Template
- tpl.add mmodule.html_namespace
- tpl.add "::<span>"
- tpl.add mclass.html_link
- tpl.add "</span>"
- return tpl
- end
-
- # Returns the MClassDef generic signature without static bounds.
- fun html_short_signature: Template do
- var tpl = new Template
- var mparameters = mclass.mparameters
- if not mparameters.is_empty then
- tpl.add "["
- for i in [0..mparameters.length[ do
- tpl.add mparameters[i].html_name
- if i < mparameters.length - 1 then tpl.add ", "
- end
- tpl.add "]"
- end
- return tpl
- end
-
- # Returns the MClassDef generic signature with static bounds.
- fun html_signature: Template do
- var tpl = new Template
- var mparameters = mclass.mparameters
- if not mparameters.is_empty then
- tpl.add "["
- for i in [0..mparameters.length[ do
- tpl.add "{mparameters[i].html_name}: "
- tpl.add bound_mtype.arguments[i].html_signature
- if i < mparameters.length - 1 then tpl.add ", "
- end
- tpl.add "]"
- end
- return tpl
- end
-
- redef fun css_classes do
- var set = new HashSet[String]
- if is_intro then set.add "intro"
- for m in mclass.intro.modifiers do set.add m.to_cmangle
- for m in modifiers do set.add m.to_cmangle
- return set.to_a
- end
-
-
- # List of all modifiers like redef, private etc.
- var modifiers: Array[String] is lazy do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- res.add mclass.visibility.to_s
- end
- res.add mclass.kind.to_s
- return res
- end
-end
-
-redef class MProperty
- redef fun html_modifiers do return intro.html_modifiers
- redef fun html_declaration do return intro.html_declaration
-
- # Returns `mclass::self`.
- redef fun html_namespace do
- var tpl = new Template
- tpl.add intro_mclassdef.mclass.html_namespace
- tpl.add "::<span>"
- tpl.add intro.html_link
- tpl.add "</span>"
- return tpl
- end
-
- # Returns `intro.html_short_signature`.
- fun html_short_signature: Template do return intro.html_short_signature
-
- # Returns `intro.html_signature`.
- fun html_signature: Template do return intro.html_signature
-
- redef fun css_classes do return intro.css_classes
-end
-
-redef class MPropDef
- # Depends if `self` is an intro or not.
- #
- # * If intro contains the visibility and kind.
- # * If redef contains the `redef` keyword and kind.
- redef fun html_modifiers do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- if mproperty.visibility != public_visibility then
- res.add mproperty.visibility.to_s
- end
- end
- return res
- end
-
- # Depends if `self` is an intro or not.
- #
- # For intro: `private fun foo(e: Object): Bar is abstract`
- # For redef: `redef fun foo(e) is cached`
- redef fun html_declaration do
- var tpl = new Template
- tpl.add "<span>"
- tpl.add html_modifiers.join(" ")
- tpl.add " "
- if is_intro then
- tpl.add html_link
- tpl.add html_signature
- else
- tpl.add mproperty.intro.html_link
- tpl.add html_short_signature
- end
- tpl.add "</span>"
- return tpl
- end
-
- # Returns `mclassdef::self`
- redef fun html_namespace do
- var tpl = new Template
- tpl.add mclassdef.html_namespace
- tpl.add "::"
- tpl.add html_link
- return tpl
- end
-
- # Returns the MPropdDef signature without static types.
- fun html_short_signature: Template is abstract
-
- # Returns the MPropDef signature with static types.
- fun html_signature: Template is abstract
-
- redef fun css_classes do
- var set = new HashSet[String]
- if is_intro then set.add "intro"
- for m in mproperty.intro.modifiers do set.add m.to_cmangle
- for m in modifiers do set.add m.to_cmangle
- return set.to_a
- end
-
- # List of all modifiers like redef, private, abstract, intern, fun etc.
- var modifiers: Array[String] is lazy do
- var res = new Array[String]
- if not is_intro then
- res.add "redef"
- else
- res.add mproperty.visibility.to_s
- end
- var mprop = self
- if mprop isa MVirtualTypeDef then
- res.add "type"
- else if mprop isa MMethodDef then
- if mprop.is_abstract then
- res.add "abstract"
- else if mprop.is_intern then
- res.add "intern"
- end
- if mprop.mproperty.is_init then
- res.add "init"
- else
- res.add "fun"
- end
- end
- return res
- end
-end
-
-redef class MAttributeDef
-
- redef fun html_modifiers do
- var res = super
- res.add "var"
- return res
- end
-
- redef fun html_short_signature do return new Template
-
- redef fun html_signature do
- var static_mtype = self.static_mtype
- var tpl = new Template
- if static_mtype != null then
- tpl.add ": "
- tpl.add static_mtype.html_signature
- end
- return tpl
- end
-end
-
-redef class MMethodDef
-
- # FIXME annotation should be handled in their own way
- redef fun html_modifiers do
- if mproperty.is_init then
- var res = new Array[String]
- if mproperty.visibility != public_visibility then
- res.add mproperty.visibility.to_s
- end
- return res
- end
- var res = super
- if is_abstract then
- res.add "abstract"
- else if is_intern then
- res.add "intern"
- end
- res.add "fun"
- return res
- end
-
- redef fun html_declaration do
- if mproperty.is_init then
- var tpl = new Template
- tpl.add "<span>"
- tpl.add html_modifiers.join(" ")
- tpl.add " "
- tpl.add html_link
- tpl.add html_signature
- tpl.add "</span>"
- return tpl
- end
- return super
- end
-
- redef fun html_short_signature do
- var new_msignature = self.new_msignature
- if mproperty.is_root_init and new_msignature != null then
- return new_msignature.html_short_signature
- end
- return msignature.as(not null).html_short_signature
- end
-
- redef fun html_signature do
- var new_msignature = self.new_msignature
- if mproperty.is_root_init and new_msignature != null then
- return new_msignature.html_signature
- end
- return msignature.as(not null).html_signature
- end
-end
-
-redef class MVirtualTypeProp
- redef fun html_link do return mvirtualtype.html_link
-end
-
-redef class MVirtualTypeDef
-
- redef fun html_modifiers do
- var res = super
- res.add "type"
- return res
- end
-
- redef fun html_short_signature do return new Template
-
- redef fun html_signature do
- var bound = self.bound
- var tpl = new Template
- if bound == null then return tpl
- tpl.add ": "
- tpl.add bound.html_signature
- return tpl
- end
-end
-
-redef class MType
- # Returns the signature of this type whithout bounds.
- fun html_short_signature: Template is abstract
-
- # Returns the signature of this type.
- fun html_signature: Template is abstract
-end
-
-redef class MClassType
- redef fun html_link do return mclass.html_link
- redef fun html_short_signature do return html_link
- redef fun html_signature do return html_link
-end
-
-redef class MNullableType
- redef fun html_short_signature do
- var tpl = new Template
- tpl.add "nullable "
- tpl.add mtype.html_short_signature
- return tpl
- end
-
- redef fun html_signature do
- var tpl = new Template
- tpl.add "nullable "
- tpl.add mtype.html_signature
- return tpl
- end
-end
-
-redef class MGenericType
- redef fun html_short_signature do
- var lnk = html_link
- var tpl = new Template
- tpl.add new Link(lnk.href, mclass.name.html_escape, lnk.title)
- tpl.add "["
- for i in [0..arguments.length[ do
- tpl.add arguments[i].html_short_signature
- if i < arguments.length - 1 then tpl.add ", "
- end
- tpl.add "]"
- return tpl
- end
-
- redef fun html_signature do
- var lnk = html_link
- var tpl = new Template
- tpl.add new Link(lnk.href, mclass.name.html_escape, lnk.title)
- tpl.add "["
- for i in [0..arguments.length[ do
- tpl.add arguments[i].html_signature
- if i < arguments.length - 1 then tpl.add ", "
- end
- tpl.add "]"
- return tpl
- end
-end
-
-redef class MParameterType
- redef fun html_short_signature do return html_link
- redef fun html_signature do return html_link
-end
-
-redef class MVirtualType
- redef fun html_signature do return html_link
-end
-
-redef class MSignature
- redef fun html_short_signature do
- var tpl = new Template
- if not mparameters.is_empty then
- tpl.add "("
- for i in [0..mparameters.length[ do
- tpl.add mparameters[i].html_short_signature
- if i < mparameters.length - 1 then tpl.add ", "
- end
- tpl.add ")"
- end
- return tpl
- end
-
- redef fun html_signature do
- var tpl = new Template
- if not mparameters.is_empty then
- tpl.add "("
- for i in [0..mparameters.length[ do
- tpl.add mparameters[i].html_signature
- if i < mparameters.length - 1 then tpl.add ", "
- end
- tpl.add ")"
- end
- var return_mtype = self.return_mtype
- if return_mtype != null then
- tpl.add ": "
- tpl.add return_mtype.html_signature
- end
- return tpl
- end
-end
-
-redef class MParameter
-
- # Returns `self` name and ellipsys if any.
- fun html_short_signature: Template do
- var tpl = new Template
- tpl.add name
- if is_vararg then tpl.add "..."
- return tpl
- end
-
- # Returns `self` name with it's static type and ellipsys if any.
- fun html_signature: Template do
- var tpl = new Template
- tpl.add "{name}: "
- tpl.add mtype.html_signature
- if is_vararg then tpl.add "..."
- return tpl
- end
-end
-
-redef class MEntityTree
- # Render `self` as a hierarchical UnorderedList.
- fun html_list: UnorderedList do
- var lst = new_unordered_list
- for r in roots do
- var li = new_mentity_item(r)
- lst.add_li li
- build_html_list(r, li)
- end
- return lst
- end
-
- # Build the html list recursively.
- private fun build_html_list(e: MEntity, li: ListItem) do
- if not sub.has_key(e) then return
- var subs = sub[e]
- var lst = new_unordered_list
- for e2 in subs do
- if e2 isa MGroup and e2.is_root then
- build_html_list(e2, li)
- else
- var sli = new_mentity_item(e2)
- lst.add_li sli
- build_html_list(e2, sli)
- end
- end
- var text = new Template
- text.add li.text
- if not lst.is_empty then text.add lst
- li.text = text
- end
-
- # HTML unordered List used to compose the tree.
- #
- # Redefine this method to add custom CSS classes or other html attributes.
- protected fun new_unordered_list: UnorderedList do return new UnorderedList
-
- # Return a li element for `mconcern` that can be displayed in a concern list
- protected fun new_mentity_item(mentity: MEntity): ListItem do
- var tpl = new Template
- tpl.add mentity.html_link
- var comment = mentity.html_synopsis
- if comment != null then
- tpl.add ": "
- tpl.add comment
- end
- return new ListItem(tpl)
- end
-end
+++ /dev/null
-# 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