禁止在环境中分段

禁止在环境中分段

环境singlepar应该包含一个段落。这意味着它包装的代码中不能有段落中断:

\begin{singlepar}
    Right.
\end{singlepar}

\begin{singlepar}
    Wrong.

    Wrong!
\end{singlepar}

我目前的方法是:

% \usepackage{xparse}
\NewDocumentEnvironment{singlepar}{}
{%
    % Ensure that this environment starts a new paragraph
    \par%
    % Save normal \par for later use
    \let\oldparforprivateuse\par%
    % Use of \par should abort the typesetting process
    \def\par{\typeout{DISALLOWED}\QUIT}%
    \ignorespaces%
}
{%
    % Issue a paragraph break
    \oldparforprivateuse%
}

但是,感觉不对。至于实际原因,我感觉这个 hack 不能处理所有情况。我相信仍然可能存在段落中断;例如,通过在环境之前使用\letalias的定义:\par

\let\takethis\par
\begin{singlepar}
    I'm gonna stab you in the back.
    \takethis
    Take this!
\end{singlepar}

我已经检查过xparse文档并且似乎没有办法像使用宏参数那样抑制段落中断(宏参数中不允许使用段落中断,除非+在宏声明中段落中断前面有)。

如何才能在代码的某一部分中完全禁止段落中断?

编辑:我说的“禁止”是指他们中止编译,以便人们注意到它。这更多是为了诊断我自己在输入文本时的错误。

答案1

我不认为你想参与\par其中结尾第一段中你真正想要允许的,对于一个段落环境来说,很自然地允许

\begin{singlepar}

aaa

\end{singlepar}

如果你犯了错误,这是不允许的\par

你不想允许的是第二段开始这就是\everypar对于事物(重新)定义仍然存在一些担忧,\everypar但这将捕获许多情况,并允许上述示例。

\documentclass{article}

%\newenvironment{singlepar}
%{\def\par{\PackageError{pkg}{par DISALLOWED}{}\ignorespaces}}%
%{}


\newenvironment{singlepar}
{\everypar{\everypar{\PackageError{pkg}{par DISALLOWED}{}}}\ignorespaces}%
{}
\begin{document}

\begin{singlepar}

aaa

\end{singlepar}


\begin{singlepar}

aaa

b
\end{singlepar}

\end{document}

答案2

你的感觉是对的。

\begin{singlepar}
Wrong.\endgraf Wrong.
\end{singlepar}

你会得到一个段落分隔符,并且不会出现错误。LaTeX 格式

\let\endgraf\par

因此使其\endgraf等同于原始的\par。 也\@@par等同于原始的\par,但它不应该困扰你,因为它@的名称中有。

你可以说

\makeatletter
\newenvironment{singlepar}
 {%
  % Ensure that this environment starts a new paragraph
  \@@par
  % Save normal \par for later use
  % Use of \par should abort the typesetting process
  \def\par{\typeout{DISALLOWED}\QUIT}%
  \let\endgraf\par
 }
 {%
  % Issue a paragraph break
  \@@par
 }
\makeatother

但它并不能解决问题,因为某些包可能会在环境中说\let\foo\@@par然后\foo导致段落中断。

由于不可能知道哪些控制序列指向原始\par内存位置以了解其含义(如\endgraf\@@par),因此该问题实际上无法解决。

可以考虑用 的变体吸收环境主体,从而\NewEnviron形成非\long宏(标准操作是像 那样做\newcommand),但这也不能解决问题。非\long宏仅禁止令牌 \par在它的参数中,但会很乐意接受\endgraf或任何与原始的等同的控制序列\par

最后,无法禁用原语。您可以通过重新定义来隐藏它,但已经控制它的序列\let将继续起作用。

相关内容