我想在一个环境中使用 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}