使用 foreach 进行迭代的包含多行元素的列表

使用 foreach 进行迭代的包含多行元素的列表

我想要一个可能包含换行符的元素列表。例如,

\def\mylist{
test,
test

with enter,
end
}

但是,如果我尝试迭代该列表,则会\foreach收到! Paragraph ended before \pgffor@normal@list was complete.错误。

如何声明和处理包含多行元素的列表?

\documentclass{article}

\usepackage{pgffor}

\newcommand{\test}[1]{\par\fbox{\parbox{\linewidth}{#1}}}

\begin{document}
\def\mylist{
test,
test

with enter,
end
}

\foreach \x in \mylist {\test{\x}}
\end{document}

答案1

错误信息是

! Paragraph ended before \pgffor@normal@list was complete.
<to be read again> 
                   \par 

这意味着 TeX\par在参数中发现了(由于空白行而插入)非\long宏。事实上\show\pgffor@normal@list给出了

> \pgffor@normal@list=macro:
#1->\def \pgffor@values {#1, \pgffor@stop ,}\ifx \pgffor@values \pgffor@emptyva
lues \def \pgffor@values {\pgffor@stop ,}\fi \let \pgffor@body =\pgfutil@empty 
\global \pgffor@continuetrue \pgffor@collectbody .

但是,仅仅制作这个宏\long是不够的,因为 和\pgffor@scanone也不\pgffor@dots@in@一定是\long

解决方法:制作宏\long

\documentclass{article}

\usepackage{pgffor,etoolbox}
\makeatletter
\patchcmd[\long]{\pgffor@normal@list}{}{}{}{}
\patchcmd[\long]{\pgffor@scanone}{}{}{}{}
\patchcmd[\long]{\pgffor@dots@in@}{}{}{}{}
\makeatother

\newcommand{\test}[1]{\par\fbox{\parbox{\linewidth}{#1}}}

\begin{document}
\def\mylist{
test,
test

with enter,
end
}

\foreach \x in \mylist {\test{\x}}
\end{document}

在此处输入图片描述

答案2

实际上,你不是在引入一条新路线,而是引入了一条新路线,段落!显然,\foreach不喜欢段落分隔符。不过,我没有在 pgfmanual 中找到原因(它只是说“任何东西都可以用作值”)。如果您想强制换行,可以使用\\,它与 配合得很好\foreach

\def\mylist{
test,
test\\ with new line,
end
}

\foreach \x in \mylist {\test{\x}}

如果您确实需要分段,可以使用以下解决方法:

\def\mylist{
test,
test\mypar with enter,
end
}    
\foreach \x in \mylist {\let\mypar=\par\test{\x}}

相关内容