環境への連続呼び出しのテスト

環境への連続呼び出しのテスト

私は統計学の授業でスライドを作成するために Beamer を使用していますが、PowerPoint に似た出力を生成する非常に優れた設定になっています (質問を参照:Beamer を使用して、1 ページあたり 3 つのスライドを配置し、横にメモを付ける (PowerPoint のように))。

このシステムを機能させるには、スライドごとにスライドに関連付けられたメモの定義が必要です。そうしないと、メモがスライドと同期しなくなります。スライドの「デフォルト」メモ定義を定義して、メモが同期しなくなることのないようにするより良い方法があるかもしれませんが、これは LaTeX での私の能力をはるかに超えており、環境が複雑すぎるため、そのための MWE を投稿するのは (私にとっては) 困難です。

代わりに、スライドにメモが定義されていないというエラーを少なくともキャッチしたいと思います。私が考えられる最も簡単な方法は、以下に示す MWE に簡略化されています。

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

質問: mypage {3} の呼び出しがなかったことを検出したときに、LaTeX がエラーをスローするようにするにはどうすればよいですか? C プログラマーの場合、パラメーターが期待値と等しくないことを C スタイルのアサートを使用して確認する方法を示すと便利です。

皆さんありがとう。

答え1

assert はありません。 もありません。 、、、、、など!=も存在します。TeXbook (Knuth) および source2e.pdf (CTAN) を参照してください。\if\ifdim\ifx\ifcase\@ifundefined\@ifl@aded

ローカル定義は環境外では利用できないことに注意してください。幸い、カウンター操作ではグローバル バージョンが使用されます。 \global\letと は\xdef使用できますが、\setlength\renewcommand使用できません。

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

答え2

別の解決策を提案します。これは現在概念実証段階です。特に、環境以外のオプションを渡すと失敗しますlabelframeこれは修正できると思いますが、事態は複雑になります。

アイデアは、スライドを別の方法で配布資料に含めることです。これには、Beamer のbeamerarticleパッケージ、環境labelのオプション、およびマクロを使用します。また、( s などをいじくり回すのにイライラしたため) およびも使用します。frame\includeslidexcoffinsminipageenviron

ワークフロー:

  • 3 つのファイルがあり、そのうち 2 つは 3 番目のファイルを入力する非常に単純なラッパーです。

  • 3 番目のファイルには は含まれません\documentclassが、スライドとノートの両方が含まれます。これが であると仮定します<main file name>.tex

  • スライドはframe通常どおり環境内にあります。これらはlabelオプションを使用してラベル付けされます。

  • メモはannot環境内にあります。これらには、対応するスライドのラベルを指定する引数が必要です。(スライドを通常どおり参照している場合は、この引数を指定します\ref{}。) オプションの引数を使用して、スライドを含めるときに使用する設定を上書きできます。

  • 最初のラッパーはスライドを生成するためにコンパイルされます。私はこれを と呼びました<main file name>-beamer.tex。このファイルの内容は次のようになります。

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

    これをコンパイルする必要がある初め

  • 2番目のラッパーは配布資料を作成するためにコンパイルされます。クラスとBeamerのモード<main file name>-article.texを使用したため、これを呼び出しました。このファイルの内容は次のようになります。articlearticle

    \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
    

    これをコンパイルする必要がある2番

次に、 に<main file name>.tex、プリアンブルの残りと本文を配置しますdocument。ここでは、カスタム内容のほとんどをプリアンブルに配置して、Beamerarticleモードに制限していますが、必要に応じてこれを配布用ラッパーに移動することもできます。

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

これはモードでのみ実行されますarticle

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

xcoffins、、environおよびpgfcalc必須です。geometry問題のあるボックスを削除しました。

まず、後で必要になる新しい長さをいくつか用意します。

  \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

ここで環境を定義しますが、コンテンツ全体を棺桶に入れたいので、ではなくannotを使用します。これが最も簡単だと思われます。(ここでは syntax` を避けようとしていました。)\NewEnviron\newenvironmentexpl3

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

これは、この注釈のフレーム以外に、スライドを配置していないフレームがあるかどうかを確認します。frameこのノートのセットに対応しないラベルがある場合は、そのフレームにはノートがないものと見なし、代わりに右側に空白スペースを付けて出力します。

\FrameCoffinここで、関連するスライド (つまり、annot環境の必須引数を使用して参照したスライド)のフレーム付きコピーを使用して、最初の棺桶 をセットアップします。

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

\AnnotCoffin次に、メモ用の2つ目の棺を設置します。

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

そのうちの 1 つをヘルパー マクロとして定義します。

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

frameこれにより、モードでの定義が変更されますarticle。通常、Beamer はframeすべてのモードでコンテンツをタイプセットします。ただし、ここではそれは必要ありません。1 つのオプション引数を取るように定義します。他のすべては消えます。ただし、オプションの最初の引数があり、それが空でない場合は、それがであると想定しlabel=<key for label>、この参照を抽出します。

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

マクロがトラックを保持している場合、\extractedref対応するノートのセットがないスライドが存在するため、そのスライドにはノートがないものと想定し、右側に空のノートのセットがあるスライドを出力します。

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

現在の ではframe、何もタイプセットしません。 参照を抽出して に格納するだけです\extractedref

    \fi
  }

次に、注釈なしで s を出力するマクロについて説明します。これは、再定義された環境と環境frameで使用されます。frameannot

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

ここでは棺桶は必要ありませんが、スライドがページ上で均等に広がるように、デフォルト設定を使用してスライドを出力し、同じ垂直スペースを入れます。

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

ここでは段落のインデントは不要だと思います。parskipパッケージの使用を検討することもできますが、メモの内容によっては、これは問題にならないかもしれません。

  \setlength\parindent{0pt}

最後の項目frameにラベルが付いているが、メモがない場合は、配布資料に必ず含める必要があります。あと 1 つ追加すれ\outputemptyば完了です。

  \AtEndDocument{\outputempty}

これが設定です。次はドキュメントです。

\begin{document}

ここに というラベルの付いたフレームがありますframe-a

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

のメモは次のとおりですframe-a

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

同様に、frame-bおよび についても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}

geometryこれにより、 のデフォルト レイアウトのページが作成されます。

こちらは ですframe-another。メモがないので、annot続きはありません。

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

モードではarticle、次のフレームframe-anotherは を出力します。これは、その に対するメモが存在しないと想定しているためですframe。MWE の画像がなくなり、飽きてしまったので、ここに素晴らしい代替案があります。

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

次のframeノートは非常に長いので、独自のページになります。ここでは少し騒々しさが減りましたが、数の多さは安全と言えるかもしれません。

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

そして最後に、注目すべき点はありませんが、最終結果がうまくいくかどうかをframe確認します。\outputempty

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

\end{document}

スライド:

スライド

配布資料 / メモ:

メモ付き配布資料

完全なコード (示されている場合はファイル名を置き換える必要があります):

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

関連情報