1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
|
% \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
|