首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有prismjs的静态html生成-如何启用行号?

带有prismjs的静态html生成-如何启用行号?
EN

Stack Overflow用户
提问于 2019-12-28 05:34:00
回答 3查看 3.4K关注 0票数 7

我使用node.js从代码中生成静态html文件,并使用prismjs格式化它们。在我的应用程序中,我无法访问支持Javascript的HTML呈现程序(我使用的是'htmllite')。所以我需要能够生成不需要Javascript的HTML。

代码语言:javascript
复制
const Prism = require('prismjs');
const loadLanguages = require('prismjs/components/');
loadLanguages(['csharp']);
const code = '<a bunch of C# code>';
const html = Prism.highlight(code, Prism.languages.csharp, 'csharp');

这个很好用。但我想使用line-numbers插件,不知道如何使它工作。我的<pre>line-numbers类,我的左边框更大,但没有行号。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-03 10:55:31

PrismJS需要DOM才能让大多数插件工作。在查看plugins/line-numbers/prism-line-numbers.js#L109内部的代码之后,我们可以看到行号只是一个带有class="line-numbers-rows"span元素,它包含每个行的空span。我们可以在不使用DOM的情况下模拟这种行为,只需使用与prism-line-numbers相同的正则表达式来获取行号,然后组成一个具有span.line-numbers-rows的html代码的字符串,并为每一行添加一个空字符串<span></span>

Prism.highlight只运行两个钩子,before-tokenizeafter-tokenize。我们将使用after-tokenize组成一个lineNumbersWrapper字符串,其中包含span.line-numbers-rows元素和空的span行元素:

代码语言:javascript
复制
const Prism = require('prismjs');
const loadLanguages = require('prismjs/components/');
loadLanguages(['csharp']);

const code = `Console.WriteLine();
Console.WriteLine("Demo: Prism line-numbers plugin with nodejs");`;

// https://github.com/PrismJS/prism/blob/master/plugins/line-numbers/prism-line-numbers.js#L109
var NEW_LINE_EXP = /\n(?!$)/g;
var lineNumbersWrapper;

Prism.hooks.add('after-tokenize', function (env) {
  var match = env.code.match(NEW_LINE_EXP);
  var linesNum = match ? match.length + 1 : 1;
  var lines = new Array(linesNum + 1).join('<span></span>');

  lineNumbersWrapper = `<span aria-hidden="true" class="line-numbers-rows">${lines}</span>`;
});

const formated = Prism.highlight(code, Prism.languages.csharp, 'csharp');
const html = formated + lineNumbersWrapper;

console.log(html);

这将产生以下结果:

代码语言:javascript
复制
Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Demo: Generate invalid numbers"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span>

它的末尾有span.line-numbers-rows

代码语言:javascript
复制
<span aria-hidden="true" class="line-numbers-rows">
  <span></span>
  <span></span>
</span>

现在,如果我们在pre.language-csharp.line-numbers code.language-csharp元素中使用该输出,我们将得到正确的行号结果。检查这个只有themes/prism.cssplugins/line-numbers/prism-line-numbers.cssthemes/prism.css,并使用上面输出的代码正确地显示行号。

请注意,每一行(第一行除外)都必须标记代码才能正确显示,这是因为我们在pre.code块中,但我想您已经知道了。

更新

如果您不依赖CSS,并且您只想在每一行之前添加一个行号,那么您可以通过拆分所有行来添加一个行,并在开始时使用index + 1添加一个空格填充的padStart

代码语言:javascript
复制
const Prism = require('prismjs');
const loadLanguages = require('prismjs/components/');
loadLanguages(['csharp']);

const code = `Console.WriteLine();
Console.WriteLine("Demo: Prism line-numbers plugin with nodejs");`;

const formated = Prism.highlight(code, Prism.languages.csharp, 'csharp');

const html = formated
  .split('\n')
  .map((line, num) => `${(num + 1).toString().padStart(4, ' ')}. ${line}`)
  .join('\n');

console.log(html);

将产出:

代码语言:javascript
复制
   1. Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   2. Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span><span class="token string">"Demo: Prism line-numbers plugin with nodejs"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
票数 11
EN

Stack Overflow用户

发布于 2020-09-27 14:20:43

我有一个带有代码片段的React网站,我使用了类似于以下方式的prismjs节点模块:

SourceCode.js

代码语言:javascript
复制
import * as Prism from "prismjs";
export default function SourceCode(props) {
    return (
        <div>
            <div style={{ maxWidth: 900 }}>
                <pre className="language-javascript" style={{ backgroundColor: "#272822", fontSize: "0.8em" }}>
                    <code
                        style={{ fontFamily: "Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace" }}
                        dangerouslySetInnerHTML={{
                            __html: Prism.highlight(props.code, Prism.languages.javascript, "javascript"),
                        }}
                    />
                </pre>
            </div>
        </div>
    );
};

然后我决定添加行号插件,我很难弄清楚如何让它与Node.js一起工作并做出反应。问题是行号使用DOM,而不是简单地在Node.js中使用DOM。

我终于做了什么。我卸载了prismjs模块,并以一种旧的方式完成了它:)。

index.html

代码语言:javascript
复制
<html lang="en-us">
    <head>
        <meta charset="utf-8" />
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
        <title>SciChart Web Demo</title>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.21.0/themes/prism-okaidia.min.css" />
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.21.0/plugins/line-numbers/prism-line-numbers.min.css" />
        <script async type="text/javascript" src="bundle.js"></script>
    </head>
    <body>
        <div id="react-root"></div>
        <script>
            window.Prism = window.Prism || {};
            Prism.manual = true;
        </script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.21.0/prism.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.21.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
    </body>
</html>

SourceCode.js

代码语言:javascript
复制
import * as React from "react";

export default function SourceCode(props) {
    React.useEffect(() => {
        window.Prism.highlightAll();
    }, []);
    return (
        <div>
            <div style={{ maxWidth: 900 }}>
                <pre
                    className="language-javascript line-numbers"
                    style={{ backgroundColor: "#272822", fontSize: "0.8em" }}
                >
                    <code style={{ fontFamily: "Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace" }}>
                        {props.code}
                    </code>
                </pre>
            </div>
        </div>
    );
};
票数 1
EN

Stack Overflow用户

发布于 2020-01-03 01:09:13

也许这能帮你:

错误代码:

链接

(代码行超过堆栈溢出的限制!)

Codepen工作正常:

链接

(代码行超过堆栈溢出的限制!)

在两者之间的变化:

代码语言:javascript
复制
pre.line-numbers {
	position: relative;
	padding-left: 3.8em;
	counter-reset: linenumber;
}

pre.line-numbers>code {
	position: relative;
}

.line-numbers .line-numbers-rows {
	position: absolute;
	pointer-events: none;
	top: 0;
	font-size: 100%;
	left: -3.8em;
	width: 3em;
	/* works for line-numbers below 1000 lines */
	letter-spacing: -1px;
	border-right: 1px solid #999;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}

.line-numbers-rows>span {
	pointer-events: none;
	display: block;
	counter-increment: linenumber;
}

.line-numbers-rows>span:before {
	content: counter(linenumber);
	color: #999;
	display: block;
	padding-right: 0.8em;
	text-align: right;
}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59508413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档