Testando chamadas consecutivas para um ambiente

Testando chamadas consecutivas para um ambiente

Eu uso o beamer para fazer slides para minha aula de estatística e agora tenho uma configuração muito boa que gera resultados semelhantes ao PowerPoint (veja a pergunta:Use o Beamer para colocar 3 slides por página com notas ao lado (como powerpoint)).

Para que este sistema funcione, preciso de uma definição para as notas associadas a um slide para cada slide ou as notas ficarão fora de sincronia com os slides. Provavelmente existe uma maneira melhor de definir uma definição de nota "padrão" para um slide, para que eles nunca fiquem fora de sincronia, mas isso está muito além da minha capacidade em látex, e o ambiente é suficientemente complicado para postar um MWE para isso seria ser difícil (para mim).

Em vez disso, quero pelo menos detectar o erro de que nenhuma nota foi definida para um slide. A maneira mais fácil que consigo pensar de fazer isso foi reduzida a um MWE mostrado abaixo:

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

PERGUNTA: Como faço para que o latex gere um erro ao detectar que não houve chamada para mypage {3}? Para programadores c, mostrar como usar uma afirmação no estilo c de que o parâmetro não é igual ao valor esperado seria ótimo!

Obrigado a todos.

Responder1

Nenhuma afirmação. Nem mesmo um !=. Há também \if, \ifdim, \ifx, \ifcase, \@ifundefined, \@ifl@aded, etc. Veja o TeXbook (Knuth) e source2e.pdf (CTAN).

Observe que as definições locais não estarão disponíveis fora de um ambiente. Felizmente, as operações de contador usam versões globais. \global\lete \xdefpode ser usado, mas \setlengthe \renewcommandnão pode.

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

Responder2

Eu sugiro uma solução diferente. Esta é atualmente uma prova de conceito. Em particular, falhará se você passar qualquer opção que não seja labelpara o frameambiente. Isto pode ser corrigido, penso eu, mas complicaria as coisas.

A ideia é incluir os slides na apostila de uma forma diferente. Isso faz uso do pacote do Beamer beamerarticle, da labelopção de frameambientes e da \includeslidemacro. Ele também usa xcoffins(porque fiquei muito frustrado brincando com minipages e coisas do gênero) e environ.

Fluxo de trabalho:

  • 3 arquivos, 2 dos quais são wrappers extremamente simples que geram o terceiro.

  • O terceiro arquivo não contém slides \documentclass, mas sim slides e notas. Suponha que isso seja <main file name>.tex.

  • Os slides vão nos frameambientes, como sempre. Eles são rotulados usando a labelopção.

  • As notas vão em annotambientes. Isso requer um argumento que forneça o rótulo do slide correspondente. (Se você estivesse se referindo ao slide normalmente, este seria o argumento que você daria \ref{}.) Um argumento opcional pode ser usado para substituir as configurações usadas ao incluir o slide.

  • O primeiro wrapper é compilado para produzir os slides. Eu liguei para isso <main file name>-beamer.tex. O conteúdo deste arquivo deve ser

    \pdfminorversion=7% comment this out if not using pdftex
    \documentclass[ignorenonframetext]{beamer}
    \input{<main file name>}% substitute appropriately here
    

    Isso deve ser compiladoprimeiro.

  • O segundo wrapper é compilado para produzir os folhetos. Chamei isso <main file name>-article.texporque usei a articleclasse e o modo Beamer article. O conteúdo deste arquivo deve 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
    

    Isso deve ser compiladosegundo.

Então em <main file name>.tex, você coloca o resto do seu preâmbulo e o documentcorpo. Coloquei a maior parte do material personalizado no preâmbulo aqui, restringindo-o ao articlemodo Beamer, mas você pode mover isso para o invólucro do folheto, se preferir.

% \jobname.tex = <main file name>.tex
\mode<article>
{

Isso só será executado no articlemodo.

  \usepackage{xcoffins,environ,geometry,calc,pgf}

xcoffins, environ, pgfe calcsão obrigatórios. geometryacabei de me livrar das caixas ruins.

Primeiro, alguns novos comprimentos que precisaremos mais tarde.

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

E alguns caixões.

  \NewCoffin\AnnotCoffin
  \NewCoffin\FrameCoffin

Agora definimos o annotambiente, mas usamos \NewEnvironem vez de \newenvironmentporque queremos colocar todo o conteúdo em um caixão e isso pareceu mais fácil. (Eu estava tentando evitar expl3a sintaxe aqui.)

  \NewEnviron{annot}[2][]{%
    \edef\tempa{\extractedref}\edef\tempb{#2}%
    \ifx\tempa\tempb\relax
    \else\outputempty\fi\xdef\extractedref{}%

Isso verifica se há algum quadro para o qual não colocamos um slide, além daquele para esta anotação. Se houver um rótulo frameao qual este conjunto de notas não corresponde, assumimos que o quadro não tem notas e o exibimos com um espaço em branco à direita.

Agora montamos nosso primeiro caixão, \FrameCoffin, com uma cópia emoldurada do slide relevante (ou seja, aquele que referenciamos usando o annotargumento obrigatório do ambiente).

    \SetVerticalCoffin\FrameCoffin{.5\linewidth-.5\annotsep}{%
      \fbox{\includeslide[width=\frmwd,#1]{#2}}% depending on theme, remove frame if not required
    }%

Agora montamos nosso segundo caixão, \AnnotCoffinpara as notas.

    \SetVerticalCoffin\AnnotCoffin{.5\linewidth-.5\annotsep}{%
      \BODY
    }%

Unimos os caixões no topo, empurrando um pouco os nós para frente e para baixo.

    \JoinCoffins\FrameCoffin[t,r]\AnnotCoffin[t,l](\annotsep,-.5\baselineskip)

Componha nossos caixões e deixe algum espaço vertical flexível para que nossos slides fiquem uniformemente espaçados na página.

    \TypesetCoffin\FrameCoffin
    \medskip\vfill\par
  }
  \usepackage{kantlipsum}

Este pacote é apenas para exemplo. Não carregue isso em seu documento real, a menos que você esteja compondo os trechos relevantes de Kant e não se importe com a tradução provavelmente desatualizada.

Alguns novos comandos.

  \newcommand\extractref{}
  \newcommand\extractedref{}

Defina um deles como uma macro auxiliar.

  \def\extractref label=#1\null{#1}

Isso altera a definição de modo framein article. Normalmente, o Beamer compõe o frameconteúdo em todos os modos. Porém, aqui não queremos isso. Nós o definimos para receber um único argumento opcional. Todo o resto desaparecerá. Mas, se houver um primeiro argumento opcional e ele não estiver vazio, assumiremos que é a label=<key for label>e extrairemos esta referência.

  \RenewEnviron{frame}[1][]{%
    \edef\tempa{#1}\edef\tempb{}%
    \ifx\tempa\tempb\relax
    \else
      \outputempty

Se a macro que mantém o rastreamento \extractedrefnão estiver vazia, então houve um slide sem um conjunto correspondente de notas, então assumimos que o slide não tem notas e produzimos esse slide com um conjunto de notas em branco à direita.

      \xdef\extractedref{\extractref #1\null}%

Para o atual frame, não escrevemos nada. Apenas extraímos e armazenamos a referência em formato \extractedref.

    \fi
  }

Agora, para a macro que gera frames sem anotações. Isso é usado pelos redefinidos framee pelos annotambientes.

  \newcommand\outputempty{%
    \edef\tempb{}%
    \edef\tempa{\extractedref}%
    \ifx\tempa\tempb\relax
    \else

Não há necessidade de caixões aqui, mas produzimos o slide usando a configuração padrão e colocamos o mesmo espaço vertical, para manter os slides distribuídos uniformemente na página.

      \fbox{\includeslide[width=\frmwd]{\extractedref}}%
      \medskip\vfill\par
    \fi
  }
}

Eu acho que você não quer recuo de parágrafo aqui. Você pode considerar usar o parskippacote, mas isso pode não importar, dependendo do conteúdo de suas anotações.

  \setlength\parindent{0pt}

Se o último frameestiver rotulado, mas sem anotações, precisamos ter certeza de que ele será incluído no folheto. Mais um \outputemptydeveria fazer isso.

  \AtEndDocument{\outputempty}

Essa é a configuração. Agora vamos ao documento.

\begin{document}

aqui está um quadro, rotulado como frame-a.

\begin{frame}[label=frame-a]{A Frame}%
  \includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image-a}
\end{frame}

Aqui estão as notas para frame-a.

\begin{annot}{frame-a}
  Not much to say about image A.
\end{annot}

Da mesma forma, para frame-be 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}

Isso cria uma página com geometryo layout padrão de.

Aqui está frame-another. Este carece de notas, então não há annotseguimento.

\begin{frame}[label=frame-another]{Another Frame}%
  \includegraphics[height=.75\textheight,width=\textwidth,keepaspectratio]{example-image}
\end{frame}

No articlemodo, o próximo quadro será frame-anothergerado, porque assumiremos que não existem notas para ele frame. Eu acabei e fiquei entediado com as imagens do MWE, então aqui está uma alternativa estrondosa.

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

A próxima frametem uma nota muito longa, então terminará em uma página própria. Um pouco menos de barulho aqui, mas segurança nos números, talvez.

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

E um último, sem nota frame, para garantir que o final \outputemptyfuncione.

\begin{frame}[label=frame-gadael]
  \includegraphics[width=\textwidth]{cath-gadael-chartref}
\end{frame}

\end{document}

Diapositivos:

diapositivos

Apostila/notas:

apostila com notas

Código completo (precisa de substituição de nomes de arquivos quando indicado):

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

informação relacionada