build(aio): map H3 headings into H4 headings for certain templates (#24000)
The sections such as methods and decorator options are already headed by a H3 heading so we need to map the H3 headings in the API doc source down to H4 headings. This commit includes general heading mapping functionality accessible via the `marked` Nunjucks filter. PR Close #24000
This commit is contained in:
parent
e371b226fa
commit
77309e2ea4
|
@ -5,5 +5,5 @@ var Package = require('dgeni').Package;
|
||||||
* @description Overrides the renderMarkdown service with an implementation based on remark
|
* @description Overrides the renderMarkdown service with an implementation based on remark
|
||||||
*/
|
*/
|
||||||
module.exports = new Package('remark', ['nunjucks'])
|
module.exports = new Package('remark', ['nunjucks'])
|
||||||
|
.factory(require('./services/markedNunjucksFilter'))
|
||||||
.factory(require('./services/renderMarkdown'));
|
.factory(require('./services/renderMarkdown'));
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Convert the value, as markdown, into HTML
|
||||||
|
* @param headingMappings A map of headings to convert (e.g. from h3 to h4).
|
||||||
|
*/
|
||||||
|
module.exports = function markedNunjucksFilter(renderMarkdown) {
|
||||||
|
return {
|
||||||
|
name: 'marked',
|
||||||
|
process: function(str, headingMappings) {
|
||||||
|
return str && renderMarkdown(str, headingMappings);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
const visit = require('unist-util-visit');
|
||||||
|
|
||||||
|
function headingToLevel(heading) {
|
||||||
|
const match = /^h(\d+)/.exec(heading);
|
||||||
|
return match ? match[1] : '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseMappings(mappings) {
|
||||||
|
const mapping = {};
|
||||||
|
Object.keys(mappings).forEach(key => mapping[headingToLevel(key)] = headingToLevel(mappings[key]));
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function mapHeadings(mappings) {
|
||||||
|
const headings = parseMappings(mappings || {});
|
||||||
|
return () => ast => {
|
||||||
|
const nodesToFix = [];
|
||||||
|
Object.keys(headings).forEach(heading => {
|
||||||
|
visit(ast, 'heading', node => {
|
||||||
|
if (node.depth === Number(heading)) {
|
||||||
|
nodesToFix.push(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the depth of the matched nodes
|
||||||
|
nodesToFix.forEach(node => node.depth = headings[node.depth]);
|
||||||
|
|
||||||
|
return ast;
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,25 +1,29 @@
|
||||||
const remark = require('remark');
|
const remark = require('remark');
|
||||||
const html = require('remark-html');
|
const html = require('remark-html');
|
||||||
const code = require('./handlers/code');
|
const code = require('./handlers/code');
|
||||||
|
const mapHeadings = require('./plugins/mapHeadings');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dgService renderMarkdown
|
* @dgService renderMarkdown
|
||||||
* @description
|
* @description
|
||||||
* Render the markdown in the given string as HTML.
|
* Render the markdown in the given string as HTML.
|
||||||
|
* @param headingMap A map of headings to convert.
|
||||||
|
* E.g. `{h3: 'h4'} will map heading 3 level into heading 4.
|
||||||
*/
|
*/
|
||||||
module.exports = function renderMarkdown() {
|
module.exports = function renderMarkdown() {
|
||||||
const handlers = { code };
|
return function renderMarkdownImpl(content, headingMap) {
|
||||||
const renderer = remark()
|
|
||||||
.use(inlineTagDefs)
|
const renderer = remark()
|
||||||
.use(noIndentedCodeBlocks)
|
.use(inlineTagDefs)
|
||||||
.use(plainHTMLBlocks)
|
.use(noIndentedCodeBlocks)
|
||||||
// USEFUL DEBUGGING CODE
|
.use(plainHTMLBlocks)
|
||||||
// .use(() => tree => {
|
// USEFUL DEBUGGING CODE
|
||||||
// console.log(require('util').inspect(tree, { colors: true, depth: 4 }));
|
// .use(() => tree => {
|
||||||
// })
|
// console.log(require('util').inspect(tree, { colors: true, depth: 4 }));
|
||||||
.use(html, { handlers });
|
// })
|
||||||
|
.use(mapHeadings(headingMap))
|
||||||
|
.use(html, { handlers: { code } });
|
||||||
|
|
||||||
return function renderMarkdownImpl(content) {
|
|
||||||
return renderer.processSync(content).toString();
|
return renderer.processSync(content).toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -95,4 +95,36 @@ describe('remark: renderMarkdown service', () => {
|
||||||
'</code-example>\n'
|
'</code-example>\n'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should map heading levels as specified', () => {
|
||||||
|
const content =
|
||||||
|
'# heading 1\n' +
|
||||||
|
'\n' +
|
||||||
|
'some paragraph\n' +
|
||||||
|
'\n' +
|
||||||
|
'## heading 2a\n' +
|
||||||
|
'\n' +
|
||||||
|
'some paragraph\n' +
|
||||||
|
'\n' +
|
||||||
|
'### heading 3\n' +
|
||||||
|
'\n' +
|
||||||
|
'some paragraph\n' +
|
||||||
|
'\n' +
|
||||||
|
'## heading 2b\n' +
|
||||||
|
'\n' +
|
||||||
|
'some paragraph\n' +
|
||||||
|
'\n';
|
||||||
|
const headingMappings = { h2: 'h3', h3: 'h5' };
|
||||||
|
const output = renderMarkdown(content, headingMappings);
|
||||||
|
expect(output).toEqual(
|
||||||
|
'<h1>heading 1</h1>\n' +
|
||||||
|
'<p>some paragraph</p>\n' +
|
||||||
|
'<h3>heading 2a</h3>\n' +
|
||||||
|
'<p>some paragraph</p>\n' +
|
||||||
|
'<h5>heading 3</h5>\n' +
|
||||||
|
'<p>some paragraph</p>\n' +
|
||||||
|
'<h3>heading 2b</h3>\n' +
|
||||||
|
'<p>some paragraph</p>\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -113,12 +113,24 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if method.description %}<tr>
|
|
||||||
|
{% if method.description -%}
|
||||||
|
<tr>
|
||||||
<td class="description">
|
<td class="description">
|
||||||
{$ method.description | marked $}
|
{$ method.description | marked({ h3: 'h4' }) $}
|
||||||
</td>
|
</td>
|
||||||
</tr>{% endif %}
|
</tr>
|
||||||
</tbody>
|
{%- endif %}
|
||||||
|
|
||||||
|
{% if method.usageNotes -%}
|
||||||
|
<tr>
|
||||||
|
<td class="usage-notes">
|
||||||
|
<h3>Usage Notes</h3>
|
||||||
|
{$ method.usageNotes | marked({ h3: 'h4' }) $}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{%- endif %}
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endmacro -%}
|
{% endmacro -%}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue