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