Comentário após frágil \end{frame} quebrar o projetor

Comentário após frágil \end{frame} quebrar o projetor

Hoje passei mais tempo do que gostaria de admitir sendo derrotado por um comentário no código...

Eu estava tentando inserir algum texto literal em uma apresentação e estava recebendo este erro:

Runaway argument?
! File ended while scanning use of \next.

Então, reduzindo tudo a um MWE, obtive o seguinte:

\documentclass{beamer}

\begin{document}

\begin{frame}[fragile]
Hello :)
\end{frame}% NO :(

\end{document}

e o erro persistiu.

Então, quando removi o comentário depois de \end{frame}tudo funcionar.

Alguém pode explicar o que acontece aqui?


Isenção de responsabilidade: não, não preciso do comentário aí: P

Responder1

Depois de pesquisar um pouco nas beamerentranhas do , descobri que a resposta era, como egreg apontou, o processador literal.

Para [fragile]frames, beamerutiliza seu processador literal, localizado em beamerbaseverbatim.sty. O Beamer tem um processador literal bacana:

\protected\long\gdef\beamer@processframeline#1^^M{%
  \edef\beamer@test{\beamer@strip@whitespace#1\beamer@strip@stop}%
  \ifx\beamer@test\beamer@stopframe%
    \let\next=\beamer@framewritten%
  \else%
    \immediate\write\beamer@verbatimfileout{#1}%
    \let\next=\beamer@processframeline%
  \fi%
  \next%
}%

O processador é uma macro delimitada que irá ler tudo até um caractere de retorno de carro (nova linha). O conteúdo lido é armazenado \beamer@teste comparado ao \beamer@stopframequal é, na maioria das vezes, definido como:

\xdef\beamer@stopframe{\string\\end\string\{frame\string\}}

que se expande para a string exata \ e n d { f r a m e }.

O processador compara \beamer@teste \beamer@stopframese eles forem diferentes, o conteúdo \beamer@testé gravado \beamer@verbatimfileout(no arquivo .vrb) e a \nextmacro deve \letser o processador, e ele se chama recursivamente para continuar lendo. Caso contrário, se \beamer@testfor a string \end{frame}, o processador sairá normalmente.

O erro ocorre porque o processador não ignora os comentários (eles podem ser necessários em contextos literais!), então o processador compara \end{frame}com o \end{frame}% NO :(, o que obviamente falha, e continua lendo além do \end{frame}.

Duas coisas podem acontecer agora:

Primeiro, este é o último quadro, então o processador nunca encontrará uma correspondência \end{frame}e o ! File ended while scanning use of \next.erro aparecerá e a compilação será interrompida.

Em segundo lugar e mais doloroso, há outro quadro que conterá os andróides \end{frame} que o processador procurava. Mas, neste caso, \nextserá \letto \beamer@framewritten, que essencialmente lê o conteúdo do arquivo .vrb de volta ao quadro. Mas o conteúdo será algo como:

Hello :)
\end{frame}% NO :(
\begin{frame}
Hello again!

o que vai fazer as coisas enlouquecerem :)

DR

Lembrem-se, crianças, ao usar [fragile]molduras, o\end{frame} deveseja oapenascoisa na fila. Não são permitidos espaços iniciais nem comentários (os espaços finais são engolidos pelo TeX).

Como Samcarter observou em seu comentário, a versão atual do Beamer permite liderareespaços em branco e tabulações à direita. A \beamer@strip@whitespacemacro consumirá espaços e tabulações antes da comparação com \beamer@stopframe.

informação relacionada