태그를 기반으로 LaTeX 비머 프레임을 동적으로 숨깁니다.

태그를 기반으로 LaTeX 비머 프레임을 동적으로 숨깁니다.

나는 많은 사람들에게 종소리를 울릴 구성에 있다고 생각합니다. 수년 동안 진행된 프로젝트의 맥락에서 나는 많은 슬라이드가 포함된 매우 큰 Beamer 프리젠테이션을 개발했습니다. LaTeX 소스는 여러 파일로 분할되어 있으며 프로젝트 프레젠테이션을 자주 다시 실행해야 하기 때문에 시간/대상에 따라 이러한 파일을 기본 문서에 포함하거나 포함하지 않습니다.

이제 포함하려는 프레임을 제어하여 프레젠테이션 생성을 자동화하고 싶습니다. <handout:0|beamer:0>프레임 정의 시 매개변수를 사용하여 정적으로 가능한 것 같습니다 .

\begin{frame}
Hello.
\end{frame}

% this frame won't be included
\begin{frame}<handout:0|beamer:0>
  Hidden
\end{frame}

나는 접근 방식을 좀 더 일반적으로 만들고 싶습니다. 그래서 나는 가능성에 대해 생각하고 있었다

  • 프레임 정의 시 [set of] 태그 연결
  • 이 태그가 있는 프레임만 고려되도록(다른 프레임은 숨겨지도록) 프레젠테이션을 컴파일할 때 사용할 태그 세트에 대해 나중에 (어떤 방식으로든) 결정합니다.

누구든지 그렇게 할 수 있는 방법을 알고 있나요?

답변1

정말 좋은 질문이에요!

이것은 다음에서 많은 영감을 받은 솔루션의 시작입니다.베르너의 코멘트제한이 거의 없습니다. 이는 솔루션이 Beamer 위에 있다는 사실 때문입니다. 그러한 이유로 저는 그것을 커뮤니티 위키에 표시해 놓았으며 모든 사람이 이를 개선할 수 있습니다(그리고 여지가 많습니다).

이는 다음을 목표로 하는 간단한 사용자 인터페이스를 제공합니다.

  • 차별화된 버전을 위한 태그 생성
  • 어떤 버전이 출력되는지 결정합니다.

첫 번째 작업은 키에 의해 제공됩니다

  1. create new version
  2. create multiple versions

이름은 아주 명확합니다. 어떤 프레임이 출력되는지 결정하려면 다음을 활용하세요.

  1. compile version
  2. compile frames한 버전 내에서 프레임의 하위 집합을 선택하려면
  3. compile generic frames다양한 버전에서 프레임을 선택합니다.

말했듯이 메커니즘은 Werner의 설명에 거의 설명되어 있습니다. 새 버전을 생성한다는 것은 단순히 프레임에 태그가 지정될 때마다 새 카운터(또는 그 이상)가 인스턴스화되고 업데이트된다는 것을 의미합니다. 버전 컴파일은 에 전달되는 목록 생성을 통해 배후에서 추적됩니다 \includeonlyframes. 여태까지는 그런대로 잘됐다.

이제 접근 방식의 한계와 주 포인트를 살펴보겠습니다. 실제로 Beamer 아래로 들어가지 않고 앞서 언급한 방식으로 프레임에 태그를 지정하려면 약간의 속임수, 즉 새로운 환경이 필요합니다. 이를 위해 sebframe다음 구문을 사용하여 선택적 인수를 허용하는 환경이 정의되었습니다.

<tag>-<list of beamer options>

문자는 -다른 Beamer 옵션에서 태그를 분리하는 데 사용됩니다. 그런데 이것은 fragile.

므웨. 주석이 달렸으며 이를 개념 증명으로 간주합니다. 주석에서 지적한 대로 몇 가지 사항이 개선될 수 있습니다.

\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}

우리가 선택한 대로:

\SebCompileOptions{create new version=A, compile version=A}

출력은 다음과 같습니다

여기에 이미지 설명을 입력하세요

선택하여

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

여기에 이미지 설명을 입력하세요

오버레이 인식 명령은 여전히 ​​작동하고 프레임 C2는 표시되지 않습니다. 시도해 보자

\SebCompileOptions{%
 create multiple versions={A,B}, 
 compile generic frames={A1,A3,B1,B2,C3}
}

이는 다음을 생성합니다.

여기에 이미지 설명을 입력하세요

예상한 대로 버전 C가 정의되어 있지 않으므로 C3 프레임이 표시되지 않습니다. 목록을 제공하는 순서는 PDF에 표시되는 순서에 영향을 주지 않습니다. 페이지 번호만 계산됩니다.

답변2

나는 당신이 제공하려는 각 프레젠테이션 유형에 대해 하나씩 여러 조건을 만들 것입니다. 이러한 유형을 "버전"이라고 부르겠습니다. 따라서 아마도 , 및 가 있을 VersionAVersionB입니다 VersionC.

각 버전에 대해 다음을 사용하여 조건을 만듭니다 \newif(기본적으로 false로 설정됨).

\newif\VersionA
\newif\VersionB
\newif\VersionC

frame그런 다음 특정 버전과 관련된 슬라이드를 래핑합니다 . 예를 들어 VersionA슬라이드는 다음과 같습니다.

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

VersionBOR 과 연결되어야 하는 슬라이드가 있는 경우 다음을 VersionC수행할 수 있습니다.

\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

모든 버전에서 볼 수 있는 슬라이드에는 조건부 래핑이 필요하지 않습니다. 다음은 설정의 최소 예입니다.

여기에 이미지 설명을 입력하세요

\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}

다음을 사용하여 비슷한 작업을 수행할 수 있습니다.comment패키지. 하지만 조건을 결합하는 것이 그리 쉬운 일은 아닙니다. 물론 해결 방법은 여러 버전에 대한 정보가 포함된 슬라이드를 복제하는 것입니다.

또 다른 실행 가능한 옵션은 다음을 사용하여 label각각에 대해 생성하는 것입니다 .frame

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

또는 \frame명령을 사용합니다. 그런 다음 ConceptX사용을 포함하여 관심 있는 버전에 추가하세요.

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

frame하지만 이를 위해서는 각각에 개념적(고유한) 레이블을 제공해야 합니다 .

관련 정보