--- /dev/null
+% \begin{meta-comment}
+%
+% $Id: mdwslides.dtx,v 1.1 2002/02/24 12:47:11 mdw Exp $
+%
+% Document class for slide sets
+%
+% (c) 2002 Mark Wooding
+%
+%----- Revision history -----------------------------------------------------
+%
+% $Log: mdwslides.dtx,v $
+% Revision 1.1 2002/02/24 12:47:11 mdw
+% Initial revision.
+%
+%
+% \end{meta-comment}
+%
+% \begin{meta-comment} <general public licence>
+%%
+%% mdwslides -- a document class for slide sets
+%% Copyright (c) 2002 Mark Wooding
+%%
+%% This program is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU General Public License as published by
+%% the Free Software Foundation; either version 2 of the License, or
+%% (at your option) any later version.
+%%
+%% This program is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this program; if not, write to the Free Software
+%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%%
+% \end{meta-comment}
+%
+% \begin{meta-comment} <Package preamble>
+%<+mdwslides>\NeedsTeXFormat{LaTeX2e}
+%<+mdwslides>\ProvidesClass{mdwslides}
+%<+mdwslides> [2002/02/20 1.00 mdwslides]
+% \end{meta-comment}
+%
+% \CheckSum{479}
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%%
+%
+% \begin{meta-comment} <driver>
+%
+%<*driver>
+\input{mdwtools}
+\title{The \package{mdwslides} document class}
+\mdwdoc
+%</driver>
+%
+% \end{meta-comment}
+%
+%^^A-------------------------------------------------------------------------
+% \section{User guide}
+%
+% Not a lot to say, really. It's a document class for sets of slides and
+% their notes. I've based it on Timothy van Zandt's \package{seminar} class,
+% but there are some important tweaks and bug fixes.
+%
+% \DescribeMacro\topic
+% The most important new feature is that the sectioning commands create
+% little summary pages automatically. Each |\section| is given a summary
+% page. The subsections are listed one per line, with the topics covered in
+% that subsection. A topic is introduced by saying
+% \syntax{"\\topic{"<text>"}"}. This only has an effect in slides-only mode;
+% it's ignored when typesetting notes.
+%
+% \DescribeMacro\xcalways
+% The notes come out best if you put the sectioning commands outside of the
+% slides. However, in order for a slides-only run to actually notice them,
+% you need to mark them as `interesting'. You can write
+% \begin{quote}
+% \syntax{"\\xcalways"<anything>"\\x"}
+% \end{quote}
+% to have \synt{anything} recognized even in slides-only mode.
+%
+% \DescribeMacro\head
+% The heading at the top of a slide is typeset by saying
+% \syntax{"\\head{"<text>"}"}. Headings come out in a large sans face by
+% default. Feel free to redefine the command if you don't like that.
+%
+% \DescribeMacro\resetseq
+% \DescribeMacro\seq
+% Maybe it's a deficiency on my part, but I tend to end up with several
+% slides on the same subject, and rather than think of different headings I
+% tend to number the successive slides. Say |\resetseq| before the heading
+% of the first in a series and insert the number by saying |\seq|. Should it
+% be necessary, you can label and make cross-references to |\seq|uence
+% numbers.
+%
+%^^A-------------------------------------------------------------------------
+% \implementation
+% \section{Implementation}
+%
+% \subsection{Initial boilerplate}
+%
+% Pass options straight on. We don't have any of our own.
+%
+% \begin{macrocode}
+%<*mdwslides>
+\DeclareOption*{\PassOptionsToClass{\CurrentOption}{seminar}}
+\ProcessOptions
+\LoadClass{seminar}
+\RequirePackage{fancyhdr}
+% \end{macrocode}
+%
+% \subsection{Fixing some bugs}
+%
+% Cool as \package{seminar} undoubtedly is, it's also buggy. Here are some
+% fixes.
+%
+% \begin{macro}{\normalsize}
+%
+% Firstly, there's a very strange bug in the list formatting for notes. This
+% fixes it.
+%
+% \begin{macrocode}
+\def\@bugfix#1\let\@listi#2#3\@@%
+ {\def\normalsize{#1#3}}
+\expandafter\@bugfix\normalsize\@@
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\slidebox@restore}
+%
+% Another list typesetting weirdness: too much top glue.
+%
+% \begin{macrocode}
+\toks@\expandafter{\slidebox@restore}
+\edef\slidebox@restore{\the\toks@\advance\topsep\parskip}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\outputloop@savedslides}
+% \begin{macro}{\output@savedslide}
+%
+% I can't quite remember what this does, though I think it's trying to stop a
+% bizarre loop condition in \package{seminar}'s fake output routine.
+%
+% \begin{macrocode}
+\ifarticle
+ \def\@bugfix#1\penalty\z@#2\@@{\def\outputloop@savedslides{#1#2}}
+ \expandafter\@bugfix\outputloop@savedslides\@@
+ \toks@\expandafter{\output@savedslide}
+ \def\@strange@hack%
+ {\begingroup\output{\unvbox\@cclv}\penalty-\@M\endgroup}
+ \edef\output@savedslide{\noexpand\@strange@hack\the\toks@}
+\fi
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@makeslide}
+%
+% Make sure that footnotes end up at the \emph{bottom} of a slide, rather
+% than just after the text.
+%
+% \begin{macrocode}
+\def\@makeslide{%
+ \setbox\@slidebox\vbox{%
+ \@begindvi % added 1997/04/15 SPQR
+ \unvbox\@cclv
+ \ifvoid\slide@footins\else
+ \vskip\skip\slide@footins
+ \vfil
+ \footnoterule
+ \unvbox\slide@footins
+ \unskip
+ \fi
+ \vskip\z@}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\@makecol}
+%
+% And do the same thing for the main text.
+%
+% \begin{macrocode}
+\def\@makecol{%
+ \setbox\@outputbox \box\@cclv
+ \xdef\@freelist{\@freelist\@midlist}%
+ \global \let \@midlist \@empty
+ \@combinefloats
+ \ifvoid\footins \else
+ \setbox\@outputbox \vbox {%
+ \boxmaxdepth \@maxdepth
+ \unvbox \@outputbox
+ \vskip \skip\footins
+ \vfil
+ \footnoterule
+ \unvbox \footins
+ \unskip
+ }%
+ \fi
+ \ifvbox\@kludgeins
+ \@makespecialcolbox
+ \else
+ \setbox\@outputbox \vbox to\@colht {%
+ \@texttop
+ \dimen@ \dp\@outputbox
+ \unvbox \@outputbox
+ \vskip -\dimen@
+ \@textbottom
+ }%
+ \fi
+ \global \maxdepth \@maxdepth
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \subsection{Hacking \env{xcomment}}
+%
+% \begin{macro}{\xcalways}
+%
+% Unfortunately, this involves rewriting rather too much of the
+% \env{xcomment} code. Sigh.
+%
+% It also involves catcode fiddling. I need some code-12 versions of various
+% usually-magical characters. This is the traditional fiddling.
+%
+% \begin{macrocode}
+\begingroup
+\catcode`\!=12\catcode`\[=12\catcode`\]=12\catcode`\"=12
+\lccode`\!=`\\\lccode`\[=`\{\lccode`\]=`\}\lccode`\"=`\%
+\catcode`\~=\active\lccode`\~=`\^^M
+\lowercase{
+% \end{macrocode}
+%
+% This is the guts of the main \env{xcomment} loop.
+%
+% \begin{macrocode}
+ \gdef\xcomment@@@#1\@nil{%
+ \def\@tempa{#1}%
+ \ifx\@tempa\@empty
+ \let\next\xcomment@
+ \else
+ \def\next{\xcomment@@#1\@nil}%
+ \@testtrue
+ \xc@checkbegin#1\relax begin[]\relax\relax
+ \if@test
+ \xc@checkend#1\relax end[]\relax\relax
+ \if@test
+ \xc@checkinput#1\relax input[]\relax\relax
+ \if@test
+ \xc@checkinclude#1\relax include[]\relax\relax
+ \if@test
+ \xc@checkendinput#1\relax endinputss\relax\relax
+% \end{macrocode}
+%
+% Now, insert the new check for my macro.
+%
+% \begin{macrocode}
+ \if@test
+ \xc@checkalways#1\relax xcalwaysfoo!x\relax\relax
+% \end{macrocode}
+%
+% And finish off.
+%
+% \begin{macrocode}
+ \fi\fi\fi\fi\fi\fi
+ \next}
+% \end{macrocode}
+%
+% Check to see whether the line contains the an |\xcalways| command. If so
+% pull the contents out, rescan them, and continue grinding through stuff
+% which is meant to be ignored.
+%
+% \begin{macrocode}
+ \gdef\xc@checkalways#1xcalways#2!x#3\relax#4\relax{%
+ \def\@tempa{#1}%
+ \ifx\@tempa\@empty%
+ \@testfalse%
+ \endgroup%
+ \toks@{#2}\rescan\toks@%
+ \def\next{\the\toks@\xc@always#3\@nil}%
+ \fi%
+ }
+% \end{macrocode}
+%
+% That's the end of the weird-catcode stuff.
+%
+% \begin{macrocode}
+}
+\endgroup
+% \end{macrocode}
+%
+% This little macro restarts the search for non-comment stuff where it left
+% off. We need to gobble the magic end-marker from last time.
+%
+% \begin{macrocode}
+\def\xc@always#1\@nil{\xc@begin#1}
+% \end{macrocode}
+%
+% And the version for slides'n'notes mode is trivial.
+%
+% \begin{macrocode}
+\def\xcalways#1\x{#1}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \subsection{Slide layout}
+%
+% This slide size seems to fit reasonably nicely onto a laptop for video
+% projection. I find that white-on-black shows up better than
+% black-on-white, for some reason.
+%
+% \begin{macrocode}
+\slidewidth=260mm
+\slideheight=160mm
+% \end{macrocode}
+%
+% For notes, I like thin frames, uncentred, with slides just put wherever
+% they fit, dammit.
+%
+% \begin{macrocode}
+\slideplacement{here}
+\slideframewidth=1pt
+\centerslidesfalse
+% \end{macrocode}
+%
+% I like to fit quite a lot onto a slide. I'm also not keen on automatic
+% breaks. This shuts up the output routine and lets me get away with rather
+% tight slides.
+%
+% \begin{macrocode}
+\def\slidefuzz{20pt}
+% \end{macrocode}
+%
+% Fiddle the margins around the actual slide content.
+%
+% \begin{macrocode}
+\def\slideleftmargin{15mm} \let\sliderightmargin=\slideleftmargin
+\def\slidetopmargin{15mm} \let\slidebottommargin=\slidetopmargin
+% \end{macrocode}
+%
+% Page tweaking for notes.
+%
+% \begin{macrocode}
+\ifarticle
+ \raggedbottom
+ \def\slide@clearpage{\if@nobreak\else\par\penalty\z@\fi}
+\fi
+% \end{macrocode}
+%
+% Finally, don't make tables bigger in slides. It just looks weird.
+%
+% \begin{macrocode}
+\def\slidearraystretch{1}
+% \end{macrocode}
+%
+% \subsection{Slide headings}
+%
+% \begin{macro}{\head}
+%
+% Very easy style hook, this.
+%
+% \begin{macrocode}
+\def\head#1{{\sffamily\bfseries\large #1}\par}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\seq}
+% \begin{macro}{\resetseq}
+%
+% Now for the sequence number stuff. Make a counter, write some macros.
+% Yawn.
+%
+% \begin{macrocode}
+\newcounter{sequence}
+\def\thesequence{\arabic{sequence}}
+\def\seq{\refstepcounter{sequence}\thesequence}
+\def\resetseq{\setcounter{sequence}{0}}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Headings for notes}
+%
+% \begin{macrocode}
+\ifarticle
+% \end{macrocode}
+%
+% The basic layout is fairly simple. Put headings on the left and right
+% pages, and page numbers at the bottom, on the outside.
+%
+% \begin{macrocode}
+\fancyhf{}
+\fancyhead[LE]{\textbf{\nouppercase{\leftmark}}}
+\fancyhead[RO]{\textbf{\nouppercase{\rightmark}}}
+\fancyfoot[LE, RO]{\thepage}
+% \end{macrocode}
+%
+% No header rules, please.
+%
+% \begin{macrocode}
+\def\headrulewidth{\z@}
+% \end{macrocode}
+%
+% Plain pages have no headers, but still the page number in the footer.
+%
+% \begin{macrocode}
+\fancypagestyle{plain}{\fancyhead{}}
+% \end{macrocode}
+%
+% Set the section heading on left hand pages, and the subsection on the
+% right. This is done here to prevent the capsification which \LaTeX\
+% insists on doing by default.
+%
+% \begin{macrocode}
+\def\sectionmark#1{\markboth{\thesection.\ #1}{}}
+\def\subsectionmark#1{\markright{\thesubsection.\ #1}}
+% \end{macrocode}
+%
+% The |\emptyslide| command removes headings and so on from a slide. It does
+% nothing in slides'n'notes mode.
+%
+% \begin{macrocode}
+\let\emptyslide\relax
+% \end{macrocode}
+%
+% Similarly, topic declarations are ignored.
+%
+% \begin{macrocode}
+\let\topic\@gobble
+% \end{macrocode}
+%
+% Finally, switch to the fancy layout I've just defined.
+%
+% \begin{macrocode}
+\pagestyle{fancy}
+% \end{macrocode}
+%
+% \subsection{Headings and summary pages for slides}
+%
+% \begin{macrocode}
+\else
+% \end{macrocode}
+%
+% The section and subsection marks put up `\syntax{<section> [--
+% <subsection>]}' style stuff at the bottom of a slide.
+%
+% \begin{macrocode}
+\def\sectionmark#1{\markboth{#1}{}}
+\def\subsectionmark#1{\markright{ -- #1}}
+% \end{macrocode}
+%
+% \begin{macro}{\emptyslide}
+%
+% Empty slides. The |\emptyslide| command says that this slide should have
+% no numbers or section information. It's used for the summary pages. We
+% remember the number of the to-be-empty slide, so that continuation slides
+% don't get clobbered too. If a slide isn't meant to be empty, typeset it
+% nicely.
+%
+% \begin{macrocode}
+\newcount\@emptyslide
+\newpagestyle{slide}%
+ {\ifnum\@emptyslide=\c@slide\else\textbf{\thetitle}\hfil\fi}%
+ {\ifnum\@emptyslide=\c@slide\else\leftmark\rightmark\hfil\theslide\fi}
+\slidepagestyle{slide}
+\def\emptyslide{\global\@emptyslide\c@slide}%
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\@sect}
+% \begin{macro}{\@ssect}
+%
+% The basic section handling gets rewritten here. It now typesets nothing,
+% but updates counters correctly (so that references are correct) and issues
+% the marking and summary commands.
+%
+% \begin{macrocode}
+\def\@sect#1#2#3#4#5#6[#7]#8{%
+ \ifnum #2>\c@secnumdepth\else%
+ \refstepcounter{#1}%
+ \fi%
+ \csname #1mark\endcsname{#7}%
+ \csname #1summary\endcsname{#7}%
+}
+\def\@ssect#1#2#3#4#5{\relax}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\sm@toks}
+% \begin{macro}{\sm@count}
+%
+% Summary handling proper starts here. The |\sm@count| register remembers
+% which summary page this is. The first one is numbered~1. The token
+% register is used when building summary pages, later on.
+%
+% \begin{macrocode}
+\newtoks\sm@toks
+\newcount\sm@count
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\sm@auxwrite}
+%
+% The sectioning commands write stuff to the |.aux| file. This is how they
+% do it. The first argument is the type of entry this is; the second is the
+% text. The |\sm@entry| macro sorts out what to do on the way back.
+%
+% \begin{macrocode}
+\def\sm@auxwrite#1#2{\immediate\write\@auxout
+ {\noexpand\sm@entry{\the\sm@count}{#1}{#2}}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\sectionsummary}
+%
+% A section summary entry. If there's a summary that's been constructed for
+% this section, then do it; otherwise don't. Then write a section heading
+% entry.
+%
+% \begin{macrocode}
+\def\sectionsummary{%
+ \global\advance\sm@count\@ne%
+ \expandafter\let\expandafter\@next%
+ \csname sm@summary@\the\sm@count\endcsname%
+ \ifx\@next\relax\else\@next\sm@endsummary\fi%
+ \sm@auxwrite{section}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\subsectionsummary}
+% \begin{macro}{\topic}
+%
+% The subsection and topic commands just write an entry to the |.aux| file.
+% \begin{macrocode}
+\def\subsectionsummary{\sm@auxwrite{subsection}}
+\def\topic{\sm@auxwrite{topic}}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\sm@entry}
+%
+% This is where summary pages are actually constructed. If the requested
+% summary entry doesn't exist, make it empty. Then attach a call to the
+% appropriate summary-building command.
+%
+% \begin{macrocode}
+\def\sm@entry#1#2#3{%
+ \begingroup%
+ \let\protect\@unexpandable@protect%
+ \expandafter\ifx\csname sm@summary@#1\endcsname\relax%
+ \expandafter\let\csname sm@summary@#1\endcsname\@empty%
+ \fi%
+ \expandafter\xdef\csname sm@summary@#1\endcsname{%
+ \csname sm@summary@#1\endcsname%
+ \expandafter\protect\csname sm@do#2\endcsname{#3}%
+ }%
+ \endgroup%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\sm@dosection}
+%
+% Build the beginning of a summary page. Start a new slide; make it empty;
+% write a heading at the top; and start a list of things.
+%
+% \begin{macrocode}
+\def\sm@dosection#1{%
+ \begingroup\slide%
+ \emptyslide%
+ \noindent\vadjust{}%
+ \vskip10\p@%
+ \centerline{\sffamily\bfseries\Large #1 -- overview}
+ \vskip10\p@%
+ \begingroup\itemize
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\sm@endsummary}
+%
+% Finish off a summary. This is called from |\sectionsummary|.
+%
+% \begin{macrocode}
+\def\sm@endsummary{\enditemize\endgroup\endslide\endgroup}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\sm@dosubsection}
+% \begin{macro}{\sm@dotopic}
+%
+% A subsection entry starts a new item; a topic entry augments the current
+% item, using the |\if@tempswa| switch to decide on punctuation.
+%
+% \begin{macrocode}
+\def\sm@dosubsection#1{\item\relax\@tempswatrue#1}
+\def\sm@dotopic#1{\if@tempswa:\@tempswafalse\else;\fi\space#1}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+\fi
+% \end{macrocode}
+%
+% And that's all there is.
+%
+% \begin{macrocode}
+%</mdwslides>
+% \end{macrocode}
+%
+% \hfill Mark Wooding, \today
+%
+% \Finale
+\endinput