【问题标题】:Is there a simple way to apply a custom theme to react-syntax-highlighter?有没有一种简单的方法可以将自定义主题应用于 react-syntax-highlighter?
【发布时间】:2021-02-06 17:01:28
【问题描述】:

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

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>
        </>
    );
};

Output Screenshot

【问题讨论】:

  • 请添加输入和预期输出的示例,以突出显示更改颜色时想要实现的目标。
  • 感谢@PdC - 我更新了问题以显示输入和输出,我面临的问题是输出中的颜色来自默认主题,而我更喜欢使用我的自己的主题颜色,无法弄清楚如何简单地做到这一点。

标签: javascript css reactjs styling react-syntax-highlighter


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

    我的配置,即看起来像这样:

    ...
    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>
        ...
        )
    }
    

    这将产生类似于在本文底部添加的 sn-p 中可见的输出。

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

    下面还添加了一个 CSS 文件作为 sn-p,它基本上定义了 VSCode 用于某些关键元素的颜色,我获得了如下图右侧的输出。出于比较目的,我还包括了 VSCode 的 dark+ 样式的原始样式以供参考。一些更改(例如更深的灰紫色背景)是故意的,因为它更适合页面的主题。

    进一步可以看出,虽然大多数颜色应该与 VSCode 在该主题中使用的颜色相似,但 RSH 返回的输出并不完全能够像 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>

    【讨论】:

      猜你喜欢
      • 2019-03-19
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多