Supongo que estoy en una configuración que a muchos les sonará: en el contexto de un proyecto que lleva muchos años en marcha, desarrollé una presentación Beamer muy grande con muchas diapositivas. Las fuentes de LaTeX están divididas en muchos archivos y como a menudo tengo que rehacer la presentación del proyecto, incluyo (o no) estos archivos en el documento principal dependiendo del tiempo/audiencia.
Ahora me gustaría automatizar de alguna manera la generación de la presentación controlando el marco que deseo incluir. Parece ser posible estáticamente con los <handout:0|beamer:0>
parámetros al definir el marco:
\begin{frame}
Hello.
\end{frame}
% this frame won't be included
\begin{frame}<handout:0|beamer:0>
Hidden
\end{frame}
Me gustaría hacer que el enfoque sea más genérico. Por eso estaba pensando en la posibilidad de
- asociar una etiqueta [conjunto de] a la definición del marco
- decidir más tarde (de alguna manera) sobre el conjunto de etiquetas a usar al compilar la presentación, de modo que solo se considere el marco que tiene esta etiqueta (y los demás, por lo tanto, estén ocultos).
¿Alguien sabe una manera de hacer eso?
Respuesta1
¡Esta es una muy buena pregunta!
Este es el comienzo de una solución altamente inspirada enEl comentario de Werner.y con pocas limitaciones. Se deben al hecho de que la solución está encima de Beamer. Por esta razón lo marco como wiki comunitario y todos pueden mejorarlo (y hay mucho espacio).
Proporciona una interfaz de usuario sencilla con el objetivo de
- crear etiquetas para las versiones diferenciadoras;
- decidir qué versión(es) salen.
La primera tarea la proporcionan las claves.
create new version
create multiple versions
y los nombres son bastante claros. Para decidir qué fotogramas salen, aproveche:
compile version
compile frames
para seleccionar un subconjunto de marcos dentro de una versióncompile generic frames
para seleccionar marcos de diferentes versiones.
Como se dijo, el mecanismo se describe prácticamente en el comentario de Werner: crear una nueva versión simplemente significa que se crea una instancia de un nuevo contador (o más) y se actualiza cada vez que se etiqueta un marco de esa manera. La compilación de versiones se traduce entre bastidores con la creación de una lista que se pasa a \includeonlyframes
. Hasta ahora, todo bien.
Veamos ahora límites y puntos semanales de la aproximación. Etiquetar cuadros de la manera antes mencionada sin pasar realmente por debajo de Beamer requiere un poco de truco, es decir, un nuevo entorno. Para ello, sebframe
se ha definido un entorno que acepta un argumento opcional con la siguiente sintaxis
<tag>-<list of beamer options>
El carácter -
se utiliza para dividir la etiqueta de otras opciones de Beamer; Por cierto, esto falla fragile
.
El mwe. Se comenta y se toma como prueba de concepto: se pueden mejorar algunas cosas como señalan los comentarios.
\documentclass{beamer}
\usepackage{lmodern} % https://tex.stackexchange.com/a/58088/13304
\usepackage{mwe} % for dummy image
\newcommand{\enlarge}{\centering\scalebox{13}}% Just for this example
% = = = = = = = = = = = = = = = = = = = = = = = =
% core of the solution
\usepackage{pgffor,pgfkeys,xstring}
\newcommand{\deflistframes}[1]{
\gdef\listframes{}% global list
\foreach \x[count=\xi] in {#1}{\global\let\maxitems\xi}% count the max number of items
\foreach \x[count=\xi] in {#1}{
\ifnum\xi=\maxitems
\xdef\listframes{\listframes \vers\x}
\else
\xdef\listframes{\listframes \vers\x,}
\fi
}
}
\newcommand{\defcustomlistframes}[1]{
\gdef\listframes{}% global list
\foreach \x[count=\xi] in {#1}{\global\let\maxitems\xi}% count the max number of items
\foreach \x[count=\xi] in {#1}{
\ifnum\xi=\maxitems
\xdef\listframes{\listframes \x}
\else
\xdef\listframes{\listframes \x,}
\fi
}
}
\makeatletter
% https://tex.stackexchange.com/a/74890/13304
\newcommand{\defversion}[1]{\@namedef{vers#1}{}}
\makeatother
% test for multiple versions compilation
\newif\ifmultipleversion
\multipleversionfalse
\pgfkeys{/seb-beamer/.cd,
create new version/.code={\gdef\vers{#1}\newcounter{#1}},
create multiple versions/.code={%
\gdef\listofversions{}
\foreach \v in {#1}{%
\defversion{\v}
\newcounter{\v}
\xdef\listofversions{\listofversions \v,}
}%
\multipleversiontrue
},
compile version/.code={% version-based: need to store in .aux a
% "total frame" counter per version (incremented in custom enviroment)
% and use it as final value (hard-coded here for simplicity)
\deflistframes{1,...,1000}
% list of frames in output
\expandafter\includeonlyframes\expandafter{\listframes}%
},
compile frames/.code={% this should be version-based -> second argument (TBA)
\deflistframes{#1}
% for the list
\expandafter\includeonlyframes\expandafter{\listframes}%
},
compile generic frames/.code={% generic for multi version compilations
\defcustomlistframes{#1}
% list of frames in output
\expandafter\includeonlyframes\expandafter{\listframes}%
},
}
\makeatletter
% see: https://tex.stackexchange.com/a/132411/13304
\newenvironment{sebframe}[1][]{
% cut the string to separate version from other options
\StrCut{#1}{-}\compvers\opt
\edef\seboptions{\opt}
\def\mylabel{}
\ifmultipleversion
\@ifundefined{c@\compvers}{}{% test if the counter is undefined
\stepcounter{\compvers}
% increment here the counter total frames per version
\edef\mylabel{label=\compvers\the\value{\compvers}}
}
\else
\IfStrEq{\vers}{\compvers}{% true
\stepcounter{\compvers}
% increment here the counter total frames per version
\edef\mylabel{label=\compvers\the\value{\compvers}}
}{% false
\edef\mylabel{}
}
\fi
\begingroup\edef\x{\endgroup\noexpand\begin{frame}[\mylabel,\seboptions]}\x}{\end{frame}}
\makeatother
\newcommand{\SebCompileOptions}[1]{%
\pgfkeys{/seb-beamer/.cd,#1}
}
% = = = = = = = = = = = = = = = = = = = = = = = =
% user interface
%\SebCompileOptions{create new version=A, compile version=A}
%\SebCompileOptions{%
% create multiple versions={A,B},
% compile generic frames={A1,A3,B1,B2,C3}
%}
\SebCompileOptions{create new version=C, compile frames={1,3}}
\begin{document}
\begin{sebframe}[A-t,allowframebreaks]
\frametitle{Version A}
\enlarge{A1}
\end{sebframe}
\begin{sebframe}[B]
\frametitle{Version B}
\enlarge{B1}
\end{sebframe}
\begin{sebframe}[C]
\frametitle{Version C}
\enlarge{C1}
\end{sebframe}
\begin{sebframe}[A]
\frametitle{Version A}
\enlarge{A2}
\end{sebframe}
\begin{sebframe}[B]
\frametitle{Version B}
\enlarge{B2}
\end{sebframe}
\begin{sebframe}[C]
\frametitle{Version C}
\enlarge{C2}
\end{sebframe}
\begin{frame}
\frametitle{Version B or C}
\enlarge{BC}
\end{frame}
\begin{sebframe}[A-t,b,containsverbatim]% just to point out that passing multiple beamer options works (unless fragile)
\frametitle{Version A}
\enlarge{A3}
\end{sebframe}
\begin{sebframe}[C]
\frametitle{Version C}
\enlarge{C3}
\vskip1ex
\includegraphics<2>[scale=0.5]{example-image}
\end{sebframe}
\begin{sebframe}[A]
\frametitle{Version A}
\enlarge{A4}
\end{sebframe}
\begin{frame}[fragile,label=A5]% add manually a label: displayed only in A version though
\frametitle{Version A \& B \& C}
\enlarge{ABC}
\end{frame}
\end{document}
Como seleccionamos:
\SebCompileOptions{create new version=A, compile version=A}
la salida es:
Seleccionando
\SebCompileOptions{create new version=C, compile frames={1,3}}
Tenga en cuenta que los comandos con reconocimiento overley aún funcionan y el cuadro C2 no se muestra. Intentemos
\SebCompileOptions{%
create multiple versions={A,B},
compile generic frames={A1,A3,B1,B2,C3}
}
que produce:
Como era de esperar, dado que la versión C no está definida, el marco C3 no se muestra. El orden en el que se proporciona la lista no afecta el orden de aparición en el PDF: para eso solo cuentan los números de página.
Respuesta2
Yo crearía un montón de condicionales, uno para cada tipo de presentación que quieras hacer. Llamemos a estos tipos "versiones". Entonces, tal vez exista VersionA
, VersionB
y VersionC
.
Para cada versión, cree un uso condicional \newif
(están configurados en falso de forma predeterminada):
\newif\VersionA
\newif\VersionB
\newif\VersionC
Luego, ajuste las diapositivas frame
asociadas con una versión específica. Por ejemplo, una VersionA
diapositiva se parecería
\ifVersionA
\begin{frame}
...
\end{frame}
\fi
Si tiene una diapositiva que debería estar asociada con (digamos) VersionB
O VersionC
, entonces puede hacerlo
\makeatletter
\let\ifCombined\ifVersionB
\ifVersionC
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\let\ifCombined\iftrue}{}
\makeatother
\ifCombined% Version B or C
\begin{frame}
..
\end{frame}
\fi
Las diapositivas que son visibles en todas las versiones no necesitan ningún ajuste condicional. Aquí hay un ejemplo mínimo de la configuración:
\documentclass{beamer}% http://ctan.org/pkg/beamer
\let\Tiny=\tiny% http://tex.stackexchange.com/q/58087/5764
\newcommand{\enlarge}{\centering\scalebox{13}}% Just for this example
\newif\ifVersionA
\newif\ifVersionB
\newif\ifVersionC
%\VersionAtrue% Show Version A
\VersionBtrue% Show Version B
%\VersionCtrue% Show Version C
\begin{document}
\ifVersionA
\begin{frame}
\frametitle{Version A}
\enlarge{A1}
\end{frame}
\fi
\ifVersionB
\begin{frame}
\frametitle{Version B}
\enlarge{B1}
\end{frame}
\fi
\ifVersionC
\begin{frame}
\frametitle{Version C}
\enlarge{C1}
\end{frame}
\fi
\ifVersionA
\begin{frame}
\frametitle{Version A}
\enlarge{A2}
\end{frame}
\fi
\ifVersionB
\begin{frame}
\frametitle{Version B}
\enlarge{B2}
\end{frame}
\fi
\makeatletter
\let\ifCombined\ifVersionB
\ifVersionC
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\let\ifCombined\iftrue}{}
\makeatother
\ifCombined% Version B or C
\begin{frame}
\frametitle{Version B or C}
\enlarge{BC}
\end{frame}
\fi
\ifVersionA
\begin{frame}
\frametitle{Version A}
\enlarge{A3}
\end{frame}
\fi
\ifVersionC
\begin{frame}
\frametitle{Version C}
\enlarge{C3}
\end{frame}
\fi
\ifVersionA
\begin{frame}
\frametitle{Version A}
\enlarge{A4}
\end{frame}
\fi
\begin{frame}
\frametitle{Version A \& B \& C}
\enlarge{ABC}
\end{frame}
\end{document}
Puedes hacer algo similar usando elcomment
paquete. Sin embargo, combinar condiciones no es tan fácil. Una solución, por supuesto, sería duplicar diapositivas que contengan información para múltiples versiones.
Otra opción viable sería crear un label
para cada frame
uso
\begin{frame}[label=ConceptX]
...
\end{frame}
o usando el \frame
comando. Y luego agregue ConceptX
a las versiones que le interesa incluir usando
\includeonlyframes{...,ConceptX,...}% Version A
Sin embargo , esto requiere que proporciones a cada uno frame
una etiqueta conceptual (única).