% \iffalse meta-comment % $Id: svn.dtx 43 2007-09-25 19:20:04Z repos $ % Copyright (C) 2003-7 by Richard Lewis % % 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 . % % 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 % % %<*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} % % \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: $|, and no % |\SVN@KeyWord@expanded| command exists, we use % |\SVN@generic@expanded{KeyWord}{}| % to define |\SVNKeyWord| to be ||. % \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: