为 python pygments 生成自定义样式
Posted
技术标签:
【中文标题】为 python pygments 生成自定义样式【英文标题】:generating a custom Styling for python pygments 【发布时间】:2021-08-03 10:42:01 【问题描述】:我目前正在为我的网站使用 python pygments 来突出显示一些代码,并想调整一些使用的颜色。到目前为止,我已经尝试了以下方法:
from pygments.token import Keyword, Name, Comment, String, Error, \
Number, Operator, Generic
from pygments.formatters import htmlFormatter
class MyStyle(Style):
styles =
Comment: '#f00000',
Keyword: '#f00000',
Name: '#f00000',
Name.Function: '#f00000',
Name.Class: '#f00000',
String: '#f00000'
code = 'print("Hello World")'
result = highlight(code, Python3Lexer(), HtmlFormatter(style=MyStyle))
print(result)
打印出来
<div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World"</span><span class="p">)</span>
</pre></div>
旁边生成的pygments.css如下:
.highlight .hll background-color: #ffffcc
.highlight background: #f8f8f8;
.highlight .c color: #8f5902; font-style: italic /* Comment */
.highlight .err color: #a40000; border: 1px solid #ef2929 /* Error */
.highlight .g color: #000000 /* Generic */
.highlight .k color: #204a87; font-weight: bold /* Keyword */
.highlight .l color: #000000 /* Literal */
.highlight .n color: #000000 /* Name */
.highlight .o color: #ce5c00; font-weight: bold /* Operator */
.highlight .x color: #000000 /* Other */
.highlight .p color: #000000; font-weight: bold /* Punctuation */
.highlight .ch color: #8f5902; font-style: italic /* Comment.Hashbang */
.highlight .cm color: #8f5902; font-style: italic /* Comment.Multiline */
.highlight .cp color: #8f5902; font-style: italic /* Comment.Preproc */
.highlight .cpf color: #8f5902; font-style: italic /* Comment.PreprocFile */
.highlight .c1 color: #8f5902; font-style: italic /* Comment.Single */
.highlight .cs color: #8f5902; font-style: italic /* Comment.Special */
.highlight .gd color: #a40000 /* Generic.Deleted */
.highlight .ge color: #000000; font-style: italic /* Generic.Emph */
.highlight .gr color: #ef2929 /* Generic.Error */
.highlight .gh color: #000080; font-weight: bold /* Generic.Heading */
.highlight .gi color: #00A000 /* Generic.Inserted */
.highlight .go color: #000000; font-style: italic /* Generic.Output */
.highlight .gp color: #8f5902 /* Generic.Prompt */
.highlight .gs color: #000000; font-weight: bold /* Generic.Strong */
.highlight .gu color: #800080; font-weight: bold /* Generic.Subheading */
.highlight .gt color: #a40000; font-weight: bold /* Generic.Traceback */
.highlight .kc color: #204a87; font-weight: bold /* Keyword.Constant */
.highlight .kd color: #204a87; font-weight: bold /* Keyword.Declaration */
.highlight .kn color: #204a87; font-weight: bold /* Keyword.Namespace */
.highlight .kp color: #204a87; font-weight: bold /* Keyword.Pseudo */
.highlight .kr color: #204a87; font-weight: bold /* Keyword.Reserved */
.highlight .kt color: #204a87; font-weight: bold /* Keyword.Type */
.highlight .ld color: #000000 /* Literal.Date */
.highlight .m color: #0000cf; font-weight: bold /* Literal.Number */
.highlight .s color: #4e9a06 /* Literal.String */
.highlight .na color: #c4a000 /* Name.Attribute */
.highlight .nb color: #204a87 /* Name.Builtin */
.highlight .nc color: #000000 /* Name.Class */
.highlight .no color: #000000 /* Name.Constant */
.highlight .nd color: #5c35cc; font-weight: bold /* Name.Decorator */
.highlight .ni color: #ce5c00 /* Name.Entity */
.highlight .ne color: #cc0000; font-weight: bold /* Name.Exception */
.highlight .nf color: #000000 /* Name.Function */
.highlight .nl color: #f57900 /* Name.Label */
.highlight .nn color: #000000 /* Name.Namespace */
.highlight .nx color: #000000 /* Name.Other */
.highlight .py color: #000000 /* Name.Property */
.highlight .nt color: #204a87; font-weight: bold /* Name.Tag */
.highlight .nv color: #000000 /* Name.Variable */
.highlight .ow color: #204a87; font-weight: bold /* Operator.Word */
.highlight .w color: #f8f8f8; text-decoration: underline /* Text.Whitespace */
.highlight .mb color: #0000cf; font-weight: bold /* Literal.Number.Bin */
.highlight .mf color: #0000cf; font-weight: bold /* Literal.Number.Float */
.highlight .mh color: #0000cf; font-weight: bold /* Literal.Number.Hex */
.highlight .mi color: #0000cf; font-weight: bold /* Literal.Number.Integer */
.highlight .mo color: #0000cf; font-weight: bold /* Literal.Number.Oct */
.highlight .sa color: #4e9a06 /* Literal.String.Affix */
.highlight .sb color: #4e9a06 /* Literal.String.Backtick */
.highlight .sc color: #4e9a06 /* Literal.String.Char */
.highlight .dl color: #4e9a06 /* Literal.String.Delimiter */
.highlight .sd color: #8f5902; font-style: italic /* Literal.String.Doc */
.highlight .s2 color: #4e9a06 /* Literal.String.Double */
.highlight .se color: #4e9a06 /* Literal.String.Escape */
.highlight .sh color: #4e9a06 /* Literal.String.Heredoc */
.highlight .si color: #4e9a06 /* Literal.String.Interpol */
.highlight .sx color: #4e9a06 /* Literal.String.Other */
.highlight .sr color: #4e9a06 /* Literal.String.Regex */
.highlight .s1 color: #4e9a06 /* Literal.String.Single */
.highlight .ss color: #4e9a06 /* Literal.String.Symbol */
.highlight .bp color: #3465a4 /* Name.Builtin.Pseudo */
.highlight .fm color: #000000 /* Name.Function.Magic */
.highlight .vc color: #000000 /* Name.Variable.Class */
.highlight .vg color: #000000 /* Name.Variable.Global */
.highlight .vi color: #000000 /* Name.Variable.Instance */
.highlight .vm color: #000000 /* Name.Variable.Magic */
.highlight .il color: #0000cf; font-weight: bold /* Literal.Number.Integer.Long */
不幸的是,没有一个样式元素是这样调整的。有没有更简单的方法来改变一些使用的颜色,例如对于“nb”类?
【问题讨论】:
【参考方案1】:TL;DR:
您需要 2 个步骤来使用您的自定义样式:
-
定义并创建:扩展
Style
类✔️
应用并整合:在 3 个HTMLFormatter
选项之间做出选择❌️
你错过了最后一个。
首先,到reproduce your code,需要添加以下导入:
from pygments import highlight
from pygments.style import Style
from pygments.lexers import Python3Lexer
定义自定义样式
您自己的样式已正确创建并遵循官方教程"Creating Own Styles"。您的 MyStyle
类(继承自基类 Style
)将 red color 分配给多个语言元素。
应用自定义样式
要使用您将其作为参数 style = MyStyle()
传递给格式化程序构造函数的自定义样式:HtmlFormatter(style=MyStyle())
。
很遗憾,这不适用于样式。它必须以某种方式与 pygments 使用的现有 默认样式 集成。
见: How can I customize the output from pygments?
要集成和应用自定义样式,您基本上可以在 3 个选项之间做出选择:
-
通过指定路径导出外部 CSS 文件
嵌入集成的 CSS(默认与您的样式合并)作为
<style>
到 HTML 中
inline 将您的样式直接添加到渲染/突出显示的代码的 HTML 元素中,例如 <span style="color: #f00000">print</span>
pygments API reference for HTMLFormatter
比较其中两个:
使用 full 选项,输出一个完整的 HTML 4 文档,包括标签内的样式定义,或者如果给出 cssfile 选项,则在单独的文件中。
这 3 个选项将在以下部分进行说明。
导出一个单独的 CSS 文件
formatter = HtmlFormatter(style=MyStyle, full=True, cssfile=`my_pygments.css`)
将完整的 CSS 样式表写入指定文件。来自文档:
如果 full 选项为 true 并且给出了此选项,则它必须是外部文件的名称。如果文件名不包含绝对路径,则假定文件路径相对于主输出文件的路径(如果可以找到后者)。然后将样式表写入此文件而不是 HTML 文件。 Pygments 0.6 中的新功能。
将 CSS 嵌入 HTML
formatter = HtmlFormatter(style=MyStyle(), full=True)
来自文档:
告诉格式化程序输出“完整”文档,即完整的自包含文档(默认值:False)。 上面我用粗体强调了使用生成的 HTML 隔离的好处,作为单个文件,没有任何依赖项,如 CSS 文件:“自包含”
将样式内联到每个代码的 HTML 元素
formatter = HtmlFormatter(style=MyStyle())
formatter.noclasses = True
这里不涉及 pygment 使用的现有 CSS 类(如 nb
)。
相反,您定义的自定义样式直接应用于 HTML 元素,例如 style="color: #f00000"
。
所以,您给定的 HTML 输出(带有样式类 nb
、p
、s2
):
<div class="highlight">
<pre>
<span></span><span class="nb">print</span>
<span class="p">(</span><span class="s2">"Hello World"</span><span class="p">)</span>
</pre>
</div>
会变成这样(没有样式类):
<div class="highlight" style="background: #ffffff">
<pre style="line-height: 125%">
<span></span><span style="color: #f00000">print</span>
(<span style="color: #f00000">"Hello World"</span>)
</pre>
</div>
解决方案
我添加了缺少的导入,提取了formatter
变量并通过传递选项full = True
启用了自包含HTML,因此您可以按预期测试CSS。
from pygments import highlight
from pygments.style import Style
from pygments.lexers import Python3Lexer
from pygments.token import Keyword, Name, Comment, String, Error, \
Number, Operator, Generic
from pygments.formatters import HtmlFormatter
# step 1: define custom style
class MyStyle(Style):
styles =
Comment: '#f00000',
Keyword: '#f00000',
Name: '#f00000',
Name.Function: '#f00000',
Name.Class: '#f00000',
String: '#f00000'
# step 2: apply custom style
formatter = HtmlFormatter(style=MyStyle, full=True) # embed Style inside HTML (self-contained, no external CSS-file
# formatter.noclasses = True # inline style to each element directly
code = 'print("Hello World")'
result = highlight(code, Python3Lexer(), formatter)
print(result)
将打印以下 HTML(包括 <style>
嵌入的 CSS):
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!--
generated by Pygments <https://pygments.org/>
Copyright 2006-2019 by the Pygments team.
Licensed under the BSD license, see LICENSE for details.
-->
<html>
<head>
<title></title>
<meta http-equiv="content-type" content="text/html; charset=None">
<style type="text/css">
/*
generated by Pygments <https://pygments.org/>
Copyright 2006-2019 by the Pygments team.
Licensed under the BSD license, see LICENSE for details.
*/
td.linenos background-color: #f0f0f0; padding-right: 10px;
span.lineno background-color: #f0f0f0; padding: 0 5px 0 5px;
pre line-height: 125%;
body .hll background-color: #ffffcc
body background: #ffffff;
body .c color: #f00000 /* Comment */
body .k color: #f00000 /* Keyword */
body .n color: #f00000 /* Name */
body .ch color: #f00000 /* Comment.Hashbang */
body .cm color: #f00000 /* Comment.Multiline */
body .cp color: #f00000 /* Comment.Preproc */
body .cpf color: #f00000 /* Comment.PreprocFile */
body .c1 color: #f00000 /* Comment.Single */
body .cs color: #f00000 /* Comment.Special */
body .kc color: #f00000 /* Keyword.Constant */
body .kd color: #f00000 /* Keyword.Declaration */
body .kn color: #f00000 /* Keyword.Namespace */
body .kp color: #f00000 /* Keyword.Pseudo */
body .kr color: #f00000 /* Keyword.Reserved */
body .kt color: #f00000 /* Keyword.Type */
body .s color: #f00000 /* Literal.String */
body .na color: #f00000 /* Name.Attribute */
body .nb color: #f00000 /* Name.Builtin */
body .nc color: #f00000 /* Name.Class */
body .no color: #f00000 /* Name.Constant */
body .nd color: #f00000 /* Name.Decorator */
body .ni color: #f00000 /* Name.Entity */
body .ne color: #f00000 /* Name.Exception */
body .nf color: #f00000 /* Name.Function */
body .nl color: #f00000 /* Name.Label */
body .nn color: #f00000 /* Name.Namespace */
body .nx color: #f00000 /* Name.Other */
body .py color: #f00000 /* Name.Property */
body .nt color: #f00000 /* Name.Tag */
body .nv color: #f00000 /* Name.Variable */
body .sa color: #f00000 /* Literal.String.Affix */
body .sb color: #f00000 /* Literal.String.Backtick */
body .sc color: #f00000 /* Literal.String.Char */
body .dl color: #f00000 /* Literal.String.Delimiter */
body .sd color: #f00000 /* Literal.String.Doc */
body .s2 color: #f00000 /* Literal.String.Double */
body .se color: #f00000 /* Literal.String.Escape */
body .sh color: #f00000 /* Literal.String.Heredoc */
body .si color: #f00000 /* Literal.String.Interpol */
body .sx color: #f00000 /* Literal.String.Other */
body .sr color: #f00000 /* Literal.String.Regex */
body .s1 color: #f00000 /* Literal.String.Single */
body .ss color: #f00000 /* Literal.String.Symbol */
body .bp color: #f00000 /* Name.Builtin.Pseudo */
body .fm color: #f00000 /* Name.Function.Magic */
body .vc color: #f00000 /* Name.Variable.Class */
body .vg color: #f00000 /* Name.Variable.Global */
body .vi color: #f00000 /* Name.Variable.Instance */
body .vm color: #f00000 /* Name.Variable.Magic */
</style>
</head>
<body>
<h2></h2>
<div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="s2">"Hello World"</span><span class="p">)</span>
</pre></div>
</body>
</html>
【讨论】:
抱歉,我想解释一下应用自定义 CSS 样式的不同选项,因此答案冗长而深入。希望它读起来很好,解释了可理解的标签并有所帮助。以上是关于为 python pygments 生成自定义样式的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Pygments 中使用 Dracula 主题作为样式?