
不久以前我問如何將 minted 擴展為顏色突出顯示我選擇的關鍵字。共識是「對外部 pygment 程式進行更改」——所以我就這麼做了。
變化很小,我修改後的 pygment 程式的輸出似乎很好。如果我在系統範圍內安裝新的 pygment 模組,我的文件將正確編譯,並且語法突出顯示的變更將按預期進行。
問題是我不想在系統範圍內安裝我的替換 pygment 模組,這太具有侵入性,並且我希望能夠分發我的文件以在其他人的電腦上進行編譯。我有一個簡單的 bash 腳本bin/pygmentize.sh
,它將新版本的 pygmentize 作為一組本地腳本呼叫。此 bash 腳本是經過測試的、功能齊全的全域pygmentize
程式的替代品。此外,當按照下面所示的方式透過 Latex/minted 呼叫它時,它會產生正確的標記,但文件無法編譯。
以下是我修改後的 pygmentize 產生的標記與原始標記的比較:
前:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+cp}{\PYGZsh{}include} \PYG{c+cpf}{\PYGZlt{}stdio.h\PYGZgt{}}
\PYG{k+kt}{void} \PYG{n+nf}{main} \PYG{p}{()}
\PYG{p}{\PYGZob{}}
\PYG{n+nf}{printf} \PYG{p}{(}\PYG{l+s}{\PYGZdq{}Hello, world!\PYGZdq{}}\PYG{p}{);}
\PYG{p}{\PYGZcb{}}
\end{Verbatim}
後:
\begin{Verbatim}[commandchars=\\\{\}]
\PYG{c+cp}{\PYGZsh{}include} \PYG{c+cpf}{\PYGZlt{}stdio.h\PYGZgt{}}
\PYG{k+kt}{void} \PYG{n+nf}{main} \PYG{p}{()}
\PYG{p}{\PYGZob{}}
\PYG{n}{printf} \PYG{p}{(}\PYG{l+s}{\PYGZdq{}Hello, world!\PYGZdq{}}\PYG{p}{);}
\PYG{p}{\PYGZcb{}}
\end{Verbatim}
在這兩種情況下,這段程式碼都是從 minted 快取目錄中取得的,它是透過 Latex 的呼叫產生的pygmentize
,而不是我自己的手動呼叫。 (我刪除了鑄造的緩存,切換到使用更新的 pygment,然後再次運行 pdflatex。)
生成的標記之間的唯一區別是,\PYG{n}{printf}
我\PYG{n+nf}{printf}
希望文檔的其餘部分將以相同的方式編譯。並非如此
(/tmp/test/minted-cache/D855E0EC6A86300E2FD8FEE675873CCC2C2645CE96B6E2A989A9815
F3192183A.pygtex
! Undefined control sequence.
<argument> \PYG {c+cp}{\PYGZsh
{}include} \PYG {c+cpf}{\PYGZlt {}stdio.h\PYG...
l.2 ...ude} \PYG{c+cpf}{\PYGZlt{}stdio.h\PYGZgt{}}
! ==> Fatal error occurred, no output PDF file produced!
編譯上述標記時會出現此錯誤。如果我正確地閱讀了此內容,則該\PYGZsh
命令未被識別。這個錯誤讓我覺得非常奇怪——minted 顯然正在加載並運行,之前的\PYG
命令曾是被識別為控制序列,並且錯誤出現在未更改的程式碼部分中。
以下是我如何調用更改後的 pygmentize:在我看到的鑄造來源中查看:
\ifcsname MintedPygmentize\endcsname\else
\newcommand{\MintedPygmentize}{pygmentize}
\fi
然後過了一會兒
\MintedPygmentize\space -l #2 -f latex -P commandprefix=PYG -F tokenmerge (...etc)
看來透過定義或重新定義\MintedPygmentize
我應該能夠呼叫不同的程式。
我在導入 minted 之前嘗試這樣做
\newcommand{\MintedPygmentize}{bash bin/pygmentize.sh}
我在導入 minted 之後嘗試這樣做
\renewcommand{\MintedPygmentize}{bash bin/pygmentize.sh}
無論哪種方式都會產生錯誤。我已確認 mybin/pygmentize.sh
已被調用,並且它正在接收輸入並產生輸出。
我得出的結論是,重新定義\MintedPygmentize
造成了一些黑魔法的副作用。
那麼,為了擁有可移植編譯的文檔,我該如何告訴 minted 套件使用我的外部腳本來產生標記,而不會導致這樣的奇怪錯誤出現?
答案1
\renewcommand{\MintedPygmentize}{bash bin/pygmentize.sh}
不適合您的原因是由於pygmentize
檢查是如何在 minted 中實現的。
這條線是在非 Windows 系統(例如 linux、macOS)上執行檢查的內容:
\immediate\write18{which #1 && touch \jobname.aex}
\IfFileExists{\jobname.aex}
{\AppExiststrue
\DeleteFile{\jobname.aex}}
{\AppExistsfalse}
\fi}
然後您的自訂命令將擴展為:
which bash bin/pygmentize.sh && touch \jobname.aex
它找到了 bash,但沒有找到bin/pygmentize.sh
.解決方案是要么使bin/pygmentize.sh
可執行檔 ( chmod u+x bin/pygmentize.sh
)which
不返回錯誤,要么完全繞過檢查。您可以透過將命令聲明為以下方式來繞過檢查:
\renewcommand{\MintedPygmentize}{which ; bash bin/pygmentize.sh}
這將擴展為:which which; bash bin/pygmentize.sh && touch \jobname.aex
,從而通過檢查。在實際呼叫中,which ;
不會產生任何輸出,因此整個命令呼叫的行為就像命令的這一部分不存在一樣。