% \iffalse meta-comment
%
% esk.dtx - Encapsulated MetaPost for LaTeX(2e)
%
% Copyright (C) 2010 by Tom Kazimiers (tom@voodoo-arts.net)
%
% Esk 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, or (at your option)
% any later version.
%
% Esk 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.
%
% This project is greatly inspired and based on EMP. EMP is a LaTeX
% package to provide a convenient way to work with metapost files and
% code from inside LaTeX documents.
%
% \fi
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% \CheckSum{397}
%% \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         \~}
%%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \MakeShortVerb{\|}
%
% \title{%
%   \ESK: \\
%   Encapsulated \SK{} for \LaTeX\thanks{%
%      This is \texttt{\filename}, version \fileversion,
%      revision \filerevision, date \filedate.}}
%
% \author{%
%   Tom Kazimiers\thanks{e-mail:
%     \texttt{tom@voodoo-arts.net}}}
%
% \maketitle
% \begin{abstract}
%   The \ESK{} package allows to encapsulate \SK{} files in \LaTeX{}
%   sources.  This is very useful for keeping illustrations in sync
%   with the text.  It also frees the user from inventing descriptive
%   names for \LaTeX{} files that fit into the confines of file
%   system conventions.
% \end{abstract}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \vfill
% \section*{Copying}
%
% \ESK{} 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, or (at your option)
% any later version.
%
% \ESK{} is distributed in the hope that it will be useful, but
% \emph{without any warranty}; without even the implied warranty of
% \emph{merchantability} or \emph{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.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \newpage
% \unitlength=1mm
% \def\topfraction{0.9}
% \def\bottomfraction{0.9}
% \def\textfraction{0.1}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Introduction}
%
% When adding illustrations to documents, one faces two bookkeeping
% problems:
% \begin{itemize}
%   \item How to encourage oneself to keep the illustrations in sync
%     with the text, when the document is updated?
%   \item How to make sure that the illustrations appear on the right
%     spot? 
% \end{itemize}
% For both problems, the best solution is to encapsulate the figures
% in the \LaTeX{} source:
% \begin{itemize}
%   \item It is much easier to remember to update an illustration if
%     one doesn't have to switch files in the editor.
%   \item One does not have to invent illustrative file names, if
%     the computer keeps track of them.
% \end{itemize}
% Therefore \ESK{} was written to allow to encapsulate
% \SK{}~\cite{Sketch} into \LaTeX~\cite{LaTeX,Knuth}. It is based on
% \texttt{emp}~\cite{emp} since it follows a similar approach for \MP{}
% \cite{MP}.
% Nevertheless, it is arguable that complex \SK{} figures may be easier
% handled in a separate file. That is because it does not directly
% improve readability for ones source code to have the \SK{} code mixed
% with \LaTeX. But that's purely a matter of taste and complexity. To
% have \SK{} code in separate files be included in your build process
% you could do the following:
% \begin{enumerate}
%   \item have your \SK{} code in a file, e.g. \emph{nice\_scene.sk}
%   \item include the file \emph{nice\_scene.sk.tex} in your document
%      source
%   \item configure your build in a way to automatically call \SK{} on all
%      \emph{\textasteriskcentered.sk} files, e.g in a Makefile:\newline
%        { |for i in `ls *.sk`; do sketch -o "$$i.tex" "$$i"; done| }  
% \end{enumerate}
% At least for less complex graphics it is more convenient to use \ESK{}
% and thus stay consistent more easily.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Usage}
%
% This chapter describes the different macros and environments provided
% by the \ESK{} package. The |esk| environment is the one that actually
% generates printable source code. Depending on what options have been
% specified with |\eskglobals| and |\eskaddtoglobals| this is TikZ or
% PSTricks code. If an |esk| environment is encountered, it gets
% processed the following way:
% \begin{enumerate}
%   \item \label{proc:gen_name}Create a file name for the current figure
%         out of the base name and a running figure number:
%         $\langle$\textit{name}$\rangle$.$\langle$\textit{number}$\rangle$.sk
%         (E. g. pyramid.1.sk)
%   \item \begin{enumerate}
%     \item \label{proc:tex_file_found} If a file exists that is named
%           like written in \ref{proc:gen_name} but with an additional
%           \textit{.tex} at the end (e.g. pyramid.1.sk.tex) it is
%           treated as a \SK{} processed result file. Thus, it is
%           included as a replacement for the environments content. 
%     \item If such an item as in \ref{proc:tex_file_found} is not found
%           a \SK{} file with the contents of the environment is saved
%           to a file with the name generated in \ref{proc:gen_name}.
%     \end{enumerate}
% \end{enumerate}
% In contrast to \MP{} \SK{} can't produce different output files out of
% one source file. This means every \SK{} figure has to be put into its
% own \SK{} file. As a consequence one has to process all generated \SK
% files with \SK and one can not have one generated file for the whole
% document. A possible way of managing the build (within a Makefile) of
% a document then could be:
% \begin{enumerate}
%   \item Call |latex| on the document source
%   \item Process all \SK{} files and stick to naming convention:\newline
%        { |for i in `ls *.sk`; do sketch -o "$$i.tex" "$$i"; done| }
%   \item Call either |latex| and |dvips| or |pdflatex| on the document
%         source to actually see TikZ or PSTricks figures.
% \end{enumerate}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Commands and Environments}
% \label{sec:commands}
%
% \DescribeEnv{esk}
% The |esk| environment contains the description of a single
% figure that will be placed at the location of the environment.
% The macro has two optional arguments. The first is the name of
% the figure and defaults to |\jobname|. It is used as the base
% name for file names. The second one consists of a comma separated
% list of names previously defined with |\eskdef|. Note that the
% names have to be put in parentheses (not brackets or braces).
% Those definitions will be prepended to the \SK-commands.
% \begin{quote}
% \begin{flushleft}
%   |\begin{esk}[|\meta{name}|](|\meta{def 1}|,|\meta{def 2}|,...)|\\
%     \qquad\meta{\SK-commands}\\
%   |\end{esk}|
% \end{flushleft}
% \end{quote}
%
% \DescribeEnv{eskdef}
% The |eskdef| environment acts as a container for \SK-commands.
% In contrast to |esk| nothing is written to a file or drawn, but
% kept in a token list register to recall it later on. Thus,
% reoccurring patterns can be factored out and used as argument
% in an |esk| environment. This is useful, because these
% environments use the |verbatim| package and can therefore
% \emph{not} be used directly as an argument to other macros.
% \begin{quote}
% \begin{flushleft}
%   |\begin{eskdef}{|\meta{name}|}|\\
%     \qquad\meta{\SK-commands}\\
%   |\end{eskdef}|
% \end{flushleft}
% \end{quote}
%
% \DescribeMacro{\eskprelude}
% Define a \SK{} prelude to be written to the top of every \SK{}
% file. The default is an empty prelude. Keep in mind that verbatim
% arguments are not allowed.
%
% \DescribeMacro{\eskaddtoprelude}
% Add to the \SK{} prelude.
% E. g.~|\eskaddtoprelude{def O (0,0,0)}| makes sure the variable O
% is available in all |esk| environments (and thus in every generated
% \SK{} file). Of cause, this could also be achieved with |Eskimo|.
%
% \DescribeMacro{\eskglobals}
% Define global \SK{} properties that get passed to the |global {...}|
% method of \SK. This defaults to |language tikz|.
%
% \DescribeMacro{\eskaddtoglobals}
% Add something to the global parameters of \SK.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Examples}
% \label{sec:examples}
%
% For a simple example, let's draw a pyramid in a coordinate
% system. Since our scene should be a composition of coordinate
% axes and the geometry, we prepare definitions for the single
% parts. In that way the parts will be reusable. First the
% coordinate system:
%    \begin{macrocode}
%<*sample>
\begin{eskdef}{axes}
  def three_axes {
    % draw the axes
    def ax (dx,0,0)
    def ay (0,dy,0)
    def az (0,0,dz)
    line[arrows=<->,line width=.4pt](ax)(O)(ay)
    line[arrows=->,line width=.4pt](O)(az)
    % annotate axes
    special |\path #1 node[left] {$z$}
                   #2 node[below] {$x$}
                   #3 node[above] {$y$};|(az)(ax)(ay)
  }
\end{eskdef}
%    \end{macrocode}
%\begin{eskdef}{axes}
  def three_axes {
    % draw the axes
    def ax (dx,0,0)
    def ay (0,dy,0)
    def az (0,0,dz)
    line[arrows=<->,line width=.4pt](ax)(O)(ay)
    line[arrows=->,line width=.4pt](O)(az)
    % annotate axes
    special |\path #1 node[left] {$z$}
                   #2 node[below] {$x$}
                   #3 node[above] {$y$};|(az)(ax)(ay)
  }
%\end{eskdef}
% Now the pyramid:
%    \begin{macrocode}
\begin{eskdef}{pyramid}
  def pyramid {
    def p0 (0,2)
    def p1 (1.5,0)
    def N 4
    def seg_rot rotate(360 / N, [J])
    % draw the pyramid by rotating a line about the J axis
    sweep[fill=red!20, fill opacity=0.5] { N<>, [[seg_rot]] }
       line[cull=false,fill=blue!20,fill opacity=0.5](p0)(p1)
  }
\end{eskdef}
%    \end{macrocode}
%\begin{eskdef}{pyramid}
  def pyramid {
    def p0 (0,2)
    def p1 (1.5,0)
    def N 4
    def seg_rot rotate(360 / N, [J])
    % draw the pyramid by rotating a line about the J axis
    sweep[fill=red!20, fill opacity=0.5] { N<>, [[seg_rot]] }
       line[cull=false,fill=blue!20,fill opacity=0.5](p0)(p1)
  }
%\end{eskdef}
% In the definitions some variable have been used that have
% not been declared so far (|O|, |dx|, |dy|, |dz|, |J|). They have
% been introduced to make the definitions more versatile. In
% order to draw the scene their declaration has to be prepended
% to our output:
%    \begin{macrocode}
\eskaddtoprelude{def O (0,0,0)}
\eskaddtoprelude{def dx 2.3}
\eskaddtoprelude{def dy 2.5}
\eskaddtoprelude{def dz dx}
\eskaddtoprelude{def J [0,1,0]}
%    \end{macrocode}
%\eskaddtoprelude{def O (0,0,0)}
%\eskaddtoprelude{def dx 2.3}
%\eskaddtoprelude{def dy 2.5}
%\eskaddtoprelude{def dz dx}
%\eskaddtoprelude{def J [0,1,0]}
%
% Now the previously created definitions can be used to do the
% actual drawing. First, the coordinate system on its own:
%\begin{center}
%\begin{esk}(axes)
  def scene {
    {three_axes}
  }
  put { view((10,4,2)) } {scene}
%\end{esk}
%\end{center}
%    \begin{macrocode}
\begin{esk}(axes)
  def scene {
    {three_axes}
  }
  put { view((10,4,2)) } {scene}
\end{esk}
%    \end{macrocode}
% Now the pyramid (note, the transparency effect will only be
% visible in a pdf):
%\begin{center}
%\begin{esk}(pyramid)
  def scene {
    {pyramid}
  }
  put { view((10,4,2)) } {scene}
%\end{esk}
%\end{center}
%    \begin{macrocode}
\begin{esk}(pyramid)
  def scene {
    {pyramid}
  }
  put { view((10,4,2)) } {scene}
\end{esk}
%    \end{macrocode}
% Finally both:
%\begin{center}
%\begin{esk}(axes,pyramid)
  def scene {
    {three_axes}
    {pyramid}
  }
  put { view((10,4,2)) } {scene}
%\end{esk}
%\end{center}
%    \begin{macrocode}
\begin{esk}(axes,pyramid)
  def scene {
    {pyramid}
    {three_axes}
  }
  put { view((10,4,2)) } {scene}
\end{esk}
%</sample>
%    \end{macrocode}
% With permission of Kjell Magne Fauske, the source code for this
% example scene has been taken from \cite{Fauske}.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{thebibliography}{99}
%   \bibitem{Sketch} Eugene K. Ressler, Sketch, 2010/04/24,
%     http://www.frontiernet.net/~eugene.ressler/
%   \bibitem{LaTeX} Leslie Lamport, \textit{\LaTeX{} --- A
%     Documentation Preparation System},
%     Addison-Wesley, Reading MA, 1985.
%   \bibitem{Knuth} Donald E. Knuth, \textit{The \TeX book},
%     Addison-Wesley, 1996
%   \bibitem{emp} Thorsten Ohl, \texttt{emp},Encapsulated MetaPost,
%     1997, available from CTAN
%   \bibitem{MP} John D.~Hobby, \textit{A User's Manual for
%     \MP}, Computer Science Report \#162, AT\&T Bell
%     Laboratories, April 1992.
%   \bibitem{Fauske} Kjell Magnus Fauske, An introduction to Sketch,
%     2010/04/24, http://www.fauskes.net/nb/introduction-to-sketch/
% \end{thebibliography}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section*{Distribution}
% \label{sec:distribution}
%
% \ESK{} is available by anonymous internet ftp from any of the
% Comprehensive \TeX{} Archive Network (CTAN) hosts
% \label{pg:CTAN}
% \begin{quote}
%   |ftp.tex.ac.uk|, |ftp.dante.de|
% \end{quote}
% in the directory
% \begin{quote}
%   |macros/latex/contrib/esk|
% \end{quote}
% It is available from host
% \begin{quote}
%   |www.voodoo-arts.net|
% \end{quote}
% in the directory
% \begin{quote}
%   |pub/tex/esk|
% \end{quote}
% A work in progress under git control is available from
% \begin{quote}
%   |http://github.com/tomka/esk|
% \end{quote}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \StopEventually{\PrintIndex\PrintChanges}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Implementation}
% \changes{v1.0}{2010/05/05}{Version 1.0 Release}
%
% This project is greatly inspired and based on EMP. EMP is a LaTeX package
% to provide a convenient way to work with metapost files and code from
% inside LaTeX documents.
%
% \iffalse meta-comment
%% TeX hints:
%%   - @ is considered a normal letter in packages and classes
%%   - There are 256 32Bit \count<num> registers (i.e. \count0=42),
%%     can be expanded with \the<register> (i.e. \the\count0)
%%   - \relax ends scanning for tokens
%%     (i.e. \count0=\macro 42 <> \count0=\macro\relax 42)
%%   - A macro defined with can has a maximum of 9 arguments
%%   - \gdef is shortcut for \global\def
%%     \xdef is shortcut for \global\edef
%%   - \string<\macro> returns the "macro" (the name of a macro)
%% Doc hints:
%%   - There must be _exactly_ four spaces between the "%" and the
%%     "\begin{macrocode}" or "\end{macrocode}.  Otherwise, Doc
%%     won't detect the end of the code fragment.
%%   - The lines of code withen \begin{macrocode}...\end{macrocode}
%%     get written exactly as is to the .ins file, with no %-stripping.
% \fi
%
% It's is good practice to identify this version of the document style
% option.  We do this by parsing an RCS |Id| string and storing the
% result in the conventional \TeX{} control sequences. The parsing macro
% is only visible locally (within the surrounding scope), but generated
% control sequences like |\filename| are defined globally (due to the
% use of |\gdef|):
%    \begin{macrocode}
%<*style>
\def\fileversion{v1.0}
{\def\RCS#1#2\endRCS{%
  % is the first parameter a "$%?
  \ifx$#1%
    \@RCS $#2 \endRCS
  \else
    \@RCS $*: #1#2$ \endRCS
  \fi}%
 \def\@RCS $#1: #2,v #3 #4 #5 #6 #7$ \endRCS{%
   % global defines (independent of current scope) of file attributes
   \gdef\filename{#2}%
   \gdef\filerevision{#3}%
   \gdef\filedate{#4}%
   \gdef\filemaintainer{#6}}%
\RCS $Id: esk.dtx,v 1.0 2010/05/05 01:23:42 kazimiers Exp $ \endRCS}%
%    \end{macrocode}
% Make clear what LaTeX version is needed:
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
%    \end{macrocode}
% And now the standard procedure:
%    \begin{macrocode}
\ProvidesPackage{esk}[\filedate\space\fileversion\space
  Encapsulated Sketch LaTeX Package (\filemaintainer)]
%    \end{macrocode}
% We do not declare options for this package, so we do not need to
% invoke processing for found ones. Some other packages needed by
% \ESK{}, partly of a minimum version, get specified.
%    \begin{macrocode}
\RequirePackage{verbatim}
\RequirePackage{kvsetkeys}[2007/09/29]
%    \end{macrocode}
% The characters "\%", "\{" and "\}" are somewhat special to \TeX. More
% precisely are they used for comments and grouping respectively. \SK{}
% uses them as well, for the same purposes. To allow convenient code
% generation by using macros to produce the symbols, three macros get
% defined:
% \begin{macro}{\p@rcent}
% That macro is used for creating comments. The \% sign is locally
% defined as a common letter (category code 11) and create a global macro
% using it. The |@| in the name of the control sequence makes it only visible
% from inside the
%  package\footnote{see http://de.wikibooks.org/wiki/LaTeX-Wörterbuch:\_\@}.
%    \begin{macrocode}
{\catcode`\%=11\gdef\p@rcent{%}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\lc@rly}
%   \begin{macro}{\rc@rly}
% Curly braces are used for scope and group definitions in \SK. Just like
% with the |\p@rcent| macro, we need to make them a common letter.
% Unfortunately we need the curly braces to define a local scope for \TeX.
% To come around this the characters $>$ and $<$ are locally defined to
% be grouping characters (category code 1). To allow normal scope closing
% we finally make the curly braces grouping characters again.
%    \begin{macrocode}
{\catcode`\>=1  \catcode`\<=2
 \catcode`\{=11 \catcode`\}=11
 \gdef\lc@rly>{<
 \gdef\rc@rly>}<
 \catcode`\{=1  \catcode`\}=2
}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\eskwrite}
% Define a macro to write the contents of its first argument to a file.
% If the Boolean toggle |@eskio| is set to true, the passed argument is
% written\footnote{see http://www.tug.org/utilities/plain/cseq.html\#write-rp}
% out to the file referenced in |@outesk|. Normally \TeX{} does the
% actual writing during a |\shipout| operation, but we force it to do it
% immediately\footnote{see http://www.tug.org/utilities/plain/cseq.html\#immediate-rp}.
% All directly following spaces on the input will be
% eaten\footnote{see http://en.wikibooks.org/wiki/TeX/ignorespaces}.
%    \begin{macrocode}
\def\eskwrite#1{%
  \if@eskio
    \immediate\write\@outesk{#1}%
  \fi
  \ignorespaces}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eskwritetoken}
% If a token list register should be put into a file, this macro should
% be used. It will expand the token variable to its current contents.
%    \begin{macrocode}
\def\eskwritetoken#1{
  \eskwrite{\the#1}}
%    \end{macrocode}
% \end{macro}
%
% Next a new private Boolean toggle is defined. It is used to reflect if
% file writing is enabled and set it to true.
%    \begin{macrocode}
\newif\if@eskio
\@eskiotrue
%    \end{macrocode}
%
% The next free output file handle will be referenced by the private macro
% |\@outesk|. At this point no file is opened, but just an output channel
% defined\footnote{see \textit{A TEX primer for scientists} by Stanley
% A. Sawyer,Steven George Krantz on p. 283}. An example file open could now
% look like: |\openout\@outesk=TEXTFILE.TXT|.
%    \begin{macrocode}
\newwrite\@outesk
%    \end{macrocode}
%
% \begin{macro}{\eskfile}
% This environment encloses each \SK{} input file.  The single optional
% argument gives the name of the file and defaults to |\jobname|. This will
% probably not be used explicitly when defining esk figures. It is invoked
% automatically with an appropriate name for a figure. The macro |\theeskfile|
% gets locally defined and stores the base name for a file.
%    \begin{macrocode}
\newcommand{\eskfile}[1][\jobname]{%
  \def\theeskfile{#1}%
%    \end{macrocode}
% Open the Sketch file. If output is enabled, check if we're running under
% AMS-\LaTeX{} and if that is the case turn off I/O during the first pass over
% equation environments. This is done by looking for |\ifmeasuring@| of
% AMS-\LaTeX{} and, if found, replacing all |\if@eskio| checks with it. 
%    \begin{macrocode}
  \if@eskio
    \@ifundefined{ifmeasuring@}%
      {}%
      {\def\if@eskio{\ifmeasuring@\else}}%
%    \end{macrocode}
% A a new output file is linked to our |\@outesk| file  number. The name of that
% file is the content of |\theeskfile| with extension \textit{.sk}. Afterwards
% a start comment is written to the new file.
%    \begin{macrocode}
    \immediate\openout\@outesk=\theeskfile.sk\relax
    \eskwrite{\p@rcent\p@rcent\p@rcent\space \theeskfile.sk -- %
              do not edit, generated automatically by \jobname.tex}%
%    \end{macrocode}
% The |esk@prelude| token list register stores a prelude that should be put at
% the beginning of the new file. If the register is empty, the expansion of it
% (|\the\esk@prelude|) will be empty. This means the |\ifx| condition is met,
% because the actual check is now if |*| equals |*|. Hence the |\else| branch
% will \emph{not} be called. If the token register is not empty (and does not
% start with an asterisk) the |\else| branch is used..
%    \begin{macrocode}
    \expandafter\ifx\expandafter*\the\esk@prelude*\else
      \eskwrite{\the\esk@prelude}%
    \fi
  \fi}
%    \end{macrocode}
%
% Define |\theeskfile|, later redefined with the name of the currently opened
% file, to be |\relax| (i.e. stop reading tokens). This should be the value
% if no file is opened.
%    \begin{macrocode}
\let\theeskfile\relax
%    \end{macrocode}
% Define a new counter |\eskfig| to count the single esk figures. It is
% initialized with 0.
%    \begin{macrocode}
\newcounter{eskfig}
%    \end{macrocode}
%
% Let \TeX{} create a new token list register alias |\esk@prelude|. It stores
% an optional prelude for the files written out. If the indirect alias
% creation |\newtoks| is used, \TeX{} selects a free register and hides the
% technical detail from us.
%    \begin{macrocode}
\newtoks\esk@prelude
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eskprelude}
%   \begin{macro}{\eskaddtoprelude}
% Define a public |\eskprelude| macro that replaces the contents of the
% internal token list register |\esk@prelude| with the argument passed.
%    \begin{macrocode}
\def\eskprelude#1{\esk@prelude={#1}}
%    \end{macrocode}
% Define a public macro that appends its argument to the internal
% |\esk@prelude| token list register. The text is added on a new line.
% This is accomplished by using |^^J|, a replacement ASCII representation
% for LF (line feed)\footnote{e.g. see: http://www.torsten-horn.de/techdocs/ascii.htm}.
%    \begin{macrocode}
\def\eskaddtoprelude#1{\esk@prelude=\expandafter{\the\esk@prelude^^J#1}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% The token list register storing the global settings of \SK{} is called
% |\esk@globals| and defaults to \emph{language tikz}.
%    \begin{macrocode}
\newtoks\esk@globals
\esk@globals={language tikz}
%    \end{macrocode}
%
% \begin{macro}{\eskglobals}
%   \begin{macro}{\eskaddtoglobals}
% The macros |\eskglobals| and |\eskaddtoglobals| are there to set and
% modify the private token list register |\esk@globals|. With them one
% has control over the general settings of \SK. On adding, new settings
% will be delimited by a comma.
%    \begin{macrocode}
\def\eskglobals#1{\esk@globals={#1}}
\def\eskaddtoglobals#1{\esk@globals=\expandafter{\the\esk@globals,#1}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{\endeskfile}
% And here is how the |empfile| environment is closed. If there are
% global settings they are written out. The last line of the generated
% file will be an end statement in form of a comment. followed by a line
% break. As a convention the macro keeping the base name of the file,
% |\theeskfile|, is set to |\relax|. That indicates that no file is open.
% To make that true, the currently opened file (if any) is finally
% closed.
%    \begin{macrocode}
\def\endeskfile{%
  \expandafter\ifx\expandafter*\the\esk@globals*\else
    \eskwrite{global \lc@rly\the\esk@globals\rc@rly }%
  \fi
  \eskwrite{\p@rcent\p@rcent\p@rcent\space the end.^^J}%
  \let\theeskfile\relax
  \if@eskio
    \immediate\closeout\@outesk
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk}
% The |esk| environment encloses \SK{} code that will be put into a file
% for being later processed by \SK. First it (re-)defines the macro
% |\esk@@name| with the environments argument. That argument is used as
% the base name for the corresponding file and defaults to |\jobname|.
% Then the internal macro |\esk@| produces a single esk graphic.
%    \begin{macrocode}
\newcommand{\esk}[1][\jobname]{%
  \def\esk@@name{#1}%
  \esk@}
%    \end{macrocode}
% \end{macro}
%
% Since the |esk| environment allows two optional parameters and only
% one can have brackets, the second parameter is surrounded by parentheses.
% A macro for an opening parenthesis is defined:
%    \begin{macrocode}
\let\leftparanthesis=(
%    \end{macrocode}
%
% \begin{macro}{\esk@}
% The private |\esk@| macro stores the immediately following token in
% the macro |\next| and invokes |\esk@impl|.
%    \begin{macrocode}
\def\esk@{
  \futurelet\next\esk@impl}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@impl}
% Now that the following token is known in |\next| it is checked
% if the second optional argument got passed. This is done by testing
% if the next token is an opening parenthesis and depending on its
% occurrence |\esk@impl@Arg| or |\esk@impl@NoArg| is invoked. Since
% we want to work with the content of the environment verbatim, we
% have to get rid of |\else| and |\fi| in the input stream. This
% can be achieved by just expanding them before calling the verbatim
% handling macros with |\expandafter|.
%    \begin{macrocode}
\def\esk@impl{%
  \ifx\next\leftparanthesis
    \expandafter\esk@impl@Arg
  \else
    \expandafter\esk@impl@NoArg
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@impl@NoArg}
%   \begin{macro}{\esk@impl@Arg}
% The macro |\esk@impl@NoArg| just calls |\esk@impl@Arg| with an
% empty argument. It is mainly there for readability.
%    \begin{macrocode}
\def\esk@impl@NoArg{\esk@impl@Arg()}
%    \end{macrocode}
% The following macro, |\esk@impl@Arg|, expects one argument
% surrounded by parentheses, namely a list of |eskdef| names.
% It makes sure some preconditions are met by invoking |\esk@start|.
% Afterwards |\esk@includegraphics| checks if a \SK{} file should
% be generated or a \LaTeX{} file be included. Finally the argument
% is parsed as a comma separated list to call |\esk@def@processor|
% for each element found and the actual \SK{} code verbatim
% processing is started with |\esk@cmds|. As the verbatim line
% processing macro name "eskwritetoken" is passed as an argument.
%    \begin{macrocode}
\def\esk@impl@Arg(#1){%
  \esk@start%
  \esk@includegraphics{\theeskfile}%
  \comma@parse{#1}{\esk@def@processor}%
  \esk@cmds{eskwritetoken}}
%    \end{macrocode}
%   \end{macro}
% \end{macro}
%
% \begin{macro}{esk@def@processor}
% The macro |\esk@def@processor| gets expanded for every element
% of the second optional argument of the |esk| environment. Here
% every |eskdef| name of that list will be included in the current
% file by invoking |\eskuse| for it.
%    \begin{macrocode}
\def\esk@def@processor#1{
  \esk@use{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@start}
% A macro for preparing for a new \SK{} figure.
%    \begin{macrocode}
\def\esk@start{%
%    \end{macrocode}
% We can't use |\stepcounter| because of the |amstext| option of
% AMS-\LaTeX{} disables it sometimes. Instead we globally advance
% the eskfig counter manually by one. Afterwards we call
% |\esk@checkfile| to make sure a file is open. Finally we invoke
% |\esk@@def| with our previously defined temporary esk file name
% to generate new |\theeskfile| and |\theeskfig| alias macros for
% the current figure.
%    \begin{macrocode}
  \global\expandafter\advance\csname c@eskfig\endcsname \@ne
  \esk@checkfile
  \esk@@def{\esk@@name}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@checkfile}
% Make sure that a Sketch file is open, otherwise \emph{really}
% obscure error messages are possible. This is done by checking
% if |\theeskfile| is the same as |\relax| (as defined during
% initialization and file closing). If so, try to open a file
% (again) and do the test again. If it still fails print and
% produce an error.
%    \begin{macrocode}
\def\esk@checkfile{%
  \ifx\theeskfile\relax
    \eskfile[\esk@@name.\arabic{eskfig}]
  \fi
  \ifx\theeskfile\relax
    \errmessage{Could not open file "\esk@@name.\arabic{eskfig}.sk"!}
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@includegraphics}
% If a file having \emph{.sk.tex} added to the base name exists
% this macro will include it. To start a new paragraph if we are
% in vertical mode and switch to horizontal mode |\leaveemode|
% is called at the beginning. Then, if the file exists, pass its
% name as an argument to |\input| (which expects the file to end
% with \emph{.tex}). If there is no such file a message is typed
% out to tell the user that the sketch files might need the actual
% processing.
%    \begin{macrocode}
\def\esk@includegraphics#1{%
  \leavevmode
  \IfFileExists{#1.sk.tex}%
    {\input{#1.sk.tex}}%
    {\typeout{%
      esk: File #1.sk.tex\space not found:^^J%
      esk: Process #1.sk with Sketch (-o #1.sk.tex) and then %
           reprocess this file.}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@cmds}
% The macro |\esk@cmds| gets the |esk| environments content by
% using the verbatim package. Each line is processed by a macro
% which name is passed as an argument. That is done to reuse
% the macro for |esk| and |eskdef| environments. The macros
% in use for the line processing are |eskwrite| and
% |esk@def@verb@proc| respectively. Due to the use of
% |\begingroup| \TeX{} enters a group that has to be terminated
% by |\endgroup| and not by \}.
%    \begin{macrocode}
\newcommand{\esk@cmds}[1]{%
  \begingroup
%    \end{macrocode}
% The macros |\@bsphack| ... |\@esphack| are used by macros such as
% |\index| and |\begin{@float}| ... |\end{@float}| that want to be
% invisible -- i.e. not leave any extra space when used in the
% middle of text.  Such a macro should begin with |\@bsphack| and
% end with |\@esphack|. The macro in question should not create any
% text, nor change the mode.
%    \begin{macrocode}
    \@bsphack
%    \end{macrocode}
% The next thing to do is to defuse \LaTeX{}' special characters:
% |\dospeciels| expands to a list of special characters of the form
% |\do\ \do\\ \do\{ \do\}|.... If one (re-)defines the "|\do|" macro
% one can execute a macro on all of them. In our case we define
% |\do| to be |\@makeother|. That assigns category code 12
% (non-letter) to all special characters, thus they get normal
% characters without any special meaning. Due to the environment
% those changes are local.
%    \begin{macrocode}
    \let\do\@makeother\dospecials
%    \end{macrocode}
% |^^M| is the ASCII representation of CR (carriage return). With
% the following line we make it an active character. Thus a macro
% with the name |^^M| can now be defined.
%    \begin{macrocode}
    \catcode`\^^M\active
%    \end{macrocode}
% Since we use the verbatim package |\verbatim@processline| is called
% after each line. We redefine it to do what we would like it to do:
% Process the line with the macro with the name passed as argument..
% The current line is available in |\verbatim@line|, a token register
% \footnote{see: Latex hacks by Anselm Lingnau, p. 43 }.
%    \begin{macrocode}
    \def\verbatim@processline{\csname#1\endcsname{\verbatim@line}}%
%    \end{macrocode}
% Enter the real verbatim mode. From here on \emph{all} characters
% have lost their special meaning (if they had any).
%    \begin{macrocode}
    \verbatim@start}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endesk@cmds}
% To end the invisible environment and the group started by
% |\esk@cmds|, this macro has to be used.
%    \begin{macrocode}
\def\endesk@cmds{%
    \@esphack
  \endgroup}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endesk}
% This macro triggers the termination of the verbatim reading and
% closes the current file.
%    \begin{macrocode}
\def\endesk{%
  \endesk@cmds
  \endeskfile}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eskdef}
% An |eskdef| environment allows to store blocks of \SK{} code in
% token list registers for using them in |esk| environments. The
% macro has one parameter, the name of the definition. First a
% private and local name for the new block is defined. Then
% |\esk@def| checks if the name is already there and does the
% rest.
%% \iffalse TODO: Make it more robust by remembering old name
%% and setting it back afterwards (if any), so it can
%% be used in esk environments \fi
%    \begin{macrocode}
\newcommand{\eskdef}[1]{%
  %% Define a new name
  \def\esk@@def@name{esk@def:#1}%
  \esk@def}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@def}
% The |\esk@def| macro relies on |\esk@@def@name| being defined
% previously. At the beginning it checks if that name is already
% registered by looking for a control sequence with the defined
% name. If so, an error message is produced.
%    \begin{macrocode}
\def\esk@def{%
  \expandafter\ifcsname\esk@@def@name\endcsname
    \errmessage{"\esk@@def@name" is already defined!}
  \fi
%    \end{macrocode}
% If a new |eskdef| name is given a new token list register is
% created and named like the expansion of |\esk@@def@name|. It
% is not necessary to tell \TeX{} that the new register will be
% global, because \emph{new...} tokens act always globally.
% Unfortunately |\newtoks| is an |\outer| macro and we use the
% wrapper |\tok@newtoks| (see below) to call it.
%    \begin{macrocode}
  \expandafter\tok@newtoks\csname\esk@@def@name\endcsname
%    \end{macrocode}
% Create or override a global definition |\esk@@def@reg|
% containing our new token register. Unfortunately, this works only
% with a global definition. Afterwards the verbatim reading of the
% environment is started with a different verbatim line processor as
% before. Finally the macro ends with removing the previously
% defined alias for the new token list register.
%    \begin{macrocode}
  \global\edef\esk@@def@reg{\csname\esk@@def@name\endcsname}
  \esk@cmds{esk@def@verb@proc}}
  \global\def\esk@@def@reg{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@def@verb@proc}
% The verbatim line processor for the |eskdef| environment first
% creates a local alias for the new token list register. This is
% done to make the code more readable.
%    \begin{macrocode}
\def\esk@def@verb@proc#1{%
  \expandafter\let\expandafter\token@reg\esk@@def@reg
%    \end{macrocode}
% If the token list register is empty it is filled with the
% current verbatim line.
%    \begin{macrocode}
  \expandafter\ifx\expandafter*\the\token@reg*
    \global\esk@@def@reg=\expandafter{\the#1}
%    \end{macrocode}
% If not, the verbatim line is appended on a new line.
%    \begin{macrocode}
  \else
    \global\esk@@def@reg=\expandafter{%
      \the\expandafter\token@reg\expandafter^^J\the#1}
  \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endeskdef}
% On ending an |eskdef| environment |\endeskdef| is expanded. Here,
% its only purpose is to invoke the macro ending the verbatim
% input environment.
%    \begin{macrocode}
\def\endeskdef{
  \endesk@cmds}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@@def}
% A macro which takes a file name as argument to globally define
% new macros |\esk@k:f:<arg>| and |\esk@k:c:<arg>| which expand
% to |\theeskfile| and |\theeskfig| respectively.
%    \begin{macrocode}
\def\esk@@def#1{%
  \global\e@namedef{esk@k:f:#1}{\theeskfile}%
  \global\e@namedef{esk@k:c:#1}{\theeskfig}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\e@namedef}
% A macro which defines a new macro with the name of the
% argument. This is done in use of |\expandafter| and
% |\csname|...|\endcsname|. The new macro expands to the
% following group, i.e. the new macros body. Due to the
% use of |\edef| this happens dynamically.
%    \begin{macrocode}
\def\e@namedef#1{%
  \expandafter\edef\csname #1\endcsname}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\esk@use}
% The |\esk@use| macro appends an \ESK{} \SK{} code definition
% defined by |\eskdef|, into the currently defined file. After
% creating an alias macro for the argument passed is is made
% sure that the definition actually exists. If not an error
% message is produced. If there is a token list register, named
% like passed as argument, a short describing comment is written.
% Further, the register is written as token to the file. The
% file writing is finished with a new line.
%    \begin{macrocode}
\def\esk@use#1{%
  \def\esk@@def@name{esk@def:#1}%
  \expandafter\ifcsname\esk@@def@name\endcsname
    \eskwrite{\p@rcent\p@rcent\space included definition: #1}%
    \expandafter\eskwritetoken\expandafter{%
     \expandafter\csname\esk@@def@name\endcsname}
    \eskwrite{^^J}
  \else
    \errmessage{esk: "#1" is undefined!}
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tok@newtoks}
% Since |\newtoks| is an |\outer| macro, it is not allowed in definitions.
% Because we are in the need of creating token list registers on the
% fly, we define a wrapper. It lets \TeX{} construct the |\newtoks| call:
%    \begin{macrocode}
\def\tok@newtoks{
  \csname newtoks\endcsname}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\futurespacelet}
% A special version of the |\futurelet| macro. It is taken from Donald. E.
% Knuths \emph{\TeX{}book} and behaves like |\futurelet|, but ignores spaces.
%    \begin{macrocode}
\def\futurenospacelet#1{\def\cs{#1}%
  \afterassignment\stepone\let\nexttoken= }
%    \end{macrocode}
% Let |\stoken| be a space token:
%    \begin{macrocode}
\def\\{\let\stoken= } \\
%    \end{macrocode}
% And define the stepwise look-ahead macros:
%    \begin{macrocode}
\def\stepone{\expandafter\futurelet\cs\steptwo}
\def\steptwo{\expandafter\ifx\cs\stoken\let\next=\stepthree
  \else\let\next=\nexttoken\fi \next}
\def\stepthree{\afterassignment\stepone\let\next= }
%</style>
%    \end{macrocode}
% \end{macro}

% \Finale
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \appendix
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Driver File}
%
%    \begin{macrocode}
%<*driver>
\documentclass[a4paper]{article}
\usepackage{doc}
\usepackage{amsmath}
%    \end{macrocode}
% The logos would come out much nicer if |mflogo| would support some
% more letters (i.e. k and K). We don't have that and so we define
% the logos the following way:
%    \begin{macrocode}
\def\ESK{\textsf{ESK}}%
\def\SK{\textsf{Sketch}}%
\def\MP{\textsf{META}\-\textsf{POST}}%

%    \end{macrocode}
% Protect against certain outdated versions of the |kvsetkeys| package:
%    \begin{macrocode}
\usepackage{kvsetkeys}[2007/09/29]
\usepackage{tikz}
\usepackage{esk}
%    \end{macrocode}
%    \begin{macrocode}
\setlength{\parindent}{0pt}
\def\manindex#1{\SortIndex{#1}{#1}}
%<manual>\OnlyDescription
\EnableCrossrefs
\RecordChanges
\CodelineIndex
\DoNotIndex{\def,\gdef,\long,\let,\begin,\end,\if,\ifx,\else,\fi}
\DoNotIndex{\immediate,\write,\newwrite,\openout,\closeout,\typeout}
\DoNotIndex{\font,\jobname,\documentclass,\char,\catcode,\ }
\DoNotIndex{\CodelineIndex,\DocInput,\DoNotIndex,\EnableCrossrefs}
\DoNotIndex{\filedate,\filename,\fileversion,\logo,\manfnt}
\DoNotIndex{\NeedsTeXFormat,\ProvidesPackage,\RecordChanges,\space}
\DoNotIndex{\begingroup,\csname,\edef,\endcsname,\expandafter}
\DoNotIndex{\usepackage,\@ifundefined,\ignorespaces,\item,\leavevmode}
\DoNotIndex{\newcounter,\newif,\par,\parindent}
\DoNotIndex{\relax,\setcounter,\stepcounter,\the,\advance}
\DoNotIndex{\CurrentOption,\DeclareOption,\documentstyle}
\DoNotIndex{\endgroup,\global,\hfuzz,\LaTeX,\LaTeXe}
\DoNotIndex{\macrocode,\OnlyDescription,\PassOptionsToPackage}
\DoNotIndex{\ProcessOptions,\RequirePackage,\string,\textsf,\unitlength}
\DoNotIndex{\@bsphack,\@esphack,\@nameuse,\@ne,\active,\do,\dospecials}
\DoNotIndex{\errhelp,\errmessage,\ifcase,\IfFileExists,\includegraphics}
\DoNotIndex{\manindex,\SortIndex,\newcommand,\newtoks,\or,\origmacrocode}
\DoNotIndex{\alpha,\displaystyle,\frac,\sin,\texttt}
%    \end{macrocode}
% Cut the line breaking some slack for macro code which might contain
% long lines (it doesn't really hurt if they stick out a bit).
%    \begin{macrocode}
\let\origmacrocode\macrocode
\def\macrocode{\hfuzz 5em\origmacrocode}
\begin{document}
  \DocInput{esk.dtx}
\end{document}
%</driver>
%    \end{macrocode}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\endinput
Local Variables:
mode:LaTeX
fill-prefix:"% "
indent-tabs-mode:nil
change-log-default-name:"TODO"
page-delimiter:"^% %%%%%%%%%*\n"
End:
