So, hier eine TeX-Frage, bitte keine LaTeX-Lösungen anbieten, sondern Plain TeX ohne e-TeX-Erweiterungen, möglichst nur Lösungen, wie man sie aus dem Texbook ableiten kann. Ich möchte die Befehlsdefinitionen verbatim auslagern und auch wieder verbatim einlesen. Wie geht das? Es geht um eine \texnewdef-Funktion, vergleichbar mit \newcommand, die sofort eine Befehlsreferenz für das aktuelle Dokument schreibt, und zwar mit Befehlsname, Beschreibung und verbatim-Code.

Anmerkung: exportiert werden sollen die Befehle in \texnewdef, und zwar das, was hinter \def steht.

Open in writeLaTeX
\texnewdef[slanted, Formatiert den ersten Parameter als slanted]{\def\slanted[#1]{{\sl #1}}}

Hier das Beispiel

Open in writeLaTeX
      %definition von verbatim in TeXBook
\outer\def\begindisplay{\obeylines\startdisplay}
{\obeylines\gdef\startdisplay#1
{\catcode`\^^M=5$$#1\halign|\bgroup\indent##\hfil&&\qquad##\hfil\cr}}
\outer\def\enddisplay{\crcr\egroup$$}
\chardef\other=12
\def\ttverbatim{\begingroup \catcode`\\=\other \catcode`\{=\other
\catcode`\}=\other \catcode`\$=\other \catcode`\&=\other
\catcode`\#=\other \catcode`\%=\other \catcode`\~=\other
\catcode`\_=\other \catcode`\^=\other
\obeyspaces \obeylines \tt}
{\obeyspaces\gdef {\ }} % \obeyspaces now gives \ , not \space|
\outer\def\begintt{$$\let\par=\endgraf \ttverbatim \parskip=0pt
\catcode`\|=0\rightskip=-5pc \ttfinish}{\catcode`\|=0 \catcode`|\=\other % 
|obeylines 
|gdef|ttfinish#1^^M#2\endtt{#1|vbox{#2}|endgroup$$}}
\catcode`\|=\active
{\obeylines\gdef|{\ttverbatim\spaceskip=\ttgl\"u\let^^M=\ \let%
|=\endgroup}}
%definition von verbatim in TeXBook

\newcount\texcomnum %Zähler für die Befehle
\newwrite\texmanual %Schreibanweisung für externe Datei
\immediate\openout\texmanual=\jobname.man %öffnen und benennen der externen Datei
\def\texdisplaymanual{\vskip1\baselineskip BEFEHLSREFERENZ von \jobname.tex
                      \vskip2\baselineskip\immediate\closeout\texmanual \input
                      \jobname.man \vfill
} %Einlesen der externen Datei

\def\texnewdef[#1,#2]#3{\advance\texcomnum by 1
\immediate\write\texmanual{\the\texcomnum. #1: {#2}\vskip0.1\baselineskip
{\tt Hier soll die Befehlsdefintion verbatim-formatiert erscheinen} \vskip1\baselineskip
}#3} %leer übergeordnete Befehlsdefinition mit Texthinweis (an der Stelle
     %steht später der Befel

\texnewdef[slanted, Formatiert den ersten Parameter als
slanted]{\def\slanted[#1]{{\sl #1}}}% Anwendung der übergeordneten Befehlsdefinition mit neuer Definition und
     % Schreibanweisung
\texnewdef[bold, Formatiert den ersten Parameter als bold]{\def\bold[#1]{{\bf
#1}}}% Anwendung der übergeordneten Befehlsdefinition mit neuer Definition und
     % Schreibanweisung
Anwendung im Text 
\slanted[Slanted text]
\bold[Bold text]
\texdisplaymanual
\bye

gefragt 06 Sep '14, 00:37

ctansearch's gravatar image

ctansearch
(ausgesetzt)
Akzeptiert-Rate: 18%

bearbeitet 09 Sep '14, 21:20


Man kann die Definition eines Makros in TeX mit \show oder mit \meaning abfragen. \show schreibt dabei immer in das Terminal und die log-Datei, taugt für Deinen Zweck also nicht. In der Ausgabe von \meaning wird als escape character immer das in \escapechar gespeicherte Zeichen verwenden, unabhängig davon, wie ein Befehl tatsächlich definiert wurde. Beispiel:

Open in writeLaTeX
\escapechar=91
\message{\meaning\bf}

führt zur Ausgabe: macro:->[fam [bffam [tenbf. Das wäre jetzt noch kein Beinbruch. Man könnte ja dafür sorgen, dass \escapgechar auch wirklich 92 ist, bevor man die Ausgabe weiterverarbeitet. Aber: War es für die Definition eines Makros notwendig, statt \ beispielsweise | als escape char zu definieren wie in Deinem Beispielcode für die Definition von \ttfinish, dann wird trotzdem nicht so angezeigt:

Open in writeLaTeX
\message{\meaing\ttfinish}

wird also angezeigt als: macro:#1^^M#2\endtt->#1\vbox {#2}\endgroup $$

Selbst, wenn man die Ausgabe irgendwie zerlegt, etwa mit

Open in writeLaTeX
\gdef\parsemacro#1:#2->#3<-{\def\isarg{#2}\def\isdef{#3}}
\expandafter\parsemacro\meaning\ttfinish<-%
\message{\string\def\string\ttfinish\isarg{\isdef}}

wird man nicht mehr die ursprüngliche Definition erhalten, sondern \def\ttfinish#1^^M#2\endtt{#1\vbox {#2}\endgroup $$}. Das entspricht zwar der Bedeutung aber nicht der Definition.

Hinweis: Statt mit \message auf die Terminal zu schreiben, kann man natürlich auch immer mit \write in eine andere Datei schreiben und erhält dabei genau das gleiche Ergebnis.

Bei Verwendung von e-TeX, das für plainTeX i. d. R. als etex oder auch als pdfetex oder auch pdftex verfügbar ist, gibt es weitere Möglichkeiten mit \detokenize oder \unexpanded, die aber alle ebenfalls das \escapechar-Problem besitzen dürften.

Übrigens: Wenn man bei \meaning den Teil vor dem Doppelpunkt in #1macro#2 aufteilen will, um \long definierte Makros zu erkennen, dann hat man bei der Definition das Problem, dass \meaning Token der Kategorie other liefert. Daher funktioniert ein einfaches

Open in writeLaTeX
\gdef\parsemacro#1macro:#2->#3<-{\def\islong{#1}\def\isarg{#2}\def\isdef{#3}}

höchstwahrscheinlich nicht. Man bräuchte das macro nach #1 ebenfalls mit \catcode other für m, a, c, r und o. Das sei nur der Vollständigkeit halber erwähnt.

Permanenter link

beantwortet 06 Sep '14, 09:48

gast3's gravatar image

gast3
(ausgesetzt)
Akzeptiert-Rate: 53%

bearbeitet 06 Sep '14, 16:11

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:

×22
×1

gestellte Frage: 06 Sep '14, 00:37

Frage wurde gesehen: 7,233 Mal

zuletzt geändert: 09 Sep '14, 21:20