連続した改行を結合する

連続した改行を結合する

次のようなものがあります:

%\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 があることを知っているかどうかにかかっているという事実もあります。もし s があり\thing1\thing2それが交互に実行できるなら、私はさらにコードを追加しなければなりません。そこに何があるか分からないと、まったく機能しません...

ご協力をよろしくお願いいたします。

答え1

あなたのハックはそれほど悪くありません。しかし、 を再定義する必要なく、より速くこれを行うことができます\\

次のソリューションは、2 つの引数を持つ の gobble バージョン\maybehide(コンテンツを非表示にする場合にアクティブにするバージョン) を定義し、2 番目の引数が に等しいかどうかを確認します\\。true の場合は が消費され、false の場合は 2 番目の引数が何であれ が出力されます。

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

たとえば、 は、\maybehide{xyz}abcいずれにせよ忘れられる最初の引数として 'xyz' を識別し (置換テキストには含まれません)、 'a' を 2 番目の引数として識別します。したがって、最初の展開は であり\ifx\\a\else a\fi、これは明らかに else ケースに展開されます。つまり、a; したがって、次のようになります: \maybehide{xyz}abc--> "abc"。実際の使用例では、 ' \maybehide{xyz}\\...' が2 番目の引数として\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}

は本質的に必要なものです(そして、それは上記の特別な解決策とまったく同じアプローチを使用します)。ここで2つの注意点があります:(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] その他のテキスト

最後に一言: 2 番目のポイントは、さらに改善できる可能性があります。現状では、取り込まれた行のオプション引数が使用されます。ただし、オプション引数も忘れることが望ましいと思います。そのためには、\\元の呼び出しのオプション引数を使用して保存されたバージョンを呼び出す別のヘルパー マクロが必要です\\

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

関連情報