
Ich habe so etwas:
%\newcommand{\maybehide}[1]{#1}
\newcommand{\maybehide}[1]{}
\newcommand{\thing}[1]{#1}
\newcommand{\bigthing}[1]{#1}
\bigthing{
\thing{1}\\
\maybehide{\thing{2}}\\
\thing{3}
}
und ich möchte, dass es sich so verhält wie
\bigthing{
\thing{1}\\
\thing{3}
}
aber es verhält sich wie
\bigthing{
\thing{1}\\
\\
\thing{3}
}
Gibt es eine Möglichkeit, das zu tun?
Die einzige Möglichkeit, die mir einfällt, besteht darin, es \\
so neu zu definieren, dass es neu definiert wird, \\
um nichts zu tun, und es dann in \thing
neu zu definieren, \\
wie es sein sollte.
\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}
}
Aber es sieht wirklich nach einem Hack aus, der irgendwann etwas kaputt machen würde, also würde ich wirklich eine andere Methode bevorzugen. Und es hängt auch davon ab, dass ich weiß, dass es \thing
s geben wird. Wenn es welche gäbe \thing1
und \thing2
das abwechseln könnte, müsste ich noch mehr Code hinzufügen und wenn ich nicht wüsste, was da sein könnte, würde es überhaupt nicht funktionieren ...
Vielen Dank im Voraus für Ihre Hilfe.
Antwort1
Dein Hack ist nicht so schlecht. Aber du kannst es viel schneller machen und musst es nicht neu definieren \\
.
Die folgende Lösung definiert die Gobble-Version von \maybehide
(die Sie aktivieren, wenn Sie den Inhalt verbergen möchten) mit zwei Argumenten und prüft, ob das zweite Argument gleich \\
ist. Wenn dies zutrifft, wird es aufgefressen, wenn nicht, wird das zweite Argument ausgegeben:
\newcommand{\maybehide}[2]{\ifx\\#2\else#2\fi}
Beispielsweise \maybehide{xyz}abc
würde 'xyz' als erstes Argument identifizieren, was aber ohnehin vergessen wird (es findet im Ersetzungstext keinen Platz) und 'a' als zweites Argument. Die erste Erweiterung ist also, \ifx\\a\else a\fi
was dann offensichtlich zum else-Fall erweitert wird, also a
: \maybehide{xyz}abc
--> "abc". Im tatsächlichen Anwendungsfall würde ' \maybehide{xyz}\\...
' als zweites Argument gefunden werden, daher wird der Test zum true-Fall erweitert, der leer ist; das heißt, wird weggeworfen und gibt einfach nichts aus.\maybehide
\\
\\
\maybehide{xyz}\\
Das vollständige Beispiel:
\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}
dann wird es zu etwas wie
1
3
anstatt
1
3
Für eine allgemeinere Lösung, die unabhängig von Ihren spezifischen Makros ist, können Sie natürlich auch neu definieren \\
. So etwas wie
\def\\#1{\ifx\\#1\newline\else\newline#1\fi}
ist im Wesentlichen das, was benötigt wird (und es verwendet genau den gleichen Ansatz wie die spezielle Lösung oben). Es gibt jetzt zwei Einschränkungen: (1) \\
kann je nach Umgebung Verschiedenes bedeuten und (2) das optionale Argument geht verloren.
- ad (1): Die einfachen Dinge zuerst. Bewahre die ursprüngliche Bedeutung,
\let\ltx@nl=\\
, und\def\\#1{\ifx\\#1\ltx@nl\else\ltx@nl#1\fi}
- zu (2): Ein optionales Argument, das standardmäßig '0pt' ist, ist grundsätzlich ausreichend:
\renewcommand{\\}[2][0pt]{\ifx\\#2\expandafter\ltx@nl\else\ltx@nl[#1]#2\fi}
. Dies stellt auch sicher, dass optionale Argumente des Überflüssigen\\
nicht auf die Ausgabe gedruckt werden, z. B.some text\\ \\[3pt] some other text
Gewohnheitumgewandelt werden in
etwas Text
[3pt] ein anderer Text
Eine letzte Bemerkung: Der zweite Punkt könnte noch besser gemacht werden. So wie es aussieht, wird das optionale Argument der verschlungenen Zeile verwendet. Aber ich würde sagen, es ist wünschenswert, auch das optionale Argument zu vergessen. Dafür braucht man ein weiteres Hilfsmakro, das die gespeicherte \\
Version mit dem optionalen Argument des ursprünglichen Aufrufs von aufruft \\
:
\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}
Ein vollständiges Beispiel zur Überprüfung aller Fälle:
\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}