次のように使用するマクロを定義しようとしています。
\usepackage[normalem]{ulem}
\newcommand{\thesis}[1]{\uline{\ignorespaces #1\unskip}}
% underlining required by school - I know, I know
% later...
\thesis{
This is the beginning of a multi-line thesis statement.
I use one sentence on each line throughout my document.
Thus, the thesis is broken as in XKCD 1285.
}
問題は、 が\unskip
最後の改行を無視しないことです。 のようなコメントを追加するとas in XKCD 1285.%
期待どおりに動作しますが、これは\unskip
本来の動作ではないのでしょうか?
最初のスペースは正しく取り込まれます。 なしでは、\ignorespaces
先頭に下線付きのスペースがありますが、\ignorespaces
削除されます。 は、\unskip
末尾の下線付きの文を削除するはずですが、削除されません。
私の理解では、それは\unskip
のようなものだと思います\ignorepreviousspace
。これは正しいですか?
MWE:
\documentclass{article}
\usepackage[normalem]{ulem}
\newcommand{\thesis}[1]{\uline{\ignorespaces #1\unskip}}
\begin{document}
\thesis{
Foo.
Bar.
Baz.
} % comment at end of previous line gives desired output
\end{document}
答え1
\uline
引数を解析してテキストを単語に分割します。解析された単語はボックス内に配置され、その幅が測定され、マーク (線、二重線、波など) が重ねられます。したがって、\unskip
新しい単語の先頭からボックスの先頭に移動します。削除するスペースはありません。したがって、効果はありません。
パッティング\unskip
後 \uline{...}
接着剤を除去するので優れています。しかし、\uline
挿入二スペースの代わりにそれらを追加します。最初のスペースは下線付きのスペース ( \leaders
) で、2 番目は小さな負のスペース (-1/300 インチ) です。これはおそらく下線部分の重なりを良くするために追加されたものです。
の\unskip
後に1つだけ追加する\uline
その他、削除された回答(10K 以上のユーザーのみ表示されます)、コメントによって行末\thesis
が削除された場合、偶然に動作します。段落の最後で、TeX は暗黙的に . によって最後のスペースを削除します\unskip
。
2つの解決策\unskip
\documentclass{article}
\usepackage[normalem]{ulem}
\newcommand*{\thesis}[1]{%
\uline{\ignorespaces #1}%
\unskip\unskip
}
\begin{document}
Before. \thesis{
Foo.
Bar.
Baz.
} After.
\end{document}
パッケージによるソリューションtrimspaces
次の例では、trimspaces
テキストを に渡す前に、パッケージを使用してスペースを削除します\uline
。これにより、ソリューションは の実装からより独立します\uline
。
\documentclass{article}
\usepackage[normalem]{ulem}
\usepackage{trimspaces}
\makeatletter
\newcommand*{\thesis}[1]{%
\def\thesis@text{#1}%
\trim@spaces@in\thesis@text
\expandafter\uline\expandafter{\thesis@text}%
}
\makeatother
\begin{document}
Before. \thesis{
Foo.
Bar.
Baz.
} After.
\end{document}
答え2
Heikoは問題を解決する方法について詳しく説明しているので、私はサブ質問についてコメントすることにします。
私の理解では、それは
\unskip
のようなものだと思います\ignorepreviousspace
。これは正しいですか?
基本的にはいいえ、その理解は正しくありません。完全に異なるレベルで機能します (\unskip
改行の前に、別のレベルで再び機能します)。\ignorespaces
%
少し簡略化すると、TeXは次のようなシーケンスを読み取ります。文字ファイルから取り出してトークン(文字のグループをコマンド名として読み取るか、文字トークンにcatcode値を割り当てることによって)その後、これらのトークンのリストが処理され、最終的に水平または垂直のリスト植字箱と接着剤。
%
レベルで動作する文字. が%
見つかった場合、その行の残りの文字と行末の改行はスキップされ、トークンに変換されません。
\ignorespaces
レベルで動作するトークン.\ignorespaces
すべてのスペース トークン (通常は垂直モードでは無視され、水平モードでは単語間の結合を追加します) は、コマンドの影響が終了したときに最初の非スペース トークンが表示されるまで無視されます。
\unskip
レベルで動作するリスト現在の水平リストに追加された前の項目 (スペースから追加されたか、明示的または暗黙的から追加されたかに関係なく\vskip
)\hskip
が現在のリストから削除され、破棄されます。(ページのメインの垂直リストを除きます。このリストでは、一度追加された項目を削除できず、\unskip
何も実行されません)。
異なる構造で動作しているという事実は別として、\ignorespaces
連続するスペースはいくつでも無視されますが、\unskip
グルーノードは1つしか削除されません(この質問の段落の最後にある処理に関連します)。連続する2つのトークンを連続するスペースとして取得する必要があるため、通常は\ignorespaces
無視するスペーストークンは1つだけです。文字単一のスペーストークンとしてトークン化されます。ただし、たとえばは\ignorespaces\space\space
両方とも無視されます。