具有可选参数的反向扩展顺序

具有可选参数的反向扩展顺序

尝试实现具有超过 9 个参数的命令(这也会反转事情),当其中有 8 个参数时,第一个调用将暂时保存\def\mytemp{\mycommandtwo{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}},并且在第二个调用接管控制后必须推迟其扩展\mycommandone:后者具有第一个可选参数。

我认为可以逐步建立论点的片段是:

\newcommand\mypriorcommand[8]{%
  \def\mytemp{\mycommandtwo{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}%
  \expandafter\mytemp\mycommandone%
}

\newcommandx\mycommandone[4][1,2,3]{%
   % #4 is mandatory
}

\newcommand\mycommandtwo[9]{%
   % #9 is one more parameter besides the eight
}

假设\mycommandone被 4 个参数饱和,在 的扩展\mytemp遇到 的第 9 个参数之前\mycommandtwo

如果没有\expandafter,正确使用\mycommandone(仍然没有任何参数)会很好:根据需要获取尽可能多的参数。在这种情况下,“\expandafter”扩展有何不同?

这是一个 MWE。

\documentclass{article}

\usepackage{xargs}

\title{MWE}
\author{tex.stackexchange.com}

\newcommand\test[1]{\typeout{--- test/1 ---}%
  \def\temp{\typeout{--- temp/3 ---}\testa{#1}}%
  \expandafter\temp\testb%
}

\newcommand\testa[2]{\typeout{--- testa/4 ---}4=#1 5=#2}

\newcommandx\testb[3][1,2]{\typeout{--- testb/2 ---}1=#1 2=#2 3=#3}

\begin{document}

\maketitle

\test{% EDIT: renamed arguments
  4th
}[1st][2nd]{%
  3rd
}{%
  5th
}

\end{document}

编辑:它排版4=4th 5=1=1st 2=2nd 3=3rd 5th并打印:

--- test/1 ---
--- temp/3 ---
--- testa/4 ---
--- testb/2 ---

而它应该排版1=1st 2=2nd 3=3rd 4=4th 5=5th,顺序应该是test/1,testb/2,temp/3,testa/4。

编辑: 以下是如何逐步建立论点不反转论点对我有用:

\newcommandx\testc[4][1,2]{2=#1 3=#2 4=#3 5=#4}
\renewcommand\test[1]{1=#1 \testc}

编辑:还可以使用以下变体\expandafter

\newcommandx\testc[4][1,2]{2=#1 3=#2 4=#3 5=#4}
\renewcommand\test[1]{1=#1 \def\temp{\relax}\expandafter\temp\testc}

请给出一个简单的TeX解决方案?谢谢。

答案1

替换宏中\expandafter\temp\testb的并在宏末尾( 之后)添加。\testb\test\temp\testb3=#3

答案2

特别是如果你有一些可选参数,那么使用以下命令生成命令通常要容易得多新命令。这是一个生成必要支持宏的 Python 脚本。例如,使用 10 个参数(3 个可选),它会生成

% Prototype: MACRO test OPT[#1={}] OPT[#2={}] OPT[#3={}] #4 #5 #6 #7 #8 #9 #10
\makeatletter
\newcommand{\test}[1][]{%
  \def\test@arg@i{#1}%
  \@ifnextchar[{\test@i}{\test@i[{}]}%
}

\def\test@i[#1]{%
  \def\test@arg@ii{#1}%
  \@ifnextchar[{\test@ii}{\test@ii[{}]}%
}

\def\test@ii[#1]#2#3#4#5#6#7#8{%
  \def\test@arg@iii{#1}%
  \def\test@arg@iv{#2}%
  \def\test@arg@v{#3}%
  \def\test@arg@vi{#4}%
  \def\test@arg@vii{#5}%
  \def\test@arg@viii{#6}%
  \def\test@arg@ix{#7}%
  \def\test@arg@x{#8}%
  % Put your code here.
  % You can refer to the arguments as \test@arg@i through \test@arg@x.
}
\makeatother

你可以这样调用./newcommand.py 'MACRO test OPT[#1={}] OPT[#2={}] OPT[#3={}] #4 #5 #6 #7 #8 #9 #10'

相关内容