所以我刚刚从 转到listings
,minted
因为listings
当背景颜色设置为深色时,线条会显示出来,这非常烦人。另一方面,Minted 很烦人,因为似乎没有一种简单的方法来定义我自己的风格,除了 Python,但是我如何在 Overleaf 中实现这一点?
答案1
更新:我错了,这似乎是可能的。参见Alex Reinking 的回答了解详情。
如果我的回答最终未被接受,我将删除它。抱歉提供错误信息!
恐怕这在 Overleaf 中是不可能的。你可以从.py
文件中加载自定义词法分析器而无需安装它,但不幸的是,没有办法从本地.py
文件加载 Pygments 样式,而无需在系统级别安装或将其注册为插件——这在 Overleaf 的编译服务器上是不可能的。
如果您需要在 Pygments 中使用自定义样式,则需要安装您自己的 TeX 发行版以在您自己的系统上进行编译。
答案2
当然,你只需要愿意稍微(滥用)使用 minted 的内部功能。minted 的工作方式是要求创建一个充满 TeX 宏的文件,这些宏决定了样式。如果该文件已经存在,它只会将其加载到名为您想要加载的样式的pygmentize
宏中。作为优化,如果该宏已经存在,它会跳过运行!\minted@PYGdef@<style>
<style>
pygmentize
因此,您可以按照以下方法将自己的样式文件插入系统minted
:
\makeatletter
\CatchFileDef{\minted@PYGdef@thesis}{thesis-style}{\catcode`@=11\catcode`\%=14\catcode``=12\endlinechar=-1}
\makeatother
\usemintedstyle{thesis}
这thesis
将从项目根目录中名为 的文件创建一个名为 的样式thesis-style.tex
(而不是.pygstyle
,以便云编辑可以正常工作)。 catcode 的任务是确保正确解释 pygstyle 文件中的字符。实际上可能只@
需要 ,但为了安全起见,我从 复制了 catcode 设置minted
。
至于pygstyle
首先创作文件,您可以尝试编辑现有文件(使用足够接近的样式构建一次并进行调整)或者通过在本地使用 Python 执行所有操作然后冻结文件pygstyle
(在我看来,开销更高)从头开始创建自己的样式。
最后,这是在最新版本的 Minted 上完成的,因此您应该在 Overleaf 上使用 TexLive 2022。
答案3
可以做到。例如,我有一个针对一种名为 Portugol 的语言的自定义词法分析器,因此我上传了该词法分析器,并命名为该名称PortugolStudioLexer.py
(名称任意)。然后,您可以使用以下方式启动 minted 环境
\begin{minted}{PortugolStudioLexer.py:PortugolStudioLexer -x}
\end{minted}
您还可以使用minted
界面创建自己的命令:
\setminted[PortugolStudioLexer.py:PortugolStudioLexer -x]{linenos}
\newmint[portugol]{PortugolStudioLexer.py:PortugolStudioLexer -x}{}
\newminted[portugolcode]{PortugolStudioLexer.py:PortugolStudioLexer -x}{
tabsize=2, obeytabs}
\newmintinline[portugolinline]{PortugolStudioLexer.py:PortugolStudioLexer -x}{}
\newmintedfile[portugolfile]{PortugolStudioLexer.py:PortugolStudioLexer -x}{tabsize=2, obeytabs}
\newcommand{\portugolitem}{\portugolfile[linenos = false, xleftmargin = 2em]}
因此您获得了命令\portugol
、\portugolinline
和\portugolcode
环境portugolcode
。
答案4
除了Alex 的回答,也可以修补 Overleaf 的 pygmentize 安装,以便从 python 源中查找和编译你的样式(这样你不必在本地预编译它们)。
这个脚本可以达到这个目的:https://gist.github.com/dn0sar/d67672d3793271a2985e4ec20f425174(脚本也粘贴在下面)
只需将脚本放在项目根目录中,然后修改脚本LOCAL_STYLE_MAP
以添加规范来导入您的样式(无论它在您的项目中的什么位置)。
最后,在你的 latex 前言中添加以下两行以使用修补后的 pygmentize 版本:
\immediate\write18{bash ./pygmentize_patcher.sh}
\renewcommand{\MintedPygmentize}{./pygmentize}
请注意,这pygmentize_patcher.sh
是脚本的名称。现在,您可以将在中指定的键名用作样式,LOCAL_STYLE_MAP
pygmentize 将找到并加载您的样式。
如果你好奇这是如何运作的,这是 pygmentize 如何查找和加载内置样式。
注意,每个导入都强制以 开头pygments.styles.
。该补丁替换了 python 内置命令__import__
,以便pygments.styles.
删除 中指定的样式的前缀LOCAL_STYLE_MAP
。
由于 Overleaf 目前不允许覆盖已安装的 python 文件,修补后的 pygmentize 将保存在项目根目录中。\renewcommand{\MintedPygmentize}{./pygmentize}
然后将默认调用替换pygmentize
为修补后的调用。
这是上面要点中的 bash 脚本:
## Tested with Pygments 2.11.0 and 2.13.0
## Add your own styles in the python map defined in the local_style_map variable
## The format specification is given in the comments inside the variable
local_style_map=$(cat <<EOF
LOCAL_STYLE_MAP = {
## this key is the alias name of your style, add more if you have more styles
'customcc' : {
## file from where to import the custom style class
## this is relative to the project root
## e.g,. if you have your custom style in custom_style/c_styles.py
## you should have the import below
"file_import": "custom_style.c_styles",
## Class name defined in the "file_import" above
"class_name": "CustomC",
},
}
EOF
)
##### DO NOT MODIFY BELOW HERE
pygmentize_path=$(which pygmentize)
# Take shebang from the current pygmentize installation
shebang=$(head -n 1 $pygmentize_path)
if [[ "${shebang:0:2}" != '#!' ]]; then
shebang=""
fi
preamble=$(cat <<EOF
import builtins
from pygments.styles import STYLE_MAP
for k in LOCAL_STYLE_MAP:
STYLE_MAP[k] = LOCAL_STYLE_MAP[k]["file_import"] + '::' + LOCAL_STYLE_MAP[k]["class_name"]
default_import = builtins.__import__
def custom_import(name, *args):
for k in LOCAL_STYLE_MAP:
if name == 'pygments.styles.' + LOCAL_STYLE_MAP[k]["file_import"]:
# print(f'Patching search path to find "{k}"')
name = LOCAL_STYLE_MAP[k]["file_import"]
return default_import(name, *args)
builtins.__import__ = custom_import
EOF
)
echo "$shebang" > pygmentize
echo "" >> pygmentize
echo "$local_style_map" >> pygmentize
echo "$preamble" >> pygmentize
echo "" >> pygmentize
cat $pygmentize_path >> pygmentize
chmod u+x pygmentize