build(aio): do not HTML format code-example contents (#15554)

The markdown renderer passes its output through an HTML pretty printer.
While this is good in most cases, it makes a mess of elements that expect
their content to be left untouched.

The pretty printer already ignores `pre` tags (and other built-ins) by
default. This fix allows us to specify other tags that should be left
alone.

Further it actually specifies this option for `code-example` and `code-pane`
tags, which expect to contain preformatted content.
This commit is contained in:
Pete Bacon Darwin
2017-03-28 16:22:44 +01:00
committed by Igor Minar
parent b7a89cec59
commit eac99c1b16
6 changed files with 48 additions and 21 deletions

View File

@ -201,7 +201,7 @@ module.exports =
// Configure nunjucks rendering of docs via templates
.config(function(
renderDocsProcessor, versionInfo, templateFinder, templateEngine, getInjectables) {
renderDocsProcessor, versionInfo, templateFinder, templateEngine, getInjectables, renderMarkdown) {
// Where to find the templates for the doc rendering
templateFinder.templateFolders = [TEMPLATES_PATH];
@ -228,6 +228,12 @@ module.exports =
renderDocsProcessor.helpers.relativePath = function(from, to) {
return path.relative(from, to);
};
// Tell the HTML formatter not to format code-example blocks
renderMarkdown.unformattedTags = [
'code-example',
'code-pane'
];
})

View File

@ -1,4 +1,10 @@
var rho = require('rho');
const rho = require('rho');
const { prettyPrint } = require('html');
const defaultUnformattedTags = [
'a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym',
'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre',
'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
/**
* @dgService renderMarkdown
@ -45,11 +51,18 @@ module.exports = function renderMarkdown() {
if (isBlock) compiler.out.push('<div>');
compiler.out.push(walk.substring(startIdx, endIdx + 1));
if (isBlock) compiler.out.push('</div>');
if (isBlock) compiler.out.push('</div>\n');
walk.startFrom(endIdx + 2);
return true;
};
return function renderMarkdownImpl(content) { return rho.toHtml(content, true); };
renderMarkdownImpl.unformattedTags = [];
return renderMarkdownImpl;
function renderMarkdownImpl(content) {
const rawHtml = new rho.BlockCompiler(rho.options).toHtml(content);
return prettyPrint(rawHtml, { indent_size: 2, unformatted: [...defaultUnformattedTags, ...renderMarkdownImpl.unformattedTags]});
};
};

View File

@ -1,7 +1,11 @@
const renderMarkdownFactory = require('./renderMarkdown');
const renderMarkdown = renderMarkdownFactory();
describe('rho: renderMarkdown service', () => {
let renderMarkdown;
beforeEach(() => {
renderMarkdown = renderMarkdownFactory();
});
it('should convert markdown to HTML', () => {
const content = '# heading 1\n' +
'\n' +
@ -17,13 +21,13 @@ describe('rho: renderMarkdown service', () => {
'<ul>\n' +
' <li>List item 1</li>\n' +
' <li>List item 2</li>\n' +
'</ul>\n');
'</ul>');
});
it('should not process markdown inside inline tags', () => {
const content = '# heading {@link some_url_path}';
const output = renderMarkdown(content);
expect(output).toEqual('<h1>heading {@link some_url_path}</h1>\n');
expect(output).toEqual('<h1>heading {@link some_url_path}</h1>');
});
it('should not put block level inline tags inside paragraphs', () => {
@ -36,6 +40,13 @@ describe('rho: renderMarkdown service', () => {
expect(output).toEqual(
'<p>A paragraph.</p>\n' +
'<div>{@example blah **blah** blah }</div>\n' +
'<p>Another paragraph</p>\n');
'<p>Another paragraph</p>');
});
it('should not format the contents of tags marked as unformatted ', () => {
renderMarkdown.unformattedTags = ['code-example'];
const content = '<code-example>\n abc\n def\n</code-example>';
const output = renderMarkdown(content);
expect(output).toEqual('<code-example>\n abc\n def\n</code-example>');
});
});