einen Befehl definiert, mit dem ich \par in ein kurzes Makro schmuggeln kann. @Bes hat mich dann in einem Kommentar darauf hingewiesen, dass LaTeX dafür schon \endgraf hätte.

Allerdings ist \endgraf kein Synonym zu LaTeXs \par-Makro, das ja immer mal wieder je nach Kontext seine Bedeutung ändert, sondern ein Synonym für das Primitiv \par, genau wie \@@par. Beide sind äquivalent definiert.

Open in writeLaTeX
\let\endgraf=\par
...
\let\@@par=\par

Daraus ergeben sich ein paar Fragen:

  • Wieso gibt es neben \@@par noch \endgraf? (Eine Remineszenz an plain TeX?) Mit \@@par ist das Primitiv ja schon ganz klar für Programmierer gespeichert.
  • Muss ich als Anwender (soll heißen, als Autor eines Dokuments, nicht als Programmierer) \endgraf/\@@par überhaupt kennen?
  • Wann sollte ich als Programmierer \endgraf/\@@par statt \par verwenden?
  • Wann, wo (in Listen? Tabellen?) und warum ändert LaTeX die Definition von \par?

Mir liegt bei möglichen Antworten neben technischen Details auch die best-practice am Herzen. Was kann/soll man empfehlen (und warum/warum nicht)?

Es geht mir nicht darum, warum man mit \endgraf ein Absatzende in ein kurzes Makro schmuggeln kann, auch nicht um das Schmuggeln an sich. Das war nur zufälligerweise, was mein Interesse geweckt hat. Sollte man schmuggeln müssen, bewegt man sich sowieso schon Abseits von best-practice-Pfaden (aus welchen Gründen auch immer – die können vielfältig sein.)

gefragt 23 Mai '14, 12:06

cgnieder's gravatar image

cgnieder
22.1k253463
Akzeptiert-Rate: 60%

bearbeitet 24 Mai '14, 17:37


Man muss unterscheiden zwischen dem \par Token, das sind sozusagen die Buchstaben " p a r" und die Bedeutung/Wirkung von \par: das ist, was passiert, wenn \par irgendwo eingefügt wird.

Das par-Token wird von TeX eingefügt, wenn es auf eine Leerzeile stößt. Das par-Token ist auch das, was den Fehler "Runaway argument" erzeugt, wenn ein Argument unerlaubterweise eine Leerzeile enthält (weil Leerzeile ja das Token einfügen). Den Fehler gibt es auch, wenn \par umdefiniert wurde und gar keinen Absatzumbruch macht: Es kommt nur darauf an, ob das Token " p a r" da ist oder nicht.

\endgraf und \@@par sind Befehle, die die "normale" Wirkung von \par enthalten. Die Befehle sind abgesehen vom Namen identisch.

\@@par gibt es für Paketautoren. Es könnte ja ein User oder ein Paket \par umdefinieren (tatsächlich wird \par immer mal wieder, auch im Kernel, umdefiniert), man aber die "normale" Wirkung von \par haben will.

\endgraf ist für normale Nutzer. Der übliche Verwendungsfall ist, dass man damit einen Absatzumbruch in ein Argument schmuggeln kann, wo er eigentlich nicht erlaubt ist (in "kurzen" Befehlen). Das braucht man nicht oft, aber es kommt schon mal vor. Historisch gesehen kommt \endgraf aus plaintex, wo es (auch) für interne Zwecke gedacht war. Aber angesichts dessen, dass LaTeX (und noch mehr LaTeX3) versucht, interne und Benutzerbefehle voneinander zu trennen, sollte man es in Paketen nicht benutzen. Und wer es in Dokumenten benutzt, sollte zumindest in etwa verstanden haben, was es von \par unterscheidet.

Der Befehl (und \@@par) funktioniert in "kurzen" Befehlen, weil ja nicht das \par-Token eingefügt wird.

Open in writeLaTeX
\documentclass{article}

\begin{document}
\newcommand*\test[1]{#1} % Wegen * "kurzer Befehl"

%\test{a\par b}      %Fehler

\test{a\endgraf b}  %Funktioniert

{\def\par{BLUB}
  xx\par yy %\par ist normaler Text
 %\test{c\par b} %trotzdem Fehler
}

\end{document}
Permanenter link

beantwortet 23 Mai '14, 13:35

Ulrike%20Fischer's gravatar image

Ulrike Fischer
3.6k23
Akzeptiert-Rate: 52%

bearbeitet 25 Mai '14, 15:45

Danke für die Antwort, aber sie beantwortet IMHO meine Frage nicht. Die Existenz von \endgraf wird von Frank Mittelbach ganz anders begründet (und bestätigt letztlich meinen Verdacht). Aus vielleicht nachvollziehbaren Gründen, bin ich geneigt, seiner Aussage hier eher zu glauben. Warum es funktioniert, dass man mit \endgraf das Primitive \par schmuggeln kann, habe ich nicht gefragt (das wusste ich schon), und wieso ich es überhaupt verwenden sollte anstatt z.B. \fakepar wird aus der Antwort auch nicht klar.

(23 Mai '14, 16:37) cgnieder

Ich habe inzwischen ein bisschen recherchiert, und möchte versuchen, hier zusammenzufassen, was ich herausgefunden habe/schon wusste.

Grundsätzliche Unterschiede zwischen \par und \endgraf

Die folgenden zwei Punkte erwähnt Frank Mittelbach in seiner Antwort auf When is it better to use par than endgraf? auf TeX.sx:

  • \par (das Makro) ist in LaTeX das Äquivalent zu einer leeren Zeile in einem Dokument! Welche Bedeutung auch immer LaTeX in einem bestimmten Kontext einer leeren Zeile gibt, ist auch das, was \par in diesem Kontext liefert. Beispielsweise werden in einer Tabelle leere Zeilen ignoriert und so enthält auch die Definition von \@array die Zeile \let\par\@empty. Auch in Listen wird es umdefiniert.
  • Im Gegensatz dazu ist \endgraf/\@@par das Primitiv, das den horizontalen Modus beendet und das Material in Zeilen bricht. (Oder nichts macht oder einen Fehler produziert oder ...)

Oder kurz und knapp (Quelle):

abstractly speaking \par implements an abstract user/document level interface and \endgraf a specific technical operation.

([...] \par implementiert ein abstraktes Dokumenten-Level-Interface, \endgraf eine bestimmte technische Operation.)

Laut Frank Mittelbach ist \endgraf allerdings lediglich ein Überbleibsel von plain TeX und sollte in LaTeX nicht verwendet werden:

actually \endgraf is a historic leftover from plain TeX and you should not use it at all in LaTeX code, you should use \@@par to indicate that it is the primitive you are after.

Mögliche Konsequenzen aus Anwendersicht

Obiges bedeutet im weiteren Schluss für mich, dass ein Anwender/eine Anwenderin (sprich: Dokumentenautor/in) eigentlich \endgraf/\@@par im Idealfall nie verwenden sollen müsste (sag niemals nie ;) ). Dafür spricht aus meiner persönlichen Sicht auch schon, dass ich mehr als 10 Jahre gut damit ausgekommen bin, \endgraf gar nicht zu kennen.

Allerdings scheinen die Meinungen hier auseinander zu gehen. @Ulrike argumentiert in ihrer Antwort, dass \endgraf für einen Anwender da ist, wenn er/sie das Primitiv braucht. Ich bin davon nicht völlig überzeugt, kann die Argumentation aber nachvollziehen. Meinem Bauchgefühl nach (und Frank bestätigt mir das), sollte man dabei aber vorsichtig sein:

no: \@@par is not intended for user level while \endgraf was (by Don) and although it is not explicitly documented in LaTeX for this purpose one can argue that \endgraf is a user level command in LaTeX. Personally I think it is a but dangerous as you need to really understand the above difference (and partly how LaTeX does par redefs) to make good use of \endgraf.

(Nein, \@@par ist nicht für das Anwenderlevel gedacht [klar zu erkennen an den @ (Clemens)]), \endgraf war es (von Don) schon, und obwohl es in LaTeX nicht explizit dokumentiert ist, kann man argumentieren, es sei ein Anwenderbefehl. Persönlich denke ich, es ist einer, aber ein gefährlicher, weil man den Unterschied [zu LaTeXs \par (Clemens)] wirklich verstanden haben muss (und zum Teil auch, wie LaTeX \par-Redefinitionen macht), um guten Gebrauch davon zu machen.)


Weil LaTeX die Definition von \par (dem Makro) immer wieder je nach Kontext anpasst, ist es also in der Regel vermutlich sicherer, \par (das Makro) zu verwenden, statt mit \endgraf auf jeden Fall (nur) das Primitiv zu bekommen.


Wenn jemand genau das Primitiv einsetzen möchte oder muss, dann sollte er \@@par verwenden (oder auf Dokument-Level eben auch \endgraf). (Hier bin ich noch auf der Suche nach Fällen, wo ich tatsächlich (ausschließlich) das Primitiv haben möchte. Meinem Gefühl nach sind die eher rar gesät, Beispiele würden mich aber interessieren.)

Permanenter link

beantwortet 23 Mai '14, 14:21

cgnieder's gravatar image

cgnieder
22.1k253463
Akzeptiert-Rate: 60%

bearbeitet 24 Mai '14, 18:28

@Bes ja, das ist klar. Es kommt mir aber auch nicht darauf an, dass man nie Notlösungen bräuchte oder verwenden soll (wir leben eben nicht in einer idealen Welt :), sondern auf den Grundgedanken hinter den Konzepten. Dass man manchmal tricksen muss, ist ja eine andere Geschichte. Darum hab ich ja auch »im Idealfall« geschrieben...

(23 Mai '14, 14:50) cgnieder

Es hat mich z.B. schon ein paar mal geärgert, dass listings' \lstnewenvironment kein \par akzeptiert (meiner Meinung nach ein Fehler in der Implementierung). Dort möchte ich dann in der Regel allerdings eher das »LaTeX-\par« hineinschmuggeln und nicht das Primitiv... (obwohl ich mir bei meinen konkreten Anwendungen zugegeben unsicher bin, ob es einen Unterschied macht. Wahrscheinlich nicht)

(23 Mai '14, 14:56) cgnieder

@Clemens Solche Implementierungsfehler mag es geben. Wobei die Frage immer ist, ob der Fehler darin liegt, dass der Entwickler vergessen hat \par zu erlauben oder das mit Absicht nicht getan hat. Wobei die Absicht wiederum ihre Ursache im Design oder in der Implementierung haben kann.

(23 Mai '14, 16:19) Bes

@Bes das kann natürlich nur der Entwickler beantworten :) (und soll von meiner Seite außerdem gar kein Vorwurf sein.) Im konkreten Fall \lstnewenvironment liegt der Verdacht allerdings nahe, dass es eigentlich wie \newenvironment funktionieren sollte und dieser Punkt einfach übersehen worden ist. Laut Doku: »The syntax comes from LaTeX's \newenvironment

(23 Mai '14, 16:27) cgnieder

Du hast doch selbst mit deinem fakepar einen zu endgraf/@@par äquivalenten Befehl definiert. D.h. du hast es gebraucht, oder stand der nur zur Deko da? Dass du den Befehl mit newcommand statt mit let definierst, ist dabei nicht wirklich relevant. In Paketen würde ich natürlich auch immer \@@par statt \endgraf benutzen, aber in Dokumenten brauchen Nutzer nunmal Befehle ohne @ -- und manchmal (nicht oft) endgraf. Ansonsten denke ich, du hast den Unterschied zwischen dem par-Token und dem par-Befehl noch nicht ganz verstanden. Ich editiere gleich mal meine Antwort ein bisschen.

(23 Mai '14, 18:14) Ulrike Fischer

@Ulrike Doch, mir ist der Unterschied zwischen Token und Befehl durchaus bewusst. Der Punkt ist: wenn ich ein Makro, das zu \par expandiert, verwende, dann erhalte ich an der enstprechenden Stelle auch die Bedeutung, die LaTeX will (also eventuell \@empty oder was auch immer). Mit \endgraf erhalte ich auf jeden Fall (nur) das Primitiv.

(23 Mai '14, 18:19) cgnieder

@Ulrike mir ist auch klar, dass aus Dokumententschreiber-Sicht ein Makro ohne @ angenehmer zu verwenden ist. Mir ist aber nicht klar, warum ein/e Dokumentenschreiber/in unbedingt genau das Primitiv und nicht LaTeXs \par (das Makro) brauchen sollte?

(23 Mai '14, 18:24) cgnieder
1

Nun, dass manchmal \newcommand und manchmal \let die "richtige" Art ist, ein Befehl zu kopieren ist doch klar. Aber das ist doch keine speziell auf \par bezogene Frage. Abgesehen davon: Warum sollte ein Dokumentenschreiber verzweifelt versuchen, \par einzufügen, wenn es gerade die Definition \@empty hat? Viel wahrscheinlicher ist doch, dass wirklich ein "normaler" Absatzumbruch gewünscht wird.

(23 Mai '14, 19:02) Ulrike Fischer

@Ulrike \@empty war ja nur ein x-beliebiges Beispiel. LaTeXs \par macht ja manchmal mehr als nur \@@par aufzurufen. Und wenn ich dann \endgraf verwende, entgeht mir das ja, oder nicht? Daher ja die Frage nach Beispielen, wo das eventuell relevant sein könnte... Es geht ja auch nicht nur um das Schmuggeln. Das ist ja allenfalls ein Teilaspekt der Frage.

(23 Mai '14, 19:11) cgnieder
1

\par ruft nicht \@@par auf. Und natürlich, wenn du die aktuelle Bedeutung von \par haben willst, dann ist \endgraf der falsche Befehl. M.E. braucht der normale Benutzer weder \endgraf noch dein \fakepar häufig. Aber wenn, dann wird er eher "wie mache ich hier einen normalen Absatzumbruch ohne Leerzeile/\par zu benutzen" als "wie füge ich hier die aktuelle (unbekannte) Bedeutung von \par ein" benötigen.

(24 Mai '14, 12:04) Ulrike Fischer

Re »\par ruft nicht \@@par auf.« – Ich meinte mit \@@par natürlich das Primitiv, mit welchem Namen auch immer, nicht unbedingt \@@par exakt. Mein Satz sollte heißen, »LaTeXs \par macht ja manchmal mehr als nur das Primitiv aufzurufen«. Ich verstehe nicht, was so falsch daran sein soll, wenn man rät, auf \endgraf im Zweifel zu verzichten?

(24 Mai '14, 12:28) cgnieder

@Bes meinst Du beim Einsatz in kurzen Argumenten? Ich glaube langsam, ich hätte den Punkt aus Frage und Antwort weglassen sollen. Darum ging es mir die ganze Zeit allenfalls am Rande. Offenbar ist meine Frage sehr missverständlich gestellt :(

(24 Mai '14, 17:18) cgnieder

Ich hatte das eigentlich nur als Aufhänger für die Fragen nehmen wollen, die ich tatsächlich ausformuliert habe

(24 Mai '14, 17:20) cgnieder

Vielleicht muss ich Frage und Antwort nochmal umformulieren und den Schmuggel-Punkt ganz rausnehmen. Dass man das eher selten wenn überhaupt braucht ist uns allen ja ohnehin klar.

(24 Mai '14, 17:30) cgnieder

Die ganze Chose wäre wahrscheinlich einfacher, wenn LaTeX \endgraf gar nicht bereitstellen würde (obwohl sich meine Frage dann auch erledigt hätte). IMHO fährt man sowohl als Anwender als auch als Entwickler ganz ausgezeichnet, wenn man es nicht kennt. Und wenn man das Primitiv wirklich bräuchte, wäre es auch nur ein Einzeiler, sich es in der Präambel zu Verfügung zu stellen

(24 Mai '14, 17:47) cgnieder

@Bes der Schluss ist inzwischen auch wieder aus der Antwort weg...

(24 Mai '14, 17:49) cgnieder

@Bes Ich weiß, wenn das Wörtchen wenn nicht wäre... ist auch egal. In expl3 sind alle Befehle lang (\cs_new:Npn) es sei denn, man stellt es explizit ab (\cs_new_nopar:Npn). Auf Anwenderebene ist es umgekehrt. mit xparse \NewDocumentCommand\foo{mm}{} sind alle Argumente kurz und man muss pro Argument explizit lang einstellen. (\NewDocumentCommand\foo{+mm}{} oder \NewDocumentCommand\foo{m+m}{} oder \NewDocumentCommand\foo{+m+m}{}). Außerdem sind in expl3 auch alle Primitive als don't use markiert (\tex_par:D) und nicht dokumentiert und damit nicht offiziell unterstützt.

(24 Mai '14, 18:04) cgnieder

@Bes @Ulrike einige der obigen Kommentare haben sich IMHO inzwischen erledigt, vielleicht können wir demnächst ein bisschen aufräumen?

(24 Mai '14, 18:04) cgnieder

@Bes Da Du implizierst, dass meine Antwort zu wertend war: ist es so besser? Oder stört Dich noch anderes?

(24 Mai '14, 18:29) cgnieder

Ich denke, du hast Frank missverstanden. Wenn er sagt, dass "\endgraf nicht benutzt werden soll", dann meint er Paketautoren. In plaintex wird nicht klar, zwischen "internen" und Benutzerbefehlen unterschieden. \endgraf ist das sozusagen für alle da. In LaTeX und noch mehr in LaTeX3 wird sehr viel klarer zwischen den Ebenen getrennt.

(25 Mai '14, 15:40) Ulrike Fischer

@Ulrike ich glaube nicht, dass ich ihn missverstanden habe?! Der Satz one can argue that endgraf is a user level command in LaTeX. Personally I think it is ist in der Hinsicht ja auch kaum misszuverstehen. Das ist doch auch, was Du sagst, und wovon ich mich inzwischen von Euch allen hab überzeugen lassen. Ich hab doch auch geschrieben »Wenn jemand genau das Primitiv einsetzen möchte oder muss, dann sollte er [...] auf Dokument-Level [...] \endgraf [verwenden].«

(25 Mai '14, 15:47) cgnieder
Ergebnis 5 von 21 show 16 more comments
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×38
×20
×18

gestellte Frage: 23 Mai '14, 12:06

Frage wurde gesehen: 16,351 Mal

zuletzt geändert: 25 Mai '14, 15:47