вещи, следующие за окружением, которое создано, вызывают ошибку

вещи, следующие за окружением, которое создано, вызывают ошибку

Рассмотрим следующий код:

\documentclass{article}
\usepackage{minted}

\begin{document}
\begin{minted}{python}
a = 0
\end{minted} % this comment is a problem
\end{document}

Это приводит к следующей ошибке:

! FancyVerb Error:
  Extraneous input ` % this comment is a problem\end{}' between \end{minted} and line end

Перемещение комментария на следующую строку устраняет ошибку. Похоже, что на той же строке после \end{minted}. Это также касается сред, определенных с помощью \newminted. verbatimС другой стороны, у среды, похоже, нет проблем с кодом, следующим на той же строке.

Я не видел описания такого поведения в документации.

Может ли кто-нибудь объяснить, в чем проблема, что ничто не может следовать за a \end{minted}на той же строке?

решение1

Пакет mintedиспользует fancyvrbпакет под капотом для своих сред дословно (см. стр. 13 в руководстве minted, например), и ошибка уже присутствует, когда вы используете этот пакет вместо этого (также, как говорится в сообщении об ошибке, оно на самом деле выдается FancyVerb, а не mintedим самим; поэтому, я полагаю, его нет в mintedдокументации). Этот код выдаст ту же ошибку:

\documentclass{article}
\usepackage{fancyvrb}
\begin{document}

\begin{Verbatim}
   This is verbatim code
\end{Verbatim}%

\end{document}

Если мы хотим проследить истоки ошибки:

Среда Verbatim сканирует свое содержимое построчно, см. раздел 12.10 документации fancyvrb,Построчное сканирование. И действительно, именно здесь мы встречаемся с определением этой ошибки. \FV@BadEndError, выданной метко названной \FancyVerbGetLineкомандой.

Команда \FancyVerbGetLineвызывает \FV@BadEndErrorэту строку в исходном коде fancyvrb:

\ifx\@tempa\FV@EnvironName%            % True if end is found
  \ifx\@tempb\FV@@@CheckEnd\else\FV@BadEndError\fi%

Прослеживая это еще дальше, мы доходим до раздела12.9 Проверка концав руководстве fancyvrb, где говорится:

Нам нужно проверить аргумент первого элемента \end{}в каждой строке, сравнить его с \FV@EnvironNameи вернуть, \iftrueесли он совпадает, и \iffalseнаоборот.

Проблема в том, что в этом месте \@tempbдолжно быть \end{}, но вместо этого теперь %\end{}. Таким образом, второе \ifxfalse, и выдается ошибка ( \@tempaиз предыдущей строки, Verbatimкстати).

В конце концов, этопочтиравнозначно прямому сравнению строк, по крайней мере, насколько я могу судить (не только проверяется fancyvrbналичие \end{}аргумента , но и проверяется, нет ли в этой строке ничего другого), с небольшим исключением — игнорированием пробелов в строке: Они действительно удаляются, тем самым не вызывая сбоя \ifx(можно проверить, посмотрев на содержимое , \@tempbесли немного изменить fancyvrbисходный код, чтобы вывести его; он не содержит пробелов).

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