10 xparse处理多个连续的optional arguments

发布于 2024-10-30 13:21:06

现希望定义一个具有多个可选参数的命令\cmd

\documentclass[12pt]{ctexart}
\usepackage[margin=1in]{geometry}
\setlength{\parindent}{0pt}
\NewDocumentCommand{\cmda}{O{default1} O{default2} m}{%
    \textbf{The result of \texttt{\string\cmda}:} \par
    optional param1: #1 \par
    optional param2: #2 \par
    mandattory param: #3 \par
}
\NewDocumentCommand{\cmdb}{O{default1} m O{default2}}{%
    \textbf{The result of \texttt{\string\cmdb}:} \par
    optional param1: #1 \par
    mandattory param: #2 \par
    optional param2: #3 \par
}
\begin{document}
    \cmda{Explorer}

    \cmda[anaconda][python]{Explorer}

    \cmda[anaconda]{Explorer}

    \cmda[][python]{Explorer} % 使用\cmda的定义方式,可否指定default2而让default1为默认值

    \cmdb{Explorer}

    \cmdb[anaconda]{Explorer}[python]

    \cmdb[anaconda]{Explorer}

    \cmdb{Explorer}[python]
\end{document}

image.png

如果采用\cmda的定义顺序方式,使用\cmda[option1][option2]{mandatory3}则无法使用\cmda[option2]{mandatory3}指定#2而让#1为默认值

如果使用\cmdb的方式,固然可实现\cmda{mandatory3}[option2],但是这种参数形式\cmd[]{}[]并不优雅

如果不使用keyvalkvoptionsl3keys等方式,是否可以将\cmda优雅的实现只指定option#2而让option#1为默认值

或者说,遇到连续的多个options用\xparse处理确实存在上面的小障碍?

查看更多

关注者
0
被浏览
99
2 个回答
Sagittarius Rover
Sagittarius Rover 7小时前
不喜欢LaTeX!!!

自己给一个基于kayval的解答。

\documentclass[12pt]{ctexart}
\usepackage[margin=1in]{geometry}
\setlength{\parindent}{0pt}
\usepackage{keyval}
\makeatletter
\def\mwe@vala{defaulta}
\define@key{mwe}{opa}{\def\mwe@vala{#1}}
\def\mwe@valb{defaultb}
\define@key{mwe}{opb}{\def\mwe@valb{#1}}
\newcommand\foo[2][]{
    \begingroup
    \setkeys{mwe}{#1}%
    The opa is: \mwe@vala. \par
    The opb is: \mwe@valb. \par
    The Parameter is: #2. \par
    \endgroup
}
\makeatother
\begin{document}
    \foo{Explorer}

    \foo[opa=opa,opb=opb]{Explorer}

    \foo[opb=opb]{Explorer}

    \foo[opa=opa]{Explorer}
\end{document}

image.png

雾月
雾月 5小时前
这家伙很懒,什么也没写!

一般情况下,如果要实现类似的需求,是交换 1、2 个参数的顺序,或者用不同类型的定界符([] () <> 等)。

也可以用一个特殊的值表示默认值,遇到这个特殊值的时候把它替换为默认值。

\ExplSyntaxOn
\cs_new_protected:Npn \__my_make_default:nnn #1#2#3
  {
    \tl_if_eq:nnTF {#3} {#1}
      { \tl_set:Nn \ProcessedArgument {#2} }
      { \tl_set:Nn \ProcessedArgument {#3} }
  }
\cs_new_eq:NN \TrueDefault \__my_make_default:nnn
\ExplSyntaxOff

\NewDocumentCommand{\cmdt}{ 
  >{\TrueDefault{?}{default1}} O{?} % 如果参数为 ? 就替换为 default1
  >{\TrueDefault{?}{default2}} O{?}
  m
}{%
    \textbf{The result of \texttt{\string\cmdt}:} \par
    optional param1: #1 \par
    optional param2: #2 \par
    mandattory param: #3 \par
}

\cmdt{Explorer}

\cmdt[anaconda][python]{Explorer}

\cmdt[anaconda]{Explorer}

\cmdt[?][python]{Explorer}

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览