隐藏“标记”框架 - beamer+listings+custom xparse 环境

隐藏“标记”框架 - beamer+listings+custom xparse 环境

有多种方法可以隐藏 Latex Beamer 文档的某些部分,但我无法将它们中的任何一种应用到我相当复杂的设置中。

下面的代码源自一个框架,用于创建各种形式的教学材料 - 主要以投影仪幻灯片的形式。这包括例如一些分别显示练习和相应解决方案的自定义块。解决方案可以通过变量隐藏,以便我可以为没有解决方案的学生创建讲义,但可以在演示时在实际幻灯片中显示它们。由于幻灯片内容不是针对单个课程,而是以模块化方式使用,因此我希望能够在设置某些变量时完全禁用演示文稿的某些部分以将其隐藏(想想学士与硕士级别)。将这些可选部分塞进单独的文件中并不真正可行(实际上,我宁愿编写并运行文件上的预处理器)。

我尝试过/看过

  • beameraudience 包
  • 评论包
  • 标记包
  • 还有许多其他方法可以简单地“如果”出结果。

我实施过程中的主要问题(可能)是至少有三个组件尝试使用非乳胶的东西(读取源代码而不立即解释):beamer、listings 和任何试图隐藏东西的东西。所以我尝试的通常结果是这样的Paragraph ended before \lst@next was complete.(不总是一样,但你明白我的意思)。

从我的 MWE 中可能可以看出,我混合了各种做类似事情的包(因为我通常从 stackexchange 获取代码或至少是一些解决方案的想法,并且大多数时候都不知道幕后真正发生了什么;)我不喜欢上面提到的任何包/方法,但是现有的解决方案块代码使用 \endcomment(隐藏tagging自定义块环境的内容(参见 MWE),因此这可能有利于仅包含另一个包。但是,如果您必须更改现有代码,我完全可以接受(当然,只要我可以将它移植到我的实际代码中;)

问题是:如果变量未按照 MWE 中的 FIXME 指定的方式设置,如何隐藏第二帧和第三帧,同时仍允许切换print_solutions

\documentclass[english,10pt,t,xcolor={usenames,svgnames}]{beamer}

\newcommand{\slidestype}{exercise}
\newcommand{\osroot}{/home/stefanct/work/lehre/os}
\newcommand{\thesession}{1}
\usepackage{etoolbox}

% The value of this variable is usually supplied externally
\newtoggle{print_solutions}
% \toggletrue{print_solutions}
\togglefalse{print_solutions}


\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{ifthen}


\usepackage[main=english,ngerman]{babel}

\usepackage{listings}

\usepackage{xcolor}
\usepackage{tagging} % provides \comment \endcomment
\usepackage{xparse} % For NewDocumentEnvironment, IfNoValueF etc.


\newcounter{prob}\setcounter{prob}{1}
\resetcounteronoverlays{prob}
\newcounter{solu}
\resetcounteronoverlays{solu}

% Save old block environment commands (with LetLtxMacro to support arguments)
\LetLtxMacro\origblock\block
\LetLtxMacro\endorigblock\endblock

% Introduce a new block whose title and body format can be customized
\newenvironment{formattedblock}[3]%
{%
  % Force expansion of the second setbeamercolor argument by using edef
  \edef\settitleformat{\noexpand\setbeamercolor{block title}{#2}}
  \settitleformat
  \edef\setbodyformat{\noexpand\setbeamercolor{block body}{#3}}
  \setbodyformat
  \begin{origblock}{#1}
}{%
  \end{origblock}%
}
% Constants for the format of various block types
% No worries, the actual colors are different ;)
% Ordinary blocks (blue-ish)
\newcommand{\normalblocktitle}{bg=blue,fg=white}
\newcommand{\normalblockbody}{bg=white!92!blue,fg=black}
% Exercise blocks (green-ish)
\newcommand{\execblocktitle}{bg=green,fg=black}
\newcommand{\execblockbody}{bg=white!90!green,fg=black}
% Solution blocks (red-ish)
\newcommand{\solublocktitle}{bg=red,fg=white}
\newcommand{\solublockbody}{bg=white!90!red,fg=black}


% execblock takes one optional parameter - the title
\NewDocumentEnvironment{execblock}{ g }%
{%
  \begin{formattedblock}{Exercise \theprob{}\IfNoValueF{#1}{: #1}}{\execblocktitle}{\execblockbody}%
}{%
  % When done with the block manage counters
  \end{formattedblock}\setcounter{solu}{\theprob}\stepcounter{prob}%
}%

\makeatletter
\iftoggle{print_solutions}{
  \NewDocumentEnvironment{solublock}{ } {%
      \ifbeamer@autobreak%
      \else%
        \pause
      \fi%
    \begin{formattedblock}{Solution \thesolu{}}{\solublocktitle}{\solublockbody}%
  }{%
    \end{formattedblock}%
  }
}{%
  % if print_solutions is not set we want to skip the environment including all its contents!
  \NewDocumentEnvironment{solublock}{ } {\expandafter\comment}{\expandafter\endcomment}
}
\makeatother

% Reformat ordinary blocks by using this formattedblock config
\RenewDocumentEnvironment{block}{ g }%
{%
  \begin{formattedblock}{#1}{\normalblocktitle}{\normalblockbody}
}{%
  \end{formattedblock}%
}


\begin{document}

\begin{frame}[fragile]{untagged}
  \begin{block}{just a block}
      some text
  \end{block}
  \begin{execblock}{an exercise block}
    some text
  \end{execblock}
  \begin{solublock}
    other text
  \end{solublock}
\end{frame}


% FIXME: some command or begin environment here that hides
% one frame (or if possible even multiple ones)
% based on the existence of a variable/tag
\begin{frame}[fragile]{tagged but excluded}
  \begin{execblock}{Exec Title}
    \begin{lstlisting}[gobble=6]
      some listing
    \end{lstlisting}
  \end{execblock}
  \begin{solublock}
    \begin{lstlisting}[gobble=6]
      some listing
    \end{lstlisting}
  \end{solublock}
\end{frame}

% FIXME: As above but this time the slide(s) should be
% enabled iff the variable/tag is set
\begin{frame}[fragile]{tagged and included}
  \begin{execblock}{Exec Title}
    \begin{lstlisting}[gobble=6]
      some listing
    \end{lstlisting}
  \end{execblock}
  \begin{solublock}
    \begin{lstlisting}[gobble=6]
      some listing
    \end{lstlisting}
  \end{solublock}
\end{frame}

\end{document}

答案1

抱歉,如果我不使用您的 (M)WE。我确实使用了以下方法根据我设置的值打印一些内容。

\documentclass[]{beamer}

\let\BEGIN\begin% just for matching case

\makeatletter%
\def\NirvanaOrDocument{1}%
\long\def\grab@toNirvana#1#2\END{%
  \expandafter\ifnum\NirvanaOrDocument<#1\relax%
    #2%
  \fi%
  \end}%
\newenvironment*{toNirvana}[1][1]{\grab@toNirvana{#1}}{}%
\makeatother%<<<

\begin{document}
\BEGIN{toNirvana}
\begin{frame}
  Foo
\end{frame}
\END{toNirvana}

\BEGIN{toNirvana}[2]
\begin{frame}
  Bar
\end{frame}
\END{toNirvana}

\BEGIN{toNirvana}[3]
\begin{frame}
  Baz
\end{frame}
\END{toNirvana}

\BEGIN{toNirvana}[4]
\begin{frame}
  Foobar
\end{frame}
\END{toNirvana}

\end{document}

您可以使用可选参数根据 的定义指定显示的可能性的阈值\NirvanaOrDocument。如果可选参数大于,则\NirvanaOrDocument显示环境的内容。

我最初创建上述环境是为了将演示文稿的部分内容移到附录中。因此,它比实际更复杂。您也可以使用以下命令:

\documentclass[]{beamer}

\def\NirvanaOrDocument{1}%
\newcommand*\ifToNirvana[1][1]{%
  \expandafter\ifnum\NirvanaOrDocument<#1\relax%
}

\begin{document}
\ifToNirvana
\begin{frame}
  Foo
\end{frame}
\fi

\ifToNirvana[2]
\begin{frame}
  Bar
\end{frame}
\fi

\ifToNirvana[3]
\begin{frame}
  Baz
\end{frame}
\fi

\ifToNirvana[4]
\begin{frame}
  Foobar
\end{frame}
\fi

\begin{frame}
  it's on
\end{frame}
\end{document}

相关内容