如何使用Highlight.jsReact正确地逐行突出显示代码?

问题描述

我需要突出显示代码块,但与此同时,我需要将代码放在单独的编号行上,以便为每行代码留下注释,就像在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维护者。]