\begingroup 和 \foreach 的扩展问题

\begingroup 和 \foreach 的扩展问题

这个问题导致了一个新的方案的出现:
nowidow

我正在尝试定义一个动态\begingroup命令来摆脱寡妇:

\usepackage{pgffor}
\newcommand{\nowidow}[1][2]{%
 \begingroup\widowpenalties #1 \foreach \n in {2,...,#1}{10000 } 0 
 \par\endgroup
}

这失败了,抱怨\begingroup需要一个数字,我猜这与扩展有关。

以下是 MWE:

\documentclass{scrbook}

\usepackage{lipsum}

\usepackage{pgffor}
\newcommand{\nowidow}[1][2]{%
 \begingroup\widowpenalties #1 \foreach \n in {2,...,#1}{10000 } 0
 \par\endgroup
}

\begin{document}

\lipsum
\nowidow

\end{document}

我怎样才能让它工作?在 Lua 中执行此操作会更容易(尽管可移植性较差)吗?

答案1

\begingroup不需要数字。它\widowpenalties会寻找数字,并且\foreach不可扩展,因此它不会直接产生数字,因此您会得到错误。最有可能\begingroup只是在错误消息的某个地方显示,因为它是错误发生前最后一个正确读取的标记。

为了解决这个问题,您需要使用可扩展循环,例如使用 e-TeX 的\numexpr

\documentclass{scrbook}

\usepackage{lipsum}

\def\nowidowX#1{%
    \ifnum#1<\nowidowmax
        10000
        \expandafter\nowidowX\expandafter{\the\numexpr(#1)+1\expandafter\relax\expandafter}%
    \fi
}

\newcommand{\nowidow}[1][2]{%
    \begingroup
    \mathchardef\nowidowmax#1\relax
    \widowpenalties #1 \nowidowX{1} 0\par
    \endgroup
}

\begin{document}

\lipsum
\nowidow

\end{document}

答案2

Martin 已经指出这\foreach是不可扩展的。我想补充的是,该expl3捆绑包提供了这样的可扩展工具。例如,

\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand {\nowidow} { O{2} }
  {
     \begingroup
     \widowpenalties #1~ \prg_replicate:nn {#1-1} {10000~} 0~
     \par\endgroup
  }
\ExplSyntaxOff

(我只是使用 xparse 。如果你愿意,\NewDocumentCommand你可以坚持使用。)\newcommand

相关内容