Fusionar saltos de línea consecutivos

Fusionar saltos de línea consecutivos

Tengo algo como esto:

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

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

y me gustaría que se comportara como

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

pero se comporta como

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

¿Hay alguna manera de hacer eso?

La única forma de hacerlo que se me ocurre es redefinir \\para que se redefina \\para no hacer nada y luego \thing, redefinir \\como debería ser.

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

Pero realmente parece un truco que eventualmente rompería algo, así que preferiría otro método. Y también está el hecho de que depende de mí saber que habrá \things. Si lo hubiera \thing1y \thing2eso pudiera alternarse, tendría que agregar algo más de código y si no sé qué puede haber allí, no funcionaría en absoluto...

Gracias de antemano por su ayuda.

Respuesta1

Tu truco no es tan malo. Pero puedes hacerlo de esta manera más rápido y sin necesidad de redefinir \\.

La siguiente solución define la versión gobble de \maybehide(la que activa en caso de que quiera ocultar el contenido) con dos argumentos y verifica si el segundo argumento es igual \\. Si es verdadero, será devorado; si es falso, imprime el segundo argumento:

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

Por ejemplo: \maybehide{xyz}abcidentificaría 'xyz' como el primer argumento que se olvida de todos modos (no aparece en el texto de reemplazo) y 'a' como el segundo argumento. Entonces, la primera expansión es \ifx\\a\else a\fila que luego se expande al caso else obviamente, es decir a; por lo tanto: \maybehide{xyz}abc--> "abc". En el caso de uso real ' \maybehide{xyz}\\...' \maybehidese encontraría \\como segundo argumento, por lo tanto, la prueba se expande al caso verdadero que está vacío; ese medio \\se desecha y \maybehide{xyz}\\simplemente no produce nada.

El ejemplo completo:

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

luego se compila en algo como

1
3

en lugar de

1

3

Para una solución más general que sea independiente de sus macros específicas, por supuesto también puede redefinirlas \\. Algo como

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

es esencialmente lo que se necesita (y utiliza exactamente el mismo enfoque de la solución especial anterior). Ahora hay dos advertencias: (1) \\puede significar cosas diferentes según su entorno y (2) el argumento opcional se pierde.

  • anuncio (1): Lo fácil primero. Almacenar el significado original, \let\ltx@nl=\\y\def\\#1{\ifx\\#1\ltx@nl\else\ltx@nl#1\fi}
  • anuncio (2): un argumento opcional cuyo valor predeterminado es '0pt' es básicamente suficiente: \renewcommand{\\}[2][0pt]{\ifx\\#2\expandafter\ltx@nl\else\ltx@nl[#1]#2\fi}. Esto también asegura que cualquier argumento opcional del superfluo \\no se imprima en la salida, por ejemplosome text\\ \\[3pt] some other text noser convertido a

algún texto

[3pt] algún otro texto

Una última observación: el segundo punto podría mejorarse aún más. Tal como está, se utilizará el argumento opcional de la línea engullida. Pero yo diría que es deseable olvidar también el argumento opcional. Para eso necesita otra macro auxiliar que llame a la \\versión almacenada con el argumento opcional de la llamada original de \\:

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

Un ejemplo completo para comprobar todos los casos:

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

información relacionada