PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Abspeichern von Tabellen in eigenem file



G.Hanisch
06-06-2013, 13:31
Hallo ihr TeXfreunde/innen,
habe folgendes Problem:

Speichere einen Teil des TeXfiles in ein anderes ab. Das funktioniert tadellos bei mathematischen Zeichen, nicht aber bei Tabellen. Lässt man das Prozentzeichen im Musterbeispiel weg, dann gibt es reihenweise Fehlermeldungen. Primitivabhilfe ist den \ wegzulassen und ihn dann ihm neuen file zu ergänzen, aber das ist wenig texlike.

Bitte um Ratschläge. Dankr
Günter

\documentclass[fontsize=11pt,headings=big,open=any]{scrbook}
\usepackage[ngerman]{babel}
\makeatletter
\newcommand\listofexamples
{\@starttoc{xmp}}
\makeatother
\newcommand{\Aufg}[2]{#1
\addtocontents{xmp}{#2}\\}%
\begin{document}
\Aufg{Text1}{Text2 z.B. $x_i^2$\\}%
\Aufg{Erster Text}{Text mit Tabelle z.B.\\
%\begin{tabular}{c}Tabellentext\\ \end{tabular}
}
\listofexamples
\end{document}

klops
06-06-2013, 15:19
Du missbrauchst hier \@starttoc und \addtocontents für Dinge, für die sie nicht gedacht sind. Dabei beachtest Du auch nicht, dass das Inhaltsargument von \addtocontents ein moving argument ist, also gilt für zerbrechliche Anweisungen bzw. alle Anweisungen, die beim Schreiben in die aux- und später in die xmp-Datei nicht expandiert werden sollen, mit \protect geschützt werden müssen.

Ich würde Dir aber schlicht stattdessen zu einem Paket wie filecontents (http://www.ctan.org/pkg/filecontents) oder einem anderen Paket, um verbatim in eine Datei zu schreiben, raten.

Übrigens: Code sollte hier im Forum als solcher gekennzeichnet (http://www.mrunix.de/forums/misc.php?do=bbcode) werden. In der Erweitert-Darstellung geht das am einfachsten mit dem #-Knopf in der Toolbar über dem Eingabefeld.

G.Hanisch
06-06-2013, 15:46
Danke für die rasche Antwort.
In verbatim zu speichern wäre optimal - die Tabellenumgebung ist ja nur ein Beispiel, wo es nicht funktioniert -, aber filecontents sammelt nicht die verschiedenen files in eines und bei meinem Problem handelt sich um mehrere hundert Anhänge. Kennt jemand ein package, dass die files in verbatim speichert, sammelt und als ein file ausgibt?
Danke

mechanicus
06-06-2013, 15:49
Hi,

vielleicht solltest du genau beschreiben, was du möchtest. Bisher habe ich es noch nicht verstanden. Was soll eigentlich mit dem Inhalt passieren? Willst du es anhängen (attach)?

Marco

G.Hanisch
06-06-2013, 16:13
Ich schreibe an einer Aufgabensammlung und die Lösungen stehen jeweils bei den Aufgaben. Dadurch können die Aufgaben leicht verschoben werden oder auch neue dazu gefügt werden. Die Lösungen hätte ich gerne beim TeXdurchlauf in ein eigenes file gesammelt, dass ich dann bearbeiten kann. Bei den Lösungen gibt es Tabellen, Aufzählungen, Grafiken etc.

klops
06-06-2013, 16:56
Es würde mich sehr wundern, wenn es das noch nicht als Paket gäbe. Notfalls könnte man sich das mit Hilfe des moreverb-Pakets einfach selbst basteln:
\documentclass[fontsize=11pt,headings=big,open=any]{scrbook}
\usepackage[ngerman]{babel}
\usepackage{moreverb}

\makeatletter
\newenvironment{examplefile}[1]{%
\@bsphack
\@ifundefined{verbatim@out@#1}{%
\expandafter\newwrite\csname verbatim@out@#1\endcsname
\expandafter\show\csname verbatim@out@#1\endcsname
\expandafter\immediate\expandafter\openout \csname
verbatim@out@#1\endcsname #1
}{%
% Am Anfang jedes Beispiels schreiben wir eine Leerzeile, um einen neuen
% Absatz zu beginnen:
\expandafter\immediate\expandafter\write \csname verbatim@out@#1\endcsname
{}%
}%
\let\do\@makeother\dospecials
\catcode`\^^M\active \catcode`\^^I=12
\def\verbatim@processline{%
\expandafter\immediate\expandafter\write\csname verbatim@out@#1\endcsname
{\the\verbatim@line}}%
\verbatim@start
}{%
\@esphack
}
\newcommand*{\inputexamples}[1]{%
\@ifundefined{verbatim@out@#1}{}{%
\expandafter\immediate\expandafter\closeout
\csname verbatim@out@#1\endcsname
\expandafter\let\csname verbatim@out@#1\endcsname\relax
}%
\InputIfFileExists{#1}{\typeout{Example file `#1' read.}}{%
\typeout{Example file `#1' not found.}%
}%
}
\makeatother

\usepackage{lipsum}% Für Demozwecke ganz nützlich.

\begin{document}
\lipsum[1]
\begin{examplefile}{\jobname.xmp}
Text1
\end{examplefile}
\lipsum[2]
\begin{examplefile}{\jobname.xmp}
Noch ein Text mit Tabelle
\begin{tabular}{c}Tabellentext\\\end{tabular}
\end{examplefile}
\lipsum[3]
\inputexamples{\jobname.xmp}
\end{document}
Falls man nicht will, dass jede examplefile-Umgebung einen neuen Absatz beginnt, kann man die entsprechenden beiden Zeilen (siehe Kommentar) auch auskommentieren. Dann muss man für Absätze in der xmp-Datei selbst sorgen.

Die Umgebung ist so angelegt, dass man unterschiedliche Dateien verwenden kann. Allerdings wird man dann sehr schnell in der "no room for new write"-Problem laufen.

G.Hanisch
06-06-2013, 17:23
Herzlichen Dank. Das Ganze funktioniert auch unter lualatex.

mechanicus
06-06-2013, 18:06
Herzlichen Dank. Das Ganze funktioniert auch unter lualatex.
Wenn du sowieso mit Lua arbeitetst, dann kannst du auch mit io.open spielen. Das spart wohl eindeutig TeX Speicher.

Marco

G.Hanisch
06-06-2013, 18:29
Habe mich leider zu früh gefreut, die Umgebung kann nicht in ein neues Makro gesteckt werden: Ich habe \newcommand{\Aufg}[2]{#1 \begin{examplefile}{\jobname.xmp} #2 \end{examplefile}} für \Aufg{Aufgabentext}{Lösungstext} eingefügt und das klappt dann leider nicht.



\documentclass[fontsize=11pt,headings=big,open=any]{scrbook}
\usepackage[ngerman]{babel}
\usepackage{moreverb}

\makeatletter
\newenvironment{examplefile}[1]{%
\@bsphack
\@ifundefined{verbatim@out@#1}{%
\expandafter\newwrite\csname verbatim@out@#1\endcsname
\expandafter\show\csname verbatim@out@#1\endcsname
\expandafter\immediate\expandafter\openout \csname
verbatim@out@#1\endcsname #1
}{%
% Am Anfang jedes Beispiels schreiben wir eine Leerzeile, um einen neuen
% Absatz zu beginnen:
\expandafter\immediate\expandafter\write \csname verbatim@out@#1\endcsname
{}%
}%
\let\do\@makeother\dospecials
\catcode`\^^M\active \catcode`\^^I=12
\def\verbatim@processline{%
\expandafter\immediate\expandafter\write\csname verbatim@out@#1\endcsname
{\the\verbatim@line}}%
\verbatim@start
}{%
\@esphack
}
\newcommand*{\inputexamples}[1]{%
\@ifundefined{verbatim@out@#1}{}{%
\expandafter\immediate\expandafter\closeout
\csname verbatim@out@#1\endcsname
\expandafter\let\csname verbatim@out@#1\endcsname\relax
}%
\InputIfFileExists{#1}{\typeout{Example file `#1' read.}}{%
\typeout{Example file `#1' not found.}%
}%
}
\makeatother

\newcommand{\Aufg}[2]{#1 \begin{examplefile}{\jobname.xmp} #2 \end{examplefile}}
\usepackage{lipsum}% Für Demozwecke ganz nützlich.

\begin{document}
\Aufg{\lipsum[1]}
%\begin{examplefile}{\jobname.xmp}
{Text1}
%\end{examplefile}
\end{document}

klops
06-06-2013, 18:58
Das kann auch nicht klappen, weil moreverb im Text nach dem Ende der Umgebung scannt, das aber Teil einer Expansion wäre, was nicht funktionieren kann. Aber das kann so ohnehin nicht funktionieren, weil verbatim lesen nur beim Scannen funktioniert. Wenn aber der Text, der verbatim geschrieben werden soll in einem Argument steckt, dann wurde er bereits nicht verbatim gelesen ist also nicht mehr verbatim. Fazit: Arbeite mit Umgebungen! Beispielsweise so:
\documentclass[fontsize=11pt,headings=big,open=any]{scrbook}
\usepackage[ngerman]{babel}
\usepackage{moreverb}

\makeatletter
\newenvironment{examplefile}[1]{%
\@bsphack
\@ifundefined{verbatim@out@#1}{%
\expandafter\newwrite\csname verbatim@out@#1\endcsname
\expandafter\show\csname verbatim@out@#1\endcsname
\expandafter\immediate\expandafter\openout \csname
verbatim@out@#1\endcsname #1
}{%
% Am Anfang jedes Beispiels schreiben wir eine Leerzeile, um einen neuen
% Absatz zu beginnen:
\expandafter\immediate\expandafter\write \csname verbatim@out@#1\endcsname
{}%
}%
\let\do\@makeother\dospecials
\catcode`\^^M\active \catcode`\^^I=12
\def\verbatim@processline{%
\expandafter\immediate\expandafter\write\csname verbatim@out@#1\endcsname
{\the\verbatim@line}}%
\verbatim@start
}{%
\@esphack
}
\newenvironment{Aufg}{%
\par
}{%
\par
}
\newenvironment{Exmpl}{%
\examplefile{\jobname.xmp}
}{%
\endexamplefile
}
\newcommand*{\inputexamples}[1]{%
\@ifundefined{verbatim@out@#1}{}{%
\expandafter\immediate\expandafter\closeout
\csname verbatim@out@#1\endcsname
\expandafter\let\csname verbatim@out@#1\endcsname\relax
}%
\InputIfFileExists{#1}{\typeout{Example file `#1' read.}}{%
\typeout{Example file `#1' not found.}%
}%
}
\makeatother

\usepackage{lipsum}% Für Demozwecke ganz nützlich.

\begin{document}
\begin{Aufg}
\lipsum
% Alternativ kann man die Umgebung Aufg bereits hier beenden.
\begin{Exmpl}
Text1
\end{Exmpl}
\end{Aufg}
\end{document}

Ich finde das so übrigens viel sauberer als große Mengen Text in eine Argument zu packen.

G.Hanisch
06-06-2013, 19:31
Danke und du hast natürlich Recht. Leider sind aber 200 Seiten bereits anders gesetzt. Das lässt sich für den Anfangsteil der Umgebung mit "Suchen - Ersetzen" ausbessern, der Rest muss aber händisch passieren.

Es funktioniert auch mit Lualatex, die Möglichkeit mit io.open muss ich noch nachschlagen.

Nochmals besten Dank

Günter

ctansearch
06-06-2013, 22:12
Wenn Du ein kleines, lauffähiges Minimalbeispiel einbringst, in dem die auszugeliedernden Texte lauffähig drin stehen, hätte ich eventuell eine Möglichkeit anzubieten.

klops
07-06-2013, 07:49
Nach einer halb schlaflosen Nacht ist mir eine Lösung eingefallen, die so simpel ist, dass es fast schon weh tut, dass ich darauf nicht früher gekommen bin:
\documentclass[fontsize=11pt,headings=big,open=any]{scrbook}
\usepackage[ngerman]{babel}
\newwrite\xmpfile
\immediate\openout\xmpfile \jobname.xmp
\newcommand\writexmp[1]{%
\immediate\write\xmpfile{%
\detokenize{#1}
^^J% Leerzeile anhängen
}%
}
\newcommand{\Aufg}[2]{#1%
\writexmp{#2}\\}%
\begin{document}
\Aufg{Text1}{Text2 z.B. $x_i^2$\\}%
\Aufg{Erster Text}{Text mit Tabelle z.B.\\
\begin{tabular}{c}Tabellentext\\ \end{tabular}
}
\immediate\closeout\xmpfile\input{\jobname.xmp}
\end{document}
Die ganzen \\ würde ich an Deiner Stelle aber noch rausnehmen. Bis auf innerhalb der Tabelle sind die nämlich schlicht falsch!

Ansonsten: Wen ich Dich richtig verstehe, willst Du eigentlich aus einem Quelldokument quasi zwei Dokumente generieren. Da käme (für die Zukunft) generell auch ein docstrip-basierter Ansatz in Frage.

G.Hanisch
07-06-2013, 09:46
Wirklich ganz herzlichen Dank. Ich habe bereits mein sty-file umgestellt und das Dokument durchlaufen lassen (in LuaLaTex). Nun kann ich meine Sternchen in \ umwandeln bzw. Texte, die ich - weil sie Fehler ergeben haben und ich die Sternchenidee noch nicht hatte - unter comment geschrieben habe, wieder "entcommentieren".

Da mein Problem aber doch alle haben, die Skripten mit Aufgaben und deren Lösungen herstellen, könntest du aus deiner Superidee nicht ein package machen und es anbieten?

Eine Frage noch: Warum ist \\ falsch? Ich stelle dadurch eine neue Zeile her.

Günter

rstuby
07-06-2013, 10:59
\\ stellt eine neue Zeile her, OHNE den Absatz zu beenden. Das ist nur in Ausnahmenfällen erwünscht. Sonst sollte man mit einer Leerzeile im Code oder mit \par einen neuen Absatz beginnen.

klops
07-06-2013, 13:49
Außerdem sollte \\ nie am Ende eines Absatzes stehen. Genau das passiert aber in der xmp-Datei. Ich vermute, Du hast die früher genommen, weil bei \addcontentsline eben am Ende keine Leerzeile geschrieben wurde. Aber auch dort hättest Du besser \protect\par genommen (zu \protect siehe meine früheren Erklärungen).

Ich glaube auch nicht, dass ich daraus ein Paket machen sollte. Wie gesagt, gehe ich davon aus, dass eines der vielen Pakete aus dem Bereich Aufgaben und Lösungen bereits entsprechende Umgebungen liefert.

mechanicus
07-06-2013, 15:09
Ich glaube auch nicht, dass ich daraus ein Paket machen sollte. Wie gesagt, gehe ich davon aus, dass eines der vielen Pakete aus dem Bereich Aufgaben und Lösungen bereits entsprechende Umgebungen liefert.
Das Paket exsheets kommt dem Nahe. Allerdings nutzt das Paket die richtige Syntax mit Umgebungen. Das wurde bereits durch Klops angesprochen, so dass ich es hier nur wiederholen möchte.

Marco

G.Hanisch
10-06-2013, 19:10
Wenn man mit Umgebungen arbeiten will. Ich finde aber deine Lösung besser.

Und danke für den Hinweis mit \\.

Günter