我有类似的东西:
%\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}
}
但它看起来确实像是一种黑客行为,最终会破坏某些东西,所以我真的更喜欢另一种方法。而且,它还取决于我是否知道会有\thing
s。如果有\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}