build(aio): automatically link code blocks to API docs
This commit is contained in:
parent
ecc356ecea
commit
a9d9aa18a0
|
@ -73,6 +73,7 @@
|
||||||
"fs-extra": "^2.1.2",
|
"fs-extra": "^2.1.2",
|
||||||
"globby": "^6.1.0",
|
"globby": "^6.1.0",
|
||||||
"hast-util-is-element": "^1.0.0",
|
"hast-util-is-element": "^1.0.0",
|
||||||
|
"hast-util-to-string": "^1.0.0",
|
||||||
"html": "^1.0.0",
|
"html": "^1.0.0",
|
||||||
"http-server": "^0.9.0",
|
"http-server": "^0.9.0",
|
||||||
"image-size": "^0.5.1",
|
"image-size": "^0.5.1",
|
||||||
|
|
|
@ -235,3 +235,8 @@ code-tabs md-tab-group *.mat-ripple-element, code-tabs md-tab-group *.mat-tab-bo
|
||||||
[role="tabpanel"] {
|
[role="tabpanel"] {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidenav-content code a {
|
||||||
|
color: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
|
@ -114,10 +114,11 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
.config(function(convertToJsonProcessor, postProcessHtml, EXPORT_DOC_TYPES) {
|
.config(function(convertToJsonProcessor, postProcessHtml, EXPORT_DOC_TYPES, autoLinkCode) {
|
||||||
const DOCS_TO_CONVERT = EXPORT_DOC_TYPES.concat([
|
const DOCS_TO_CONVERT = EXPORT_DOC_TYPES.concat([
|
||||||
'decorator', 'directive', 'pipe', 'module'
|
'decorator', 'directive', 'pipe', 'module'
|
||||||
]);
|
]);
|
||||||
convertToJsonProcessor.docTypes = convertToJsonProcessor.docTypes.concat(DOCS_TO_CONVERT);
|
convertToJsonProcessor.docTypes = convertToJsonProcessor.docTypes.concat(DOCS_TO_CONVERT);
|
||||||
postProcessHtml.docTypes = convertToJsonProcessor.docTypes.concat(DOCS_TO_CONVERT);
|
postProcessHtml.docTypes = convertToJsonProcessor.docTypes.concat(DOCS_TO_CONVERT);
|
||||||
|
autoLinkCode.docTypes = DOCS_TO_CONVERT;
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,6 +37,7 @@ module.exports = new Package('angular-base', [
|
||||||
.factory(require('./services/getImageDimensions'))
|
.factory(require('./services/getImageDimensions'))
|
||||||
|
|
||||||
.factory(require('./post-processors/add-image-dimensions'))
|
.factory(require('./post-processors/add-image-dimensions'))
|
||||||
|
.factory(require('./post-processors/auto-link-code'))
|
||||||
|
|
||||||
.config(function(checkAnchorLinksProcessor) {
|
.config(function(checkAnchorLinksProcessor) {
|
||||||
// This is disabled here to prevent false negatives for the `docs-watch` task.
|
// This is disabled here to prevent false negatives for the `docs-watch` task.
|
||||||
|
@ -123,12 +124,13 @@ module.exports = new Package('angular-base', [
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
.config(function(postProcessHtml, addImageDimensions) {
|
.config(function(postProcessHtml, addImageDimensions, autoLinkCode) {
|
||||||
addImageDimensions.basePath = path.resolve(AIO_PATH, 'src');
|
addImageDimensions.basePath = path.resolve(AIO_PATH, 'src');
|
||||||
postProcessHtml.plugins = [
|
postProcessHtml.plugins = [
|
||||||
require('./post-processors/autolink-headings'),
|
require('./post-processors/autolink-headings'),
|
||||||
addImageDimensions,
|
addImageDimensions,
|
||||||
require('./post-processors/h1-checker'),
|
require('./post-processors/h1-checker'),
|
||||||
|
autoLinkCode,
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
const visit = require('unist-util-visit');
|
||||||
|
const is = require('hast-util-is-element');
|
||||||
|
const textContent = require('hast-util-to-string');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically add in a link to the relevant document for simple
|
||||||
|
* code blocks, e.g. `<code>MyClass</code>` becomes
|
||||||
|
* `<code><a href="path/to/myclass">MyClass</a></code>`
|
||||||
|
*
|
||||||
|
* @property docTypes an array of strings. Only docs that have one of these docTypes
|
||||||
|
* will be linked to.
|
||||||
|
* Usually set to the API exported docTypes, e.g. "class", "function", "directive", etc.
|
||||||
|
*/
|
||||||
|
module.exports = function autoLinkCode(getDocFromAlias) {
|
||||||
|
autoLinkCodeImpl.docTypes = [];
|
||||||
|
return autoLinkCodeImpl;
|
||||||
|
|
||||||
|
function autoLinkCodeImpl() {
|
||||||
|
return (ast) => {
|
||||||
|
visit(ast, node => {
|
||||||
|
if (is(node, 'code')) {
|
||||||
|
const docs = getDocFromAlias(textContent(node));
|
||||||
|
if (docs.length === 1 && autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1) {
|
||||||
|
const link = {
|
||||||
|
type: 'element',
|
||||||
|
tagName: 'a',
|
||||||
|
properties: { href: docs[0].path },
|
||||||
|
children: node.children
|
||||||
|
};
|
||||||
|
node.children = [link];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,39 @@
|
||||||
|
var createTestPackage = require('../../helpers/test-package');
|
||||||
|
var Dgeni = require('dgeni');
|
||||||
|
|
||||||
|
describe('autoLinkCode post-processor', () => {
|
||||||
|
let processor, autoLinkCode, aliasMap;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const testPackage = createTestPackage('angular-base-package');
|
||||||
|
const dgeni = new Dgeni([testPackage]);
|
||||||
|
const injector = dgeni.configureInjector();
|
||||||
|
autoLinkCode = injector.get('autoLinkCode');
|
||||||
|
autoLinkCode.docTypes = ['class', 'pipe'];
|
||||||
|
aliasMap = injector.get('aliasMap');
|
||||||
|
processor = injector.get('postProcessHtml');
|
||||||
|
processor.docTypes = ['test-doc'];
|
||||||
|
processor.plugins = [autoLinkCode];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should insert an anchor into every code item that matches the id of an API doc', () => {
|
||||||
|
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||||
|
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||||
|
processor.$process([doc]);
|
||||||
|
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass">MyClass</a></code>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should insert an anchor into every code item that matches an alias of an API doc', () => {
|
||||||
|
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass', 'foo.MyClass'], path: 'a/b/myclass' });
|
||||||
|
const doc = { docType: 'test-doc', renderedContent: '<code>foo.MyClass</code>' };
|
||||||
|
processor.$process([doc]);
|
||||||
|
expect(doc.renderedContent).toEqual('<code><a href="a/b/myclass">foo.MyClass</a></code>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore code items that do not match a link to an API doc', () => {
|
||||||
|
aliasMap.addDoc({ docType: 'guide', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
|
||||||
|
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
|
||||||
|
processor.$process([doc]);
|
||||||
|
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue