Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions esdoc-integrate-manual-plugin/src/Plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,27 @@ class Plugin {
}

for (const filePath of manual.files) {
results.push({
kind: 'manual',
longname: path.resolve(filePath),
name: filePath,
content: fs.readFileSync(filePath).toString(),
static: true,
access: 'public'
});
if (typeof filePath === "string") {
results.push({
kind: 'manual',
longname: path.resolve(filePath),
name: filePath,
content: fs.readFileSync(filePath).toString(),
static: true,
access: 'public'
});
} else if (typeof filePath === "object") {
const {src, destPrefix} = filePath;
results.push({
kind: 'manual',
longname: path.resolve(src),
name: src,
destPrefix: destPrefix,
content: fs.readFileSync(src).toString(),
static: true,
access: 'public'
});
}
}

return results;
Expand Down
10 changes: 9 additions & 1 deletion esdoc-integrate-manual-plugin/test/esdoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@
"./test/manual/example.md",
"./test/manual/advanced.md",
"./test/manual/faq.md",
"./test/CHANGELOG.md"
"./test/CHANGELOG.md",
{
"src": "./test/manual/destPrefixChange.md",
"destPrefix": "dest1"
},
{
"src": "./test/manual/destPrefixChange.md",
"destPrefix": "dest2"
}
]
}
}
Expand Down
8 changes: 8 additions & 0 deletions esdoc-integrate-manual-plugin/test/manual/all.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,12 @@ describe('test/manual:', ()=>{
const doc = find('longname', /CHANGELOG.md$/);
assert.equal(doc.content, file(doc.name));
});

it('has manual file(s) with destination prefix', () => {
const [doc1, doc2] = find('destPrefix', /dest1/, /dest2/);
assert.equal(doc1.content, file(doc1.name));
assert.equal(doc1.destPrefix, 'dest1');
assert.equal(doc2.content, file(doc2.name));
assert.equal(doc2.destPrefix, 'dest2');
});
});
2 changes: 2 additions & 0 deletions esdoc-integrate-manual-plugin/test/manual/destPrefixChange.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Destination Prefix
this file is generated in different prefix locations
2 changes: 1 addition & 1 deletion esdoc-integrate-manual-plugin/test/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ exports.find = function(key, ...values) {
for (const value of values) {
const result = global.docs.find(doc => {
if (typeof value === 'string') return doc[key] === value;
if (value instanceof RegExp) return doc[key].match(value);
if (value instanceof RegExp) return doc[key] && doc[key].match(value);
});

results.push(result);
Expand Down
284 changes: 284 additions & 0 deletions esdoc-publish-html-plugin/out/src/Builder/ClassDocBuilder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});

var _iceCap = require('ice-cap');

var _iceCap2 = _interopRequireDefault(_iceCap);

var _DocBuilder = require('./DocBuilder.js');

var _DocBuilder2 = _interopRequireDefault(_DocBuilder);

var _util = require('./util.js');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
* Class Output Builder class.
*/
class ClassDocBuilder extends _DocBuilder2.default {
exec(writeFile) {
const ice = this._buildLayoutDoc();
ice.autoDrop = false;
const docs = this._find({ kind: ['class'] });
for (const doc of docs) {
const fileName = this._getOutputFileName(doc);
const baseUrl = this._getBaseUrl(fileName);
const title = this._getTitle(doc);
ice.load('content', this._buildClassDoc(doc), _iceCap2.default.MODE_WRITE);
ice.attr('baseUrl', 'href', baseUrl, _iceCap2.default.MODE_WRITE);
ice.text('title', title, _iceCap2.default.MODE_WRITE);
writeFile(fileName, ice.html);
}
}

/**
* build class output.
* @param {DocObject} doc - class doc object.
* @returns {IceCap} built output.
* @private
*/
_buildClassDoc(doc) {
const expressionExtends = this._buildExpressionExtendsHTML(doc);
const mixinClasses = this._buildMixinClassesHTML(doc);
const extendsChain = this._buildExtendsChainHTML(doc);
const directSubclass = this._buildDirectSubclassHTML(doc);
const indirectSubclass = this._buildIndirectSubclassHTML(doc);
const instanceDocs = this._find({ kind: 'variable' }).filter(v => {
return v.type && v.type.types.includes(doc.longname);
});

const ice = new _iceCap2.default(this._readTemplate('class.html'));

// header
if (doc.export && doc.importPath && doc.importStyle) {
const link = this._buildFileDocLinkHTML(doc, doc.importPath);
ice.into('importPath', `import ${doc.importStyle} from '${link}'`, (code, ice) => {
ice.load('importPathCode', code);
});
}
ice.text('access', doc.access);
ice.text('kind', doc.interface ? 'interface' : 'class');
ice.load('source', this._buildFileDocLinkHTML(doc, 'source'), 'append');
ice.text('since', doc.since, 'append');
ice.text('version', doc.version, 'append');
ice.load('variation', this._buildVariationHTML(doc), 'append');

ice.into('expressionExtends', expressionExtends, (expressionExtends, ice) => ice.load('expressionExtendsCode', expressionExtends));
ice.load('mixinExtends', mixinClasses, 'append');
ice.load('extendsChain', extendsChain, 'append');
ice.load('directSubclass', directSubclass, 'append');
ice.load('indirectSubclass', indirectSubclass, 'append');
ice.load('implements', this._buildDocsLinkHTML(doc.implements, null, false, ', '), 'append');
ice.load('indirectImplements', this._buildDocsLinkHTML(doc._custom_indirect_implements, null, false, ', '), 'append');
ice.load('directImplemented', this._buildDocsLinkHTML(doc._custom_direct_implemented, null, false, ', '), 'append');
ice.load('indirectImplemented', this._buildDocsLinkHTML(doc._custom_indirect_implemented, null, false, ', '), 'append');

// self
ice.text('name', doc.name);
ice.load('description', doc.description);
ice.load('deprecated', this._buildDeprecatedHTML(doc));
ice.load('experimental', this._buildExperimentalHTML(doc));
ice.load('see', this._buildDocsLinkHTML(doc.see), 'append');
ice.load('todo', this._buildDocsLinkHTML(doc.todo), 'append');
ice.load('decorator', this._buildDecoratorHTML(doc), 'append');

ice.into('instanceDocs', instanceDocs, (instanceDocs, ice) => {
ice.loop('instanceDoc', instanceDocs, (i, instanceDoc, ice) => {
ice.load('instanceDoc', this._buildDocLinkHTML(instanceDoc.longname));
});
});

ice.into('exampleDocs', doc.examples, (examples, ice) => {
ice.loop('exampleDoc', examples, (i, example, ice) => {
const parsed = (0, _util.parseExample)(example);
ice.text('exampleCode', parsed.body);
ice.text('exampleCaption', parsed.caption);
});
});

ice.into('tests', doc._custom_tests, (tests, ice) => {
ice.loop('test', tests, (i, test, ice) => {
const testDoc = this._find({ longname: test })[0];
ice.load('test', this._buildFileDocLinkHTML(testDoc, testDoc.testFullDescription));
});
});

// summary
ice.load('staticMemberSummary', this._buildSummaryHTML(doc, 'member', 'Members', true));
ice.load('staticMethodSummary', this._buildSummaryHTML(doc, 'method', 'Methods', true));
ice.load('constructorSummary', this._buildSummaryHTML(doc, 'constructor', 'Constructor', false));
ice.load('memberSummary', this._buildSummaryHTML(doc, 'member', 'Members', false));
ice.load('methodSummary', this._buildSummaryHTML(doc, 'method', 'Methods', false));

ice.load('inheritedSummary', this._buildInheritedSummaryHTML(doc), 'append');

// detail
ice.load('staticMemberDetails', this._buildDetailHTML(doc, 'member', 'Members', true));
ice.load('staticMethodDetails', this._buildDetailHTML(doc, 'method', 'Methods', true));
ice.load('constructorDetails', this._buildDetailHTML(doc, 'constructor', 'Constructors', false));
ice.load('memberDetails', this._buildDetailHTML(doc, 'member', 'Members', false));
ice.load('methodDetails', this._buildDetailHTML(doc, 'method', 'Methods', false));

return ice;
}

/**
* build variation of doc.
* @param {DocObject} doc - target doc object.
* @returns {string} variation links html.
* @private
* @experimental
*/
_buildVariationHTML(doc) {
const variationDocs = this._find({ memberof: doc.memberof, name: doc.name });
const html = [];
for (const variationDoc of variationDocs) {
if (variationDoc.variation === doc.variation) continue;

html.push(this._buildDocLinkHTML(variationDoc.longname, `(${variationDoc.variation || 1})`));
}

return html.join(', ');
}

/**
* build mixin extends html.
* @param {DocObject} doc - target class doc.
* @return {string} mixin extends html.
*/
_buildMixinClassesHTML(doc) {
if (!doc.extends) return '';
if (doc.extends.length <= 1) return '';

const links = [];
for (const longname of doc.extends) {
links.push(this._buildDocLinkHTML(longname));
}

return `<div>${links.join(', ')}</div>`;
}

/**
* build expression extends html.
* @param {DocObject} doc - target class doc.
* @return {string} expression extends html.
*/
_buildExpressionExtendsHTML(doc) {
if (!doc.expressionExtends) return '';

const html = doc.expressionExtends.replace(/[A-Z_$][a-zA-Z0-9_$]*/g, v => {
return this._buildDocLinkHTML(v);
});

return `class ${doc.name} extends ${html}`;
}

/**
* build class ancestor extends chain.
* @param {DocObject} doc - target class doc.
* @returns {string} extends chain links html.
* @private
*/
_buildExtendsChainHTML(doc) {
if (!doc._custom_extends_chains) return '';
if (doc.extends.length > 1) return '';

const links = [];
for (const longname of doc._custom_extends_chains) {
links.push(this._buildDocLinkHTML(longname));
}

links.push(doc.name);

return `<div>${links.join(' → ')}</div>`;
}

/**
* build in-direct subclass list.
* @param {DocObject} doc - target class doc.
* @returns {string} html of in-direct subclass links.
* @private
*/
_buildIndirectSubclassHTML(doc) {
if (!doc._custom_indirect_subclasses) return '';

const links = [];
for (const longname of doc._custom_indirect_subclasses) {
links.push(this._buildDocLinkHTML(longname));
}

return `<div>${links.join(', ')}</div>`;
}

/**
* build direct subclass list.
* @param {DocObject} doc - target class doc.
* @returns {string} html of direct subclass links.
* @private
*/
_buildDirectSubclassHTML(doc) {
if (!doc._custom_direct_subclasses) return '';

const links = [];
for (const longname of doc._custom_direct_subclasses) {
links.push(this._buildDocLinkHTML(longname));
}

return `<div>${links.join(', ')}</div>`;
}

/**
* build inherited method/member summary.
* @param {DocObject} doc - target class doc.
* @returns {string} html of inherited method/member from ancestor classes.
* @private
*/
_buildInheritedSummaryHTML(doc) {
if (['class', 'interface'].indexOf(doc.kind) === -1) return '';

const longnames = [...(doc._custom_extends_chains || [])
// ...doc.implements || [],
// ...doc._custom_indirect_implements || [],
];

const html = [];
for (const longname of longnames) {
const superDoc = this._find({ longname })[0];

if (!superDoc) continue;

const targetDocs = this._find({ memberof: longname, kind: ['member', 'method', 'get', 'set'] });

targetDocs.sort((a, b) => {
if (a.static !== b.static) return -(a.static - b.static);

let order = { get: 0, set: 0, member: 1, method: 2 };
if (order[a.kind] !== order[b.kind]) {
return order[a.kind] - order[b.kind];
}

order = { public: 0, protected: 1, private: 2 };
if (a.access !== b.access) return order[a.access] - order[b.access];

if (a.name !== b.name) return a.name < b.name ? -1 : 1;

order = { get: 0, set: 1, member: 2 };
return order[a.kind] - order[b.kind];
});

const title = `<span class="toggle closed"></span> From ${superDoc.kind} ${this._buildDocLinkHTML(longname, superDoc.name)}`;
const result = this._buildSummaryDoc(targetDocs, '----------');
if (result) {
result.load('title', title, _iceCap2.default.MODE_WRITE);
html.push(result.html);
}
}

return html.join('\n');
}
}
exports.default = ClassDocBuilder;
Loading