合并连续的换行符

合并连续的换行符

我有类似的东西:

%\newcommand{\maybehide}[1]{#1}
\newcommand{\maybehide}[1]{}
\newcommand{\thing}[1]{#1}
\newcommand{\bigthing}[1]{#1}

\bigthing{  
\thing{1}\\
  \maybehide{\thing{2}}\\
  \thing{3}
}

我希望它表现得像

\bigthing{
  \thing{1}\\
  \thing{3}
}

但它表现为

  \bigthing{
    \thing{1}\\
    \\
    \thing{3}
  }

有没有什么办法可以做到这一点?

我能想到的唯一方法是重新定义,\\使其重新定义为\\不执行任何操作,然后\thing重新定义\\为它应该的样子。

  \let\mylinebreak\\
  \let\mything\thing

  \def\mynewlinebreak{
    \def\\{}
    \mylinebreak  
  }
  \def\mynewthing{
    \def\\{\mynewlinebreak}
    \mything
  }

  \def\\{\mynewlinebreak}
  \def\thing{\mynewthing}

  \bigthing{
    \thing{1}\\
    \maybehide{\thing{2}}\\
    \thing{3}
  }

但它看起来确实像是一种黑客行为,最终会破坏某些东西,所以我真的更喜欢另一种方法。而且,它还取决于我是否知道会有\things。如果有\thing1并且\thing2可以交替使用,我必须添加更多代码,如果我不知道那里可能有什么,它根本就行不通……

预先感谢您的帮助。

答案1

你的 hack 还不错。但你可以更快地完成此操作,而无需重新定义\\

以下解决方案定义了吞噬版本\maybehide(如果你想隐藏内容,可以激活该版本),它有两个参数,并检查第二个参数是否相等\\。如果为 true,它将被吞噬;如果为 false,它将打印第二个参数的内容:

\newcommand{\maybehide}[2]{\ifx\\#2\else#2\fi}

例如:\maybehide{xyz}abc将识别“xyz”为第一个参数,该参数无论如何都会被遗忘(它不会出现在替换文本中),并将“a”识别为第二个参数。因此,第一个扩展是,\ifx\\a\else a\fi然后显然会扩展到 else 情况,即a;因此:\maybehide{xyz}abc-->“abc”。在实际用例中,\maybehide{xyz}\\...\maybehide找到\\第二个参数,因此测试会扩展为 true 情况,即为空;这意味着\\被丢弃并且\maybehide{xyz}\\什么也不输出。

完整示例:

\documentclass{article}

\parindent0pt

\makeatletter
%\newcommand{\maybehide}[1]{#1}
\newcommand{\maybehide}[2]{\ifx#2\\\else#2\fi}% in case you wanna hide
\newcommand{\thing}[1]{#1}
\newcommand{\bigthing}[1]{#1}
\makeatother

\begin{document}
\bigthing{%
  \thing{1}\\
  \maybehide{\thing{2}}\\
  \thing{3}
}
\end{document}

然后编译成类似

1
3

代替

1

3

对于更通用的解决方案,即独立于特定宏的解决方案,您当然也可以重新定义\\。例如

\def\\#1{\ifx\\#1\newline\else\newline#1\fi}

本质上就是所需要的(它使用与上面的特殊解决方案完全相同的方法。)现在有两个注意事项:(1)\\根据周围环境可能意味着不同的事情;(2)可选参数丢失。

  • ad (1): 先说简单的事情。存储原意,\let\ltx@nl=\\\def\\#1{\ifx\\#1\ltx@nl\else\ltx@nl#1\fi}
  • ad (2): 默认为 '0pt' 的可选参数基本上就足够了:\renewcommand{\\}[2][0pt]{\ifx\\#2\expandafter\ltx@nl\else\ltx@nl[#1]#2\fi}。这还可以确保多余的任何可选参数\\不会打印到输出中,例如some text\\ \\[3pt] some other text 惯于转换为

一些文字

[3pt] 其他一些文字

最后一点:第二点可以做得更好。目前,将使用 gobbled 行的可选参数。但是,我认为最好也忘记可选参数。为此,您需要另一个辅助宏,该宏使用\\原始调用的可选参数调用存储的版本\\

\newcommand{\ltx@nl@}[1][]{\ltx@nl[\@tempa]}% \@tempa will hold the optional argument of \\
\renewcommand{\\}[2][0pt]{%
  \def\@tempa{#1}%
  \ifx\\#2
    \expandafter\ltx@nl@
  \else
    \ltx@nl[#1]#2
  \fi}

检查所有情况的完整示例:

\documentclass{article}

\parindent0pt

\makeatletter
\let\ltx@nl=\\
\renewcommand{\\}[2][0pt]{%
  \def\@tempa{#1}%
  \ifx\\#2
    \expandafter\ltx@nl@
  \else
    \ltx@nl[#1]#2
  \fi}
\newcommand{\ltx@nl@}[1][]{\ltx@nl[\@tempa]}
\makeatother

\begin{document}
some text\\[16pt]  %linebreak with 16pt vertical offset
\\[4pt]            %will be forgotten completely
someother text\\   %regular forced linebreak
hello world
\end{document}

相关内容