diff --git a/docs/angular.io-package/index.js b/docs/angular.io-package/index.js
new file mode 100644
index 0000000000..cdeb17f110
--- /dev/null
+++ b/docs/angular.io-package/index.js
@@ -0,0 +1,48 @@
+var path = require('canonical-path');
+var Package = require('dgeni').Package;
+var basePackage = require('../public-docs-package');
+
+var PARTIAL_PATH = 'partials';
+var MODULES_DOCS_PATH = PARTIAL_PATH + '/api';
+
+module.exports = new Package('angular.io', [basePackage])
+
+.factory(require('./services/renderMarkdown'))
+.processor(require('./processors/addJadeDataDocsProcessor'))
+
+// Configure rendering
+.config(function(templateFinder, templateEngine) {
+
+ templateFinder.templateFolders
+ .unshift(path.resolve(__dirname, 'templates'));
+})
+
+.config(function(writeFilesProcessor) {
+ writeFilesProcessor.outputFolder = 'dist/angular.io';
+})
+
+
+.config(function(computeIdsProcessor, computePathsProcessor, EXPORT_DOC_TYPES) {
+
+ computePathsProcessor.pathTemplates.push({
+ docTypes: ['module'],
+ pathTemplate: '${id}.html',
+ outputPathTemplate: MODULES_DOCS_PATH + '/${id}/index.jade'
+ });
+
+ computePathsProcessor.pathTemplates.push({
+ docTypes: EXPORT_DOC_TYPES,
+ pathTemplate: '${moduleDoc.id}/${name}-${docType}.html',
+ outputPathTemplate: MODULES_DOCS_PATH + '/${moduleDoc.id}/${name}-${docType}.jade',
+ });
+
+ computePathsProcessor.pathTemplates.push({
+ docTypes: ['jade-data'],
+ pathTemplate: '${originalDoc.id}/_data',
+ outputPathTemplate: MODULES_DOCS_PATH + '/${path}.json'
+ });
+})
+
+.config(function(getLinkInfo) {
+ getLinkInfo.relativeLinks = true;
+});
\ No newline at end of file
diff --git a/docs/angular.io-package/processors/addJadeDataDocsProcessor.js b/docs/angular.io-package/processors/addJadeDataDocsProcessor.js
new file mode 100644
index 0000000000..8421816a0c
--- /dev/null
+++ b/docs/angular.io-package/processors/addJadeDataDocsProcessor.js
@@ -0,0 +1,75 @@
+var _ = require('lodash');
+var path = require('canonical-path');
+
+var titleCase = function(text) {
+ return text.replace(/(.)(.*)/, function(_, first, rest) {
+ return first.toUpperCase() + rest;
+ });
+};
+
+/*
+* Create _data.json file for Harp pages
+*
+* http://harpjs.com/docs/development/metadata
+*
+* This method creates the meta data required for each page
+* such as the title, description, etc. This meta data is used
+* in the harp static site generator to create the title for headers
+* and the navigation used in the API docs
+*
+*/
+
+module.exports = function addJadeDataDocsProcessor(EXPORT_DOC_TYPES) {
+ return {
+ $runAfter: ['adding-extra-docs', 'cloneExportedFromDocs'],
+ $runBefore: ['extra-docs-added'],
+ $process: function(docs) {
+ var extraDocs = [];
+ var modules = [];
+
+
+ /*
+ * Create Data for Modules
+ *
+ * Modules must be public and have content
+ */
+
+ _.forEach(docs, function(doc) {
+ if (doc.docType === 'module' && doc.exports.length) {
+ modules.push(doc);
+
+ // GET DATA FOR INDEX PAGE OF MODULE SECTION
+ var indexPageInfo = [{
+ name: 'index',
+ title: _.map(path.basename(doc.fileInfo.baseName).split('_'), function(part) {
+ return titleCase(part);
+ }).join(' '),
+ intro: doc.description.replace('"', '\"').replace(/\r?\n|\r/g,"")
+ }];
+
+ // GET DATA FOR EACH PAGE (CLASS, VARS, FUNCTIONS)
+ var modulePageInfo = _.map(doc.exports, function(exportDoc) {
+ return {
+ name: exportDoc.name + '-' + exportDoc.docType,
+ title: exportDoc.name + ' ' + titleCase(exportDoc.docType)
+ };
+ });
+
+ //COMBINE PAGE DATA
+ var allPageData = indexPageInfo.concat(modulePageInfo);
+
+ // PUSH DATA TO EXTRA DOCS ARRAY
+ extraDocs.push({
+ id: doc.id + "-data",
+ docType: 'jade-data',
+ originalDoc: doc,
+ data: allPageData
+ });
+ }
+ });
+
+
+ return docs.concat(extraDocs);
+ }
+ };
+};
\ No newline at end of file
diff --git a/docs/angular.io-package/services/renderMarkdown.js b/docs/angular.io-package/services/renderMarkdown.js
new file mode 100644
index 0000000000..538fb0537c
--- /dev/null
+++ b/docs/angular.io-package/services/renderMarkdown.js
@@ -0,0 +1,52 @@
+var marked = require('marked');
+var Encoder = require('node-html-encoder').Encoder;
+var html2jade = require('html2jade');
+var indentString = require('indent-string');
+var S = require('string');
+
+// entity type encoder
+var encoder = new Encoder('entity');
+
+
+
+/**
+ * @dgService renderMarkdown
+ * @description
+ * Render the markdown in the given string as HTML.
+ */
+module.exports = function renderMarkdown(trimIndentation) {
+
+ var renderer = new marked.Renderer();
+
+ renderer.code = function(code, lang, escaped) {
+
+ var cssClasses = ['prettyprint', 'linenums'];
+ var trimmedCode = trimIndentation(code);
+
+ if(lang) {
+ if(lang=='html') {
+ trimmedCode = encoder.htmlEncode(trimmedCode);
+ }
+ cssClasses.push(this.options.langPrefix + escape(lang, true));
+ }
+
+ return 'pre(class="' + cssClasses.join(' ') + '")\n'
+ + indentString('code.\n', ' ', 2)
+ + trimmedCode;
+ };
+
+ renderer.heading = function (text, level, raw) {
+ var headingText = marked.Renderer.prototype.heading.call(renderer, text, level, raw);
+ var title = 'h2 ' + S(headingText).stripTags().s;
+
+ if (level==2) {
+ title = '.l-main-section\n' + indentString(title, ' ', 2) ;
+ }
+
+ return title;
+ };
+
+ return function(content) {
+ return marked(content, { renderer: renderer });
+ };
+};
\ No newline at end of file
diff --git a/docs/angular.io-package/templates/class.template.html b/docs/angular.io-package/templates/class.template.html
new file mode 100644
index 0000000000..cd31e928a3
--- /dev/null
+++ b/docs/angular.io-package/templates/class.template.html
@@ -0,0 +1,48 @@
+{% include "lib/paramList.html" -%}
+{% extends 'layout/base.template.html' -%}
+
+{% block body %}
+p.location-badge.
+ exported from {$ doc.moduleDoc.id $}
+ defined in {$ doc.location.start.source.name $}.js (line {$ doc.location.start.line $})
+
+:markdown
+{$ doc.description | indent(2, true) $}
+
+{%- if doc.constructorDoc or doc.members.length -%}
+.l-main-section
+ h2 Members
+
+{%- if doc.constructorDoc %}
+ .l-sub-section
+ h3 {$ doc.constructorDoc.name $}
+
+ {% if doc.constructorDoc.params %}
+ pre.prettyprint
+ code.
+ {$ doc.constructorDoc.name $}{$ paramList(doc.constructorDoc.params) | indent(4, true) | trim $}
+ {% endif %}
+ :markdown
+{$ doc.constructorDoc.description | indent(6, true) | replace('## Example', '') | replace('# Example', '') $}
+
+
+{% endif -%}
+
+{%- for member in doc.members %}
+ .l-sub-section
+ h3 {$ member.name $}
+
+ {% if member.params %}
+ pre.prettyprint
+ code.
+ {$ member.name $}{$ paramList(member.params) | indent(4, true) | trim $}
+ {% endif %}
+ :markdown
+{$ member.description | indent(6, true) | replace('## Example', '') | replace('# Example', '') $}
+
+
+
+{% endfor %}
+{%- endif -%}
+
+{% endblock %}
\ No newline at end of file
diff --git a/docs/angular.io-package/templates/function.template.html b/docs/angular.io-package/templates/function.template.html
new file mode 100644
index 0000000000..bd198ba0fe
--- /dev/null
+++ b/docs/angular.io-package/templates/function.template.html
@@ -0,0 +1,16 @@
+{% include "lib/paramList.html" -%}
+{% extends 'layout/base.template.html' -%}
+
+{% block body %}
+.l-main-section
+ h2(class="function export") {$ doc.name $}
+
+ p {$ paramList(doc.parameters) $}
+
+ p.location-badge.
+ exported from {$ doc.moduleDoc.id $}
+
+ :markdown
+{$ doc.description | indent(4, true) $}
+
+{% endblock %}
\ No newline at end of file
diff --git a/docs/angular.io-package/templates/jade-data.template.html b/docs/angular.io-package/templates/jade-data.template.html
new file mode 100644
index 0000000000..fcafb63db7
--- /dev/null
+++ b/docs/angular.io-package/templates/jade-data.template.html
@@ -0,0 +1,8 @@
+{
+{%- for item in doc.data %}
+ "{$ item.name $}" : {
+ "title" : "{$ item.title $}"{% if item.intro %},
+ "intro" : "{$ item.intro $}"{% endif %}
+ }{% if not loop.last %},{% endif %}
+{% endfor -%}
+}
\ No newline at end of file
diff --git a/docs/angular.io-package/templates/layout/base.template.html b/docs/angular.io-package/templates/layout/base.template.html
new file mode 100644
index 0000000000..16a0d9dc96
--- /dev/null
+++ b/docs/angular.io-package/templates/layout/base.template.html
@@ -0,0 +1 @@
+{% block body %}{% endblock %}
\ No newline at end of file
diff --git a/docs/angular.io-package/templates/lib/paramList.html b/docs/angular.io-package/templates/lib/paramList.html
new file mode 100644
index 0000000000..b84a8d7162
--- /dev/null
+++ b/docs/angular.io-package/templates/lib/paramList.html
@@ -0,0 +1,7 @@
+{% macro paramList(params) -%}
+ {%- if params -%}
+ ({%- for param in params -%}
+ {$ param | escape $}{% if not loop.last %}, {% endif %}
+ {%- endfor %})
+ {%- endif %}
+{%- endmacro -%}
\ No newline at end of file
diff --git a/docs/angular.io-package/templates/module.template.html b/docs/angular.io-package/templates/module.template.html
new file mode 100644
index 0000000000..497b3ca956
--- /dev/null
+++ b/docs/angular.io-package/templates/module.template.html
@@ -0,0 +1,11 @@
+{% extends 'layout/base.template.html' -%}
+{% block body -%}
+ul
+ for page, slug in public.docs[current.path[1]][current.path[2]][current.path[3]][current.path[4]]._data
+ if slug != 'index'
+ url = "/docs/" + current.path[1] + "/" + current.path[2] + "/" + current.path[3] + "/" + current.path[4] + "/" + slug + ".html"
+
+ li.c8
+ != partial("../../../../../_includes/_hover-card", {name: page.title, url: url })
+
+{% endblock %}
\ No newline at end of file
diff --git a/docs/angular.io-package/templates/var.template.html b/docs/angular.io-package/templates/var.template.html
new file mode 100644
index 0000000000..3ff0248082
--- /dev/null
+++ b/docs/angular.io-package/templates/var.template.html
@@ -0,0 +1,11 @@
+{% extends 'layout/base.template.html' %}
+
+{% block body %}
+.l-main-section
+ h2 {$ doc.name $} variable
+ p.location-badge.
+ exported from {$ doc.moduleDoc.id $}
+
+ :markdown
+{$ doc.description | indent(4, true) $}
+{% endblock %}
\ No newline at end of file
diff --git a/docs/links-package/index.js b/docs/links-package/index.js
index 86a835f19c..a3ffc71991 100644
--- a/docs/links-package/index.js
+++ b/docs/links-package/index.js
@@ -2,10 +2,10 @@ var Package = require('dgeni').Package;
module.exports = new Package('links', [])
-.factory(require('dgeni-packages/ngdoc/inline-tag-defs/link'))
+.factory(require('./inline-tag-defs/link'))
.factory(require('dgeni-packages/ngdoc/services/getAliases'))
.factory(require('dgeni-packages/ngdoc/services/getDocFromAlias'))
-.factory(require('dgeni-packages/ngdoc/services/getLinkInfo'))
+.factory(require('./services/getLinkInfo'))
.config(function(inlineTagProcessor, linkInlineTagDef) {
inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
diff --git a/docs/links-package/inline-tag-defs/link.js b/docs/links-package/inline-tag-defs/link.js
new file mode 100644
index 0000000000..a1c4c5a047
--- /dev/null
+++ b/docs/links-package/inline-tag-defs/link.js
@@ -0,0 +1,22 @@
+var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/;
+
+module.exports = function linkInlineTagDef(getLinkInfo, createDocMessage) {
+ return {
+ name: 'link',
+ description: 'Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors',
+ handler: function(doc, tagName, tagDescription) {
+
+ // Parse out the uri and title
+ return tagDescription.replace(INLINE_LINK, function(match, uri, title) {
+
+ var linkInfo = getLinkInfo(uri, title, doc);
+
+ if ( !linkInfo.valid ) {
+ throw new Error(createDocMessage(linkInfo.error, doc));
+ }
+
+ return "" + linkInfo.title + "";
+ });
+ }
+ };
+};
\ No newline at end of file
diff --git a/docs/links-package/services/getLInkInfo.js b/docs/links-package/services/getLInkInfo.js
new file mode 100644
index 0000000000..a0874329b5
--- /dev/null
+++ b/docs/links-package/services/getLInkInfo.js
@@ -0,0 +1,70 @@
+var _ = require('lodash');
+var path = require('canonical-path');
+
+/**
+ * @dgService getLinkInfo
+ * @description
+ * Get link information to a document that matches the given url
+ * @kind function
+ * @param {String} url The url to match
+ * @param {String} title An optional title to return in the link information
+ * @return {Object} The link information
+ *
+ * @property {boolean} relativeLinks Whether we expect the links to be relative to the originating doc
+ */
+module.exports = function getLinkInfo(getDocFromAlias, encodeCodeBlock, log) {
+
+ return function getLinkInfoImpl(url, title, currentDoc) {
+ var linkInfo = {
+ url: url,
+ type: 'url',
+ valid: true,
+ title: title || url
+ };
+
+ if ( !url ) {
+ throw new Error('Invalid url');
+ }
+
+ var docs = getDocFromAlias(url, currentDoc);
+
+ if ( docs.length > 1 ) {
+
+ linkInfo.valid = false;
+ linkInfo.error = 'Ambiguous link: "' + url + '".\n' +
+ docs.reduce(function(msg, doc) { return msg + '\n "' + doc.id + '" ('+ doc.docType + ') : (' + doc.area + ')'; }, 'Matching docs: ');
+
+ } else if ( docs.length === 1 ) {
+
+ linkInfo.url = docs[0].path;
+ linkInfo.title = title || encodeCodeBlock(docs[0].name, true);
+ linkInfo.type = 'doc';
+
+ if ( getLinkInfoImpl.relativeLinks && currentDoc && currentDoc.path ) {
+ var currentFolder = path.dirname(currentDoc.path);
+ var docFolder = path.dirname(linkInfo.url);
+ var relativeFolder = path.relative(path.join('/', currentFolder), path.join('/', docFolder));
+ linkInfo.url = path.join(relativeFolder, path.basename(linkInfo.url));
+ log.debug(currentDoc.path, docs[0].path, linkInfo.url);
+ }
+
+ } else if ( url.indexOf('#') > 0 ) {
+ var pathAndHash = url.split('#');
+ linkInfo = getLinkInfoImpl(pathAndHash[0], title, currentDoc);
+ linkInfo.url = linkInfo.url + '#' + pathAndHash[1];
+ return linkInfo;
+
+ } else if ( url.indexOf('/') === -1 && url.indexOf('#') !== 0 ) {
+
+ linkInfo.valid = false;
+ linkInfo.error = 'Invalid link (does not match any doc): "' + url + '"';
+
+ } else {
+
+ linkInfo.title = title || (( url.indexOf('#') === 0 ) ? url.substring(1) : path.basename(url, '.html'));
+
+ }
+
+ return linkInfo;
+ };
+};
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 8e8637581a..0a23dfa325 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -284,6 +284,18 @@ function createDocsTasks(publicBuild) {
createDocsTasks(true);
createDocsTasks(false);
+gulp.task('docs/angular.io', function() {
+ try {
+ var dgeni = new Dgeni([require('./docs/angular.io-package')]);
+ return dgeni.generate();
+ } catch(x) {
+ console.log(x);
+ console.log(x.stack);
+ throw x;
+ }
+});
+
+
// ------------------
// CI tests suites
diff --git a/package.json b/package.json
index 6f66189cd4..2ef510330b 100644
--- a/package.json
+++ b/package.json
@@ -73,6 +73,9 @@
"gulp-traceur": "0.17.*",
"gulp-typescript": "ivogabe/gulp-typescript#3422fbff06532ccc57368f3b4c8801de8f72ef27",
"gulp-webserver": "^0.8.7",
+ "html2jade": "^0.8.3",
+ "indent-string": "^1.2.1",
+ "js-beautify": "^1.5.5",
"js-yaml": "^3.2.7",
"karma": "^0.12.23",
"karma-chrome-launcher": "^0.1.4",
@@ -81,12 +84,14 @@
"karma-jasmine": "^0.2.2",
"lodash": "^2.4.1",
"madge": "^0.5.0",
+ "marked": "^0.3.3",
"merge": "^1.2.0",
"merge2": "^0.3.5",
"minijasminenode2": "^1.0.0",
"minimatch": "^2.0.1",
"minimist": "1.1.x",
"mock-fs": "^2.5.0",
+ "node-html-encoder": "0.0.2",
"parse5": "1.3.2",
"protractor": "2.0.0",
"q": "^1.0.1",
@@ -94,6 +99,7 @@
"sorted-object": "^1.0.0",
"source-map": "^0.3.0",
"sprintf-js": "1.0.*",
+ "string": "^3.1.1",
"symlink-or-copy": "^1.0.1",
"systemjs-builder": "^0.10.3",
"temp": "^0.8.1",