Warum funktioniert das Aufheben des Überspringens hier nicht?

Warum funktioniert das Aufheben des Überspringens hier nicht?

Ich versuche, ein Makro zu definieren, das wie folgt verwendet werden soll:

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

Das Problem ist, dass \unskipder letzte Zeilenumbruch nicht übernommen wird. Wenn ich einen Kommentar hinzufüge (wie as in XKCD 1285.%), funktioniert es wie erwartet, aber ist das nicht das, was \unskippassieren soll?

Das Leerzeichen am Anfang wird korrekt weggeschluckt. Ohne \ignorespacessteht am Anfang ein unterstrichenes Leerzeichen, \ignorespacesentfernt dieses aber. Das \unskipsoll die unterstrichene Anweisung am Ende entfernen, tut es aber nicht.

Nach meinem Verständnis ist das \unskipso ähnlich wie \ignorepreviousspace. Ist das richtig?

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}

Antwort1

\ulineparst sein Argument, um den Text in Wörter zu unterteilen. Ein geparstes Wort wird in eine Box gesetzt, um seine Breite zu messen und es mit den Markierungen (Linie, Doppellinie, Welle, ...) zu überlagern. \unskipGeht also beim Start eines neuen Wortes an den Anfang einer Box. Es gibt kein Leerzeichen, das entfernt werden könnte. Es ist also wirkungslos.

Putten\unskip nach \uline{...}ist besser, weil es den Kleber entfernt. Aber \ulineEinsätzezweidavon anstelle eines Leerzeichens. Das erste ist das unterstrichene Leerzeichen ( \leaders), das zweite ist ein kleines negatives Leerzeichen (-1/300 Zoll), das wahrscheinlich hinzugefügt wurde, um eine bessere Überlappung der unterstrichenen Segmente zu erreichen.

Das Hinzufügen von nur einem \unskipnach \ulinein derandere, inzwischen gelöschte Antwort(nur für 10K+-Benutzer sichtbar), wenn das Zeilenende danach \thesisdurch einen Kommentar entfernt wird, funktioniert es versehentlich. Am Ende eines Absatzes entfernt TeX das letzte Leerzeichen durch ein implizites \unskip.

Lösung mit zwei\unskip

\documentclass{article}
\usepackage[normalem]{ulem}
\newcommand*{\thesis}[1]{%
  \uline{\ignorespaces #1}%
  \unskip\unskip
}

\begin{document}
Before. \thesis{
  Foo.
  Bar.
  Baz.
} After.
\end{document}

Ergebnis

Lösung mit Pakettrimspaces

Im nächsten Beispiel wird das Paket verwendet, trimspacesum die Leerzeichen zu entfernen, bevor der Text an übergeben wird \uline. Dadurch wird die Lösung unabhängiger von der Implementierung von \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}

Antwort2

Heiko hat eine ausführliche Beschreibung der Lösung des Problems gegeben, daher beschränke ich mich auf die Kommentierung der Unterfrage

Nach meinem Verständnis ist das \unskipso ähnlich wie \ignorepreviousspace. Ist das richtig?

Grundsätzlich nein, dieses Verständnis ist nicht richtig. \unskip und \ignorespacesarbeiten auf völlig unterschiedlichen Ebenen (und %vor einem Zeilenumbruch noch einmal auf einer anderen Ebene).

Etwas vereinfacht liest TeX eine Folge vonFigurenaus der Datei und verwandelt sich dann inToken(entweder durch Lesen einer Gruppe von Zeichen als Befehlsname oder durch Zuweisen von Catcode-Werten zu Zeichentoken) Anschließend werden diese Tokenlisten verarbeitet und können schließlich horizontale oder vertikaleListenvon Setzkästen und Klebstoff.

%arbeitet auf der Ebene vonFiguren. Wenn ein %angezeigt wird, werden die restlichen Zeichen in dieser Zeile und der Zeilenumbruch am Ende der Zeile übersprungen und überhaupt nicht in Token umgewandelt.

\ignorespacesarbeitet auf der Ebene vonToken. Nachdem \ignorespacesalle Leerzeichen-Token (die normalerweise im vertikalen Modus ignoriert werden oder im horizontalen Modus eine Verbindung zwischen Wörtern hinzufügen) ignoriert wurden, bis das erste Token ohne Leerzeichen angezeigt wird, wenn die Befehle Enden beeinflussen.

\unskiparbeitet auf der Ebene vonListen. Wenn das vorherige Element zur aktuellen horizontalen Liste hinzugefügt wurde (unabhängig davon, ob es aus einem Leerzeichen oder von einem expliziten oder impliziten Befehl stammt) \vskipoder \hskipaus der aktuellen Liste entfernt und verworfen wird. (Außer in der vertikalen Hauptliste auf der Seite, wo Sie hinzugefügte Elemente nicht mehr entfernen dürfen und wo es \unskipsich um einen No-Op handelt.)

Abgesehen von der Tatsache, dass sie auf unterschiedlichen Strukturen arbeiten, beachten Sie (was für die Verarbeitung am Ende eines Absatzes in dieser Frage relevant ist), dass \ignorespacesjede Anzahl aufeinanderfolgender Leerzeichen ignoriert wird, aber \unskipimmer nur ein Verbindungsknoten entfernt wird. Normalerweise wird natürlich \ignorespacesnur ein Leerzeichen-Token zum Ignorieren angezeigt, da Sie arbeiten müssen, um zwei aufeinanderfolgende Token als aufeinanderfolgendes Leerzeichen zu erhaltenFigurenwerden als einzelnes Leerzeichen tokenisiert. \ignorespaces\space\spaceWürde aber beispielsweise beide ignorieren.

verwandte Informationen