Ocultar dinámicamente el marco del proyector LaTeX según las etiquetas

Ocultar dinámicamente el marco del proyector LaTeX según las etiquetas

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.

  1. create new version
  2. create multiple versions

y los nombres son bastante claros. Para decidir qué fotogramas salen, aproveche:

  1. compile version
  2. compile framespara seleccionar un subconjunto de marcos dentro de una versión
  3. compile generic framespara 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, sebframese 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:

ingrese la descripción de la imagen aquí

Seleccionando

\SebCompileOptions{create new version=C, compile frames={1,3}}

ingrese la descripción de la imagen aquí

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:

ingrese la descripción de la imagen aquí

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, VersionBy 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 frameasociadas con una versión específica. Por ejemplo, una VersionAdiapositiva se parecería

\ifVersionA
\begin{frame}
  ...
\end{frame}
\fi

Si tiene una diapositiva que debería estar asociada con (digamos) VersionBO 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:

ingrese la descripción de la imagen aquí

\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 elcommentpaquete. 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 labelpara cada frameuso

\begin{frame}[label=ConceptX]
  ...
\end{frame}

o usando el \framecomando. Y luego agregue ConceptXa las versiones que le interesa incluir usando

\includeonlyframes{...,ConceptX,...}% Version A

Sin embargo , esto requiere que proporciones a cada uno frameuna etiqueta conceptual (única).

información relacionada