5

我一直在尝试使用 react-syntax-highlighter 在渲染的文本编辑器上在我的网站上生成一段代码。我花了一段时间使用这个插件并喜欢它,但是我遇到了一个我找不到答案的问题。我想更改生成代码的一些颜色,但除了使用他们的默认主题选择之外,找不到任何其他方法来做到这一点。它们允许您将样式应用于背景和代码,但不能将样式应用于保存颜色的跨度,是否有任何简单的方法来创建和应用自定义主题,或者简单地针对特定类并更改它们的颜色?

import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { atomDark } from "react-syntax-highlighter/dist/esm/styles/prism";

const CodeDisplay = ({ active }) => {

const templateString = `
    const NewObject = New Shop(
        console.log('shop');
    )
`
    return (
        <>
            <SyntaxHighlighter
                language="jsx"
                style={atomDark}
                wrapLongLines
                customStyle={{
                    backgroundColor: "transparent",
                    opacity: "1",
                    marginTop: "-2rem",
                }}
                codeTagProps={{
                    style: {
                        color: "white",
                    },
                }}>
                {templateString}
            </SyntaxHighlighter>
        </>
    );
};

输出截图

4

2 回答 2

2

我认为最好的方法就是复制主题并进行编辑。

您在代码中导入的主题位于https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/src/styles/prism/atom-dark.js

您可以下载该文件,将其添加到您的源代码管理中并根据需要进行修改。然后只需将您编辑的文件导入您使用的任何地方SyntaxHighlighter

如果您做了很多您认为非常酷的更改,请考虑对库进行 PR,以便其他人也可以使用它!

于 2021-10-02T23:55:52.213 回答
2

为了在 Visual Studio Code 中设置类似于dark+主题的代码样式,最适合我的方法是指定useInlineStyles={false}防止 react-syntax-highlighter (RSH) 向生成的每个 span 元素添加内联 css 样式信息。然而,RSH 会为该对象指定一个特定的类名,进而允许您定义自己的 CSS 样式。

我的配置ie看起来像这样:

...
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter'
import ts from 'react-syntax-highlighter/dist/esm/languages/hljs/typescript';

import './rsh-style.css';

SyntaxHighlighter.registerLanguage('typescript', ts);


const calcMinLineNumberWidth = (code: string): string | null => {
    const lines = [...code].reduce((prev, current) => prev + (current === '\n' ? 1 : 0), 1);
    if (lines > 99) {
        return "50px";
    } else if (lines > 9) {
        return "40px";
    } else {
        return null;
    }
}

const highlightLine = (lineNumber: number, markLines: number[], color: string = "#FFDB81"):
    React.HTMLProps<HTMLElement> => {

    // only works when showLineNumbers and wrapLines are both enabled
    const style: React.CSSProperties = { display: "block", width: "fit-content" };
    if (markLines.includes(lineNumber)) {
        style.backgroundColor = color;
    }
    return { style };
}

const CodeList: FunctionComponent = (props: CodeListProps) => {
    const minWidth = calcMinLineNumberWidth(code);
    return (
    ...
        <div className="container">
            <div className="divider" />
            <SyntaxHighlighter language="typescript" style={style}
                className={"syntax-highlighter"}
                useInlineStyles={false}
                showLineNumbers={true}
                lineNumberStyle={{minWidth: minWidth}}
                wrapLines={true}
                lineProps={(line: number) => highlightLine(line, props.highlightLines, props.highlightColor)}
            >
                {code}
            </SyntaxHighlighter>
        </div>
    ...
    )
}

这将产生一个输出,如在本文底部添加的片段中可见。

词法分析器react-syntax-highlighter使用显然存在一些问题,因为在多行注释的情况下,由新行号指示的新行开始在此处注释为class="hljs-comment"明显不应该的情况。此外,还有很多东西无法识别,因此无法正确标记,因此在您选择的编辑器中突出显示代码可能不可行。

随着 CSS 文件也添加为下面的片段,它基本上定义了 VSCode 用于某些关键元素的颜色,我获得了如下图右侧的输出。出于比较目的,我还包括了dark+VSCode 样式的原始样式以供参考。像更灰紫色的背景这样的一些变化是故意的,因为它更适合页面的主题。

进一步可以看出,RSH 返回的输出不能像 VSCode 那样格式化代码,尽管大多数颜色应该与 VSCode 在该主题中使用的颜色相似,至少颜色选择器确实返回了这些颜色值。

在此处输入图像描述

右图中的第 19-21 行展示了通过lineProps属性中使用的相应函数突出显示的行,以防万一有人想知道为什么它们有不同的颜色。

.container {
    display: inline-block;
    position: relative;
    left: 0px;
    width: 760px;
}

.container > .syntax-highlighter {
    width:100%;
    height: 100%;
    color: #D4D4D4;
    /*background-color: #030003;*/
    background-color: rgb(40, 44, 52) !important;
    font-family: Droid Sans Mono;
    letter-spacing: 1.5px;
    border-radius: 15px;
    padding-top: 10px;
    padding-bottom: 10px;
    margin-left: -10px;
    font-weight: 500;
}

.container > .syntax-highlighter .language-typescript > span:hover {
    background-color: rgba(224, 224, 173, 0.2) !important;
}

.container > .syntax-highlighter .language-typescript .linenumber {
    color: rgb(126, 120, 135) !important;
    margin-left: 15px;
    margin-right: 15px;
    background-color: transparent;
    border-right: 2px solid rgb(126, 120, 135);
}

.container > .syntax-highlighter .language-typescript .linenumber:hover {
    color: rgb(213, 214, 133) !important;
    margin-left: 15px;
    margin-right: 15px;
}

.container > .syntax-highlighter .language-typescript .hljs-comment {
    color: #48a454;
    font-weight: 450;
}

.container > .syntax-highlighter .language-typescript .hljs-keyword {
    color: #d86fc0;
}

.container > .syntax-highlighter .language-typescript .hljs-function {
    color: #4098d7;
}

.container > .syntax-highlighter .language-typescript .hljs-title {
    color: #d8e2a9;
}

.container >.syntax-highlighter .language-typescript .hljs-tag {
    color: #d4d4d4;
}

.container >.syntax-highlighter .language-typescript .hljs-name {
    color: #4098d7;
}

.container >.syntax-highlighter .language-typescript .hljs-attr {
    color: #86ddff;
}

.container >.syntax-highlighter .language-typescript .hljs-string {
    color: #dc8a77;
}

.container >.syntax-highlighter .language-typescript .hljs-built_in {
    color: #00d5b0;
}
<div class="container"><pre class="hljs syntax-highlighter"><code class="language-typescript" style="white-space: pre;"><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">1</span><span class="hljs-comment">/**
</span></span><span style="display: block;" class="hljs-comment"><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">2</span> * Some multi-line comment
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">3</span><span class="hljs-comment"> */</span><span class="">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">4</span><span class=""></span><span class="hljs-keyword">import</span><span class=""> React </span><span class="hljs-keyword">from</span><span class=""> </span><span class="hljs-string">'react'</span><span class="">;
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">5</span><span class=""></span><span class="hljs-keyword">import</span><span class=""> logo </span><span class="hljs-keyword">from</span><span class=""> </span><span class="hljs-string">'./logo.svg'</span><span class="">;
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">6</span><span class=""></span><span class="hljs-keyword">import</span><span class=""> </span><span class="hljs-string">'./App.css'</span><span class="">;
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">7</span>
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; padding-right: 1em; text-align: right; user-select: none; min-width: 40px;">8</span><span class=""></span><span class="hljs-keyword">interface</span><span class=""> SomeInterface {
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">9</span><span class="">    </span><span class="hljs-attr">items</span><span class="">: </span><span class="hljs-built_in">string</span><span class="">[];
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">10</span>}
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">11</span>
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">12</span><span class=""></span><span class="hljs-keyword">type</span><span class=""> SomeType = {
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">13</span><span class="">    </span><span class="hljs-attr">items</span><span class="">: </span><span class="hljs-built_in">string</span><span class="">[];
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">14</span>}
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">15</span>
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">16</span><span class=""></span><span class="hljs-comment">// line comment</span><span class="">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">17</span><span class=""></span><span class="hljs-function hljs-keyword">function</span><span class="hljs-function"> </span><span class="hljs-function hljs-title">App</span><span class="hljs-function">(</span><span class="hljs-function">) </span><span class="">{
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">18</span><span class="">  </span><span class="hljs-keyword">return</span><span class=""> (
</span></span><span style="display: block; background-color: rgb(57, 61, 65);" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">19</span><span class="">    </span><span class="xml hljs-tag">&lt;</span><span class="xml hljs-tag hljs-name">div</span><span class="xml hljs-tag"> </span><span class="xml hljs-tag hljs-attr">className</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"App"</span><span class="xml hljs-tag">&gt;</span><span class="xml">
</span></span><span style="display: block; background-color: rgb(57, 61, 65);" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">20</span><span class="xml">      </span><span class="xml hljs-tag">&lt;</span><span class="xml hljs-tag hljs-name">header</span><span class="xml hljs-tag"> </span><span class="xml hljs-tag hljs-attr">className</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"App-header"</span><span class="xml hljs-tag">&gt;</span><span class="xml">
</span></span><span style="display: block; background-color: rgb(57, 61, 65);" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">21</span><span class="xml">        </span><span class="xml hljs-tag">&lt;</span><span class="xml hljs-tag hljs-name">img</span><span class="xml hljs-tag"> </span><span class="xml hljs-tag hljs-attr">src</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">{logo}</span><span class="xml hljs-tag"> </span><span class="xml hljs-tag hljs-attr">className</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"App-logo"</span><span class="xml hljs-tag"> </span><span class="xml hljs-tag hljs-attr">alt</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"logo"</span><span class="xml hljs-tag"> /&gt;</span><span class="xml">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">22</span><span class="xml">        </span><span class="xml hljs-tag">&lt;</span><span class="xml hljs-tag hljs-name">p</span><span class="xml hljs-tag">&gt;</span><span class="xml">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">23</span><span class="xml">          Edit </span><span class="xml hljs-tag">&lt;</span><span class="xml hljs-tag hljs-name">code</span><span class="xml hljs-tag">&gt;</span><span class="xml">src/App.tsx</span><span class="xml hljs-tag">&lt;/</span><span class="xml hljs-tag hljs-name">code</span><span class="xml hljs-tag">&gt;</span><span class="xml"> and save to reload.
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">24</span><span class="xml">        </span><span class="xml hljs-tag">&lt;/</span><span class="xml hljs-tag hljs-name">p</span><span class="xml hljs-tag">&gt;</span><span class="xml">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">25</span><span class="xml">        </span><span class="xml hljs-tag">&lt;</span><span class="xml hljs-tag hljs-name">a</span><span class="xml hljs-tag">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">26</span><span class="xml hljs-tag">          </span><span class="xml hljs-tag hljs-attr">className</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"App-link"</span><span class="xml hljs-tag">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">27</span><span class="xml hljs-tag">          </span><span class="xml hljs-tag hljs-attr">href</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"https://reactjs.org"</span><span class="xml hljs-tag">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">28</span><span class="xml hljs-tag">          </span><span class="xml hljs-tag hljs-attr">target</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"_blank"</span><span class="xml hljs-tag">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">29</span><span class="xml hljs-tag">          </span><span class="xml hljs-tag hljs-attr">rel</span><span class="xml hljs-tag">=</span><span class="xml hljs-tag hljs-string">"noopener noreferrer"</span><span class="xml hljs-tag">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">30</span><span class="xml hljs-tag">        &gt;</span><span class="xml">
</span></span><span style="display: block;" class="xml"><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">31</span>          Learn React
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">32</span><span class="xml">        </span><span class="xml hljs-tag">&lt;/</span><span class="xml hljs-tag hljs-name">a</span><span class="xml hljs-tag">&gt;</span><span class="xml">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">33</span><span class="xml">      </span><span class="xml hljs-tag">&lt;/</span><span class="xml hljs-tag hljs-name">header</span><span class="xml hljs-tag">&gt;</span><span class="xml">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">34</span><span class="xml">    </span><span class="xml hljs-tag">&lt;/</span><span class="xml hljs-tag hljs-name">div</span><span class="xml hljs-tag">&gt;</span><span class="">
</span></span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">35</span>  );
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">36</span>}
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">37</span>
</span><span style="display: block;" class=""><span class="comment linenumber react-syntax-highlighter-line-number" style="display: inline-block; min-width: 40px; padding-right: 1em; text-align: right; user-select: none;">38</span><span class=""></span><span class="hljs-keyword">export</span><span class=""> </span><span class="hljs-keyword">default</span><span class=""> App;</span></span></code></pre></div>

于 2021-09-30T10:46:09.590 回答