LaTeX3:解析存储在宏中的 CSV 列表

LaTeX3:解析存储在宏中的 CSV 列表

这个问题是对这个问题的回答的一种后续:如何迭代以逗号分隔的列表?

不同之处在于,我想迭代存储在宏中的 csv 列表\myTerms。按照 MWE,中的列表\myTerms似乎按字面意思理解,而不是解析为 CSV。我尝试用 来修复它\expanded{},但似乎不起作用。

梅威瑟:

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\myList}{mm}
 {
  \clist_set:Nn \l_tmpa_clist { #1 }
  \clist_use:Nnnn \l_tmpa_clist { #2 } { #2 } { #2 }
 }
 \ExplSyntaxOff

\newcommand{\mySeparator}{\textbullet}

\newcommand{\makeMyList}[1]{
  \begingroup
    \scshape\myList{#1}{\mySeparator}
  \endgroup
}

\newcommand{\myTerms}{test, another test}

\begin{document}
\makeMyList{\expanded{\myTerms}}
\end{document}

当我不使用宏myTerms而只是将列表写出\makeMyList参数时,就可以实现所需的输出,如下所示:

期望输出:

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\myList}{mm}
 {
  \clist_set:Nn \l_tmpa_clist { #1 }
  \clist_use:Nnnn \l_tmpa_clist { #2 } { #2 } { #2 }
 }
 \ExplSyntaxOff

\newcommand{\mySeparator}{\textbullet}

\newcommand{\makeMyList}[1]{
  \begingroup
    \scshape\myList{#1}{\mySeparator}
  \endgroup
}

\begin{document}
\makeMyList{test, another test}
\end{document}

这让我认为\expanded{}需要扩展控制,但我似乎犯了另一个错误。我该如何解决这个问题?

答案1

当您使用时expl3,只要您不进行低级编程,我建议坚持使用它提供的扩展方法。我的意思是:您不必费心将列表扩展为输入,我认为最好让它在级别上处理expl3

您的使用\expanded不起作用,因为在\expanded完成其工作之前,您的意志\makeMyList会抓住它的参数并将其\expanded{\myTerms}视为输入,没有找到逗号,因此将其用作单个术语。

该级别的扩展expl3可以通过两种不同的方式进行:

  • 有根据的猜测,如果只提供了一个参数,那么很可能这是一个存储值的宏
  • 例如通过星号在 处提供一个“开关” \makeMyList,在这种情况下我们可以使用\exp_args:No或类似的。

以下工具两个都,但使用\expandafter第二种方法代替 -layer expl3

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\myList}{mm}
  {
    \tl_if_single:nTF {#1}
      {
        % if the single item is a group we don't expand it
        \tl_trim_spaces_apply:nN {#1} \tl_if_head_is_group:nTF
          { \clist_set:Nn }
          {
            % if it's no group it must be N-type, and the test for group is
            % faster
            % there might be spaces around #1 but those will be removed by TeX's
            % argument grabbing, so don't hurt
            \token_if_expandable:NTF #1
              \clist_set:NV
              \clist_set:Nn
          }
      }
      { \clist_set:Nn }
        \l_tmpa_clist {#1}
    \clist_use:Nn \l_tmpa_clist {#2}
  }
\ExplSyntaxOff

\newcommand{\mySeparator}{\textbullet}

\NewDocumentCommand \makeMyList { s m }
  {
    \begingroup
      \scshape
      \IfBooleanTF {#1}
        {\expandafter\myList\expandafter{#2}\mySeparator}
        {\myList{#2}\mySeparator}%
    \endgroup
  }

\newcommand{\myTerms}{test, another test}

\begin{document}
% expansion-guess at the expl3 level
\makeMyList{\myTerms}\par
\makeMyList{\myTerms,abc}

% expansion of first token in the list by the interface
\makeMyList*{\myTerms}\par
\makeMyList*{\myTerms,abc}
\end{document}

编辑:按照建议添加了更多测试@AndrewStacey

在此处输入图片描述

答案2

您的建议的问题在于,\expanded直到太晚才会被看到。根据您想要实现的具体目标,有几种方法可以做到这一点。一个简单的方法是将更改为\clist_set:Nn\clist_set:NV这需要价值宏的作为要使用的列表。您还需要删除 周围的括号#1。这将进行一次扩展,因此如果您的列表包含宏,则它们不会被扩展。

(我现在没有可以轻松测试这一点的设备,所以您可能需要进行一些其他调整。)

相关内容