Added support for rendering inlined HTML in MD documents

This commit is contained in:
Andrey Okonetchnikov 2016-09-26 13:18:22 +02:00
parent 1860a2389d
commit 20e681e7ec
3 changed files with 60 additions and 13 deletions

View File

@ -1,5 +1,6 @@
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import MarkupIt, { Syntax, BLOCKS, STYLES, ENTITIES } from 'markup-it'; import MarkupIt, { Syntax, BLOCKS, STYLES, ENTITIES } from 'markup-it';
import htmlSyntax from 'markup-it/syntaxes/html';
const defaultRenderers = { const defaultRenderers = {
[BLOCKS.DOCUMENT]: 'article', [BLOCKS.DOCUMENT]: 'article',
@ -8,7 +9,12 @@ const defaultRenderers = {
[BLOCKS.BLOCKQUOTE]: 'blockquote', [BLOCKS.BLOCKQUOTE]: 'blockquote',
[BLOCKS.PARAGRAPH]: 'p', [BLOCKS.PARAGRAPH]: 'p',
[BLOCKS.FOOTNOTE]: 'footnote', [BLOCKS.FOOTNOTE]: 'footnote',
[BLOCKS.HTML]: (props) => null, [BLOCKS.HTML]: (token) => {
return <MarkitupReactRenderer
value={token.get('raw')}
syntax={htmlSyntax}
/>;
},
[BLOCKS.HR]: 'hr', [BLOCKS.HR]: 'hr',
[BLOCKS.HEADING_1]: 'h1', [BLOCKS.HEADING_1]: 'h1',
[BLOCKS.HEADING_2]: 'h2', [BLOCKS.HEADING_2]: 'h2',
@ -39,6 +45,7 @@ function renderToken(token, index = 0, key = '0') {
const type = token.get('type'); const type = token.get('type');
const data = token.get('data'); const data = token.get('data');
const text = token.get('text'); const text = token.get('text');
const raw = token.get('raw');
const tokens = token.get('tokens'); const tokens = token.get('tokens');
const nodeType = defaultRenderers[type]; const nodeType = defaultRenderers[type];
key = `${key}.${index}`; key = `${key}.${index}`;
@ -52,7 +59,12 @@ function renderToken(token, index = 0, key = '0') {
children = text; children = text;
} }
if (nodeType !== null) { if (nodeType !== null) {
if (typeof nodeType === 'function') {
return nodeType(token);
}
// If this is a react element // If this is a react element
console.log(data.toJS());
return React.createElement( return React.createElement(
nodeType, nodeType,
{ key, ...data.toJS() }, // Add key as a prop { key, ...data.toJS() }, // Add key as a prop

View File

@ -81,6 +81,22 @@ Text with **bold** & _em_ elements
}); });
}); });
describe('Headings', () => {
for (const heading of [...Array(6).keys()]) {
it(`should render Heading ${heading + 1}`, () => {
const value = padStart(' Title', heading + 7, '#')
const component = shallow(
<MarkitupReactRenderer
value={value}
syntax={markdownSyntax}
/>
);
const tree = component.html();
expect(tree).toMatchSnapshot()
})
}
})
describe('Lists', () => { describe('Lists', () => {
it('should render lists', () => { it('should render lists', () => {
const value = ` const value = `
@ -121,8 +137,7 @@ I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]
/> />
); );
const tree = component.html(); const tree = component.html();
const expected = '<article><p>I get 10 times more traffic from <a href="http://google.com/" title="Google">Google</a> than from <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p></article>'; expect(tree).toMatchSnapshot();
expect(tree).toEqual(expected);
}); });
}); });
@ -136,8 +151,7 @@ I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]
/> />
); );
const tree = component.html(); const tree = component.html();
const expected = '<article><p>Use the <code>printf()</code> function.</p></article>'; expect(tree).toMatchSnapshot();
expect(tree).toEqual(expected);
}); });
it('should render code 2', () => { it('should render code 2', () => {
@ -149,8 +163,7 @@ I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]
/> />
); );
const tree = component.html(); const tree = component.html();
const expected = '<article><p><code>There is a literal backtick (`) here.</code></p></article>'; expect(tree).toMatchSnapshot();
expect(tree).toEqual(expected);
}); });
}); });
@ -159,10 +172,10 @@ I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]
const value = ` const value = `
# Title # Title
<dl> <ul>
<dt>Test HTML content</dt> <li>Test HTML content</li>
<dd>Testing HTML in Markdown</dd> <li>Testing HTML in Markdown</li>
</dl> </ul>
`; `;
const component = shallow( const component = shallow(
<MarkitupReactRenderer <MarkitupReactRenderer
@ -192,7 +205,7 @@ I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]
describe('HTML rendering', () => { describe('HTML rendering', () => {
it('should render HTML', () => { it('should render HTML', () => {
const value = '<p class="test class">Paragraph with <em>inline</em> element</p>'; const value = '<p>Paragraph with <em>inline</em> element</p>';
const component = shallow( const component = shallow(
<MarkitupReactRenderer <MarkitupReactRenderer
value={value} value={value}

View File

@ -1,9 +1,31 @@
exports[`MarkitupReactRenderer HTML rendering should render HTML 1`] = `"<article><p>Paragraph with <em>inline</em> element</p></article>"`; exports[`MarkitupReactRenderer HTML rendering should render HTML 1`] = `"<article><p>Paragraph with <em>inline</em> element</p></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Code should render code 1`] = `"<article><p>Use the <code>printf()</code> function.</p></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Code should render code 2 1`] = `"<article><p><code>There is a literal backtick (\`) here.</code></p></article>"`;
exports[`MarkitupReactRenderer Markdown rendering General should render markdown 1`] = `"<article><h1>H1</h1><p>Text with <strong>bold</strong> &amp; <em>em</em> elements</p><h2>H2</h2><ul><li>ul item 1</li><li>ul item 2</li></ul><h3>H3</h3><ol><li>ol item 1</li><li>ol item 2</li><li>ol item 3</li></ol><h4>H4</h4><p><a href=\"http://google.com\">link title</a></p><h5>H5</h5><p><img alt=\"alt text\" src=\"https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg\"/></p><h6>H6</h6></article>"`; exports[`MarkitupReactRenderer Markdown rendering General should render markdown 1`] = `"<article><h1>H1</h1><p>Text with <strong>bold</strong> &amp; <em>em</em> elements</p><h2>H2</h2><ul><li>ul item 1</li><li>ul item 2</li></ul><h3>H3</h3><ol><li>ol item 1</li><li>ol item 2</li><li>ol item 3</li></ol><h4>H4</h4><p><a href=\"http://google.com\">link title</a></p><h5>H5</h5><p><img alt=\"alt text\" src=\"https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg\"/></p><h6>H6</h6></article>"`;
exports[`MarkitupReactRenderer Markdown rendering HTML should render HTML as is using Markdown 1`] = `"<article><h1>Title</h1></article>"`; exports[`MarkitupReactRenderer Markdown rendering HTML should render HTML as is using Markdown 1`] = `"<article><h1>Title</h1><article><ul><li>Test HTML content</li><li>Testing HTML in Markdown</li></ul></article></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 1 1`] = `"<article><h1>Title</h1></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 2 1`] = `"<article><h2>Title</h2></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 3 1`] = `"<article><h3>Title</h3></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 4 1`] = `"<article><h4>Title</h4></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 5 1`] = `"<article><h5>Title</h5></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Headings should render Heading 6 1`] = `"<article><h6>Title</h6></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Links should render links 1`] = `"<article><p>I get 10 times more traffic from <a href=\"http://google.com/\" title=\"Google\">Google</a> than from <a href=\"http://search.yahoo.com/\" title=\"Yahoo Search\">Yahoo</a> or <a href=\"http://search.msn.com/\" title=\"MSN Search\">MSN</a>.</p></article>"`;
exports[`MarkitupReactRenderer Markdown rendering Lists should render lists 1`] = `"<article><ol><li>ol item 1</li><li>ol item 2<ul><li>Sublist 1</li><li>Sublist 2</li><li>Sublist 3<ol><li>Sub-Sublist 1</li><li>Sub-Sublist 2</li><li>Sub-Sublist 3</li></ol></li></ul></li><li>ol item 3</li></ol></article>"`; exports[`MarkitupReactRenderer Markdown rendering Lists should render lists 1`] = `"<article><ol><li>ol item 1</li><li>ol item 2<ul><li>Sublist 1</li><li>Sublist 2</li><li>Sublist 3<ol><li>Sub-Sublist 1</li><li>Sub-Sublist 2</li><li>Sub-Sublist 3</li></ol></li></ul></li><li>ol item 3</li></ol></article>"`;
exports[`MarkitupReactRenderer custom elements should extend default renderers with custom ones 1`] = `"<article><p></p></article>"`;
exports[`MarkitupReactRenderer custom elements should support custom syntax 1`] = `"<article></article>"`; exports[`MarkitupReactRenderer custom elements should support custom syntax 1`] = `"<article></article>"`;
exports[`MarkitupReactRenderer custom elements should support custom syntaxes 1`] = `"<article><p></p></article>"`;