Utilizo Beamer para hacer diapositivas para mi clase de estadística y ahora tengo una configuración muy buena que genera resultados similares a los de PowerPoint (consulte la pregunta:Utilice Beamer para colocar 3 diapositivas por página con notas al lado (como PowerPoint)).
Para que este sistema funcione, necesito una definición de las notas asociadas con una diapositiva para cada diapositiva o las notas no estarán sincronizadas con las diapositivas. Probablemente haya una mejor manera de definir una definición de nota "predeterminada" para una diapositiva para que nunca se desincronicen, pero esto está mucho más allá de mi capacidad en látex, y el entorno es lo suficientemente complicado como para publicar un MWE para eso. ser difícil (para mí).
En cambio, quiero al menos detectar el error de que no se han definido notas para una diapositiva. La forma más sencilla que se me ocurre de hacerlo se ha reducido a un MWE que se muestra a continuación:
\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}
PREGUNTA: ¿Cómo hago para que Latex arroje un error cuando detecta que no hubo ninguna llamada para mi página {3}? Para los programadores de C, sería fantástico mostrar cómo utilizar una afirmación de estilo C de que el parámetro no es igual al valor esperado.
Gracias a todos.
Respuesta1
No afirmar. Ni siquiera un !=
. También hay \if
, \ifdim
, \ifx
, \ifcase
, \@ifundefined
, \@ifl@aded
etc. Consulte TeXbook (Knuth) y source2e.pdf (CTAN).
Tenga en cuenta que las definiciones locales no estarán disponibles fuera de un entorno. Afortunadamente, las contraoperaciones utilizan versiones globales. \global\let
y \xdef
se puede utilizar, pero \setlength
y \renewcommand
no.
\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}
Respuesta2
Sugiero una solución diferente. Actualmente, esta es una prueba de concepto. En particular, fallará si pasa cualquier opción que no sea label
la del frame
entorno. Creo que esto se puede solucionar, pero complicaría las cosas.
La idea es incluir las diapositivas en el folleto de una manera diferente. Para ello se hace uso del paquete de Beamer beamerarticle
, la label
opción de frame
entornos y la \includeslide
macro. También usa xcoffins
(porque me frustré demasiado jugando con minipage
sy cosas similares) y environ
.
Flujo de trabajo:
3 archivos, 2 de los cuales son contenedores extremadamente simples que ingresan el tercero.
El tercer archivo no contiene archivos
\documentclass
, sino diapositivas y notas. Supongamos que esto es<main file name>.tex
.Los toboganes van en
frame
ambientes, como es habitual. Estos están etiquetados usando lalabel
opción.Las notas van en
annot
ambientes. Estos requieren un argumento que proporcione la etiqueta de la diapositiva correspondiente. (Si normalmente te estuvieras refiriendo a la diapositiva, este es el argumento que darías\ref{}
). Se puede usar un argumento opcional para anular la configuración utilizada al incluir la diapositiva.El primer contenedor se compila para producir las diapositivas. Llamé a esto
<main file name>-beamer.tex
. El contenido de este archivo debe ser\pdfminorversion=7% comment this out if not using pdftex \documentclass[ignorenonframetext]{beamer} \input{<main file name>}% substitute appropriately here
Esto debería ser compilado.primero.
El segundo envoltorio se compila para producir los folletos. Llamé a esto
<main file name>-article.tex
porque usé laarticle
clase y el modo Beamerarticle
. El contenido de este archivo debe ser\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
Esto debería ser compilado.segundo.
Luego <main file name>.tex
, colocas el resto del preámbulo y el document
cuerpo. Puse la mayoría de las cosas personalizadas en el preámbulo aquí, restringiéndolas al article
modo Beamer, pero puedes mover esto al envoltorio del folleto si lo prefieres.
% \jobname.tex = <main file name>.tex
\mode<article>
{
Esto sólo se ejecutará en article
modo.
\usepackage{xcoffins,environ,geometry,calc,pgf}
xcoffins
, environ
, pgf
y calc
son obligatorios. geometry
Acabo de deshacerme de las cajas defectuosas.
Primero, un par de longitudes nuevas que necesitaremos más adelante.
\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}%
}
Y un par de ataúdes.
\NewCoffin\AnnotCoffin
\NewCoffin\FrameCoffin
Ahora definimos el annot
entorno, pero lo usamos \NewEnviron
en lugar de \newenvironment
porque queremos poner todo el contenido en un ataúd y esto nos pareció más fácil. (Estaba tratando de evitar expl3
la sintaxis` aquí).
\NewEnviron{annot}[2][]{%
\edef\tempa{\extractedref}\edef\tempb{#2}%
\ifx\tempa\tempb\relax
\else\outputempty\fi\xdef\extractedref{}%
Esto verifica si hay algún marco para el cual no hayamos incluido una diapositiva, aparte del de esta anotación. Si ha habido una etiqueta frame
a la que este conjunto de notas no corresponde, asumimos que ese marco no tiene notas y en su lugar lo generamos con un espacio en blanco a la derecha.
Ahora configuramos nuestro primer ataúd, \FrameCoffin
con una copia enmarcada de la diapositiva relevante (es decir, a la que hicimos referencia usando el annot
argumento obligatorio del entorno).
\SetVerticalCoffin\FrameCoffin{.5\linewidth-.5\annotsep}{%
\fbox{\includeslide[width=\frmwd,#1]{#2}}% depending on theme, remove frame if not required
}%
Ahora preparamos nuestro segundo ataúd, \AnnotCoffin
para las notas.
\SetVerticalCoffin\AnnotCoffin{.5\linewidth-.5\annotsep}{%
\BODY
}%
Unimos los ataúdes en la parte superior, empujando los nodos un poco hacia arriba y hacia abajo.
\JoinCoffins\FrameCoffin[t,r]\AnnotCoffin[t,l](\annotsep,-.5\baselineskip)
Componga nuestros ataúdes y deje un espacio vertical flexible para que nuestras diapositivas queden espaciadas uniformemente en la página.
\TypesetCoffin\FrameCoffin
\medskip\vfill\par
}
\usepackage{kantlipsum}
Este paquete es sólo para el ejemplo. No cargue esto en su documento real a menos que esté escribiendo los extractos relevantes de Kant y no le importe la traducción probablemente desactualizada.
Un par de comandos nuevos.
\newcommand\extractref{}
\newcommand\extractedref{}
Defina uno de ellos como macro auxiliar.
\def\extractref label=#1\null{#1}
Esto cambia la definición de modo frame
en article
. Normalmente, Beamer compone el frame
contenido en todos los modos. Sin embargo, aquí no queremos eso. Lo definimos para que tome un único argumento opcional. Todo lo demás desaparecerá. Pero, si hay un primer argumento opcional y no está vacío, asumiremos que es a label=<key for label>
y extraeremos esta referencia.
\RenewEnviron{frame}[1][]{%
\edef\tempa{#1}\edef\tempb{}%
\ifx\tempa\tempb\relax
\else
\outputempty
Si la macro que mantiene el seguimiento \extractedref
no está vacía, entonces ha habido una diapositiva sin un conjunto de notas correspondiente, por lo que asumimos que la diapositiva no tiene notas y generamos esa diapositiva con un conjunto de notas en blanco a la derecha.
\xdef\extractedref{\extractref #1\null}%
Por el momento frame
, no escribimos nada. Simplemente extraemos y almacenamos la referencia en formato \extractedref
.
\fi
}
Ahora para la macro que genera frame
s sin anotaciones. Esto es utilizado por los redefinidos frame
y los annot
entornos.
\newcommand\outputempty{%
\edef\tempb{}%
\edef\tempa{\extractedref}%
\ifx\tempa\tempb\relax
\else
Aquí no se necesitan ataúdes, pero generamos la diapositiva usando la configuración predeterminada y colocamos el mismo espacio vertical para mantener las diapositivas distribuidas uniformemente en la página.
\fbox{\includeslide[width=\frmwd]{\extractedref}}%
\medskip\vfill\par
\fi
}
}
Supongo que no quieres sangría de párrafo aquí. Podrías considerar usar el parskip
paquete, pero puede que esto no importe, dependiendo del contenido de tus notas.
\setlength\parindent{0pt}
Si lo último frame
está etiquetado pero sin notas, debemos asegurarnos de que se incluya en el folleto. Uno más \outputempty
debería hacerlo.
\AtEndDocument{\outputempty}
Esa es la configuración. Ahora el documento.
\begin{document}
Aquí hay un marco, etiquetado frame-a
.
\begin{frame}[label=frame-a]{A Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-a}
\end{frame}
Aquí están las notas para frame-a
.
\begin{annot}{frame-a}
Not much to say about image A.
\end{annot}
De manera similar, para frame-b
y 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}
Esto crea una página con geometry
el diseño predeterminado.
Aquí está frame-another
. Este carece de notas, por lo que no hay annot
seguidores.
\begin{frame}[label=frame-another]{Another Frame}%
\includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image}
\end{frame}
En article
modo, se generará el siguiente cuadro frame-another
, porque asumiremos que no existen notas para ese frame
. Se me acabaron las imágenes de MWE y me aburrí, así que aquí tengo una excelente alternativa.
\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}
El siguiente frame
tiene una nota muy larga, por lo que terminará en su propia página. Un poco menos de rugido aquí, pero quizás haya seguridad en los números.
\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}
Y un último, sin mencionar frame
, para asegurarnos de que el final \outputempty
funcione.
\begin{frame}[label=frame-gadael]
\includegraphics[width=\textwidth]{cath-gadael-chartref}
\end{frame}
\end{document}
Diapositivas:
Folleto/notas:
Código completo (necesita sustitución de nombres de archivos donde se indique):
\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}