Wie gibt man für „minted“ richtig eine Alternative zum externen Befehl „pygmentize“ an?

Wie gibt man für „minted“ richtig eine Alternative zum externen Befehl „pygmentize“ an?

Vor einiger ZeitIch fragtewie ich Minted erweitern kann, um meine ausgewählten Schlüsselwörter farblich hervorzuheben. Der Konsens war „Nehmen Sie die Änderungen im externen Pygment-Programm vor“ – also habe ich es getan.

Die Änderungen sind gering und die Ausgabe meines geänderten Pygment-Programms scheint in Ordnung zu sein.Wenn ich mein neues Pygment-Modul systemweit installiere, wird mein Dokument korrekt kompiliert und die Änderungen an der Syntaxhervorhebung sind wie erwartet.

Der Haken ist, dass ich mein Ersatzmodul für Pygment nicht systemweit installieren möchte, das wäre zu invasiv und ich möchte mein Dokument zur Kompilierung auf den Computern anderer Leute verteilen können. Ich habe ein einfaches Bash-Skript, bin/pygmentize.shdas die neue Version von Pygmentize als Satz lokaler Skripte aufruft.Dieses Bash-Skript ist ein getesteter, funktionierender Drop-In-Ersatz für das globale pygmentizeProgramm.Darüber hinaus wird beim Aufruf über Latex/Minted in der unten gezeigten Weise zwar die richtige Auszeichnung generiert, das Dokument kann jedoch nicht kompiliert werden.

Hier ist ein Vergleich der von meinem geänderten Pygmentize generierten Auszeichnung mit dem Original:

Vor:

\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}

Nach:

\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}

Dieser Code wurde in beiden Fällen aus dem Minted-Cache-Verzeichnis entnommen und durch den Aufruf von durch Latex generiert pygmentize, nicht durch meinen eigenen manuellen Aufruf. (Ich habe den Minted-Cache gelöscht, bin auf die Verwendung meines aktualisierten Pygments umgestiegen und habe pdflatex erneut ausgeführt.)

Der einzige Unterschied zwischen dem generierten Markup besteht darin, dass es so \PYG{n}{printf}wird \PYG{n+nf}{printf}, dass ich erwarten würde, dass der Rest des Dokuments auf die gleiche Weise kompiliert wird. Nicht so

(/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!

Dieser Fehler tritt beim Kompilieren des obigen Markup-Teils auf. Wenn ich das richtig lese, ist es der \PYGZshBefehl, der nicht erkannt wird. Dieser Fehler kommt mir sehr merkwürdig vor – minted wird eindeutig geladen und ausgeführt, der frühere \PYGBefehlWarals Steuersequenz erkannt und der Fehler manifestiert sich in einem Codeabschnitt, der sich nicht geändert hat.

So habe ich es geschafft, dass mein geändertes Pygmentize aufgerufen wird: Beim Herumstöbern im geprägten Quellcode ist mir Folgendes aufgefallen:

\ifcsname MintedPygmentize\endcsname\else
  \newcommand{\MintedPygmentize}{pygmentize}
\fi

Dann etwas später

\MintedPygmentize\space -l #2 -f latex -P commandprefix=PYG -F tokenmerge (...etc)

Es scheint, dass ich durch Definieren oder Neudefinieren \MintedPygmentizeein anderes Programm aufrufen können sollte.

Ich habe dies versucht, bevor ich Minted importiert habe

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

und ich habe versucht, dies zu tun, nachdem ich minted importiert habe

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

In beiden Fällen tritt der Fehler auf. Ich habe bestätigt, dass mein bin/pygmentize.shaufgerufen wird und dass es seine Eingaben empfängt und seine Ausgaben erzeugt.

Ich bin zu dem Schluss gekommen, dass die Neudefinition \MintedPygmentizeeinige Nebenwirkungen der schwarzen Magie verursacht hat.

Wie weise ich also das Minted-Paket an, mein externes Skript zum Generieren der Auszeichnung zu verwenden, um ein portabel kompilierbares Dokument zu erhalten, ohne dass seltsame Fehler wie dieser auftreten?

Antwort1

Der Grund, warum \renewcommand{\MintedPygmentize}{bash bin/pygmentize.sh}es bei Ihnen nicht funktioniert, liegt an der pygmentizeImplementierung der Prüfung in Minted.

Diese Linieführt die Prüfung auf Nicht-Windows-Systemen (z. B. Linux, macOS) aus:

    \immediate\write18{which #1 && touch \jobname.aex}
    \IfFileExists{\jobname.aex}
     {\AppExiststrue
      \DeleteFile{\jobname.aex}}
     {\AppExistsfalse}
  \fi}

Ihr benutzerdefinierter Befehl wird dann wie folgt erweitert:

which bash bin/pygmentize.sh && touch \jobname.aex

Das findet bash, aber nicht bin/pygmentize.sh. Die Lösung besteht darin, entweder bin/pygmentize.shexecutable ( chmod u+x bin/pygmentize.sh) zu machen, sodass whichkein Fehler zurückgegeben wird, oder die Prüfung vollständig zu umgehen. Sie können die Prüfung umgehen, indem Sie Ihren Befehl wie folgt deklarieren:

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

Dies wird zu: erweitert which which; bash bin/pygmentize.sh && touch \jobname.aexund besteht somit die Prüfung. Bei tatsächlichen Aufrufen which ;erzeugt keine Ausgabe, sodass sich der gesamte Befehlsaufruf so verhält, als wäre dieser Teil des Befehls nicht vorhanden.

verwandte Informationen