100 LaTeX 宏命令复杂参数处理

发布于 2025-04-16 15:46:51

我在写一个宏命令 \MyCMD,它有一个参数。
但这个参数本身包含不确定个数的tokens。
比如:\MyCMD{{par 1}{par 2}{par 3}}
在原始版本中每一个参数都传递给另一个命令 \__MyCMD_deal:n 进行外理。
现在我需要将 \__MyCMD_deal:n 升级为 \__MyCMD_deal_newversion:nn ,它多吸收一个可选参数。
此时 \MyCMD 命令依然只有一个参数,它的用法类似:
\MyCMD{{par 1}[opt 1]{par 2}{par 3}[opt 3]}

显然在 \MyCMD 中无法再用 \tl_map_inline:nn 来分割参数。
现在这个 \MyCMD 怎么写呢?

代码逻辑如下:

\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \__MyCMD_deal:n #1
{
        output: #1 \par %伪应用
}

\NewDocumentCommand{\__MyCMD_deal_newversion:nn}{+m+O{}}
{
        output: #1 ~ option: #2 \par %伪应用
}

\NewDocumentCommand{\MyCMD}{+m}
{
        \tl_map_inline:nn {#1}
        {
                \__MyCMD_deal:n {##1}
        }
}
\ExplSyntaxOff

\begin{document}
\MyCMD{{par 1}{par 2}{par 3}}

\MyCMD{{par 1}{par 2}}

%\MyCMD{{par 1}[opt 1]{par 2}[opt 2]{par 3}[opt 3]}

%\MyCMD{{par 1}[opt 1]{par 2}[opt 2]}

%\MyCMD{{par 1}{par 2}[opt 2]{par 3}}
\end{document}

查看更多

关注者
0
被浏览
138
雾月
雾月 2天前
这家伙很懒,什么也没写!

使用尾递归即可,这是比较常见的处理方式,\tl_map_.. 也是用尾递归实现的。

\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \__MyCMD_deal:n #1
  {
    output: #1 \par %伪应用
  }

\quark_new:N \q__MyCMD_stop
\NewDocumentCommand{\__MyCMD_deal_newversion:nw}{+m+O{}}
  {
    \tl_if_eq:nnF {#1} { \q__MyCMD_stop }
      {
        output: #1 ~ option: #2 \par %伪应用
        
        \__MyCMD_deal_newversion:nw
      }
  }
\NewDocumentCommand{\MyCMD}{+m}
  {
    \__MyCMD_deal_newversion:nw #1 \q__MyCMD_stop []
  }
\ExplSyntaxOff

\begin{document}
\MyCMD{{par 1}{par 2}{par 3}}

\MyCMD{{par 1}{par 2}}

\MyCMD{{par 1}[opt 1]{par 2}[opt 2]{par 3}[opt 3]}

\MyCMD{{par 1}[opt 1]{par 2}{par 3}[opt 3]}

\MyCMD{{par 1}[opt 1]{par 2}[opt 2]}

\MyCMD{{par 1}{par 2}[opt 2]{par 3}}
\end{document}

由于不需要可展的实现,可以用 \tl_if_eq:nn 比较,无需可展的 \quark_if_..,这样更快。

1 个回答

撰写答案

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

发布
问题

分享
好友

手机
浏览

扫码手机浏览