% \iffalse meta-comment
% $Id: svn.dtx 43 2007-09-25 19:20:04Z repos $
% Copyright (C) 2003-7 by Richard Lewis <rpil2+svn.sty@rtf.org.uk>
%
% This file may be distributed and/or modified under the conditions
% of the LaTeX Project Public License, either version 1.3 of this
% license or (at your option) any later version.  The latest version
% of this license is in:
%
%    http://www.latex-project.org/lppl.txt
%
% and version 1.3 or later is part of all distributions of LaTeX
% version 2003/06/01 or later.
%
% This work has the LPPL maintenance status `maintained', and the
% Current Maintainer of this work is Richard Lewis <rpil2+svn.sty@rtf.org.uk>.
%
% This work consists of all files listed in the `Contents' section of
% the README file.
%
% \fi
%
% \iffalse
%<*package>
%\NeedsTeXFormat{LaTeX2e}
%\def\svn@Id $Id: #1 #2 #3-#4-#5 #6$%
%  {\def\svn@date{#3/#4/#5}%
%   \def\svn@revision{#2}}
%
%\svn@Id $Id: svn.dtx 43 2007-09-25 19:20:04Z repos $
%\edef\next{%
%  \noexpand\ProvidesPackage{svn}[\svn@date\space r\svn@revision\space
%                                 Typeset subversion keywords.]}
%\next
%</package>
%
%<*driver>
\documentclass{ltxdoc}
 \usepackage[T1]{fontenc}
 \usepackage[utf8x]{inputenc}
 \usepackage[british]{babel}
 \usepackage{lmodern} % ensures we use Type 1 fonts, comment this out to get Type 3 fonts
 \usepackage{svn}
 \EnableCrossrefs
 \CodelineIndex
%\OnlyDescription
%\RecordChanges
 \begin{document}
   \DocInput{svn.dtx}
 \end{document}
%</driver>
% \fi
%
% \CheckSum{106}
%
% \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         \~}
%
% \GetFileInfo{svn.sty}
% \DoNotIndex{\NeedsTeXFormat,\ProvidesPackage,\next}
% \DoNotIndex{\newcommand,\def,\edef,\gdef,\global,\let}
% \DoNotIndex{\noexpand,\expandafter,\csname,\endcsname}
% \DoNotIndex{\protect}
% \DoNotIndex{\if,\ifx,\else,\fi,\begingroup,\endgroup}
% \DoNotIndex{\space,\@empty,\@ifundefined,\@nameuse}
%
%
% \let\prog\textsf
% \let\format\texttt
% \def\shell#1{`\texttt{#1}'}
% \let\package\textsf
% \let\email\texttt
% \let\url\texttt
% \def\param#1{\texttt{\##1}}
% \def\Subversion{\prog{Subversion}}
% \def\CVS{\prog{CVS}}
% \def\RCS{\prog{RCS}}
%
% \title{The \package{svn} package\thanks{This document
%   corresponds to \package{svn}~\fileversion, dated \filedate.}}
% \author{Richard Lewis \\ \email{rpil2+svn.sty@rtf.org.uk}}
%
% \def\convertfiledate/#1/#2/#3/{%
%   \def\convertedfiledate{\begingroup\day#3 \month#2 \year#1 \today\endgroup}
% }
% \expandafter\convertfiledate\expandafter/\filedate/
% \date{\convertedfiledate}
% \maketitle
%
% \section{Introduction}
% \Subversion\ is a replacement for \CVS\ and \RCS.  It is similar to
% \CVS\ but with some improvements (e.g., it understands
% renaming and deletion of version controlled files---see
% \url{http://subversion.tigris.org/} for more information).  As with
% \CVS\ and \RCS, a file registered with \Subversion\ may
% contain keywords (such as |$Date$| or |$Revision$|) that
% \Subversion\ will replace with status information about the file
% (such as the date the file was last committed, or the revision at
% which it last changed).\footnote{Unlike \RCS\ and \CVS, the
%  expansion of  such keywords is customisable, and not enabled by
%  default: use  \shell{svn propset svn:keywords "Date Id" myfile.tex}
%  to tell \Subversion\ to expand the keywords
%  \texttt{\string$Date\string$}  and \texttt{\string$Id\string$} in
%  \shell{myfile.tex}.}
%
% For typesetting the contents of \RCS\ and \CVS\ keywords
% there is the \package{rcs} package\footnote{Written by Joachim
% Schrod with minor modification by Jeffrey Goldberg}; although highly
% recommended, that package does not cope with the format of
% \Subversion's |$Date$| keyword, so I wrote the \package{svn} package
% to do just that.
%
% \section{Usage}
% \subsection{Quick Example}
% The main use for this package is to get the date the file was last
% committed into the output of |\maketitle|.  The solution is simple:
%
% \begin{verbatim}
% \documentclass{article}
% \usepackage{svn}
% \SVNdate $Date$
% \title{Hope this works}
%
% \begin{document}
% \maketitle
% \end{document}
% \end{verbatim}
%
% \subsection{More General Usage}
% As usual, load the \package{svn} package with |\usepackage{svn}|.
%
% The main command is |\SVN $|\meta{Keyword}|$| (which mimics
% `|\RCS $|\meta{Keyword}|$|' from the \package{rcs} package).
% By default the following happens:
% \begin{itemize}
%  \item If you say |\SVN $Keyword: stuff $| (i.e,
%  |$Keyword$| has been expanded to `|stuff|') then:
%  \begin{itemize}
%   \item If |$Keyword$| is |$Date$| or |$\LastChangedDate$|, then
%    |stuff| is parsed and |\SVNDate| is defined to be the date, and
%    |\SVNTime| the time, that the file was checked in.  |\SVNRawDate|
%    is defined to be the whole string `|stuff|'.
%   \item Otherwise a command |\SVNKeyword| is defined to be
%     `|stuff|'.
%  \end{itemize}
%  \item If you say |\SVN $Keyword$| (i.e., |$Keyword$| was
%   not expanded---perhaps it doesn't appear in the \url{svn:keywords}
%   property, or perhaps the file has not been checked in since the
%   line was added), then:
%   \begin{itemize}
%    \item If |$Keyword$| is |$Date$| (or |$\LastChangedDate$|),
%    |\SVNDate| is defined to be |\today|, and |\SVNTime| and
%    |\SVNRawDate| are set to |\SVNempty| (which is empty by default,
%    and may be changed with |\renewcommand|).
%    \item Otherwise |\SVNKeyword| is defined to be |\SVNempty|.
%   \end{itemize}
% \end{itemize}
% In principle you may use |\SVN| anywhere, but you may find problems
% if some package has made characters appearing in keywords active
% (e.g., \package{babel} with the |french| option---|\SVN| still works
% in the preamble though).
%
% \subsection{\texttt{\string\SVNdate}}
% Since you probably want to have the date of check-in the output of
% |\maketitle|, we provide the construct `|\SVNdate $Date$|' to do
% just that (note the difference between this and |\SVNDate|: the
% latter expands to the check-in time (or |\today|)).  This is exactly
% the same as saying `|\SVN $Date$ \date{\SVNDate}|', but saves some
% typing.
%
%
% \subsection{Advanced Usage and Customisation}
% The default behaviour described above can be modified to do all
% kinds of fancy things with all kinds of fancy keywords.  When you
% say |\SVN $keYwoRd: stuff$|, if the command |\SVN@keYwoRd@expanded|
% exists\footnote{As ever, `exists' means ``defined and not equal to
% `\texttt{\string\relax}'''} then it will be executed with two arguments:
% `|\SVN@keYwoRd@expanded{keYwoRd}{stuff : }|' (note the trailing
% `\verb*| : |').  If |\SVN@keYwoRd@expanded| does not exist then
% |\SVN@generic@expanded| is run (again with arguments
% `|{keYwoRd}{stuff : }|), which defines |\SVNkeYwoRD| to be |stuff|.
%
% If instead we had an unexpanded keyword (e.g., `|\SVN $keYwoRd$|')
% then \package{svn} will try and run
% |\SVNkeYwoRd@unexpanded{keYwoRd}{}|, falling back to
% |\SVN@generic@unexpanded{keYwoRd}{}| if
% |\SVN@keYwoRd@unexpanded| does not exist.
% |\SVN@generic@unexpanded{keYwoRd}{}| will define |\SVNkeYwoRd| to be
% |\SVNempty|, which is initially just |\relax|, but may be redefined
% (just use |\renewcommand|).
%
% So if you want some fancy behaviour for some fancy new keyword, you
% just need to define |\SVN@|\meta{Keyword}|@expanded| and
% |\SVN@|\meta{Keyword}|@unexpanded| to do what you want.  Both variants
% should take two arguments which are \marg{KeywordName}\marg{expansion}.
% |\SVN@|\meta{Keyword}|@unexpanded| will be called with
% \meta{expansion} empty, and |\SVN@|\meta{Keyword}|@expanded| will
% be called with \meta{expansion} as the keyword expansion text plus a
% trailing `\verb*| : |' (which can be removed using the predefined
% |\svn@set| command---see the following example).
%
%  As a simple example, |\SVN $Rev$| will define a
% |\SVNRev| command.  Subversion treats |$LastChangedRevision$| as
% an alias for |$Rev$|, so if you wanted both
% |\SVN $Rev$| and |\SVN $LastChangedRevision$| to define both
% |\SVNLastChangedRevision| and |\SVNRev| then you
% could put the following in your preamble:
% \begin{verbatim}
% \makeatletter
%  %%These first two are run when \SVN sees a `Rev' keyword.
%  \def\SVN@Rev@unexpanded#1#2{%
%    \let\SVNRev\SVNempty
%    \let\SVNLastChangedRevision\SVNRev
%  }
%  %%The `@expanded' receives the keyword name as #1 and the
%  %%keyword expansion (with trailing ` : ') as #2.
%  \def\SVN@Rev@expanded#1#2{%
%    \svn@set\SVNRev$#2$%
%    \let\SVNLastChangedRevision\SVNRev
%  }
%  %%These next two lines make \SVN treat `LastChangedRevision'
%  %%exactly the same as `Rev'
%  \let\SVN@LastChangedRevision@unexpanded\SVN@Rev@unexpanded
%  \let\SVN@LastChangedRevision@expanded\SVN@Rev@expanded
% \makeatother
% \end{verbatim}
% \subsection{Known Issues}
% If you use \package{babel} you will get the date produced by the
% |\SVNDate| command in the correct style for the current language,
% and if you change the language the text produced by |\SVNDate| may
% change.  This may be undesirable, and the naïve solution is to say
% |\edef\SVNDateText{\SVNDate}| before the language change.  However,
% with the code stolen from the \package{rcs}, inside an |\edef|,
% |\SVNDate| expands to |\today| whatever the check-in date.  To work
% around this, |\SVNDate| has been designed to generate an error
% inside an |\edef|.
%
% One way to store the check-in date in a language-independent way is
% the following, which defines |\fixatedSVNDate| to be the german
% version of the check-in date, but note that
% |\edef\foo{\fixatedSVNDate}\foo| will still give |\today|'s date
% (and no error).
% \begin{verbatim}
%   \def\fixateSVNDate{%
%     \def\foo{\today}
%     \ifx\SVNDate\foo
%       \let\fixatedSVNDate\today
%     \else
%       \expandafter\fixateSVNDateExpanded\SVNDate
%     \fi
%   }
%
%   \def\fixateSVNDateExpanded\begingroup#1\day#2\today\endgroup{%
%     \let\fixedtoday\today
%     \def\fixatedSVNDate{\begingroup\day#2\fixedtoday\endgroup}%
%   }
%
%   %% To fix the Date format, use \fixateSVNDate:
%   \SVN $Date: 3999-07-30 14:58:54 +0100 (Thu, 30 Jul 3999) $
%   german: \selectlanguage{german}\fixateSVNDate\SVNDate\\
%   english : \selectlanguage{english} \SVNDate\\
%   We still have access to german format: \fixatedSVNDate
% \end{verbatim}
%
% \subsection{Avoiding Unwanted Keyword Expansion}
% Although nothing to do with this package, the following may be
% useful.
%
% Sometimes your document contains strings of the form `|$...$|' which,
% although looking like keywords, should not be expanded by
% \Subversion.  There are several ways to stop this expansion.
%
% Firstly, \Subversion\ only expands the keywords you tell it to,
% so if you say \shell{svn propset svn:keywords "Id" myfile.tex}
% (and then commit), |$Date$| will not be expanded anywhere.  This
% leaves the case where you want to use something like
%  |\SVNdate $Date$| at the top, but also use |$Date$| somewhere else.
% \begin{description}
%  \item[In-line maths:] If you are using |$Date$| because it is the
%   product of the variables $D$, $a$, $t$ and $e$, then you could use
%   |\(Date\)| or replace the dollars with |^^24|: `|^^24Date^^24|'.
%  \item[Verbatim:] If you want the string |$Date$|
%   to appear verbatim in your \format{dvi}, then you could use
%   |\texttt{\string$Date\string$}| (or use |\verb| around the |$|, but
%   that will break in footnotes)
% \end{description}
%
% \StopEventually{\PrintIndex}
%
% \section{Implementation}
% \subsection{General Admin Stuff}
% \begin{macro}{\svn@date}
% \begin{macro}{\svn@revision}
% First we do the usual |\ProvidesPackage| stuff.  Of course,
% \url{svn.dtx} is itself under \Subversion, and we want to get the
% package date and version from the \texttt{\string$Id\string$}
% keyword.
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\def\next $Id: #1 #2 #3-#4-#5 #6${%
  \def\svn@date{#3/#4/#5}%
  \def\svn@revision{#2}%
}
\next $Id: svn.dtx 43 2007-09-25 19:20:04Z repos $
\edef\next{%
  \noexpand\ProvidesPackage{svn}[\svn@date\space r\svn@revision\space
                                 Typeset Subversion keywords.]%
}
\next
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%\subsection{The generic \texttt{\string\SVN} command}
% \begin{macro}{\SVN}
% |\SVN| is the main construct (see above for
% usage). The single argument should be of the form
% |$|\meta{Keyword}|$| or
% |$|\meta{Keyword}:\meta{space}\meta{value}\meta{space}|$|, where \meta{Keyword}
% and \meta{value} must be non-empty as well as brace- and
% |\if|--|\fi|- balanced. \meta{space} is a single space (if more are
% present they will be subsumed into \meta{value}).
% If |$empty$|, |$generic$|, |$RawDate$|, or |$Time$| ever become
% keywords, or if keywords containing |@| ever exist then we may have
% problems.
%    \begin{macrocode}
\def\SVN $#1${\svn@$#1: $}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SVNempty}
% If \meta{Keyword} is unexpanded then |\SVNKeyword| is |\let| to
% |\SVNempty|, which is initially empty.
%    \begin{macrocode}
\newcommand{\SVNempty}{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\svn@}
%  \begin{macro}{\svn@tmp}
% |\snv@| does the work for |\SVN|.  It takes two arguments, the first
% is the \meta{Keyword}'s name, the second is empty (in which case
% \meta{Keyword} was unexpanded) or \meta{value}, the expansion of
% \meta{keyword}.
%    \begin{macrocode}
\def\svn@$#1: #2${%
  \def\svn@tmp{#2}%
%    \end{macrocode}
%   \begin{macro}{\svn@suffix}
% If \param2 is empty, then the keyword was unexpanded and
% |\svn@suffix| is set to |@unexpanded|, otherwise we had an expanded
% keyword so |\svn@suffix| is set to |@expanded|.
%    \begin{macrocode}
  \ifx\svn@tmp\@empty
    \def\svn@suffix{@unexpanded}%
  \else
    \def\svn@suffix{@expanded}%
  \fi
%    \end{macrocode}
% If |\SVN@|\param1\meta{suffix} is defined
% then run it with arguments `\param1\param2', else
% run |\SVN@generic@|\meta{suffix} (again with argument
% \param1\param2---by default this defines `|\SVN|\meta{\param1}' to
% be \param2, or |\SVNempty| in the unexpanded case).
%    \begin{macrocode}
  \@ifundefined{SVN@#1\svn@suffix}%
      {\@nameuse{SVN@generic\svn@suffix}{#1}{#2}}%
    {\@nameuse{SVN@#1\svn@suffix}{#1}{#2}}%
}
%    \end{macrocode}
%   \end{macro}
%  \end{macro}
% \end{macro}
%
% \subsection{Dealing with general \texttt{\string$Keyword\string$}s}
% \begin{macro}{\SVN@generic@expanded}
% When we see |\SVN $KeyWord: <stuff> $|, and no
% |\SVN@KeyWord@expanded| command exists, we use
% |\SVN@generic@expanded{KeyWord}{<stuff>}|
% to define |\SVNKeyWord| to be |<stuff>|.
%    \begin{macrocode}
\def\SVN@generic@expanded#1#2{%
  \expandafter\svn@set\csname SVN#1\endcsname$#2$%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SVN@generic@unexpanded}
% When we see |\SVN $KeyWord$| and no
% |\SVN@KeyWord@unexpanded| command exists, we use
% |\SVN@generic@unexpanded{KeyWord}|
% to define |\SVNKeyWord| to be |\SVNempty|.
%    \begin{macrocode}
\def\SVN@generic@unexpanded#1#2{%
  \expandafter\global\expandafter\let\csname SVN#1\endcsname\SVNempty
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\svn@set}
% |\svn@set#1$#2$| defines the command in \param{1} to be \param{2}
% without the trailing `\verb*| : |' that the call to |\svn@| added.
%    \begin{macrocode}
\def\svn@set#1$#2 : ${\gdef#1{#2}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Dealing with the \texttt{\string$Date\string$} keyword}
% \begin{macro}{\SVN@Date@unexpanded}
%  \begin{macro}{\SVN@LastChangedDate@unexpanded}
% When we see a |\SVN $Date$| (or |\SVN $LastChangedDate$|), we
% define |\SVNDate| and |\SVNTime| to be the current date and
% time.  The argument \param1 will be the name of the keyword
% actually used (i.e., |Date| or |LastChangedDate|), and \param2 will be
% empty since \param1 was not expanded.
% Note that we don't say |\let\SVNDate\today| as we want \package{babel} to
% be able to influence the formatting of |\SVNDate|.
%    \begin{macrocode}
\def\SVN@Date@unexpanded#1#2{%
  \gdef\SVNDate{\today}%
  \global\let\SVNTime\SVNempty
  \global\let\SVNRawDate\SVNempty
}
\let\SVN@LastChangedDate@unexpanded\SVN@Date@unexpanded
%    \end{macrocode}
%  \end{macro}
% \end{macro}
%
% \begin{macro}{\SVN@Date@expanded}
% \begin{macro}{\SVN@LastChangedDate@expanded}
% When we see |\SVN $Date: <date> <time> ... $|,
% we set |\SVNRawDate| to the whole `|<date> <time> ...|' string, and
% put the date and time of check-in into |\SVNDate| and
% |\SVNTime|.
%    \begin{macrocode}
\def\SVN@Date@expanded#1#2{%
  \svn@set\SVNRawDate$#2$%
  \svn@parse@date$#2$%
}
\let\SVN@LastChangedDate@expanded\SVN@Date@expanded
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \begin{macro}{\svn@parse@date}
%  \begin{macro}{\SVNDate}
%  \begin{macro}{\SVNTime}
% |\svn@parse@date| is what actually puts the date of check-in (or
% |\today|) into |\SVNDate|. The idea for this is copied from the
% \package{rcs} package.
%
% We use the |$|'s to remove the leading space and then, inside a group,
% we change the current date and then call |\today|---this way if
% \package{babel} is used, we'll get |\SVNdate| in the correct
% language format.  Since the |\day| commands are not
% expandable but |\today| is, we add a |\def| to give an error
% inside an |\edef| (see also the ``Known Issues'' section).
%    \begin{macrocode}
\def\svn@parse@date$#1-#2-#3 #4:#5:#6 #7${%
  \gdef\SVNDate{%
    \begingroup
      \def\svn@tmp{\PackageError{svn}{\SVNDate should not
      be used in an \protect\edef}{See the svn.sty documentation for a
      work-around.}}%
      \day#3 \month#2 \year#1
      \today
    \endgroup}%
%    \end{macrocode}
% We could add `GMT' to |\SVNTime|. Or not bother.
%    \begin{macrocode}
  \gdef\SVNTime{#4:#5:#6}%
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
% \end{macro}
%
% \begin{macro}{\SVNdate}
% |\SVNdate $Date$| puts the check-in date into the output of |\maketitle|.
%    \begin{macrocode}
\def\SVNdate $#1${\SVN $#1$\date{\SVNDate}}
%    \end{macrocode}
% \end{macro}
%
%
% \Finale
\endinput
