WIP on React renderer for any Markit-up syntax
This commit is contained in:
parent
862b85e4c3
commit
95008d8607
69
src/components/Widgets/MarkitupReactRenderer.js
Normal file
69
src/components/Widgets/MarkitupReactRenderer.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import React, { PropTypes } from 'react';
|
||||||
|
import MarkupIt, { Syntax, JSONUtils } from 'markup-it';
|
||||||
|
|
||||||
|
const defaultRenderers = {
|
||||||
|
'doc': 'article',
|
||||||
|
'header_one': 'h1',
|
||||||
|
'header_two': 'h2',
|
||||||
|
'header_three': 'h3',
|
||||||
|
'header_four': 'h4',
|
||||||
|
'header_five': 'h5',
|
||||||
|
'header_six': 'h6',
|
||||||
|
'paragraph': 'p',
|
||||||
|
'ordered_list': 'ol',
|
||||||
|
'unordered_list': 'ul',
|
||||||
|
'list_item': 'li',
|
||||||
|
'link': 'a',
|
||||||
|
'image': 'img',
|
||||||
|
'BOLD': 'strong',
|
||||||
|
'ITALIC': 'em',
|
||||||
|
'text': null,
|
||||||
|
'unstyled': null,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class MarkitupReactRenderer extends React.Component {
|
||||||
|
|
||||||
|
renderToken = (token) => {
|
||||||
|
const { type, data, text, tokens } = token;
|
||||||
|
const element = defaultRenderers[type];
|
||||||
|
|
||||||
|
// Only render if type is registered as renderer
|
||||||
|
if (typeof element !== 'undefined') {
|
||||||
|
let children = null;
|
||||||
|
if (Array.isArray(tokens) && tokens.length) {
|
||||||
|
children = tokens.map(this.renderToken);
|
||||||
|
} else if (type === 'text') {
|
||||||
|
children = text;
|
||||||
|
}
|
||||||
|
if (element !== null) {
|
||||||
|
// If this is a react element
|
||||||
|
return React.createElement(element, data, children);
|
||||||
|
} else {
|
||||||
|
// If this is a text node
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { value, syntax } = this.props;
|
||||||
|
|
||||||
|
if (typeof this.parser === 'undefined') {
|
||||||
|
this.parser = new MarkupIt(syntax);
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = this.parser.toContent(value);
|
||||||
|
const json = JSONUtils.encode(content);
|
||||||
|
// console.log(JSON.stringify(json, null, 2));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>{this.renderToken(json.token)}</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MarkitupReactRenderer.propTypes = {
|
||||||
|
value: PropTypes.string,
|
||||||
|
syntax: PropTypes.instanceOf(Syntax).isRequired
|
||||||
|
};
|
@ -0,0 +1,70 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import renderer from 'react-test-renderer';
|
||||||
|
import markdownSyntax from 'markup-it/syntaxes/markdown';
|
||||||
|
import htmlSyntax from 'markup-it/syntaxes/html';
|
||||||
|
import MarkitupReactRenderer from '../MarkitupReactRenderer';
|
||||||
|
|
||||||
|
describe('MarkitupReactRenderer', () => {
|
||||||
|
it('should render markdown', () => {
|
||||||
|
const value = `
|
||||||
|
# H1
|
||||||
|
|
||||||
|
Text with **bold** & _em_ elements
|
||||||
|
|
||||||
|
## H2
|
||||||
|
|
||||||
|
* ul item 1
|
||||||
|
* ul item 2
|
||||||
|
|
||||||
|
### H3
|
||||||
|
|
||||||
|
1. ol item 1
|
||||||
|
1. ol item 2
|
||||||
|
1. ol item 3
|
||||||
|
|
||||||
|
#### H4
|
||||||
|
|
||||||
|
[link title](http://google.com)
|
||||||
|
|
||||||
|
##### H5
|
||||||
|
|
||||||
|
![alt text](https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg)
|
||||||
|
|
||||||
|
###### H6
|
||||||
|
|
||||||
|
`;
|
||||||
|
const component = renderer.create(
|
||||||
|
<MarkitupReactRenderer
|
||||||
|
value={value}
|
||||||
|
syntax={markdownSyntax}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const tree = component.toJSON();
|
||||||
|
expect(tree).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support custom syntax', () => {
|
||||||
|
const value = `
|
||||||
|
`;
|
||||||
|
const component = renderer.create(
|
||||||
|
<MarkitupReactRenderer
|
||||||
|
value={value}
|
||||||
|
syntax={markdownSyntax}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const tree = component.toJSON();
|
||||||
|
expect(tree).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render HTML', () => {
|
||||||
|
const value = '<p class="test class">Paragraph with <em>inline</em> element</p>';
|
||||||
|
const component = renderer.create(
|
||||||
|
<MarkitupReactRenderer
|
||||||
|
value={value}
|
||||||
|
syntax={htmlSyntax}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const tree = component.toJSON();
|
||||||
|
expect(tree).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,90 @@
|
|||||||
|
exports[`MarkitupReactRenderer should render HTML 1`] = `
|
||||||
|
<div>
|
||||||
|
<article>
|
||||||
|
<p>
|
||||||
|
Paragraph with
|
||||||
|
<em>
|
||||||
|
inline
|
||||||
|
</em>
|
||||||
|
element
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`MarkitupReactRenderer should render markdown 1`] = `
|
||||||
|
<div>
|
||||||
|
<article>
|
||||||
|
<h1
|
||||||
|
id={null}>
|
||||||
|
H1
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
Text with
|
||||||
|
<strong>
|
||||||
|
bold
|
||||||
|
</strong>
|
||||||
|
&
|
||||||
|
<em>
|
||||||
|
em
|
||||||
|
</em>
|
||||||
|
elements
|
||||||
|
</p>
|
||||||
|
<h2
|
||||||
|
id={null}>
|
||||||
|
H2
|
||||||
|
</h2>
|
||||||
|
<ul>
|
||||||
|
<li
|
||||||
|
loose={false}>
|
||||||
|
ul item 1
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
loose={false}>
|
||||||
|
ul item 2
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3
|
||||||
|
id={null}>
|
||||||
|
H3
|
||||||
|
</h3>
|
||||||
|
<ol>
|
||||||
|
<li
|
||||||
|
loose={false}>
|
||||||
|
ol item 1
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
loose={false}>
|
||||||
|
ol item 2
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
loose={false}>
|
||||||
|
ol item 3
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<h4
|
||||||
|
id={null}>
|
||||||
|
H4
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
href="http://google.com">
|
||||||
|
link title
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<h5
|
||||||
|
id={null}>
|
||||||
|
H5
|
||||||
|
</h5>
|
||||||
|
<p>
|
||||||
|
<img
|
||||||
|
alt="alt text"
|
||||||
|
src="https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg" />
|
||||||
|
</p>
|
||||||
|
<h6
|
||||||
|
id={null}>
|
||||||
|
H6
|
||||||
|
</h6>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
`;
|
Loading…
x
Reference in New Issue
Block a user