LaTex macht mich noch wahnsinnig

Antwort erstellen


Diese Frage dient dazu, das automatisierte Versenden von Formularen durch Spam-Bots zu verhindern.
Smilies
:D :) :( :o :shock: :? 8) :lol: :-x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:

BBCode ist eingeschaltet
[img] ist eingeschaltet
[flash] ist ausgeschaltet
[url] ist eingeschaltet
Smilies sind eingeschaltet

Die letzten Beiträge des Themas

Ich habe die Datenschutzerklärung gelesen und bin damit einverstanden.

   

Wenn du eine Datei oder mehrere Dateien anhängen möchtest, gib die Details unten ein.

Ansicht erweitern Die letzten Beiträge des Themas: LaTex macht mich noch wahnsinnig

von Rolli » Fr 24. Jan 2020, 21:14

Ich danke Euch allen für die Erläuterungen. So ganz verstehe ich es immer noch nicht, aber ich werde mich irgendwie durchwursteln …

Gruß vom Rolli

von oft gesehener » Mi 22. Jan 2020, 07:43

Da TeX den nicht zutreffenden Zweig eines \if…\else…\fi nicht ausführt, sondern darin nur nach balancierten \if…, \else und \fi Ausschau hält, müssen dafür eben ein paar Bedingungen gelten. So würde beispielsweise bei:
\iffalse
\newif\iftest
\iftest
Ja,
\else
Nein,
\fi
das wird nie ausgeführt.
\fi
das \iftest, das im nicht zutreffenden Zweig definiert wird, für TeX keine \if…-Anweisung und damit würden das \else und \fi danach bereits zum \iffalse gehören. Damit wird »Das wird nie ausgeführt.« eben doch ausgeführt und das zweite \fi wird als Fehler gemeldet:
\documentclass{article}
\begin{document}
\iffalse
\newif\iftest
\iftest
Ja,
\else
Nein,
\fi
das wird nie ausgeführt.
\fi
\end{document}
ergibt also:
Extra \fi.
l.11 \fi
und im Dokument steht der Satz »Nein, das wird nie ausgeführt.«

Angewendet auch dein Beispiel wird beim zweiten Einlesen, wenn \aHeader nicht definiert ist, \makeatletter nicht ausgeführt. Damit lautet die Anweisung nicht mehr \ifin@, sondern \ifin. Das ist für TeX keine definierte \if…-Anweisung. Also gehört das \fi dahinter bereits zu \ifdefined\aHeader und beendet dieses. Die weiteren \fi in der Datei sind dann zuviel.

Der Umgang mit \if… ist also weit weniger trivial, als man das auf den ersten Blick vermutet.

In einer Wrapper-Klasse wäre das übrigens in der Tat aus zwei Gründen nicht passiert:
  • Man braucht in einer Klasse kein \makeatlettetr, sondern @ sind automatisch Buchstaben.
  • LaTeX selbst verhindert das mehrfache Einlesen von Klassen und Paketen.
Dafür muss man in einer Wrapper-Klasse schon mit Patches arbeiten, wenn beispielsweise nach \begin{document} bereits automatisch Satzanweisungen folgen sollen, beispielweise um den Titel auszugeben o. ä. Es gibt jedoch Pakete, die den Klassenautor dabei unterstützen.

von Rolli » Mi 22. Jan 2020, 04:42

Danke für die Erläuterung, Ulrike!
Ich sehe, dass es so funktioniert:
\begin{filecontents*}{myTest.tex}
 \ifdefined\aHeader%
  \let\aHeader\undefined%
  \documentclass{scrartcl}
  \usepackage{xinttools}

  %\makeatletter
  \newcommand\myCheck[2]{%
   \xintFor*##1 in{#1}:
	{%
	 \in@{##1}{#2}%
	 \unless\ifin@\expandafter\xintBreakFor\fi
	}%
	\ifin@\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  }
  %\makeatother
 \fi 
\end{filecontents*}

\def\aHeader{}
\makeatletter
\input{myTest.tex}
\makeatother
\makeatletter
\input{myTest.tex} % Führt nicht mehr zum Fehler “Too many }'s”.
\makeatother

\begin{document}
 Hallo, Welt!
\end{document}
Aber sehen heißt nicht: verstehen. Das TeXbook sagt doch auf S. 207
The general form of such “conditional text” is \if<condition><true text>\else<false text>\fi where the <true text> is skipped unless the <condition> is true, and the <false text> is skipped unless the <condition> is false. If the <false text> is empty, you can omit the \else.
Nach meinem Verständnis ist TeX doch ein single-pass-Compiler, stimmts? D.h. beim ersten Durchlauf meines “myTest-Codes” kommt \myCheck in die Symboltabelle. Beim zweiten Durchlauf dürfte daran doch nie etwas geändert werden, weil kein \else und \if falsch (S. 207 TeXbook) ???

Außerdem: Nach meinem Verständnis ändert \makeatletter lediglich temporär den CatCode für @ von 12 auf 11, bis zum \makeatother, der es wieder zurück auf 12 setzt. D.h., im puren TeX \catcode'@=11 bzw. \catcode'@=12. Damit wird @ rein textuell Teil des Makros und ist somit 1:1 in der Symboltabelle - oder habe ich das grob falsch verstanden???

Gruß vom Rolli

von u_fischer » Di 21. Jan 2020, 18:10

Dein \makeatletter kommt zu spät.

Wenn der Header nicht definiert ist, wird es nicht ausgeführt, und dann wird \ifin@ nicht als if-Befehl erkannt, und \ifdefined findet das \else und versucht den Zweig auszuführen.

Ich kann nur davon abraten, komplizierte Codeblöcke in \if-Zweige zu stecken. Das ist oft ziemlich trickig.

von Gast » Di 21. Jan 2020, 14:42

https://texwelt.de/fragen/1479/wie-erst ... ntenklasse

So eine Wrapperklasse kann sehr einfach, aber auch sehr komplex sein. Die einfachste, denkbare Wrapperklasse wäre:
\documentclass{myarticle}
\LoadClassWithOptions{article}
\endinput
Eine extrem komplexe Wrapperklasse ist beispielsweise tudscrbook aus tudscr.

von Rolli » Di 21. Jan 2020, 13:52

… habe ich noch nie gemacht, kannst Du mich etwas "ankicken"?

von Gast » Di 21. Jan 2020, 13:49

Warum schreibst du nicht einfach eine Wrapper-Klasse?

LaTex macht mich noch wahnsinnig

von Rolli » Di 21. Jan 2020, 13:15

Hallo!

Ich bastele seit heute morgen 8 Uhr an diesem Problem:

Ich möchte eine Header-Datei haben, in der meine Standard-Präambel, mein Standard-Code rund um \begin{document}, und mein Standard-Code rund um \end{document} übersichtlich zusammen sind.

Hier ein abgespecktes Code-Beispiel, welches den Fehler zeigt, der mich gerade in die Verzweiflung treibt:
\begin{filecontents*}{myTest.tex}
\ifdefined\aHeader%
\let\aHeader\undefined%
\documentclass{scrartcl}
\usepackage{xinttools}
      
\makeatletter
\newcommand\myCheck[2]{%
\xintFor*##1 in{#1}:
{%
\in@{##1}{#2}%
\unless\ifin@\expandafter\xintBreakFor\fi
}%
\ifin@\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}
\makeatother
\fi 
\end{filecontents*}

\def\aHeader{}
\input{myTest.tex}
\input{myTest.tex} % Führt zu Fehler Too many }'s

\begin{document}
   Hallo, Welt!
\end{document}

Wenn ich die viertletzte Zeile (das doppelte \input...) lösche, funktioniert es wie beabsichtigt.
Mit dem doppelten \input gibt es einen Fehler "Too many }'s" in meinem \myCheck.
1. Da sind nicht zu viele { oder } - die sind sauber gepaart …
2. Wieso wird das überhaupt ein zweites Mal ausgeführt???

Hilfe …

Gruß vom Rolli

Edit: Wenn ich den Code in myTest.tex in die Hauptdatei packe, anstatt es auszulagern, klappt alles wunderbar ...

Nach oben