Как правильно указать альтернативу внешней команде pygmentize для minted?

Как правильно указать альтернативу внешней команде pygmentize для minted?

Некоторое время назадЯ спросилкак расширить 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, а не моим собственным ручным вызовом. (Я удалил кэш 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: покопавшись в исходниках Minted, я увидел следующее:

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

В любом случае возникает ошибка. Я подтвердил, что мой bin/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 ; не создает никаких выходных данных, поэтому весь вызов команды будет вести себя так, как будто этой части команды нет.

Связанный контент