我使用投影機為我的統計課程製作幻燈片,並且現在有一個非常好的設置,可以產生類似於 powerpoint 的輸出(請參閱問題:使用 Beamer 每頁放置 3 張投影片,並在旁邊加入註解(如 powerpoint))。
為了使該系統正常運作,我需要為每張投影片與投影片關聯的註解進行定義,否則註解將與投影片不同步。可能有更好的方法來定義幻燈片的「預設」註釋定義,以便它們永遠不會不同步,但這遠遠超出了我在乳膠中的能力,而且環境足夠複雜,為此發布 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}
問題:當 Latex 偵測到沒有呼叫 mypage {3} 時,如何讓 Latex 拋出錯誤?對於 C 程式設計師來說,展示如何使用 C 風格的斷言來判斷參數不等於預期值會很棒!
謝謝大家。
答案1
沒有斷言。甚至沒有!=
。還有\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
我建議一個不同的解決方案。目前這是一個概念驗證。特別是,如果您將任何選項傳遞label
給環境以外的選項,它將失敗frame
。我認為這個問題可以解決,但這會使事情變得複雜。
我們的想法是以不同的方式將幻燈片納入講義中。這利用了 Beamer 的beamerarticle
套件、環境label
選項frame
和\includeslide
巨集。它也使用(因為我對s 之類的xcoffins
事情感到太沮喪)和.minipage
environ
工作流程:
3 個文件,其中 2 個是非常簡單的包裝器,輸入第三個文件。
第三個文件不包含
\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
這應該編譯第一的。
第二個包裝器被編譯以產生講義。我這樣稱呼是
<main file name>-article.tex
因為我使用了article
類別和Beamer的article
模式。該文件的內容應該是\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
這應該編譯第二。
然後<main file name>.tex
,您將其餘的序言和正文放入其中document
。我將大部分自訂內容放在此處的序言中,將其限制為 Beamerarticle
模式,但如果您願意,可以將其移至講義包裝中。
% \jobname.tex = <main file name>.tex
\mode<article>
{
這只會在article
模式下執行。
\usepackage{xcoffins,environ,geometry,calc,pgf}
xcoffins
、environ
、pgf
和calc
為必填項。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
環境,但我們使用\NewEnviron
而不是\newenvironment
因為我們想將整個內容放入棺材中,這似乎是最簡單的。 (我試圖expl3
在這裡避免語法。)
\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
用來存放筆記。
\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}
frame
這改變了in模式的定義article
。通常,Beamer 會frame
在所有模式下排版內容。然而,在這裡我們不希望這樣。我們將其定義為採用單一可選參數。其他一切都會消失。但是,如果有一個可選的第一個參數並且它不為空,我們將假設它是 alabel=<key for label>
並且我們將提取此引用。
\RenewEnviron{frame}[1][]{%
\edef\tempa{#1}\edef\tempb{}%
\ifx\tempa\tempb\relax
\else
\outputempty
如果巨集 keep trac\extractedref
不為空,則表示存在一張沒有相應註釋集的投影片,因此我們假設該投影片沒有註釋,並在右側輸出帶有一組空白註釋的投影片。
\xdef\extractedref{\extractref #1\null}%
目前frame
,我們沒有排版任何內容。我們只需提取引用並將其存儲在\extractedref
.
\fi
}
現在是輸出沒有註解的 s 的巨集frame
。這是由重新定義frame
和annot
環境使用的。
\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
有標籤但沒有註釋,我們需要確保它進入講義。還\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}