3

I have something like this :

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

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

and I would like it to behave as

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

but it behaves as

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

Is there some way to do that?

The only way of doing it I could think of is to redefine \\ so that it redefines \\ to do nothing and then in \thing, redefine \\ as what it should be.

  \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}
  }

But it really looks like a hack that would eventually break something so I'd really prefer another method. And there's also the fact that it depends on me knowing that there will be \things. If there was \thing1 and \thing2 that could alternate, I'd have to add some more code and if I don't know what can be there it wouldn't work at all...

Thank you in advance for your help.

  • 3
    can't you just use \maybehide{\thing{2}\\} – David Carlisle Aug 3 '15 at 14:28
  • 2
    also don't forget % at ends of code lines. – David Carlisle Aug 3 '15 at 14:29
  • ... and also don't forget to \newcommand{\maybehide}[1]{\@bsphack\@esphack}. – Ruben Aug 3 '15 at 14:43
  • @DavidCarlisle : No because the code is generated by LyX :/ – xavierm02 Aug 3 '15 at 14:50
  • If \maybehide{} is always followed by a \\, then you could \makeatletter\newcommand{\maybehide}[1]{\@gobble}\makeatother. – Steven B. Segletes Aug 4 '15 at 19:55
3

Your hack isn't too bad. But you can do this way faster and without any need of redefining \\.

The following solution defines the gobble-version of \maybehide (the one you activate in case you wanna hide the content) with two arguments and checks if the second argument equals \\. If true it will be eaten up, if false it prints whatever the second argument was:

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

For example: \maybehide{xyz}abc would identify 'xyz' as the first argument which is forgotten anyway (it does not take place in the replacement text) and 'a' as the second argument. So the first expansion is \ifx\\a\else a\fi which then expands to the else case obviously, i.e. a; therefore: \maybehide{xyz}abc --> "abc". In the actual use case '\maybehide{xyz}\\...' \maybehide would find \\ as second argument, hence the test expands to the true case which is empty; that means \\ is thrown away and \maybehide{xyz}\\ outputs simply nothing.

The complete example:

\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}

then compiles to something like

1
3

instead of

1

3

For a more general solution that is indipendent from your specific macros you can of course also redefine \\. Something like

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

is essentially what is needed (and it uses the exact same approach of the special solution above.) There are two caveats now: (1) \\ can mean different things according to its surroundings and (2) the optional argument is lost.

  • ad (1): The easy things first. Store the orifinal meaning, \let\ltx@nl=\\, and \def\\#1{\ifx\\#1\ltx@nl\else\ltx@nl#1\fi}
  • ad (2): An optional argument that defaults to '0pt' is basically sufficent: \renewcommand{\\}[2][0pt]{\ifx\\#2\expandafter\ltx@nl\else\ltx@nl[#1]#2\fi}. This also secures that any optional argument of the superflous \\ isn't printed to the output, e.g. some text\\ \\[3pt] some other text won't be converted to

some text

[3pt] some other text

A last remark: The second point could be done even better. As it stands the optional argument of the gobbled line will be used. But, I'd say it is desiderable to forget also the optional argument. For that you need another helper macro that calls the stored \\ version with the optional argument of the original call of \\:

\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}

A complete example to check all cases:

\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}
  • Nice. It's still very specific to this pattern with the maybehide though. I tried to modify your example to redefine \\ using an \ifx to make it "eat" any following \\ but didn't manage to. Shouldn't that be possible too? – xavierm02 Aug 3 '15 at 16:02
  • 1
    @xavierm02 -- see the updatet version. – Ruben Aug 4 '15 at 19:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.