逗号分隔列表替换

逗号分隔列表替换

我有一个逗号分隔的信息列表,由作者提供,作为文档的序言。然后我想使用这个列表,并且我想每行放一个列表中的项目。我的想法只是用换行符代替逗号。但是当我对元素进行格式化时,它不起作用。

我希望作者能够随意添加他喜欢的格式(或在词汇表中引用),而不会出现任何问题。

分数维:

\documentclass{article}

\usepackage{xstring}

\begin{document}
    % In my case, the first argument is a command in the reality
    \StrSubstitute{Test, Test2, Test3}{,}{\newline}             % OK
    \StrSubstitute{Test, \textit{Test2}, Test3}{,}{\newline}    % NOK
\end{document}

答案1

要格式化用逗号分隔的项目列表或根据需要使用任何其他格式,您可以使用listofitems

姆韦

\documentclass{article}
\usepackage{listofitems}
\setsepchar{,}
\readlist\foo{Test1,\textit{Test2},{\bfseries Test3},\LaTeX,Test4}
\renewcommand\showitemsmacro[1]{\qquad\textbullet\quad #1\par}
\begin{document}

\foo[1] made with \foo[4]:

\showitems\foo

End of the example.

\end{document}

或得到相同的结果:

\documentclass{article}
\usepackage{listofitems}
\setsepchar{,}
\readlist\foo{Test1,\textit{Test2},{\bfseries Test3},\LaTeX,Test4}
\begin{document}

\foo[1] made with \foo[4]:

\foreachitem\test\in\foo{\qquad\textbullet\quad \test\par}

End of the example.

\end{document}

答案2

这是旧版 LaTeX 的版本:

\documentclass{article}

\makeatletter
\newcommand\commatonewline[1]{%
   \@for\user@tmp:=#1\do{\user@tmp\newline}%
}
\makeatother

\begin{document}
indentation is normal at start of paragraph

    % In my case, the first argument is a command in the reality
    \commatonewline{Test, Test2, Test3}            % OK
    \commatonewline{Test, \textit{Test2}, Test3}   % OK, too
\end{document}

其他答案会告诉您使用现代 LaTeX(或使用自制循环,与旧的 LaTeX2e 相比可能具有优势)。

宏的输出

答案3

主要问题是xstring尝试完全扩展其命令的参数。

下面介绍如何使用 进行操作expl3

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\typesetlist}{m +O{} +m +O{}}
 {
  #2 % before
  \exp_args:NV \clist_use:nn { #1 } { #3 }
  #4
 }

\ExplSyntaxOff

\newcommand{\listprovidedbytheauthor}{Test1,\textit{Test2},{\bfseries Test3},\LaTeX,Test4}

\begin{document}

\typesetlist{\listprovidedbytheauthor}[\begin{flushleft}]{\\}[\end{flushleft}]

\typesetlist{\listprovidedbytheauthor}[\noindent Keywords: ]{, }

\end{document}

在此处输入图片描述

如您所见,项目周围的括号被删除,如果输入错误\bfseries Test3(带括号或不带括号),则可能会产生不良后果。为了避免此类输入错误,您可以使用两步方法:我们用逗号分隔列表,然后用括号将每个项目括起来。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\typesetlist}{m +O{} +m +O{}}
 {
  #2 % before
  \clem_list_typeset:Vn #1 { #3 }
  #4
 }

\seq_new:N \l__clem_typeset_list_in_seq
\seq_new:N \l__clem_typeset_list_out_seq

\cs_new_protected:Nn \clem_list_typeset:nn
 {
  \seq_set_from_clist:Nn \l__clem_typeset_list_in_seq { #1 }
  \seq_set_map:NNn \l__clem_typeset_list_out_seq \l__clem_typeset_list_in_seq { {##1} }
  \seq_use:Nn \l__clem_typeset_list_out_seq { #2 }
 }
\cs_generate_variant:Nn \clem_list_typeset:nn { V }


\ExplSyntaxOff

\newcommand{\listprovidedbytheauthor}{Test1,\textit{Test2},{\bfseries Test3},\LaTeX,Test4}

\begin{document}

\typesetlist{\listprovidedbytheauthor}[\begin{flushleft}]{\\}[\end{flushleft}]

\typesetlist{\listprovidedbytheauthor}[\noindent Keywords: ]{, }

\end{document}

在此处输入图片描述

答案4

如果你只是想处理列表以进行打印,则无需使用xstringetoolbox提供列表处理功能:

在此处输入图片描述

\documentclass{article}

\usepackage{etoolbox}

\newcommand{\processlist}[2][,]{%
  \def\itemdelim{\def\itemdelim{#1}}% Item delimiter delayed by one cycle (https://tex.stackexchange.com/a/89187/5764)
  \renewcommand*{\do}[1]{\itemdelim##1}% How each item is processed
  \docsvlist{#2}}% Process CSV list

\begin{document}

\setlength{\parindent}{0pt}% Just for this example

First list:

\processlist[\newline]{Test, Test2, Test3}

\hrulefill

Second list:

\processlist[\newline]{Test, \textit{Test2}, Test3}

\end{document}

LaTeX3 中也有列表解析器/处理器。以下内容部分取自xparse 文档并产生与上面相同的结果:

\documentclass{article}

\NewDocumentCommand{\nextitem}{ m }{ #1 \par}
\NewDocumentCommand{\processlist}{ > { \SplitList { , } } m }{%
  \ProcessList{#1}{ \nextitem } }

\begin{document}

\setlength{\parindent}{0pt}% Just for this example

First list:

\processlist{Test, Test2, Test3}

\hrulefill

Second list:

\processlist{Test, \textit{Test2}, Test3}

\end{document}

相关内容