我正在尝试定义一个具有灵活参数的宏:3 个强制参数和 2 个可选参数 - 如下所示:
\macro{<enter code here>}[arg2] arg3 = arg4 | arg5;
因此参数 2 和 5 是可选的,也是如此|
。
现在我被困在 TeX 的某个地方。也许有人可以解释一下这个问题——我是个新手,我认为,一定有很多可能性。我有尝试了很多但对 、\expandafter
和朋友不够熟悉。我被困在这里:\futurelet
\xdef
\makeatother
\def\@pop#1{}
\def\@split#1;{\def\@@tmp{#1|}\expandafter\@@split\@@tmp\@end@token}
\def\@@split#1|{\@ifnextchar\@end@token{{#1}{}\@pop}{\@@@split{#1}}}
\def\@@@split#1#2|{{#1}{#2}\@pop}
\def\display#1{\@ifnextchar[{\@display{#1}}{\@display{#1}[1]}}
\def\@display#1[#2]#3={\def\@tmp{\@@display{#1}{#2}{#3}}\expandafter\@tmp\@split}
\def\@@display#1#2#3#4#5{*#1*#2*#3*#4*#5*}
\makeatletter
\display{aaa}[bbb] AAA = BBB | CCC;
输出应该是这样的:
*aaa*bbb*AAA*BBB*CCC*
但我得到的却是
/tmp/problem.tex:56: Missing control sequence inserted.
<inserted text>
\inaccessible
l.42 \display{aaa} AAA = BBB;
...正在使用 a href="http://gummi.midnightcoding.org/"gummi/a ...在我看来,好东西!
答案1
使用 LaTeX2e 的解决方案仅适用于\@ifnextchar
:
\documentclass{article}
\makeatletter
\def\display#1{%
\@ifnextchar[%]
{\display@aux@i{#1}}
{\display@aux@i{#1}[]}%
}
\def\display@aux@i#1[#2]#3=#4;{%
\display@aux@ii{#1}{#2}{#3}#4||\@nil
}
\def\display@aux@ii#1#2#3#4|#5|#6\@nil{%
*#1*#2*#3*#4*#5*
}
\makeatother
\begin{document}
\noindent
\display{aaa}[bbb] AAA = BBB | CCC; \\
\display{aaa}[bbb] AAA = BBB ;
\end{document}
选择xparse
基于解决方案:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareDocumentCommand \display
{ m o u { = } > { \SplitArgument { 1 } { | } } u { ; } } {
* #1 * #2 * #3 * \display_aux:nn #4 *
}
\cs_new:Npn \display_aux:nn #1#2 { #1 * #2 }
\ExplSyntaxOff
\begin{document}
\noindent
\display{aaa}[bbb] AAA = BBB | CCC; \\
\display{aaa}[bbb] AAA = BBB ;
\end{document}
答案2
一样,只是反过来 :-)
\documentclass{minimal}
\makeatletter
\def\display#1{\@ifnextchar[{\display@i{#1}}{\display@i{#1}[]}}
\def\display@i#1[#2]#3;{\display@ii#3||\@nil{#1}[#2]}
\def\display@ii#1=#2|#3|#4\@nil#5[#6]{*#5*#6*#1*#2*#3*}
\def\blub{\@ifnextchar[\blub@i{\blub@i[]}}
\def\blub@i[#1]#2;{\blub@ii[#1]#2++\@nil}
\def\blub@ii[#1]#2+#3+#4\@nil{blub[#1] & #2 & #3}
\makeatother
\makeatother
\begin{document}
\display{aaa}[bbb] AAA = BBB|CCC;
\display{aaa}[bbb] AAA = BBB;
\end{document}
答案3
您已经收到了有效的 LaTeX 解决方案,但对于其他想要在 ConTeXt 中执行类似操作的人,我提供了一个 ConTeXt 解决方案。这与使用 的 LaTeX 解决方案类似\@ifnextchar
,但使用更高级别的宏\dodoubleargument
来检查两个可选参数(ConTeXt 还提供其他变体\do...argument
:single
、double
、triple
、quadruple
、quintuple
和sixtuple
)seventuple
。
\def\Macro#1%
{\dodoubleargument\doMacro[#1]}
\def\doMacro[#1][#2]#3=#4;%
{\dostartMacro{#1}{#2}{#3}#4||\dostopMacro}
\def\dostartMacro#1#2#3#4|#5|#6\dostopMacro
{*#1*#2*#3*#4*#5*}
\starttext
\startlines
\Macro{aaa} AAA = BBB ;
\Macro{aaa} AAA = BBB | CCC ;
\Macro{aaa}[bbb] AAA = BBB ;
\Macro{aaa}[bbb] AAA = BBB | CCC;
\stoplines
\stoptext
答案4
我学到了很多东西 - 现在让我展示一下这个纯 TeX 版本,使用 \futurelet:(如果你可以缩短它,请随意编辑)
\documentclass{article}
\def\b{\ba[]}
\def\ba[#1]#2;{\bar{#1}#2++\nil}
\def\bar#1#2+#3+#4\nil{blub[#1]}
\def\blu{\ifx\next[\let\f\ba\else\let\f\b\fi\f}
\def\blub{\futurelet\next\blu}
\begin{document}
\begin{tabular}{lll}
\blub foo; \\
\blub[bla] bar; \\
\blub foo + bar; \\
\blub[bla] foo + bar; \\
\end{tabular}
\end{document}
哦...我只是想知道远程图像怎么不能被禁用......