So speichern Sie Textteile robust für die spätere Verwendung

So speichern Sie Textteile robust für die spätere Verwendung

Ich versuche, mir ein Paket ähnlich dem Übungspaket zu schreiben, damit ich Aufgabensätze für meine Studenten vorbereiten kann. Ich möchte die Ausgabe von Aufgaben und/oder Lösungen verzögern, bis eine geeignete Stelle im Dokument erreicht ist. Ich habe etwas, das einigermaßen funktioniert, aber es ist etwas klobig. Das hier funktioniert zum Beispiel ziemlich gut:

\usepackage{environ}
\NewEnviron{testb}{\global\expandafter\let\csname bar\endcsname\BODY}

Ich verwende \csname, weil die Namen dynamisch generiert werden. Das funktioniert nicht so gut, wenn der Befehl etwas anderes als ist \BODY. Wenn ich beispielsweise verwende \let\bar{\BODY}, hat Latex ein Aneurysma (es bindet \barnur an {).

Es gibt hierfür eine alternative Möglichkeit:

\NewEnviron{testc}{\global\expandafter\edef\csname foo\endcsname{\BODY}}

Das funktioniert irgendwie. Folgendes funktioniert: \begin{testc}hi\end{testc}, aber das verursacht ein Aneurysma bei LaTeX: \begin{testc}\bf hi\end{testc}. (Die Fehlermeldung lautet ). Ich habe versucht, es selbst zu debuggen, aber ich verheddere mich hoffnungslos in Paketen, die ich nicht verstehe. Wenn Sie es mit anstelle von \incompletetun, erhalten Sie die völlig andere LaTeX-Fehlermeldung:\tiny\bf! TeX capacity exceeded, sorry [input stack size=5000].

\BODYWie kann ich nicht nur , sondern eine ausgeklügelte Kombination aus und anderen Dingen für später zurücklegen \BODYund gleichzeitig dafür sorgen, dass es gegenüber dem, was zwischen Anfang und Ende liegt, robust bleibt?

Bearbeiten: ok, mehrere Lösungen unten

Antwort1

Mit \unexpandedkönnen Sie sich Sorgen über ersparen \protected@xdef.

\documentclass{article}
\usepackage{environ}

\NewEnviron{exercise}{%
  \xdef\savedexercises{%
    \unexpanded\expandafter{\savedexercises}%
    \noexpand\begin{printedexercise}%
    \unexpanded\expandafter{\BODY}%
    \noexpand\end{printedexercise}%
  }%
}
\newcommand{\printexercises}{%
  \savedexercises
  \gdef\savedexercises{}%
}
\newcommand{\savedexercises}{}

\newtheorem{printedexercise}{Exercise}

\begin{document}

Here we talk about addition and show that $1+1=2$.

\begin{exercise}
Compute $1+2$
\end{exercise}

Here we talk about integrals.

\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$

\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}

Now we can print the exercises.

\printexercises

\end{document}

Ich habe es \newtheoremnur als Beispiel verwendet.

Bildbeschreibung hier eingeben

Mit xparseder Veröffentlichung vom 05.03.2019 oder später:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentEnvironment{exercise}{+b}
 {
  \tl_gput_right:Nn \g_loisel_exercises_tl
   {
    \begin{printedexercise}
    #1
    \end{printedexercise}
   }
 }{}

\NewDocumentCommand{\printexercises}{}
 {
  \tl_use:N \g_loisel_exercises_tl
  \tl_gclear:N \g_loisel_exercises_tl
 }

\tl_new:N \g_loisel_exercises_tl

\ExplSyntaxOff

\newtheorem{printedexercise}{Exercise}

\begin{document}

Here we talk about addition and show that $1+1=2$.

\begin{exercise}
Compute $1+2$
\end{exercise}

Here we talk about integrals.

\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$

\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}

Now we can print the exercises.

\printexercises

\end{document}

Antwort2

Wenn Sie BODYsparen und dann dynamisch Dinge hinzufügen möchten, verwenden Sie am besten zwei Makros:

\documentclass{article}
\usepackage{environ}
\NewEnviron{testb}{%
  \global\expandafter\let\csname bar\endcsname\BODY
  \expandafter\xdef\csname barplus\endcsname{%
    \expandafter\noexpand\csname bar\endcsname
    \noexpand\bf Hi
  }%
}
\begin{document}

\begin{testb}
  \bfseries
  Hi
\end{testb}
\show\barplus
\end{document}

Wenn Sie die Verwendung vermeiden möchten, \BODYkönnen Sie verwendenxparse

\documentclass{article}
\usepackage{xparse}
\NewDocumentEnvironment{testb}{+b}{\expandafter\gdef\csname bar\endcsname{#1}}{}
\begin{document}

\begin{testb}
  \bfseries
  Hi
\end{testb}
\show\bar
\end{document}

Antwort3

Ein Trick zum Auslösen der Erweiterung ist die Verwendung von \romannumeral:

Wenn aufgrund von \romannumeral(La)TeX eine Ziffernfolge mit anschließendem Leerzeichen als Zahl erstellt wird, die es umwandeln muss, werden erweiterbare Token erweitert.

Kommt am Ende eine Zahl zusammen, die nicht positiv ist, so wird (La)TeX als Ergebnis der Konvertierung keinerlei Token liefern.

Man kann es also gut (missbrauchen), \romannumeralum eine Menge Erweiterungsarbeit und Argumentumkehrarbeit auszulösen, solange man sicherstellt, dass am Ende \romannumeralkeine positive Zahl herauskommt.

Hier ist eine Variante vonegregs Antwortwas mit \romannumeralund \exchangeanstelle von \xdefund erfolgt \unexpanded.

\documentclass{article}
\usepackage{environ}

\newcommand\exchange[2]{#2#1}

\NewEnviron{exercise}{%
  \expandafter\gdef\expandafter\savedexercises\expandafter{%
    \romannumeral0\expandafter\exchange\expandafter{\BODY}{%
      \exchange{ }{\expandafter}\savedexercises
      \begin{printedexercise}%
    }%
    \end{printedexercise}%
  }%
}
\newcommand{\printexercises}{%
  \savedexercises
  \gdef\savedexercises{}%
}
\newcommand{\savedexercises}{}

\newtheorem{printedexercise}{Exercise}

\begin{document}

Here we talk about addition and show that $1+1=2$.

\begin{exercise}
Compute $1+2$
\end{exercise}

Here we talk about integrals.

\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$

\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}

Now we can print the exercises.

\printexercises

\end{document}

Bildbeschreibung hier eingeben

Wenn Sie den Namen des zu definierenden Makros in \csname.. einschließen möchten, also anstelle \endcsnamevon verwenden möchten , können Sie sich die Tatsache zunutze machen, dass (La)TeX erweiterbare Tokens erweitert, indem es den Namen eines Steuersequenz-Tokens erfasst und hiermit nach dem passenden sucht :\csname savedexercises\endcsname\savedexercises\csname\endcsname

\documentclass{article}
\usepackage{environ}

\newcommand\exchange[2]{#2#1}

\NewEnviron{exercise}{%
  \expandafter\gdef\csname savedexercises\expandafter\endcsname\expandafter{%
    \romannumeral0\expandafter\exchange\expandafter{\BODY}{%
      \exchange{ }{\expandafter\expandafter\expandafter}\csname savedexercises\endcsname
      \begin{printedexercise}%
    }%
    \end{printedexercise}%
  }%
}
\newcommand{\printexercises}{%
  \csname savedexercises\endcsname
  \expandafter\gdef\csname savedexercises\endcsname{}%
}
\expandafter\newcommand\expandafter{\csname savedexercises\endcsname}{}

\newtheorem{printedexercise}{Exercise}

\begin{document}

Here we talk about addition and show that $1+1=2$.

\begin{exercise}
Compute $1+2$
\end{exercise}

Here we talk about integrals.

\begin{exercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$

\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{exercise}

Now we can print the exercises.

\printexercises

\end{document}

Bildbeschreibung hier eingeben

Beachten Sie, dass Sie mit den bisher vorgestellten Ansätzen nicht \printexercisesan beliebigen Stellen Übungen einfügen können. Sie können Übungen nur an Stellen des Dokuments einfügen, die in der Quelle den Stellen hinter den Übungsumgebungen entsprechen.

Vielleicht eine Umgebung, die ihren Inhalt unter dem Verbatim-Catcode-Regime liest, um ihn nicht erweitert in eine .aux-Datei zu schreiben, und zwar auf eine Weise, bei der er aus der .aux-Datei unter dem Verbatim-Catcode-Regime auch zum Definieren eines Makros zurückgelesen wird \scantokens, auf das es angewendet wird, und somit eine Art Neuimplementierung des \label-Mechanismus \refoder des \tableofcontents-Mechanismus für verbatimiertes Material, die es möglich machen könnte, Übungen im gesamten Dokument druckbar zu machen.

Die Implementierung eines solchen Mechanismus könnte eine schöne Herausforderung sein. Doch bevor man das überhaupt in Betracht zieht, sind genaue Informationen über den beabsichtigten Einsatzzweck und die gewünschte „Benutzeroberfläche“ erforderlich, d. h., welche zusätzlichen Dinge Sie auf welche Weise angeben möchten usw. ...

Antwort4

Eine weitere Variante ist die Verwendung von filecontentsdef v1.4, Unterstützt verbatimInhalte (falls erforderlich).

\documentclass{article}
\usepackage{filecontentsdef,pgffor}
\setlength{\parindent}{0pt}
\pagestyle{empty}
\newtheorem{exercise}{Exercise}
% savedexercise
\newcounter{exeNr}
\newenvironment{savedexercise}
{\stepcounter{exeNr}%
\begingroup
\filecontentsdefmacro{exercise-\the\value{exeNr}}}%
{\endfilecontentsdefmacro\endgroup}
\newcommand{\printexercise}[1]{\filecontentsexec{exercise-\the\numexpr#1\relax}}
\newcommand{\printsrcexercise}[1]{\filecontentsprint{exercise-\the\numexpr#1\relax}}

\begin{document}
\section{Talk about math}
Here we talk about addition and show that $1+1=2$.

\begin{savedexercise}
Compute $1+2$
\end{savedexercise}

Here we talk about integrals.

\begin{savedexercise}
Compute the following integrals:
\begin{itemize}
\item $\displaystyle\int_0^x e^{-t^2}\,dt$

\item $\displaystyle\int_1^x \frac{e^t}{t}\,dt$, for $t>0$.
\end{itemize}
\end{savedexercise}

\section{The exercises}
Now we can print the exercises.

\foreach \i in {1,...,2} {
\begin{exercise}
\printexercise{\i}
\end{exercise}
}

\section{The src exercises}
Now we can print the src of exercises.

\foreach \i in {1,...,2} {
\printsrcexercise{\i}
}

\section{Back to first exercises}
Remember the first exercise

\setcounter{exercise}{0}
\begin{exercise}
\printexercise{1}
\end{exercise}
\end{document}

Beispiel für die erhaltene Ausgabe

verwandte Informationen