
У меня что-то вроде этого:
%\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
Ваш хак не так уж плох. Но вы можете сделать это быстрее и без необходимости переопределения \\
.
Следующее решение определяет gobble-версию \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}
. Это также гарантирует, что любой необязательный аргумент superflous\\
не будет выведен на выход, напримерsome text\\ \\[3pt] some other text
не будетбыть преобразован в
какой-то текст
[3pt] какой-то другой текст
Последнее замечание: второй пункт можно было бы сделать еще лучше. В нынешнем виде будет использоваться необязательный аргумент сожранной строки. Но я бы сказал, что желательно забыть и необязательный аргумент. Для этого вам понадобится еще один вспомогательный макрос, который вызывает сохраненную версию \\
с необязательным аргументом исходного вызова \\
:
\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}