合併連續換行符

合併連續換行符

我有這樣的東西:

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

但它看起來確實像是一個最終會破壞某些東西的駭客,所以我真的更喜歡另一種方法。還有一個事實是,這取決於我是否知道會有\things。如果有\thing1並且\thing2可以交替,我必須添加更多程式碼,如果我不知道那裡可以有什麼,那麼它根本不起作用...

預先感謝您的幫忙。

答案1

你的黑客技術還不錯。但是您可以更快地完成此操作,並且無需重新定義\\

以下解決方案使用兩個參數定義了 gobble 版本\maybehide(您在想要隱藏內容時啟動的版本),並檢查第二個參數是否等於\\。如果為真,它將被吃掉,如果為假,它將列印第二個參數的內容:

\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會找到\\第二個參數,因此測試擴展到為空的真實情況;這意味著\\被丟棄並且\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)可選參數丟失。

  • 廣告(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]一些其他文字

最後一點:第二點可以做得更好。按照目前的情況,將使用吞噬行的可選參數。但是,我想說最好也忘記可選參數。為此,您需要另一個輔助宏,它\\使用原始呼叫的可選參數來呼叫儲存的版本\\

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

相關內容