React:呈现语法高亮显示的代码块
React : Rendering a syntax highlighted code block
我正在使用React和JSX开发一个文章系统。我的文章有时会在内容中包含代码示例。我已经实现了highlight.js来为这些块添加样式。我的主要问题是我的文章使用HTML标记,因此我使用React的dangerouslySetInnerHTML方法。这可以正常工作,但当然,我的代码块中的任何HTML代码都会被解释为HTML。我想知道你们中是否有人对我应该如何实现这一点有任何见解。在安全地将其呈现为文本之前,我应该从内容中删除所有HTML并对其进行解析(使用markdown)吗?
感谢您阅读本文。
我使用带高亮的markdown,然后使用innerHtml。这是来自https://github.com/calitek/ProjectNotes.
'use strict';
var fs = require('fs');
var Remarkable = require('remarkable');
var hljs = require('highlight.js');
let lodash = require('lodash');
var md = new Remarkable({
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(lang, str).value;
} catch (err) {}
}
try {
return hljs.highlightAuto(str).value;
} catch (err) {}
return '';
}
});
var rootDataPath = './data';
var getFile = function(clientData, doneCallBack) {
let getNote = function(fileData) {
var filePath = rootDataPath + '/filenotes.json';
var notesReadCallBack = function(err, data){
if (err) doneCallBack({fileData: fileData, noteData: {note: 'error'}});
else {
let noteData;
var jsonData = JSON.parse(data.toString());
let noteRecord = lodash.findWhere(jsonData, {nodeid: clientData.nodeid});
if (noteRecord) {
let noteIndex = lodash.indexOf(jsonData, noteRecord);
noteData = jsonData[noteIndex];
} else {
noteData = {nodeid: clientData.nodeid, note: ""};
}
let returnObject = {
noteData: noteData,
fileData: fileData
}
return doneCallBack(returnObject);
}
};
fs.readFile(filePath, notesReadCallBack);
}
var fileReadCallBack = function(err, data){
if (err) doneCallBack({note: 'error'});
else {
let inData = data.toString();
let inFile = clientData.filePath;
if (inFile.endsWith('.js') || inFile.endsWith('.json') || inFile.endsWith('.css')) {
inData = '``` javascript'n' + inData + '```';
}
let outData = md.render(inData);
getNote(outData);
}
};
fs.readFile(clientData.filePath, fileReadCallBack);
};
我正在服务器上进行降价渲染。然后将其发送到组件。
import React from 'react';
let FileCtrlSty = {
height: '60%',
marginBottom: '20px',
width: '100%'
};
export default class FileCtrl extends React.Component {
render() {
let htmlDivSty = {height: '100%', width: '100%'}
if (this.props.fileData.startsWith('<pre>')) htmlDivSty.overflow = 'hidden';
else htmlDivSty.overflow = 'auto';
let fileHtml = {__html: this.props.fileData};
return (
<div id='FileCtrlSty' style={FileCtrlSty}>
<div dangerouslySetInnerHTML={fileHtml} style={htmlDivSty}></div>
</div>
);
}
}
我的解决方案是在我的文章视图中实现一个类似"markdown"的简单解析器。其思想是使用regex解析markdown,并从这些结果中返回JSX元素。我不太擅长正则表达式(这可能会有所改进),但现在来看:
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]);
}
}
});
相关文章:
- 从桌面读取python文件时高亮显示代码
- I'我试图在网页中添加一个javascript小片段,但它只是在页面上显示代码
- 扰流板显示代码
- 如何在AngularJS应用程序中显示代码块
- 使用 JavaScript 突出显示代码示例中的语法
- HTML 在服务器上运行时在 jQuery 中显示代码而不是字符
- 以编程方式显示代码中的弹出是否弹出
- 谷歌地图API:显示代码中的鼠标悬停窗口
- 悬停并显示代码
- JavaScript显示代码而不是运行
- 如何使用ACE编辑器突出显示代码
- 在CKEditor上显示代码,删除abbr标签
- 解析标记为HTML并突出显示代码语法
- 托管JS文件而不显示代码
- 如何在带有“节”的输出中显示代码编辑器HTML;页面滚动从html
- 我的javascript显示代码有个奇怪的bug
- 为什么JavaScript警告消息不工作?无法显示代码错误
- Jquery beautyofCode显示代码行从一个字符串
- 如何让用户张贴代码片段使用反引号和显示代码使用谷歌代码预置
- Chrome扩展:注入Javascript显示代码,而不是输出