在嵌套自定义环境之后神秘地插入了 vspace

在嵌套自定义环境之后神秘地插入了 vspace

我创建了自己的环境,使用 tabu 创建了一个表,然后在其后放置了一些垂直空间,除非我的环境是嵌套的,在这种情况下我希望它跳过垂直空间。但是,即使在嵌套使用我的环境之后,垂直空间似乎也会被插入。我做错了什么?

MWE(尽管我希望它更接近 M):

\documentclass{article}

\usepackage{tabu}
\usepackage{environ}
\usepackage{xparse}

\makeatletter

\newcommand{\lxtabu@table}[1]{
  \begin{tabu}{X}
    #1
  \end{tabu}%
}

\newcounter{lxtabu@counter}

\NewDocumentEnvironment {lxtabu} {}
{%
  \stepcounter{lxtabu@counter}
  \Collect@Body\lxtabu@table
}{%
  \typeout{ending lxtabu}%
  \addtocounter{lxtabu@counter}{-1}%
  % Only output vspace if we're not in a nested lxtabu.
  \ifnum\value{lxtabu@counter} = 0 %
    % If you comment this out the extra vertical space between lines 2
    % and 3 goes away.  (But so does the space between lines 3 and 4,
    % which is bad.)
    \typeout{inserting space}\vspace{\baselineskip}%
  \fi
}

\makeatother

\begin{document}

\begin{lxtabu}
  Line 1 \\
    \begin{lxtabu}
      Line 2 \\
    \end{lxtabu}
  \\
  Line 3, should not have big empty space above it \\
\end{lxtabu}

Line 4, should have \verb|\baselineskip| space above it.

\end{document}

结果:

渲染的 MWE

我希望第 2 行和第 3 行之间的间距应该与第 1 行和第 2 行之间的间距相同。

我不是积极的正在“执行”它\vspace不应该执行的命令,但如果我将其更改为,\vspace{0pt}第 2 行和第 3 行之间不需要的空格就会消失。\typeout我添加的命令产生了预期的结果,“插入空格”只在末尾出现一次。

还有几点说明:

  • 我正在使用 MacTeX 2014 中的 LuaLaTex,它大概是基于 TeX Live 2014 构建的。

  • 我之所以使用,是\Collect@Body因为\begin{tabu}\end{tabu}在分别用于的开头和结尾时会出现错误。与和\NewDocumentEnvironment存在同样的问题。\tabu\endtabu

  • 虽然 MWE 中没有显示,但我需要它的参数解析。但是,如果我仍然可以声明一个可以在强制参数之后解析可选参数的环境,即,我\NewDocumentEnvironment会接受不涉及的解决方案。\NewDocumentEnvironment\begin{lxtabu}{Foo}[Bar]

  • 我的lxtabu环境需要确保其底部与下一个内容之间有空间,下一个内容可能是文本、另一个lxtabu环境,或者可能是更奇特的东西。我不想移动环境\vspace的外部lxtabu

答案1

谜题很容易解决:tabu处理输入两次或更多次。它在试验处理期间禁用一些命令,但忘记对\stepcounter和执行此操作\addtocounter。它禁用的命令之一是\write,结果是\vspace添加了 但没有发出消息。

\documentclass{article}

\usepackage{tabu}
\usepackage{environ}
\usepackage{xparse}
\usepackage{xpatch}
\usepackage{showframe}

\makeatletter

\patchcmd{\tabu@setstrategy}
  {\let\color}
  {\let\stepcounter\@gobble\let\addtocounter\@gobbletwo\let\color}
  {}{}

\newcommand{\lxtabu@table}[1]{%
  \begin{tabu}{|X|}
    #1
  \end{tabu}%
}

\newcounter{lxtabu@counter}

\NewDocumentEnvironment {lxtabu} {}
{%
  \stepcounter{lxtabu@counter}%
  \Collect@Body\lxtabu@table
}{%
  \typeout{ending lxtabu}%
  \addtocounter{lxtabu@counter}{-1}%
  % Only output vspace if we're not in a nested lxtabu.
  \ifnum\value{lxtabu@counter} = 0 %
    % If you comment this out the extra vertical space between lines 2
    % and 3 goes away.  (But so does the space between lines 3 and 4,
    % which is bad.)
    \typeout{inserting space}\vspace{1\baselineskip}%
  \fi
  \ignorespacesafterend
}

\makeatother

\begin{document}

\begin{lxtabu}
  Line 1 \\
    \begin{lxtabu}
      Line 2 \\
    \end{lxtabu}
  \\
  Line 3, should not have big empty space above it \\
\end{lxtabu}

Line 4, should have \verb|\baselineskip| space above it.

\end{document}

我不知道这个补丁是否会产生其他后果;我从来没有使用过它,tabu因为它有几个问题,而且它的作者宣布下一个版本将与当前版本基本不兼容。

我添加了这个showframe包只是为了显示页面框架和垂直规则,以便tabu更清楚地了解所涉及的环境。这个\ignorespacesafterend更好,尽管可能不需要。

在此处输入图片描述

答案2

通过删除一些“\\”,特别是第 2 行之后的“\\”和第 3 行之前的“\\”,我得到了所需的结果:

\begin{document}

\begin{lxtabu}
  Line 1\\ 
    \begin{lxtabu}
      Line 2 %\\
    \end{lxtabu}
%\\
Line 3, should not have big empty space above it \\
\end{lxtabu}

Line 4, should have \verb|\baselineskip| space above it.

\end{document}

编译代码

相关内容