Discussion:
\chapter -> Command \do undefined
(zu alt für eine Antwort)
Ekkart Kleinod
2021-02-11 11:24:38 UTC
Permalink
Hi Ihr,

ich hab ein wahrscheinlich exotisches Problem.

Das Beispiel läuft durch, wenn allerdings der \chapter-Befehl genutzt
wird, ist das \do plötzlich undefiniert und der Fehler "Command \do
undefined" wird geworfen.

Die Konstruktion mit \renewcommand*{\do} ist aus der Doku von etoolbox.

Ist das ein Bug in KomaScript (eher unwahrscheinlich bei Markus)? Ich
kann testen, ob \do definiert ist und dann \newcommand oder
\renewcommand benutzen, aber das fühlt sich wie ein Hack an, der am
eigentlichen Problem vorbeigeht.

Google war auch nicht so richtig hilfreich, evtl. falsche Suchbegriffe.

Könnt Ihr mir da helfen bzw. mich in die richtige Richtung schubsen?

Danke,

Gruß, Ekkart.


MWE:

\documentclass{scrbook}

\usepackage{etoolbox}

\begin{document}

% \chapter{Chap} % creates error: LaTeX Error: Command \do undefined
\renewcommand*{\do}[1]{#1 -- }
\docsvlist{a,b,c}

\end{document}
Ekkart Kleinod
2021-02-11 11:27:53 UTC
Permalink
On 11.02.2021 12:24, Ekkart Kleinod wrote:

<ingrid />
Post by Ekkart Kleinod
Google war auch nicht so richtig hilfreich, evtl. falsche Suchbegriffe.
<https://tex.stackexchange.com/questions/367418/adding-chapter-in-koma-scrbook-generates-a-latex-error-do-undefined>

Gefunden. Da werde ich wohl testen, ob \do definiert ist und dann den
richtigen Befehl (newcommand/renewcommand) nutzen.

Danke für Eure Aufmerksamkeit :)

Gruß, Ekkart.
Ulrike Fischer
2021-02-11 18:13:23 UTC
Permalink
Post by Ekkart Kleinod
<https://tex.stackexchange.com/questions/367418/adding-chapter-in-koma-scrbook-generates-a-latex-error-do-undefined>
Gefunden. Da werde ich wohl testen, ob \do definiert ist und dann den
richtigen Befehl (newcommand/renewcommand) nutzen.
Ich würde einfach \def verwenden. \do ist ein
low-level-Mehrzweckbefehl. Da kann es dann auch einfach mal TeX
werden.
--
Ulrike Fischer
http://www.troubleshooting-tex.de/
Ekkart Kleinod
2021-02-12 08:18:24 UTC
Permalink
Post by Ulrike Fischer
Post by Ekkart Kleinod
<https://tex.stackexchange.com/questions/367418/adding-chapter-in-koma-scrbook-generates-a-latex-error-do-undefined>
Gefunden. Da werde ich wohl testen, ob \do definiert ist und dann den
richtigen Befehl (newcommand/renewcommand) nutzen.
Ich würde einfach \def verwenden. \do ist ein
low-level-Mehrzweckbefehl. Da kann es dann auch einfach mal TeX
werden.
gute Idee. Mal sehen, ob es def wird oder die providecommand-Variante
von Axel.

Danke,

Gruß, Ekkart.
Ulrich Diez
2021-02-17 16:34:08 UTC
Permalink
[...]
Post by Ekkart Kleinod
Post by Ulrike Fischer
Ich würde einfach \def verwenden. \do ist ein
low-level-Mehrzweckbefehl. Da kann es dann auch einfach mal TeX
werden.
gute Idee. Mal sehen, ob es def wird oder die providecommand-Variante
von Axel.
[...]

Ich verstehe die Vorbehalte beim Verwenden von \def nicht.

\def definiert eine Kontrollsequenz in der Gruppe, innerhalb
derer das \def-Assignment stattfindet.
\def ist egal, ob sie bereits definiert ist.
Falls sie bereits definiert ist, wird sie in der Gruppe,
innerhalb derer das \def-Assignment stattfindet,
stillschweigend umdefiniert.


Aber wer Angst vor \def hat, kann vielleicht trotzdem
wagemutig \csname..\endcsname verwenden:

\documentclass{scrbook}

\usepackage{etoolbox}

\begin{document}

\chapter{Chap}
\csname\csname @ifundefined\endcsname{do}{}{re}newcommand\endcsname*{\do}[1]{#1 -- }
\docsvlist{a,b,c}

\end{document}
Axel Berger
2021-02-17 21:26:27 UTC
Permalink
Post by Ulrich Diez
Ich verstehe die Vorbehalte beim Verwenden von \def nicht.
Ich habe keine Vorbehalte, ich verstehe nur zu wenig. Ich habe \def
schon mehrfach aus Beispielen anderer übernommen und abgeschieben, aber
ich habe keine Ahnung ob und welche Rand- und Nebeneffekte es unter
bestimmten Bedingungen haben könnte.

Die verschiedenen Varianten von \*command{}{} sind im Anfängerlehrbuch
von Lamport genau beschrieben und als Anfänger scheint es mir sicherer,
mich soweit möglich darauf zu beschränken.
Post by Ulrich Diez
Aber wer Angst vor \def hat, kann vielleicht trotzdem
Das Konstrukt verstehe ich schon rein gar nicht und habe keine Ahnung,
was es tut. Ich habe komplette Codeblöcke damit aus anderen Beispielen
übernommen, würde mich aber nie trauen, in dem Bereich irgendetwas zu
verändern.

Ich kenne genug Anwendungen von \def, um halbwegs zu wissen, was es tut,
aber in eigenem Code beschränke ich mich dennoch wo immer möglich auf
das, was ich wirklich verstehe.
--
/¯\ No | Dipl.-Ing. F. Axel Berger Tel: +49/ 221/ 7771 8067
\ / HTML | Roald-Amundsen-Straße 2a Fax: +49/ 221/ 7771 8069
 X in | D-50829 Köln-Ossendorf http://berger-odenthal.de
/ \ Mail | -- No unannounced, large, binary attachments, please! --
Ulrich Diez
2021-02-18 11:38:20 UTC
Permalink
[...]
Post by Axel Berger
Post by Ulrich Diez
Aber wer Angst vor \def hat, kann vielleicht trotzdem
Das Konstrukt verstehe ich schon rein gar nicht und habe keine Ahnung,
was es tut. Ich habe komplette Codeblöcke damit aus anderen Beispielen
übernommen, würde mich aber nie trauen, in dem Bereich irgendetwas zu
verändern.
Falls Dich interessiert, was \csname tut:

\csname ist ein expandierbares Primitive.

\csname sammelt Buchstaben ein bzw Character-Token. Beim
Einsammeln werden expandierbare Token expandiert.
Wenn es beim Einsammeln auf ein nicht-expandierbares Token
stösst, das kein Buchstabe ist, gibt es eine Fehlermeldung aus.
\csname sammelt so lange, bis es ein \endcsname findet.
Wenn \endcsname gefunden ist, werden die eingesammelten
Buchstaben/Character-Token als der Name eines Kontrollsequenz-
Token begriffen und dieses Kontrollsequenz-Token wird geliefert.
Wenn es nicht definiert ist, wird es beim Liefern auch gleich
definiert und zwar gleich dem \relax-Primitive.

--------------------------------------------------------------------------------
\csname\csname @ifundefined\endcsname{do}{}{re}newcommand\endcsname*{\do}[1]{#1 -- }
--------------------------------------------------------------------------------

tut salopp gesagt also folgendes:

Das erste \csname bewirkt, dass TeX anfängt, Buchstaben einzusammeln,
die den Namen einer Kontrollsequenz bilden:

--------------------------------------------------------------------------------
% Expansion des ersten \csname und damit das Einsammeln von Buchstaben,
% die den Namen eines Kontrollsequenz-Token bilden, läuft.
\csname @ifundefined\endcsname{do}{}{re}newcommand\endcsname*{\do}[1]{#1 -- }
--------------------------------------------------------------------------------

Beim Einsammeln wird das zweite \csname gefunden und expandiert, d.h. es wird
begonnen, die Buchstaben für den Namen eines weiteren Kontrollsequenz-Token
einzusammeln:

--------------------------------------------------------------------------------
% Expansion des ersten \csname und damit das Einsammeln von Buchstaben,
% die den Namen eines Kontrollsequenz-Token bilden, läuft.
% Expansion des zweiten \csname und damit das Einsammeln von Buchstaben,
% die den Namen eines weiteren Kontrollsequenz-Token bilden, läuft.
@ifundefined\endcsname{do}{}{re}newcommand\endcsname*{\do}[1]{#1 -- }
--------------------------------------------------------------------------------

Beim Einsammeln der Buchstaben, die den Namen des weiteren Kontrollsequenz-
Token bilden, wird die Buchstabensequenz "@ifundefined" gefunden, gefolgt von
\endcsname, welches die Suche nach Buchstaben, die den Namen des weiteren
Kontrollsequenz-Token bilden , beendet.
Also wird das Kontrollsequenz-Token \@ifundefined geliefert und mit der Lieferung
das Expandieren des zweiten \csname beendet:

--------------------------------------------------------------------------------
% Expansion des ersten \csname und damit das Einsammeln von Buchstaben,
% die den Namen eines Kontrollsequenz-Token bilden, läuft.
\@ifundefined{do}{}{re}newcommand\endcsname*{\do}[1]{#1 -- }
--------------------------------------------------------------------------------

\@ifundefined wiederum ist ein expandierbarer Befehl, der drei Argumente verarbeitet:
Das erste Argument stellt den Namen eines Kontrollsequenz-Token dar.
Das zweite Argument beinhaltet die Token, die geliefert werden sollen, wenn das
Kontrollsequenz-Token, dessen Name im ersten Argument angegeben ist, entweder
nicht definiert oder gleich dem \relax-Primitive gesetzt ist.
Das dritte Argument beinhaltet die Token, die geliefert werden sollen, wenn das
Kontrollsequenz-Token, dessen Name im ersten Argument angegeben ist, definiert,
ist, aber nicht dem \relax-Primitive gleichgesetzt ist.

Wenn \do nicht definiert ist, liefert das \@ifundefined-Konstrukt also gar nichts.
Wenn \do definiert ist, liefert es die Buchstaben "re". Beim Einsammeln der Buchstaben
wird also bis zu dem \endcsname, welches das Eisammeln beendet, entweder die
Buchstabensequenz "newcommand" oder die Buchstabensequenz "renewcommand"
gefunden und dafür das entsprechende Kontrollsequenz-Token geliefert, also entweder
\newcommand oder \renewcommand, je nachdem, ob \do nicht definiert oder
definiert ist.

Wenn \do nicht definiert ist, ergibt sich also
--------------------------------------------------------------------------------
\newcommand*{\do}[1]{#1 -- }
--------------------------------------------------------------------------------

Wenn \do definiert ist, ergibt sich also
--------------------------------------------------------------------------------
\renewcommand*{\do}[1]{#1 -- }
--------------------------------------------------------------------------------

Ulrich
Axel Berger
2021-02-18 14:59:38 UTC
Permalink
Vielen Dank für Deine ausführliche und gut verständliche Erklärung.
Bitte sieh mir nach, daß ich mir das vermutlich nicht merken kann --
zumindest nicht gut genug für eine eigene fehlerfreie Umsetzung -- und
deshalb \csname weiter unter "zu kompliziert für mich" ablege.
--
/¯\ No | Dipl.-Ing. F. Axel Berger Tel: +49/ 221/ 7771 8067
\ / HTML | Roald-Amundsen-Straße 2a Fax: +49/ 221/ 7771 8069
 X in | D-50829 Köln-Ossendorf http://berger-odenthal.de
/ \ Mail | -- No unannounced, large, binary attachments, please! --
Holger Schieferdecker
2021-02-19 08:14:17 UTC
Permalink
Post by Ulrich Diez
[...]
Post by Axel Berger
Post by Ulrich Diez
Aber wer Angst vor \def hat, kann vielleicht trotzdem
Das Konstrukt verstehe ich schon rein gar nicht und habe keine Ahnung,
was es tut. Ich habe komplette Codeblöcke damit aus anderen Beispielen
übernommen, würde mich aber nie trauen, in dem Bereich irgendetwas zu
verändern.
\csname ist ein expandierbares Primitive.
Auch von mir vielen Dank für die gute Erklärung, die die Verwendung von
\csname für mich erhellt. Der Trick mit dem fallweisen Voranstellen von
re ist nett.

Aber jetzt mal ganz naiv gefragt, wäre denn nicht auch folgendes
gegangen? Natürlich muß man dann darauf achten, die neue Definition
zweimal exakt gleich zu schreiben.

\@ifundefined{do}
{\newcommand*{\do}[1]{#1 -- }}
{\renewcommand*{\do}[1]{#1 -- }}

Holger
Ulrike Fischer
2021-02-19 10:46:57 UTC
Permalink
Post by Holger Schieferdecker
Aber jetzt mal ganz naiv gefragt, wäre denn nicht auch folgendes
gegangen? Natürlich muß man dann darauf achten, die neue Definition
zweimal exakt gleich zu schreiben.
{\newcommand*{\do}[1]{#1 -- }}
{\renewcommand*{\do}[1]{#1 -- }}
Ja, aber wozu der Aufwand? Was du hier tust, ist \do umzudefinieren.
Auf jeden Fall. Ohne Ausnahme.

Wenn du dich damit ins Knie schießt, hilft es nicht, das
mit einem (bzw. mehreren, weil \newcommand ja das gleiche nochmal
testet) Test zu umgeben, den du dann ignorierst.

\def\do#1{#1 --} ist kürzer, weniger fehleranfällig, weil du die
Definition nur einmal schreibst und genauso sicher (oder unsicher).
--
Ulrike Fischer
http://www.troubleshooting-tex.de/
Holger Schieferdecker
2021-02-19 12:00:40 UTC
Permalink
Post by Ulrike Fischer
Post by Holger Schieferdecker
Aber jetzt mal ganz naiv gefragt, wäre denn nicht auch folgendes
gegangen? Natürlich muß man dann darauf achten, die neue Definition
zweimal exakt gleich zu schreiben.
{\newcommand*{\do}[1]{#1 -- }}
{\renewcommand*{\do}[1]{#1 -- }}
Ja, aber wozu der Aufwand? Was du hier tust, ist \do umzudefinieren.
Auf jeden Fall. Ohne Ausnahme.
Wenn du dich damit ins Knie schießt, hilft es nicht, das
mit einem (bzw. mehreren, weil \newcommand ja das gleiche nochmal
testet) Test zu umgeben, den du dann ignorierst.
\def\do#1{#1 --} ist kürzer, weniger fehleranfällig, weil du die
Definition nur einmal schreibst und genauso sicher (oder unsicher).
Das stimmt natürlich.

Vielleicht habe ich mich nicht klar genug ausgedrückt, mir ging es
eigentlich darum, ob ein Unterschied zwischen dem Konstrukt mit \csname
(das Ulrich ins Spiel gebracht hat) und dem direkten Hinschreiben gibt.
Also:

\csname\csname
@ifundefined\endcsname{do}{}{re}newcommand\endcsname*{\do}[1]{#1 -- }

vs.

\@ifundefined{do}
{\newcommand*{\do}[1]{#1 -- }}
{\renewcommand*{\do}[1]{#1 -- }}

Letzteres ist zumindest für mich auf einen Blick verständlich, ersteres
hätte ich ohne die Erklärung von Ulrich vermutlich nicht durchschaut.

Holger
Ulrich Diez
2021-02-19 11:18:40 UTC
Permalink
Post by Holger Schieferdecker
Aber jetzt mal ganz naiv gefragt, wäre denn nicht auch folgendes
gegangen? Natürlich muß man dann darauf achten, die neue Definition
zweimal exakt gleich zu schreiben.
{\newcommand*{\do}[1]{#1 -- }}
{\renewcommand*{\do}[1]{#1 -- }}
Das wäre, sofern man vor \makeatletter...\makeatother
keine Angst hat, auch gegangen. ;-)

Aber wenn überhaupt, dann eher:

\@ifundefined{do}{\newcommand}{\renewcommand}*{\do}[1]{#1 -- }}%

, dann muss man die Definition nur einmal schreiben.

Ich würde das alles aber eher gar nicht machen, sondern statt dessen
einfach \def verwenden. ;-)

Denn, wie Ulrike Fischer sagt, soll \do in jedem Fall umdefiniert werden.

Wozu also testen, ob \do schon definiert ist, nur, um in diesem Fall
genau diesen Test durch Verwendung von \renewcommand
wegzulassen.

Wer keine Angst vor \let hat, könnte \do erst per \let einem
Befehl gleichmachen, der definiert ist und dann \renewcommand
verwenden. So in die Richtung

\let\do=\begin
\renewcommand\do*{\do}[1]{#1 -- }}

Aber wozu zwei Assignments, wo es auch ein einziges, nämlich \def,
tut?


Ulrich
Ulrich Diez
2021-02-19 11:25:13 UTC
Permalink
Post by Ulrich Diez
Wer keine Angst vor \let hat, könnte \do erst per \let einem
Befehl gleichmachen, der definiert ist und dann \renewcommand
verwenden. So in die Richtung
\let\do=\begin
\renewcommand\do*{\do}[1]{#1 -- }}
Das war natürlich Murks, wie er zustandekommt wenn man beim
copy-paste nicht aufpasst. Es muss heissen:

\let\do=\begin
\renewcommand*{\do}[1]{#1 -- }}


Ulrich
Holger Schieferdecker
2021-02-19 12:18:34 UTC
Permalink
Post by Ulrich Diez
Post by Holger Schieferdecker
Aber jetzt mal ganz naiv gefragt, wäre denn nicht auch folgendes
gegangen? Natürlich muß man dann darauf achten, die neue Definition
zweimal exakt gleich zu schreiben.
{\newcommand*{\do}[1]{#1 -- }}
{\renewcommand*{\do}[1]{#1 -- }}
Das wäre, sofern man vor \makeatletter...\makeatother
keine Angst hat, auch gegangen. ;-)
Das habe ich nicht, kam bei mir schon ab und zu vor. Daß es in der
Konstruktion mit \csname @ifundefined\endcsname nicht notwendig ist,
wußte ich bis zu meinem Test gerade nicht. Ich hatte @ gedanklich als
immer zu maskieren abgespeichert. Aber das gilt wohl nur, wenn es in
einem Makronamen vorkommt.
Post by Ulrich Diez
, dann muss man die Definition nur einmal schreiben.
Noch eine Überraschung, ich hätte nicht gedacht, daß das auch geht. Ich
glaube, mein Gehirn hat das Konzept des Einlesens von Zeichen und deren
Verknüpfung bei LaTeX noch nicht verinnerlicht. Da bin ich noch zu sehr
den Konstrukten aus Programmiersprachen verhaftet, etwa:

if ... then ... else ... ;

Und da kann man halt nicht schreiben

if a<3 then x else y ; =7;
Post by Ulrich Diez
Ich würde das alles aber eher gar nicht machen, sondern statt dessen
einfach \def verwenden. ;-)
Denn, wie Ulrike Fischer sagt, soll \do in jedem Fall umdefiniert werden.
Wozu also testen, ob \do schon definiert ist, nur, um in diesem Fall
genau diesen Test durch Verwendung von \renewcommand
wegzulassen.
Schon richtig. Aber darauf wollte ich gar nicht hinaus, siehe auch meine
Antwort an Ulrike.

Holger
Ulrich Diez
2021-02-19 14:47:14 UTC
Permalink
Holger Schieferdecker schrieb:

[...]
Post by Holger Schieferdecker
immer zu maskieren abgespeichert. Aber das gilt wohl nur, wenn es in
einem Makronamen vorkommt.
Donald Ervin Knuth, der Erfinder von TeX, vergleicht TeX in seinem TeXbook
mit einem Organismus, der Augen und einen Verdauungstrakt hat.

Die Augen lesen den .tex-Quelltext zeilenweise und nehmen ihn als Serie
von Anweisungen, Buchstaben/Character in den Mund zu nehmen.

Der Mund teilt die Buchstaben in Häppchen ein, sogenannte Token.
Dabei spielen die Category-Codes eine Rolle.

Das können Character-Token sein, bestehend aus einem Character-Code,
der den Code-Point des entsprechenden Buchstaben in der ASCII-Codierung
bzw bei XeTeX und LuaTeX in Unicode-Codierung angibt, und einem
Category-Code, der etwas über die Funktion aussagt (geschweifte Klammern
haben zB Kategoriecode 1 bzw 2. Wenn man diese Kategoriecodes
anderen Zeichen auch zuweist, kann man sie wie die geschweiften Klammern
verwenden).

Das können Kontrollsequenz-Token sein. Entweder Primitives
oder Makros.
Kontrollsequenz-Token, deren Namen aus einem einzigen Zeichen besteht,
das gerade nicht Kategoriecode 11 (Buchstabe/letter) hat, sind Control-
Symbols/Kontrollsymbole.
Kontrollsequenz-Token, deren Namen aus mehreren Zeichen bestehen,
sind Control-Words/Kontrollworte.
Eine Sonderrolle haben "Active Characters". Sie haben den Kategoriecode
13(active) und ihren jeweiligen Character-Code. Man kann sie verwenden
wie Kontrollsequenz-Token. Sie sind aber keine Kontrollsequenz-Token
sondern Character-Token. Zusammen mit den Kontrollsequenz-Token
bilden sie die Menge der Kontrollsequenzen.

Vom Mund kommen die Token in die Speiseröhre. Dort werden expandierbare
Token expandiert, sofern Expansion gerade nicht abgeschaltet/verboten ist,
wie es zB nach \def oder \newcommand (aber nicht bei \edef) der Fall ist,
denn bei \def und \newcommand will man ja, dass die Token, die den
Parametertext und die Token, die den Definitionstext bilden, nicht expandiert
werden.

Von der Speiseröhre kommen die Token in den Magen.
Hier werden Assignments (das Definieren von Makros, das Zuweisen von
Werten zu Registern, etc) statt. Hier werden Boxen und Seiten gebastelt.

Als Verdauungsprodukte erhält man Meldungen auf dem Terminal,
.log-Datei, Hilfsdateien und output-Datei (.dvi- oder .pdf-Datei).

Wenn der Mund von TeX der Speiseröhre ein Token liefern soll, und als
nächstes einen Character vom Kategoriecode 0 (escape) findet - normalerweise
hat nur der Backslash-Character \ den Kategoriecodec 0(escape), fängt er an,
ein Kontrollwort-Token oder ein Kontrollsymbol-Token zu basteln, je
nachdem, ob der folgende Character Kategoriecode 11(Buchstabe) hat oder
nicht.

Wenn der folgende Buchstabe einen von Kategoriecode 11(Buchstabe)
verschiedenen Kategoriecode hat, wird ein Kontroll-Symbol-Token gebastelt,
dessen Name nur aus diesem einen folgenden Buchstaben besteht.

Wenn der folgende Buchstabe Kategoriecode 11(Buchstabe) hat, wird
ein Kontroll-Wort-Token gebastelt: Es werden so lange im Mund liegende
Buchstaben gesammelt, bis einer gefunden wird, der nicht Kategoriecode
11(Buchstabe/letter) hat. Die Sequenz an Kategoriecode-11-Buchstaben
bildet den Namen des Kontrollwort-Tokens, welches der Mund in die
Speiseröhre schickt.

Die Anweisung \makeatletter weist dem Zeichen @ den Kategoriecode 11
(Buchstabe/letter) zu. Der Mund behandelt daraufhin beim Basteln von Token
das Zeichen @ wie andere Zeichen mit Kategoriecde 11(Buchstabe/letter)
auch. D. h. er akzeptiert es als Teil des Namens von Kontroll-Sequenz-
Token.

Die Anweisung \makeatother weist dem Zeichen @ den Kategoriecode 12
(etwas anderes/other) zu: Der Mund akzeptiert daraufhin das Zeichen @
nicht als Teil des Namens von Kontroll-Sequenz-Token.
Wenn der Mund das Zeichen @ findet, während er aufgrund eines direkt
vorher gefunenen Backslashes/Zeichens vom Kategoriecode 0 nur weiss,
dass er ein Kontrollsequenz-Token basteln soll, aber noch nicht weiss, ob
Kontrollsymbol-Token oder Kontrollwort-Token, wird er das Kontrollsymbol-
Token \@ basteln und die Speiseröhre hinunterschicken.
Wenn der Mund das Zeichen @ findet, während er gerade dabei ist, ein
Kontrollwort-Token zu basteln, wird er es nicht als Teil des Namens des
zu bastelnden Kontrollwort-Token akzeptieren, sondern die bis zum @
gesammelten Zeichen als Namen des zu bastelnden Kontrollwort-Token
hernehmen und das entsprechende Kontrollwort-Token an die Speiseröhre
liefern. Wenn die Speiseröhre danach wieder Token anfordert, wird der
Mund ein Character-Token @ mit Kategoriecode 12(etwas anderes/other)
an die Speiseröhre liefern.

\makeatletter..\makeatother weisen dem Zeichen @ einen bestimmten
Kategoriecode zu, was sich darauf auswirkt, wie der Mund beim Basteln
von Token verfährt, wenn er dieses Zeichen verarbeitet.



[...]
Post by Holger Schieferdecker
Noch eine Überraschung, ich hätte nicht gedacht, daß das auch geht. Ich
glaube, mein Gehirn hat das Konzept des Einlesens von Zeichen und deren
Verknüpfung bei LaTeX noch nicht verinnerlicht.
Dieser Satz hat mich zu meinen eben getätigten etwas länglich geratenen
Ausführungen bewogen.

Wenn ich die Sache bildlich veranschaulichen soll, arbeite ich ab und zu mit
folgendem Bild:

Der TeX-Organismus ist ein schnuckeliges Wesen, welches
auf einem Sandstrand liegt, dessen Sand aus Characters/Zeichen besteht.
Character/Zeichen werden also als kleine Gegenstände gesehen.
TeX räkelt sich da also gemütlich im Zeichensand und liest gerne
.tex-Quelltext.
Es interpretiert den .tex-Quelltext als Anweisung, sich aus dem Sand die
entsprechenden Zeichen herauszupicken und in den Mund zu stecken.
Der Mund macht dann daraus Token und schickt die Token die Speiseröhre
hinunter.
Die Speiseröhre expandiert expandierbare Token.
Im Magen landen Token, die nicht expandiert wurden.
Wenn TeX beim Lesen von Quelltext etwas nicht versteht oder mit
etwas nicht einverstanden ist, stösst es kurz auf - in Form einer Fehlermeldung.

Oder ich arbeite mit dem Bild einer Fabrik mit Produktionsstraße.
Am Anfang stehen die Leute, die den Quelltext lesen und dafür Zeichen aufs
Fließband legen.
In der Token-Erzeugungs-Abteilung (Mund) werden die auf dem Fließband
liegenden Zeichen zu Token zusammengefasst.
Die Regeln dafür werden im Wesentlichen durch die zugewiesenen
Kategoriecodes gebildet.
In der Expansionsabteilung (Speiseröhre) werden expandierbare Token
expandiert, d.h. vom Fließband genommen und durch andere Token ersetzt.
Die Regeln dazu werden zB durch \def- oder \newcommand-Anweisungen
gebildet.
Von der Expansionsabteilung fährt das Fließband mit den Token in
die weiteren Abteilungen, wo Boxen gebastelt und Seiten hergestellt
werden und vieles mehr. In den weiteren Abteilungen werden auch die
Hebel für die Fabrik selbst gestellt, zB indem \def-Anweisungen (betreffen
die Expansionsabteilung) oder \catcode-Anweisungen (betreffen die
Token-Erzeugungs-Abteilung) ausgeführt werden.

Bis zu einem gewissen Grad kann man sich die Sache vorstellen wie
einen Mechanismus, der kleine Gegenstände erezeugt und nach Regeln
gegen andere kleine Gegenstände austauscht.

Ulrich
Holger Schieferdecker
2021-02-23 14:15:27 UTC
Permalink
Post by Ulrich Diez
[...]
Post by Holger Schieferdecker
immer zu maskieren abgespeichert. Aber das gilt wohl nur, wenn es in
einem Makronamen vorkommt.
Donald Ervin Knuth, der Erfinder von TeX, vergleicht TeX in seinem TeXbook
mit einem Organismus, der Augen und einen Verdauungstrakt hat.
[...]

Vielen Dank für die gute und ausführliche Erklärung, die ich jetzt erst
lesen konnte. Die letzten Tage war leider zu wenig Zeit.

Jetzt habe ich die Behandlung des @ auch mal verstanden. Letztlich ist
ein @ nichts anderes als ein . oder eine Ziffer, rein vom Category-Code
her. Die können alle nicht (ohne weiteres) Teil eines
Kontrollwort-Tokens sein. Sie werden im normalen Text aber nicht
besonders behandelt.

Die Ausname bei @ wird durch \makeatletter bzw. \makeatother
bewerkstelligt. In Packages ist \makeatletter implizit schon aktiviert.
Theoretisch könnte man also auch etwa sowas wie \makedotletter und
\makedotother passend definieren und dann Punkte als Teil von Makronamen
verwenden.

Holger

Axel Berger
2021-02-11 18:43:44 UTC
Permalink
Post by Ekkart Kleinod
Da werde ich wohl testen, ob \do definiert ist und dann den
richtigen Befehl (newcommand/renewcommand) nutzen.
Erscheint mir zu kompliziert und aufwendig. In solchen Fällen, wenn ich
nicht sicher sein kann, verwende ich nacheinander \providecommand und
\renewcommand. Ein Schritt mehr als \renewcommand allein aber geht
immer.

Leute, die mehr können und verstehen, nehmen auch schon mal \def, aber
ich fühle mich damit unsicher und bleibe gern bei dem, was Lamport für
mich leichtverständlich dokumentiert hat.
--
/¯\ No | Dipl.-Ing. F. Axel Berger Tel: +49/ 221/ 7771 8067
\ / HTML | Roald-Amundsen-Straße 2a Fax: +49/ 221/ 7771 8069
 X in | D-50829 Köln-Ossendorf http://berger-odenthal.de
/ \ Mail | -- No unannounced, large, binary attachments, please! --
Ekkart Kleinod
2021-02-12 08:19:13 UTC
Permalink
Post by Axel Berger
Post by Ekkart Kleinod
Da werde ich wohl testen, ob \do definiert ist und dann den
richtigen Befehl (newcommand/renewcommand) nutzen.
Erscheint mir zu kompliziert und aufwendig. In solchen Fällen, wenn ich
nicht sicher sein kann, verwende ich nacheinander \providecommand und
\renewcommand. Ein Schritt mehr als \renewcommand allein aber geht
immer.
Leute, die mehr können und verstehen, nehmen auch schon mal \def, aber
ich fühle mich damit unsicher und bleibe gern bei dem, was Lamport für
mich leichtverständlich dokumentiert hat.
Auch ein guter Ansatz. Mal sehen, bo ich den Unterschied verstehen,
sonst bin ich der Augen-zu-und-durch-Typ (was dann oft zu rewrite von
Code führt 😁)

Danke,

Gruß, Ekkart.
Lesen Sie weiter auf narkive:
Loading...