我想要一个可能包含换行符的元素列表。例如,
\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}}