My solution was to implement a simple "markdown" like parser within my article view. The idea is to parse the markdown using regex and return JSX elements from those results. I'm not so good at regular expressions (this could probably be improved) but here goes :
module.exports = React.createClass({
//this regex matchs \n\n, all wrapping ** **, wrapping ''' '''
mainRegex: /(\n\n|\*\*(?:[\s\S]*?)\*\*|'''(?:[\s\S]*?)''')/g,
titleRegex : /(?:\*\*([\s\S]*?)\*\*)/,
codeRegex : /(?:'''([\s\S]*?)''')/,
getInitialState: function() {
return {
content: []
};
},
setContent: function() {
if (this.props.htmlContent && !this.state.content.length) this.setState( {content: this.formatText(this.props.htmlContent) });
},
formatText: function(_text) {
var _this = this;
var _content = [];
_text = _text.split(this.mainRegex);
_text.forEach(function(_frag) {
if (!/\n\n/g.test(_frag) ) {
if (_this.titleRegex.test(_frag)) _content.push( {type: "h2", value: _frag.match(_this.titleRegex)[1] } );
else if (_frag!=="") _content.push({type: "p", value: _frag});
} else if (_this.codeRegex.test(_frag)) {
_content.push( {type: "code", value: _frag.match(_this.codeRegex)[1] } );
}
});
return _content;
},
render: function() {
return <article>
{this.state.content.map(this.renderText)}
</article>;
},
renderText:function(_tag, i) {
switch (_tag.type) {
case "p":
return <p key={i}>{_tag.value}</p>;
break;
case "h2":
return <h2 key={i}>{_tag.value}</h2>;
break;
case "code":
return <pre key={i}><code clasName="js">{_tag.value}</code></pre>;
break;
}
},
componentDidUpdate: function() {
this.setContent();
this.highlightCode();
},
highlightCode: function() {
var _codeBlocks = document.getElementsByTagName('code');
for (var i = 0, j = _codeBlocks.length; i<j; ++i) {
hljs.highlightBlock(_codeBlocks[i]);
}
}
});