minted の pygmentize 外部コマンドの代替を適切に指定するにはどうすればよいでしょうか?

minted の pygmentize 外部コマンドの代替を適切に指定するにはどうすればよいでしょうか?

少し前に私は尋ねたminted を拡張して、選択したキーワードを色で強調表示する方法。 合意は「外部の pygment プログラムに変更を加える」ということでした。そのため、私はそうしました。

変更は小さく、修正した pygment プログラムの出力は問題ないようです。新しい pygment モジュールをシステム全体にインストールすると、ドキュメントは正しくコンパイルされ、構文の強調表示の変更も期待どおりになります。

問題は、代替の pygment モジュールをシステム全体にインストールしたくないということです。それはあまりにも侵入的であり、他の人のコンピューターでコンパイルできるようにドキュメントを配布できるようにしたいのです。私は、bin/pygmentize.shローカル スクリプトのセットとして pygmentize の新しいバージョンを呼び出す簡単な bash スクリプトを持っています。この 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 キャッシュ ディレクトリから取得され、pygmentize私自身の手動呼び出しではなく、latex の 呼び出しによって生成されました。(minted キャッシュを削除し、更新された 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}

そして、私はミントをインポートした後にこれを試しました

\renewcommand{\MintedPygmentize}{bash bin/pygmentize.sh}

bin/pygmentize.shどちらの方法でもエラーが発生します。myが呼び出され、入力を受信して​​出力を生成していることを確認しました。

\MintedPygmentize再定義によって黒魔術的な副作用が生じたと結論付けました。

では、移植可能なコンパイル可能なドキュメントを作成するには、このような奇妙なエラーが発生しないように、外部スクリプトを使用してマークアップを生成するように minted パッケージに指示するにはどうすればよいでしょうか。

答え1

\renewcommand{\MintedPygmentize}{bash bin/pygmentize.sh}機能しない理由は、pygmentizeminted でのチェックの実装方法によるものです。

この行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 ;出力は生成されないので、コマンド呼び出し全体は、コマンドのこの部分が存在しないかのように動作します。

関連情報