如何将接收的逗号分隔列表中的单个项目作为参数发出信号?

如何将接收的逗号分隔列表中的单个项目作为参数发出信号?

我想定义一个带有xparse's的命令\NewDocumentCommand,它接收以逗号分隔的列表作为参数,但能够以某种方式发出信号表示该列表上的某些项目应该特殊处理。

我对此的第一个想法是使用支撑。我想到了类似的东西:

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand \mylist { > { \SplitList { , } } m }
  {
    \tl_map_inline:nn {#1}
      {
        \tl_if_head_is_group:nTF {##1}
          { Hi,~I'm~special~##1! \par }
          { ##1 \par }
      }
  }
\ExplSyntaxOff

\begin{document}

\mylist{item1,item2,{{item3}},item4,{{item5}},item6}

\end{document}

正如预期的那样,打印结果如下:

在此处输入图片描述

而且,如果我不能依赖排版中展开的额外括号,就像上面的例子一样,我可以使用类似这样的方法:

\cs_new:Npn \__my_tl_set_unbraced:Nn #1#2
  {
    \tl_if_head_is_group:nTF {#2}
      { \tl_set:Nn #1 #2 }
      { \tl_set:Nn #1 {#2} }
  }

在我检索到“信号”之后,可以传递一个包含该函数的变量集作为参数,使其像列表中的任何其他“非特殊”项一样工作。

虽然这一切确实有效,乍一看感觉还不错,但我发现它有点太“有创意”了,甚至有点让人厌烦,我想知道是否还有其他选择。因此我提出了这个问题。

我想知道的是:这是一个合理的程序吗?(从技术方面和用户界面方面来看)。你认为其中有什么明显的警告吗?有没有好的替代方案?

答案1

您的代码是合理并且可以工作,但是需要{{special item}},因为 TeX 的规则是,当不平衡的标记列表不会出现时,参数周围的一对括号会被剥离。

我会使用|special item|更简单的类型并避免\SplitList:无论如何你都需要达到该expl3级别。

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand \mylist { m }
  {
    \gusbrs_mylist:n { #1 }
  }

\cs_new_protected:Nn \gusbrs_mylist:n
  {
    \clist_map_inline:nn {#1}
      {
        \str_if_eq:eeTF { \tl_head:n { ##1 } } { | }
          { \__gusbrs_mylist_special:w ##1 }
          { ##1 \par }
      }
  }

\cs_new:Npn \__gusbrs_mylist_special:w | #1 |
  {
    Hi,~I'm~special~#1! \par
  }
\ExplSyntaxOff

\begin{document}

\mylist{item1,item2,|item3|,item4,|item5|,item6}

\end{document}

|作为练习,您可以在调用函数之前添加尾随测试:w并引发警告或错误。

在此处输入图片描述

阅读评论后,您还可以在此处仅使用前缀字符来标记特殊项目|

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand \mylist { m }
  {
    \gusbrs_mylist:n { #1 }
  }

\cs_new_protected:Nn \gusbrs_mylist:n
  {
    \clist_map_inline:nn {#1}
      {
        \str_if_eq:eeTF { \tl_head:n { ##1 } } { | }
          { \__gusbrs_mylist_special:e { \tl_tail:n { ##1 } } }
          { ##1 \par }
      }
  }

\cs_new:Nn \__gusbrs_mylist_special:n
  {
    Hi,~I'm~special~#1! \par
  }
\cs_generate_variant:Nn \__gusbrs_mylist_special:n { e }

\ExplSyntaxOff

\begin{document}

\mylist{item1,item2,|item3,item4,|item5,item6}

\end{document}

答案2

这是 latex2e 的一种方式,使用listofitems。特殊项目包含*,它应该出现在项目的末尾。可以通过编辑\setsepchar列表中的最后一个条目来更改特殊字符表示符。

\documentclass{article}
\usepackage{listofitems}
\newcommand\processmylist[1]{%
  \setsepchar{,/*}%
  \readlist*\mylist{#1}%
  \foreachitem\z\in\mylist[]{%
    \ifnum\listlen\mylist[\zcnt]=1
      \z
    \else
      SPECIAL: \mylist[\zcnt,1]%
    \fi
    \\
  }%
}
\begin{document}
\noindent\processmylist{item1, item2, item3*, item4, item 5*}
\end{document} 

在此处输入图片描述

相关内容