问题描述
我需要突出显示代码块,但与此同时,我需要将代码放在单独的编号行上,以便为每行代码留下注释,就像在Github上所做的一样。我设法做到了这一点,但是因为我突出显示了每一行的代码,所以多行上的“ sql”代码将无法正确突出显示(仅突出显示第一行),并且我无法解决此问题。你有什么建议吗?
if (data.success === 1) {
setCodeLanguage(translateLanguage(data.code.language));
let rows = [];
data.code.source_code.split("\n").forEach((line,index) => {
rows.push(
<tr key={index} className="line">
<td className="line-number">{index + 1}</td>
<td id={"plus" + index} className="plus-square-line">
<PlusSquareTwoTone className="plus-square" />
</td>
<td id={"codeblock" + index}
className={'language-' + codeLanguage} style={rowStyle}>
{line}
</td>
</tr>
);
});
setCodeRows(rows);
for (let i = 0; i < codeRows.length; ++i) {
hljs.highlightBlock(document.getElementById("codeblock" + i));
}
解决方法
您不能简单地在\n
上拆分输出,因为跨度可以跨越线边界:
var x = <span class="string>"This is a
really long string
that spans multiple lines
super annoying"</span>
您必须编写代码才能将其转换为:
var x = <span class="string">"This is a</span>
<span class="string">really long string</span>
<span class="string">that spans multiple lines</span>
<span class="string">super annoying"</span>
IE,您必须随时跟踪所有打开的标签,并在一行结束时将其关闭,然后在下一行开始之前将其打开。
可以说,这并不是Highlight.js的典型用例,因此您必须自己构建它。
没有简单的方法,但是如果您访问原始解析树(而不是生成的HTML),则可以编写一些内容,逐节点遍历并找出行的位置是。如何访问解析树对象(发射器):
highlight(code).__emitter
或者您可以简单地用您自己的自定义发射器替换发射器。请参阅源文件以了解您需要实现的API:
https://github.com/highlightjs/highlight.js/blob/master/src/lib/token_tree.js
然后,您必须走在树上,跟踪打开了哪些标签,当发现行尾时,需要关闭标签...在下一行再次将其重新打开。 IE,您几乎需要从解析树开始并编写自己的HTML呈现引擎。
请注意:整个__emitter
API不被认为是公共API的一部分,并且在以后的更新中随时可能会更改或中断-尽管通常只要您做出以下声明就可以“相当安全”地使用一定要测试新版本。我没有计划在不久的将来对其进行重大更改。
[免责声明:我是当前的Highlight.js维护者。]