解析可选的宏参数

解析可选的宏参数

我正在尝试定义一个具有灵活参数的宏: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.
&lt;inserted text&gt;
                \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...argumentsingledoubletriplequadruplequintuplesixtupleseventuple

\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]&#2&#3}
\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}

哦...我只是想知道远程图像怎么不能被禁用...... 替代文本

相关内容