假设我的 LaTeX 包仅定义\MyMarvelousCommand
。在我的包文档中,我有许多使用 minted 排版的不同列表。\MyMarvelousCommand
应该在每个列表内以红色显示。
这是我的实际解决方案:
- 使用 minted 的
escapeinside||
- 在我的所有列表中,替换
\MyMarvelousCommand
为|\MyMarvelousCommand|
\MyMarvelousCommand
使用钩子在铸造环境的开始处重新定义。
\documentclass{article}
\RequirePackage{minted}
\newcommand\MyMarvelousCommand[1]{Do marvelous things with #1}
\AtBeginEnvironment{minted}{
\def\MyMarvelousCommand{{\color{red}\string\MyMarvelousCommand}}
}
\begin{document}
\begin{minted}[escapeinside=||]{latex}
\texttt{|\MyMarvelousCommand|{\LaTeX}}
\end{minted}
\texttt{\MyMarvelousCommand{\LaTeX}}
\end{document}
这远非最佳:
- 我必须自己解析代码
- 它使用虚假字符破坏了 MWE,这是非常恼人的
- 它不适用于列表+输出示例(例如在 tcblisting 中)
还有其他方法吗
答案1
在这里我添加了两个选项minted
post processor=<script.py>
post processor args=<more_args>
minted
也被修补为每次python3 <script.py> <hash.pygtex> <more_arg>
输入文件之前执行。这里表示的(中间)输出 tex 文件。您可以将其视为缓存的。<hash.pygtex>
<hash.pygtex>
pygments
_mint-<main>/<hash.pygtex>
然后,您可以通过一个简单的 Python 脚本来满足您的需求,该脚本替换\MyMarvelousCommand
为包装形式,例如\wrapper{\MyMarvelousCommand}
。由于我们正在处理pygments
输出,\<cmd>
实际上是\PYGZbs{}<cmd>
。
由于pygments
它本身就是一个 Python 库,因此执行 Python 脚本不会添加任何额外的依赖项。此外,以下脚本或多或少是一个概念验证,因此您可以扩展该脚本以使其更加灵活。
#!/usr/bin/python3
import fileinput
import sys
# This is `highlightcmd.py`
# Usage: python3 highlightcmd.py xxx.pygtex MyCommandFirst
if len(sys.argv) < 4:
raise ValueError(f'Need three args, given {len(sys.argv)}')
fin = sys.argv[1]
cmd = sys.argv[2]
wrapper = sys.argv[3]
# python highlighter of vscode accepts only uppercase `R` to represent raw string
# see https://github.com/MagicStack/MagicPython/issues/114
pattern_find = fR'{{\PYGZbs{{}}{cmd}}}'
pattern_sub = fR'{{\{wrapper}{{\PYGZbs{{}}{cmd}}}}}'
with fileinput.input(fin, inplace=True) as file:
for line in file:
print(line.replace(pattern_find, pattern_sub), end='')
\documentclass{article}
\usepackage{minted}
\newcommand\MyMarvelousCommand[1]{Do marvelous things with #1}
\makeatletter
\pretocmd\minted@inputpyg{%
\minted@postprocesspyg
{\minted@get@opt{post processor}{}}
{\minted@outputdir\minted@infile}
{\minted@get@opt{post processor args}{}}%
}{}{\fail}
\minted@def@opt{post processor}
\minted@def@opt{post processor args}
% #1 = name of the python script, e.g., "process.py"
% #2 = input ".pygtex" file, always be "\minted@outputdir\minted@infile"
% #3 = more args passed to the python script, possibly empty
\newcommand{\minted@postprocesspyg}[3]{%
\ifstrempty{#1}{}{%
% execute "python3 <script.py> <file.pygtex> <more_args>"
\ShellEscape{python3 #1 #2 #3}%
}%
}
\makeatother
\begin{document}
\setminted{
autogobble,
post processor=highlightcmd.py,
post processor args=MyMarvelousCommand wrapper
}
\newcommand{\wrapper}[1]{\textcolor{red}{#1}}
\begin{minted}{latex}
\MyMarvelousCommand{\LaTeX}
\end{minted}
\texttt{\MyMarvelousCommand{\LaTeX}}
\end{document}