Ich verwende Beamer, um Folien für meinen Statistikkurs zu erstellen und habe jetzt ein sehr schönes Setup, das eine Ausgabe ähnlich der von Powerpoint erzeugt (siehe Frage:Verwenden Sie Beamer, um 3 Folien pro Seite mit Notizen daneben zu platzieren (wie bei Powerpoint)).
Damit dieses System funktioniert, benötige ich für jede Folie eine Definition der Notizen, die mit einer Folie verknüpft sind, da die Notizen sonst nicht mehr mit den Folien synchronisiert sind. Es gibt wahrscheinlich eine bessere Möglichkeit, eine „Standard“-Notizendefinition für eine Folie zu definieren, damit sie nie nicht mehr synchronisiert sind, aber das übersteigt meine Fähigkeiten in Latex bei weitem, und die Umgebung ist so kompliziert, dass es (für mich) schwierig wäre, ein MWE dafür zu veröffentlichen.
Stattdessen möchte ich zumindest den Fehler abfangen, dass für eine Folie keine Notizen definiert wurden. Der einfachste Weg, der mir dazu einfällt, lässt sich auf ein MWE reduzieren, das unten gezeigt wird:
\documentclass[10pt]{article}
\newcounter{mypagecount}
\setcounter{mypagecount}{1}
\newcommand\incpagecount{
\stepcounter{mypagecount}
}
\newcommand\getpagecount{
\themypagecount
}
\newenvironment{mypage}[1]{%
Parameter: #1 Expected: \getpagecount Body :}{ \incpagecount \\ }
\begin{document}
\begin{mypage}{1} foo \end{mypage}
\begin{mypage}{2} foo \end{mypage}
\begin{mypage}{4} foo \end{mypage}
\begin{mypage}{5} foo \end{mypage}
\end{document}
FRAGE: Wie bringe ich Latex dazu, einen Fehler auszugeben, wenn es feststellt, dass es keinen Aufruf für mypage {3} gab? Für C-Programmierer wäre es toll, zu zeigen, wie man eine C-artige Behauptung verwendet, dass der Parameter nicht dem erwarteten Wert entspricht!
Danke an alle.
Antwort1
Keine Behauptung. Nicht einmal ein !=
. Es gibt auch \if
, \ifdim
, \ifx
, , \ifcase
, \@ifundefined
, \@ifl@aded
, usw. Siehe das TeXbook (Knuth) und source2e.pdf (CTAN).
Beachten Sie, dass lokale Definitionen außerhalb einer Umgebung nicht verfügbar sind. Glücklicherweise verwenden die Zähleroperationen globale Versionen. \global\let
und \xdef
können verwendet werden, und jedoch \setlength
nicht \renewcommand
.
\documentclass[10pt]{article}
\newcounter{mypagecount}
\setcounter{mypagecount}{1}
\newcommand\incpagecount{%
\stepcounter{mypagecount}%
}
\newcommand\getpagecount{% redundant
\themypagecount
}
\newenvironment{mypage}[1]{%
\ifnum\value{mypagecount}=#1\relax
\else
\errmessage{Parameter: #1 Expected: \getpagecount}%
\setcounter{mypagecount}{#1}%
\fi
\noindent Body :}%
{ \incpagecount \\ }
\begin{document}
\begin{mypage}{1} foo \end{mypage}
\begin{mypage}{2} foo \end{mypage}
\begin{mypage}{4} foo \end{mypage}
\begin{mypage}{5} foo \end{mypage}
\end{document}
Antwort2
Ich schlage eine andere Lösung vor. Dies ist derzeit ein Proof-of-Concept. Insbesondere schlägt es fehl, wenn Sie andere Optionen als label
die frame
Umgebung übergeben. Dies kann meiner Meinung nach behoben werden, würde die Sache aber verkomplizieren.
Die Idee ist, die Folien auf andere Weise in das Handout einzubinden. Dabei werden das beamerarticle
Paket von Beamer, die label
Option für frame
Umgebungen und das \includeslide
Makro verwendet. Außerdem werden (weil ich zu frustriert war, mit s und dergleichen xcoffins
herumzuspielen ) und verwendet .minipage
environ
Arbeitsablauf:
3 Dateien, von denen 2 extrem einfache Wrapper sind, die die dritte eingeben.
Die dritte Datei enthält kein
\documentclass
, sondern sowohl Folien als auch Notizen. Angenommen, dies ist<main file name>.tex
.Die Folien kommen
frame
wie gewohnt in Umgebungen. Diese werden mit derlabel
Option gekennzeichnet.Die Notizen werden in
annot
Umgebungen eingefügt. Diese erfordern ein Argument, das die Bezeichnung für die entsprechende Folie angibt. (Wenn Sie sich normal auf die Folie beziehen würden, würden Sie dieses Argument angeben\ref{}
.) Ein optionales Argument kann verwendet werden, um die beim Einfügen der Folie verwendeten Einstellungen zu überschreiben.Der erste Wrapper wird kompiliert, um die Folien zu erstellen. Ich habe dies genannt
<main file name>-beamer.tex
. Der Inhalt dieser Datei sollte sein\pdfminorversion=7% comment this out if not using pdftex \documentclass[ignorenonframetext]{beamer} \input{<main file name>}% substitute appropriately here
Dies sollte zusammengestellt werdenErste.
Der zweite Wrapper wird kompiliert, um die Handouts zu erstellen. Ich habe ihn aufgerufen,
<main file name>-article.tex
weil ich diearticle
Klasse und den Beamer-article
Modus verwendet habe. Der Inhalt dieser Datei sollte sein\pdfminorversion=7% comment this out if not using pdftex \documentclass{article}% adjust if you prefer a different class \usepackage{beamerarticle,graphicx} \setjobnamebeamerversion{<main file name>-beamer}% substitute appropriately here \input{<main file name>}% substitute appropriately here
Dies sollte zusammengestellt werdenzweite.
Dann <main file name>.tex
fügen Sie den Rest Ihrer Präambel und den document
Text ein. Ich habe die meisten benutzerdefinierten Dinge hier in die Präambel eingefügt und sie auf den Beamer- article
Modus beschränkt, aber Sie könnten dies auch in den Handout-Wrapper verschieben, wenn Sie das bevorzugen.
% \jobname.tex = <main file name>.tex
\mode<article>
{
Dies wird nur im article
Modus ausgeführt.
\usepackage{xcoffins,environ,geometry,calc,pgf}
xcoffins
, environ
, pgf
und calc
sind erforderlich. geometry
Habe gerade die defekten Kartons entsorgt.
Zunächst ein paar neue Längen, die wir später brauchen.
\newlength\annotsep
\setlength\annotsep{.5em}% set the horizontal separation of frames and annotations
\newlength\frmwd
\AtBeginDocument{%
\setlength\frmwd{.5\linewidth-.5\annotsep-2\fboxsep-2\fboxrule}%
}
Und ein paar Särge.
\NewCoffin\AnnotCoffin
\NewCoffin\FrameCoffin
Jetzt definieren wir die annot
Umgebung, verwenden aber „ \NewEnviron
eher“ als „ \newenvironment
, weil wir den gesamten Inhalt in einen Sarg packen wollen und dies am einfachsten erschien. (Ich habe expl3
hier versucht, „syntax“ zu vermeiden.)
\NewEnviron{annot}[2][]{%
\edef\tempa{\extractedref}\edef\tempb{#2}%
\ifx\tempa\tempb\relax
\else\outputempty\fi\xdef\extractedref{}%
Dadurch wird überprüft, ob es Frames gibt, für die wir außer dem für diese Anmerkung keine Folie eingefügt haben. Wenn es eine Beschriftung gibt, frame
der dieser Satz von Notizen nicht entspricht, nehmen wir an, dass der Frame keine Notizen hat, und geben ihn stattdessen mit einem Leerzeichen auf der rechten Seite aus.
Nun stellen wir unseren ersten Sarg auf, \FrameCoffin
mit einer gerahmten Kopie der entsprechenden Folie (also der Folie, auf die wir mit dem annot
obligatorischen Argument der Umgebung verwiesen haben).
\SetVerticalCoffin\FrameCoffin{.5\linewidth-.5\annotsep}{%
\fbox{\includeslide[width=\frmwd,#1]{#2}}% depending on theme, remove frame if not required
}%
Nun stellen wir unseren zweiten Sarg auf, \AnnotCoffin
für die Notizen.
\SetVerticalCoffin\AnnotCoffin{.5\linewidth-.5\annotsep}{%
\BODY
}%
Wir verbinden die Särge oben, indem wir die Knoten etwas quer und nach unten schieben.
\JoinCoffins\FrameCoffin[t,r]\AnnotCoffin[t,l](\annotsep,-.5\baselineskip)
Setzen Sie unsere Särge und lassen Sie etwas flexiblen vertikalen Raum, sodass unsere Folien gleichmäßig auf der Seite verteilt sind.
\TypesetCoffin\FrameCoffin
\medskip\vfill\par
}
\usepackage{kantlipsum}
Dieses Paket dient nur als Beispiel. Laden Sie es nicht in Ihr echtes Dokument, es sei denn, Sie setzen die relevanten Passagen von Kant und haben nichts gegen die wahrscheinlich veraltete Übersetzung.
Ein paar neue Befehle.
\newcommand\extractref{}
\newcommand\extractedref{}
Definieren Sie eines davon als Hilfsmakro.
\def\extractref label=#1\null{#1}
Dies ändert die Definition des frame
Modus article
. Normalerweise setzt Beamer den frame
Inhalt in allen Modi. Dies möchten wir hier jedoch nicht. Wir definieren es so, dass es ein einzelnes optionales Argument annimmt. Alles andere verschwindet. Wenn jedoch ein optionales erstes Argument vorhanden ist und es nicht leer ist, nehmen wir an, dass es ein ist, label=<key for label>
und extrahieren diese Referenz.
\RenewEnviron{frame}[1][]{%
\edef\tempa{#1}\edef\tempb{}%
\ifx\tempa\tempb\relax
\else
\outputempty
Wenn das Makro, das den Trace speichert, \extractedref
nicht leer ist, gab es eine Folie ohne einen entsprechenden Satz Notizen. In diesem Fall nehmen wir an, dass diese Folie keine Notizen enthält, und geben diese Folie mit einem leeren Satz Notizen auf der rechten Seite aus.
\xdef\extractedref{\extractref #1\null}%
Für den aktuellen frame
setzen wir nichts. Wir extrahieren und speichern lediglich die Referenz in \extractedref
.
\fi
}
Nun zum Makro, das s ohne Annotationen ausgibt . Dies wird von den neu definierten und den Umgebungen frame
verwendet .frame
annot
\newcommand\outputempty{%
\edef\tempb{}%
\edef\tempa{\extractedref}%
\ifx\tempa\tempb\relax
\else
Särge sind hier nicht erforderlich, aber wir geben die Folie mit der Standardkonfiguration aus und fügen den gleichen vertikalen Abstand ein, um die Folien gleichmäßig auf der Seite zu verteilen.
\fbox{\includeslide[width=\frmwd]{\extractedref}}%
\medskip\vfill\par
\fi
}
}
Ich vermute, Sie möchten hier keine Absatzeinrückung. Sie könnten die Verwendung des parskip
Pakets in Betracht ziehen, aber je nach Inhalt Ihrer Notizen ist das möglicherweise nicht wichtig.
\setlength\parindent{0pt}
Wenn das letzte frame
beschriftet, aber unbeschriftet ist, müssen wir sicherstellen, dass es in das Handout kommt. Ein weiteres \outputempty
sollte genügen.
\AtEndDocument{\outputempty}
Das ist die Konfiguration. Jetzt zum Dokument.
\begin{document}
hier ist ein Rahmen mit der Beschriftung frame-a
.
\begin{frame}[label=frame-a]{A Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-a}
\end{frame}
Hier sind die Hinweise für frame-a
.
\begin{annot}{frame-a}
Not much to say about image A.
\end{annot}
Gleiches gilt für frame-b
und frame-c
.
\begin{frame}[label=frame-b]{B Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-b}
\end{frame}
\begin{annot}{frame-b}
Not much to say about image b.
\end{annot}
\begin{frame}[label=frame-c]{C Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-c}
\end{frame}
\begin{annot}{frame-c}
Not much to say about image C.
\end{annot}
Dadurch wird eine Seite mit geometry
dem Standardlayout erstellt.
Hier ist frame-another
. Hier fehlen die Notizen, deshalb gibt es keine annot
Fortsetzung.
\begin{frame}[label=frame-another]{Another Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image}
\end{frame}
Im article
Modus wird der nächste Frame frame-another
ausgegeben, da wir davon ausgehen frame
, dass keine Notizen dafür vorhanden sind. Ich hatte keine Bilder von MWE mehr und war gelangweilt, also hier eine tolle Alternative.
\begin{frame}[label=frame-tiger]{Tiger Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{tiger}
\end{frame}
\begin{annot}{frame-tiger}
This frame shows a large, wild cat.
Well, what it actually shows is a small picture of a wild cat, but you are meant to infer that it represents a larger reality.
\end{annot}
Der nächste frame
hat eine sehr lange Notiz und landet daher auf einer eigenen Seite. Hier ist das Gebrüll etwas weniger laut, aber vielleicht ist man in der Gruppe sicherer.
\begin{frame}[label=frame-cats]{Cats Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{cathod}
\end{frame}
\begin{annot}{frame-cats}
\kant[1-2]
\end{annot}
\begin{frame}[label=frame-which]{Which Frame?}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{cauldron}
\end{frame}
\begin{annot}{frame-which}
This frame includes a pun, a cauldron and a question.
More accurately, it includes a pun, a depiction of a cauldron and a question mark.
\end{annot}
Und ein letztes, nichtssagendes frame
, um sicherzustellen, dass das Finale \outputempty
funktioniert.
\begin{frame}[label=frame-gadael]
\includegraphics[width=\textwidth]{cath-gadael-chartref}
\end{frame}
\end{document}
Folien:
Handout/Mitschriften:
Vollständiger Code (Dateinamen müssen bei Bedarf ersetzt werden):
\begin{filecontents}{\jobname-beamer.tex}
\documentclass[ignorenonframetext]{beamer}
\input{<main file name>}% substitute \jobname or whatever here
\end{filecontents}
\begin{filecontents}{\jobname-article.tex}
\documentclass{article}
\usepackage{beamerarticle,graphicx}
\setjobnamebeamerversion{<main file name>-beamer}% substitute \jobname or whatever here
\input{<main file name>}% substitute \jobname or whatever here
\end{filecontents}
% \jobname.tex = <main file name>.tex
\mode<article>
{
\usepackage{xcoffins,environ,geometry,calc,pgf}
\newlength\annotsep
\setlength\annotsep{.5em}% set the horizontal separation of frames and annotations
\newlength\frmwd
\AtBeginDocument{%
\setlength\frmwd{.5\linewidth-.5\annotsep-2\fboxsep-2\fboxrule}%
}
\NewCoffin\AnnotCoffin
\NewCoffin\FrameCoffin
\NewEnviron{annot}[2][]{%
\edef\tempa{\extractedref}\edef\tempb{#2}%
\ifx\tempa\tempb\relax
\else\outputempty\fi\xdef\extractedref{}%
\SetVerticalCoffin\FrameCoffin{.5\linewidth-.5\annotsep}{%
\fbox{\includeslide[width=\frmwd,#1]{#2}}% depending on theme, remove frame if not required
}%
\SetVerticalCoffin\AnnotCoffin{.5\linewidth-.5\annotsep}{%
\BODY
}%
\JoinCoffins\FrameCoffin[t,r]\AnnotCoffin[t,l](\annotsep,-.5\baselineskip)
\TypesetCoffin\FrameCoffin
\medskip\vfill\par
}
\usepackage{kantlipsum}
\newcommand\extractref{}
\newcommand\extractedref{}
\def\extractref label=#1\null{#1}
\RenewEnviron{frame}[1][]{%
\edef\tempa{#1}\edef\tempb{}%
\ifx\tempa\tempb\relax
\else
\outputempty
\xdef\extractedref{\extractref #1\null}%
\fi
}
\newcommand\outputempty{%
\edef\tempb{}%
\edef\tempa{\extractedref}%
\ifx\tempa\tempb\relax
\else
\fbox{\includeslide[width=\frmwd]{\extractedref}}%
\medskip\vfill\par
\fi
}
\setlength\parindent{0pt}
\AtEndDocument{\outputempty}
}
\begin{document}
\begin{frame}[label=frame-a]{A Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-a}
\end{frame}
\begin{annot}{frame-a}
Not much to say about image A.
\end{annot}
\begin{frame}[label=frame-b]{B Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-b}
\end{frame}
\begin{annot}{frame-b}
Not much to say about image b.
\end{annot}
\begin{frame}[label=frame-c]{C Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-c}
\end{frame}
\begin{annot}{frame-c}
Not much to say about image C.
\end{annot}
\begin{frame}[label=frame-another]{Another Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image}
\end{frame}
\begin{frame}[label=frame-tiger]{Tiger Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{tiger}
\end{frame}
\begin{annot}{frame-tiger}
This frame shows a large, wild cat.
Well, what it actually shows is a small picture of a wild cat, but you are meant to infer that it represents a larger reality.
\end{annot}
\begin{frame}[label=frame-cats]{Cats Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{cathod}
\end{frame}
\begin{annot}{frame-cats}
\kant[1-2]
\end{annot}
\begin{frame}[label=frame-which]{Which Frame?}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{cauldron}
\end{frame}
\begin{annot}{frame-which}
This frame includes a pun, a cauldron and a question.
More accurately, it includes a pun, a depiction of a cauldron and a question mark.
\end{annot}
\begin{frame}[label=frame-gadael]
\includegraphics[width=\textwidth]{cath-gadael-chartref}
\end{frame}
\end{document}