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