如何在宏/环境中使用 catcodes

如何在宏/环境中使用 catcodes

我想在一个环境中使用 catcodes,并且 catcodes 需要针对文档中很短的部分进行更改。

锰氧化物:

\documentclass[a5paper, 11pt]{scrartcl}
\usepackage{environ}


\NewEnviron{Lied}[3][]{
\subsection{#3 - Variant: #2}
{%catcode
\catcode`\&=13%
\def&{\\}%
\catcode`\==4%
\fbox{
\begin{tabular}{l l}
Meta data name = Meta data value &
\hline
#1
\end{tabular}
}%fbox
}%end catcode

\BODY
}

\begin{document}
{
%catcode
%\catcode`\&=13
%\def&{\\}
%\catcode`\==4
\begin{Lied}[
abc = def &
123 = 456 &
khi = jkl &
Herr = Michael Mustermann
]{var1}{1}
Nothing
\end{Lied}
}
\end{document}

这不起作用。如果我取消注释文档环境中的 catcodes,并注释掉 Lied 环境中的部分,它也不起作用。如果我还将表格的标题行切换为,它就会起作用。Meta data name & Meta data value \\理论上,展开的表格如下所示:

Meta data name & Meta data value \\
\hline
abc = def &
123 = 456 &
khi = jkl &
Herr = Michael Mustermann

& + \\这是两种符号(和)的混合= + &,并产生以下输出: 输出 这没有任何意义。看起来 tabular 的行为类似于 edef,阻止 catcodes 稍后生效。但是,第一个版本应该可以工作。

附注:我如何更改问题中图像的大小。

答案1

首先是一些评论。无论何时你这样做

\NewEnviron{foo}[0]{%
  <something>
  \BODY
}

您误用了该工具,当您想要进行某些处理而\BODY不仅仅是将其不加改变地重新插入到输入流中时,该工具很有用。

我也看不出有什么理由玩 catcode,这总是有点危险。输入有什么好处

abc = def &

超过

abc & def \\

哪一个输入起来同样容易?

无论如何,这是一个可行的实现。定义环境时,您还必须更改 catcode;然后您需要将它们改回来,在启动环境之前重新分配,然后恢复。

\documentclass[a5paper, 11pt]{scrartcl}

\catcode`& \active
\catcode`= 4

\NewDocumentEnvironment{Lied}{O{}mm}{%
  \subsection{#3 -- Variant: #2}
  \def&{\\}%
  \fbox{%
    \begin{tabular}{l l}
    Meta data name = Meta data value &
    \hline
    #1
    \end{tabular}
  }%fbox
  \par
}{\par}

\catcode`= 12
\catcode`& 4

\BeforeBeginEnvironment{Lied}{\catcode`= 4 \catcode`& \active}
\AfterEndEnvironment{Lied}{\catcode`= 12 \catcode`& 4 }

\begin{document}

\begin{Lied}[
  abc = def &
  123 = 456 &
  khi = jkl &
  Herr = Michael Mustermann
]{var1}{1}
Nothing
\end{Lied}

\end{document}

请注意 catcode 分配中缺少的符号,当catcode 为 4=时该符号无效。=

在此处输入图片描述

如果您确实需要\NewEnviron,我建议改用\NewDocumentEnvironment和它的b参数类型,这样您可以使用参数(在本例中#4)代替\BODY

\documentclass[a5paper, 11pt]{scrartcl}

\catcode`& \active
\catcode`= 4

\NewDocumentEnvironment{Lied}{O{}mm +b}{%
  \subsection{#3 -- Variant: #2}
  \def&{\\}%
  \fbox{%
    \begin{tabular}{l l}
    Meta data name = Meta data value &
    \hline
    #1
    \end{tabular}
  }%fbox
  \par
  #4% do some processing here?
  \par
}{}

\catcode`= 12
\catcode`& 4

\BeforeBeginEnvironment{Lied}{\catcode`= 4 \catcode`& \active}
\AfterEndEnvironment{Lied}{\catcode`= 12 \catcode`& 4 }

\begin{document}

\begin{Lied}[
  abc = def &
  123 = 456 &
  khi = jkl &
  Herr = Michael Mustermann
]{var1}{1}
Nothing
\end{Lied}

\end{document}

如果您需要它=并且&在环境中具有通常的角色并且只在第一个参数中是特殊的(我认为这是相当奇怪的语法),您可以使用 catcodes 进行一些处理。

\documentclass[a5paper, 11pt]{scrartcl}

\catcode`& \active
\catcode`= 4

\NewDocumentEnvironment{Lied}{O{}mm}{%
  \begingroup
  \subsection{#3 -- Variant: #2}
  \def&{\\}%
  \fbox{%
    \begin{tabular}{l l}
    Meta data name = Meta data value &
    \hline
    #1
    \end{tabular}
  }%fbox
  \endgroup
  \catcode`& 4 \catcode`= 12
  \par
}{\par}

\catcode`= 12
\catcode`& 4

\BeforeBeginEnvironment{Lied}{\catcode`= 4 \catcode`& \active}
\AfterEndEnvironment{Lied}{\catcode`= 12 \catcode`& 4 }

\begin{document}

\begin{Lied}[
  abc = def &
  123 = 456 &
  khi = jkl &
  Herr = Michael Mustermann
]{var1}{1}
Nothing $a=b$

\begin{tabular}{cc} a & b \\ c & d \end{tabular}
\end{Lied}

\end{document}

在此处输入图片描述

但如果你真的需要\NewEnviron,要采取不同的方法,即替换标记而不是更改类别代码。

\documentclass[a5paper, 11pt]{scrartcl}

\ExplSyntaxOn
\NewDocumentEnvironment{Lied}{O{}mm +b}
 {
  \subsection{#3 -- Variant: #2}
  \tl_set:Nn \l_tmpa_tl { #1 }
  \tl_replace_all:Nnn \l_tmpa_tl { & } { \\ }
  \tl_replace_all:Nnn \l_tmpa_tl { = } { & }
  \fbox
   {
    \begin{tabular}{l l}
    Meta ~ data ~ name & Meta ~ data ~ value ~ \\
    \hline
    \tl_use:N \l_tmpa_tl
    \end{tabular}
   }%fbox
  \par#4\par
}{}
\ExplSyntaxOff

\begin{document}

\begin{Lied}[
  abc = def &
  123 = 456 &
  khi = jkl &
  Herr = Michael Mustermann
]{var1}{1}
Nothing $a=b$

\begin{tabular}{cc} a & b \\ c & d \end{tabular}
\end{Lied}

\end{document}

答案2

&首先,你需要在定义中激活,这样\def&就不会出现错误

\catcode`\&13 % space before % here important
\catcode`\=4 % space before % here important
\NewEnviron{Lied}[3][]{
\subsection{#3 - Variant: #2}
{%catcode
\def&{\\}%
\fbox{ %space here?
\begin{tabular}{l l}
Meta data name = Meta data value &
\hline
#1
\end{tabular} %space here?
}%fbox
}%

\BODY
}
\catcode`\=12
\catcode`\&4

那么您需要在扫描环境之前在本地切换 catcode

\let\oldLied\Lied
\def\Lied{\catcode`\&=\active\catcode`\=4 \oldLied}

在此处输入图片描述

\documentclass[a5paper, 11pt]{scrartcl}
\usepackage{environ}

\catcode`\&13 % space before % here important
\catcode`\=4 % space before % here important
\NewEnviron{Lied}[3][]{
\subsection{#3 - Variant: #2}
{%catcode
\def&{\\}%
\fbox{ %space here?
\begin{tabular}{l l}
Meta data name = Meta data value &
\hline
#1
\end{tabular} %space here?
}%fbox
}%

\BODY
}
\catcode`\=12
\catcode`\&4

\let\oldLied\Lied
\def\Lied{\catcode`\&=\active\catcode`\=4 \oldLied}

\begin{document}
{
%catcode
%\catcode`\&=13
%\def&{\\}
%\catcode`\==4
\begin{Lied}[
abc = def &
123 = 456 &
khi = jkl &
Herr = Michael Mustermann
]{var1}{1}
Nothing
\end{Lied}
}
\end{document}

相关内容