环境名称中的破折号

环境名称中的破折号

我正在尝试创建一个名为“my-environ”的逐字环境

\documentclass{article}

\usepackage{fancyvrb}

\DefineVerbatimEnvironment{myenviron}{Verbatim}{numbers=left,frame=lines,label=My Environ,labelposition=topline}

%\DefineVerbatimEnvironment{my-environ}{Verbatim}{numbers=left,frame=lines,label=My-Environ,labelposition=topline}

\begin{document}

\begin{myenviron}
Hello
\end{myenviron}

%\begin{my-environ}
%Hello
%\end{my-environ}

\end{document}

如果取消注释代码,您会发现它无法编译。我不必使用fancyvrb,但我想要类似的功能。

答案1

在他的回答egreg 已经解释过,连字符-在 verbatim 环境中有不同的 catcode。包从中fancyvrb保存环境名称。有 catcode\begin{my-environ}\FV@EnvironName-逐字环境的 catcode 发生变化,通常为 12(其他)。然后在环境内部fancyvrb查找\end{...}并检查是否...匹配\FV@EnvironName。但-现在 catcode 为 13(活动),并且由于 catcode 不同,字符串my-environ不匹配-,并且fancyvrb无法看到环境的结尾。

该示例破解了 的宏,fancyvrb以定义\FV@EnvironCheckName存储my-environverbatim 环境的 catcode。由于\scantokens\everyeof和 ,该破解需要 e-TeX\unexpanded来获取未扩展的环境名称和 catcode,这些 catcode 在 verbatim 环境的 catcode 设置后处于活动状态。

\documentclass{article}

\usepackage{fancyvrb}

\DefineVerbatimEnvironment{my-environ}{Verbatim}{
  numbers=left,
  frame=lines,
  label=My-Environ,
  labelposition=topline,
}

\makeatletter
\renewcommand*{\VerbatimEnvironment}{%
  \ifx\FV@EnvironName\relax
    \xdef\FV@EnvironName{\@currenvir}%
    \begingroup
      \endlinechar=-1 %
      \everyeof{\@nil\noexpand}%
      \xdef\FV@EnvironCheckName{%
        \expandafter
        \FV@CatchUnexpanded\scantokens\expandafter{\@currenvir}%
      }%
    \endgroup
  \fi
}
\def\FV@CatchUnexpanded#1\@nil{\unexpanded{#1}}
\begingroup
\catcode`\^^M=\active
\gdef\FancyVerbGetLine#1^^M{%
  \@nil%
  \FV@CheckEnd{#1}%
  \ifx\@tempa\FV@EnvironCheckName%            % True if end is found
    \ifx\@tempb\FV@@@CheckEnd\else\FV@BadEndError\fi%
    \let\next\FV@EndScanning%
  \else%
    \def\FV@Line{#1}%
    \def\next{\FV@PreProcessLine\FV@GetLine}%
  \fi%
  \next%
}%
\endgroup
\makeatother

\begin{document}

\begin{my-environ}
Hello
\end{my-environ}

\end{document}

结果

答案2

问题很微妙。一般来说,连字符可以出现在环境名称中,就像任何其他非特殊字符一样(实际上也包括一些特殊字符)。但是,在逐字环境中无法使用其中一些字符,因为逐字模式使它们积极的;latex.ltx你会发现

\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-}

并且列表中的字符`<,'-被激活,以便 (La)TeX 不会产生通常的连字

?` !` << >> ,, `` '' -- ---

但是,您的环境的结尾verbatim细绳

\end{my-verbatim}

在设置上述活动字符之前构建fancyvrb。字符串的含义是所有字符都具有类别代码 12;fancyvrb一次加载一行并将其与结束字符串进行比较。但是,如果环境名称包含上述字符之一,则无法找到结束字符串。

也许可以破解宏以便允许使用这些字符,但最好只使用字母。

相关内容