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
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
|
% \iffalse meta-comment
%
% Copyright (C) 2016 by Philippe Faist <philippe.faist@bluewin.ch>
% -------------------------------------------------------
%
% 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 2005/12/01 or later.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{phfsvnwatermark.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[2005/12/01]
%<package>\ProvidesPackage{phfsvnwatermark}
%<*package>
[2016/08/15 v1.0 phfsvnwatermark package]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{xcolor}
\usepackage[id=svn-multi,watermark=false]{phfsvnwatermark}
\svnid{$Id$}
\usepackage[preset=xpkgdoc]{phfnote}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
\DocInput{phfsvnwatermark.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{0}
%
% \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 \~}
%
%
% \changes{v1.0}{2016/05/03}{Initial version}
%
% \GetFileInfo{phfsvnwatermark.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment,\def,\gdef,\edef,\xdef,\if,\else,\fi,\ifx}
%
% \title{\phfqitltxPkgTitle{phfsvnwatermark}}
% \author{Philippe Faist\quad\email{philippe.faist@bluewin.ch}}
% \date{\pkgfmtdate\filedate}
% \maketitle
%
% \begin{abstract}
% \pkgname{phfsvnwatermark}---Add a watermark on each page with version control
% information from SVN.
% \end{abstract}
%
% \inlinetoc
%
% \section{Introduction}
%
% This package allows you to add version control information as a gray watermark on each
% page of your document.
%
% The watermark may be placed automatically on each page, or its placement may be
% controlled manually by the user.
%
% It is based on reading SVN keywords from your source file (e.g.\@ |$Id$|, which SVN
% expands upon the following commit to |$Id: file.tex ... $|). The tags are read with
% either the \pkgname{svn} or \pkgname{svn-multi} packages (at your option).
%
% There is also decent support for multiple files, with \pkgname{svn-multi} and
% \pkgname{currfile}. This allows to both display overall document version information as
% well as information for the current file.
%
%
% \section{SVN Identification Methods}
%
% The SVN version of the input file(s) is read with the help of SVN keyword |$Id$|. (The
% \pkgname{svn} package may also read |$Date$| and |$Author$|, I'm not sure any more [TODO: CHECK].)
%
% Don't forget to enable source keyword expansion for your \LaTeX{} source(s). This is
% done with the help of the command:
% \begin{verbatim}
% svn propset svn:keywords "Id Date Author" my-file.tex
% \end{verbatim}
%
% You must specify an identification method with the package option |id=|\meta{method}.
%
% \begin{pkgoptions}
% \item[id=svn] Read the keywords with the \pkgname{svn} package. Keywords are set in the
% file with the command |\SVN $Id$|. (The |$Id$| keyword contains all the relevant
% information and only this one needs to be set.) See below.
% \item[id=gitnotsvn] Read the keywords with the \pkgname{svn} pacakge. However, a script
% is used to fake these tags from what are in fact GIT meta-information. This causes
% |$Id$| not to contain all the information, and the |$Date$| and |$Author$| tags must
% be read and included in the watermark, as well. See below.
% \item[id=svn-multi] Read the keywords with the \pkgname{svn-multi} package. The ID
% information is set with the command |\svnid{$Id$}|. (The |$Id$| keyword contains all
% the relevant information.) See below.
% \item[id=svn-multi-currfile] Read the keywords with the \pkgname{svn-multi} package, with
% \pkgname{currfile} support. Ideal for a document with multiple source files which are
% |\input| into each other. The ID information is set in each file with the command
% |\svnid{$Id$}|. (The |$Id$| keyword contains all the relevant information.) See
% below.
% \end{pkgoptions}
%
% In each case, the relevant SVN package is automatically loaded \pkgname{svn},
% \pkgname{svn-multi} and/or \pkgname{currfile}.
%
%
% \subsection{SVN Keywords read with the \pkgname{svn} package}
%
%
% Probably the most straightforward solution. Just introduce in your \LaTeX{} source
% file, somewhere near the top, the line:
% \begin{verbatim}
% \SVN $Id$
% \end{verbatim}
%
% Don't forget to enable source keyword expansion for this \LaTeX{} file, and next time
% you commit your file to SVN, the |$Id$| tag will be replaced by something like:
% \begin{verbatim}
% \SVN $Id: thesis.tex 1488 2016-05-03 16:19:34Z pfaist $
% \end{verbatim}
% which identifies the file version.
%
%
%
% \subsection{GIT information faked as SVN keywords and read with the \pkgname{svn} package}
%
% \begin{pkgwarning}
% This method is buggy, and keywords won't always get updated. I'm currently seeking a
% better method. Unfortunately all methods for obtaining GIT meta-data require running
% GIT hooks or auxiliary scripts.
%
% To force update the GIT keywords, make sure you file has no local modifications,
% delete the file and run |git checkout |\meta{file}.
% \end{pkgwarning}
%
% The idea is to use the same keyword parsing engine, with the \pkgname{svn} package, but
% to plug in the GIT meta-information instead inside faked svn keyword tags.
%
% In your source file, add the lines
% \begin{verbatim}
% \SVN $Id$
% \SVN $Date$
% \SVN $Author$
% \end{verbatim}
%
% And then, with the additional GIT configuration described below, these keywords will be
% expanded to the hash of the file contents (and not the commit, this may be misleading!),
% the date of the commit and the author.
%
% In order to set up GIT for this, add to the |.gitattribtes| file (create it in the
% repository directory if necessary):
% \begin{verbatim}
% *.tex ident filter=rcs-keyword
% \end{verbatim}
%
% Then copy the following code, and paste it at the end of your |REPO/.git/config| or
% |HOME/.gitconfig|:
% \begin{samepage}
% \begin{verbatim}
% [filter "rcs-keyword"]
% clean = perl -pwe \"s/\\\\\\$(Date|Author)[^\\\\\\$]*\\\\\\$/\\\\\\$\\$1\\\\\\$/\"
% smudge = "echo >&2 'Applying RCS filter rules on '%f'.' && perl -we \
% \"\\$f=%f; use Date::Parse; use POSIX;\
% chomp(\\$author=\\`git log -1 --format=format:%ae -- \\$f\\`);\
% chomp(\\$gitdate=\\`git log -1 --format=format:%aD -- \\$f\\`);\
% \\$date=POSIX::strftime('%Y-%m-%d %H:%M:%S %z (%a, %e %b %Y)',\
% localtime(str2time(\\$gitdate)));\
% print STDERR \\\"formatted date: \\$date\\\\n\\\";\
% while (<>) {\
% s/\\\\\\$Date[^\\\\\\$]*\\\\\\$/'\\$Date: '.\\$date.' \\$'/e;\
% s/\\\\\\$Author[^\\\\\\$]*\\\\\\$/'\\$Author: '.\\$author.' \\$'/e;\
% print \\$_; }\""
% \end{verbatim}
% \end{samepage}
%
% \subsection{SVN Keywords read with the \pkgname{svn-multi} package}
%
% The \pkgname{svn-multi} package is an alternative, more powerful, package for parsing SVN
% keywords.
%
% Add near the top of your files the command
% \begin{verbatim}
% \svnid{$Id$}
% \end{verbatim}
% and make sure keyword expansion is enabled in your source files.
%
%
% \subsection{SVN Keywords read with the \pkgname{svn-multi} package, with \pkgname{currfile} support}
%
% This method is the same as for the |id=svn-multi| method with the \pkgname{svn-multi}
% package, but with added support for multiple files.
%
% Now, the watermark displays \emph{two} lines, with the overall document version
% information, and the version information of the current file.
%
%
%
% \section{Placement of the Watermark}
%
% First, there is a master switch for enabling or disabling the watermark. In either
% case, the relevant SVN-related package is loaded anyway, to allow files to provide their
% meta-information regardless of whether the watermark is displayed or not.
% \begin{pkgoptions}
% \item[watermark=true] Show the watermark with the ID information.
% \item[watermark=false] Do not show the watermark with the ID information. (Note that
% manually placed watermarks are not affected by this option.)
% \end{pkgoptions}
%
%
% \begin{pkgoptions}
% \item[placement=shipout] Place the watermark at the bottom of each page;
% \item[placement=manual] Don't place the watermark anywhere automatically; the user is
% responsible for placing it with a call to |\phfsvnVersionIdTag| wherever they want.
% \end{pkgoptions}
%
% \subsection{Watermark on each page}
%
% With the |placement=shipout| option, the watermark is automatically added on each page.
%
% \DescribeMacro{\phfsvnShipoutWatermarkXposRight}
% \DescribeMacro{\phfsvnShipoutWatermarkYposBaseline} \null\par\vspace*{\baselineskip} The
% macros |\phfsvnShipoutWatermarkXposRight| and |\phfsvnShipoutWatermarkYposBaseline|
% determine the position of the watermark. They are macros which expand to a length, not
% lengths themselves. You may redefine them to adjust the placement of the watermark.
%
% \subsection{Manual placement}
%
% You may also opt to place the watermark manually on the page with the |placement=manual|
% option. Do this if you want the information to appear for example in a header or
% footer.
%
% \DescribeMacro{\phfsvnVersionIdTag}\DescribeMacro{\phfsvnVersionIdTag*} Places the ID
% tag immediately, at the given location. The starred version produces a box of zero
% width.
%
%
%
% \StopEventually{\PrintChangesAndIndex}
%
% \section{Implementation}
%
% Include useful packages.
% \begin{macrocode}
\RequirePackage{kvoptions}
\RequirePackage{calc}
% \end{macrocode}
%
%
% make sure the 'color' or 'xcolor' package is loaded
% \begin{macrocode}
\@ifpackageloaded{xcolor}{}{%
\@ifpackageloaded{color}{}{%
\RequirePackage{xcolor}%
}
}
% \end{macrocode}
%
%
% \subsection{Common Formatting of ID tag}
%
% common exterior formatting for Version ID tag.
%
% \begin{macrocode}
\definecolor{phfsvnversionidcolor}{rgb}{0.6,0.6,0.6}
\def\phfsvnVersionIdTagOuterFont{\normalfont\scriptsize}
\def\phfsvnVersionIdTagInnerFont{\ttfamily}
\def\phfsvn@versionidtag{%
\begingroup%
\color{phfsvnversionidcolor}\phfsvnVersionIdTagOuterFont%
[\,\begingroup\phfsvnVersionIdTagInnerFont%
{\phfsvn@versionidtag@contents}\endgroup\,]%
\endgroup%
}
% \end{macrocode}
%
%
% \begin{macro}{\phfsvnVersionIdTag}
% For manual placement. Starred version does not smash the thing.
% \begin{macrocode}
\newcommand\phfsvnVersionIdTag{%
\@ifstar\phfsvn@smashedsvnversionidtag\phfsvn@versionidtag
}
\def\phfsvn@smashedsvnversionidtag{%
\hspace*{0pt}\smash{\phfsvn@clap{\phfsvn@versionidtag}}
}
% \end{macrocode}
% \end{macro}
%
% Helper macro\footnote{see \url{https://www.tug.org/TUGboat/tb22-4/tb72perlS.pdf}}:
% \begin{macrocode}
\def\phfsvn@clap#1{\hbox to 0pt{\hss#1\hss}}
% \end{macrocode}
%
%
%
% \subsection{Definitions for the different SVN info engines}
%
% \begin{macro}{\phfsvn@versionidtag@contents@svn}
% \begin{macro}{\phfsvn@doincludesvn@svn}
% Definitions for method \phfverb{id=svn}:
% \begin{macrocode}
\def\phfsvn@versionidtag@contents@svn{%
\SVNId%
}
\def\phfsvn@doincludesvn@svn{
\RequirePackage{svn}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\phfsvn@versionidtag@contents@gitnotsvn}
% \begin{macro}{\phfsvn@versionidtag@contents@gitnotsvn}
% Definitions for method \phfverb{id=gitnotsvn}. Use the \pkgname{svn}
% package because the files have fake SVN tags with in fact the GIT
% meta-info
% \begin{macrocode}
\def\phfsvn@versionidtag@contents@gitnotsvn{%
\SVNId\hspace*{1.5em}\SVNDate~\SVNTime\hspace*{1.5em}\SVNAuthor%
}
\def\phfsvn@doincludesvn@gitnotsvn{
\RequirePackage{svn}%
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\phfsvn@versionidtag@contents@svnmulti}
% \begin{macro}{\phfsvn@doinludesvn@svnmulti}
% Definitions for method \phfverb{id=svn-multi}:
% \begin{macrocode}
\def\phfsvn@versionidtag@contents@svnmulti{%
SVN Document Version:\hspace*{1ex}%
\svnmainfilename~r\svnrev~\svndate~\svnauthor%
}
\def\phfsvn@doincludesvn@svnmulti{
\PassOptionsToPackage{filehooks}{svn-multi}
\RequirePackage{svn-multi}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\phfsvn@versionidtag@for@svnmulticurrfile}
% \begin{macro}{\phfsvn@doincludesvn@svnmulticurrfile}
% Definitions for method \phfverb{id=svn-multi-currfile}:
% \begin{macrocode}
\def\phfsvn@svnmulticurrfile@maxwidth{0.8\paperwidth}
\newsavebox\phfsvn@box@upperline
\newsavebox\phfsvn@box@lowerline
\def\phfsvn@svnmulticurrfile@upperline{%
SVN Document Version:\hspace{1.5ex}r\svnrev~\svndate~\svnauthor}%
\def\phfsvn@svnmulticurrfile@lowerline{%
\svnkw{Filename}:\hspace{1.5ex}r\svnfilerev~\svnfiledate~\svnfileauthor}%
\def\phfsvn@versionidtag@for@svnmulticurrfile{%
\begingroup%
\color{phfsvnversionidcolor}%
\phfsvnVersionIdTagOuterFont\phfsvnVersionIdTagInnerFont%
\sbox\phfsvn@box@upperline{\phfsvn@svnmulticurrfile@upperline}%
\sbox\phfsvn@box@lowerline{\phfsvn@svnmulticurrfile@lowerline}%
\begin{minipage}[t]{\minof{\phfsvn@svnmulticurrfile@maxwidth}%
{\maxof{\wd\phfsvn@box@upperline}{\wd\phfsvn@box@lowerline}}}%
\parindent=0pt\relax\parskip=0pt\relax%
\raggedleft%
% \end{macrocode}
% Don't just |\usebox| the saved boxes, because if the filenames are long we want to
% re-layout and allow line breaks:
% \begin{macrocode}
\par\phfsvn@svnmulticurrfile@upperline%
\par\phfsvn@svnmulticurrfile@lowerline%
\end{minipage}%
\endgroup%
}%
\def\phfsvn@doincludesvn@svnmulticurrfile{%
\RequirePackage{currfile}%
\RequirePackage[filehooks]{svn-multi}%
}%
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \subsection{Placement Methods}
%
% \begin{macro}{\phfsvn@doplace@shipout}
% The |shipout| placement method.
% \begin{macrocode}
\def\phfsvn@doplace@shipout{%
\RequirePackage{eso-pic}
\AddToShipoutPicture{%
\setlength{\@tempdimb}{\phfsvnShipoutWatermarkXposRight}%
\setlength{\@tempdimc}{\phfsvnShipoutWatermarkYposBaseline}%
\setlength{\unitlength}{1pt}%
\put(2,\strip@pt\@tempdimc){%
\makebox(\strip@pt\@tempdimb,0)[r]%
{\hfill\phfsvn@versionidtag}}%
}%
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\phfsvnShipoutWatermarkXposRight}
% \begin{macro}{\phfsvnShipoutWatermarkYposBaseline}
% Control the position of the watermark. These are proper macros which expand to a
% length; they are not declared as lengths directly. (This allows to calculate the
% lengths on the spot.)
% \begin{macrocode}
\def\phfsvnShipoutWatermarkXposRight{0.9\paperwidth}
\def\phfsvnShipoutWatermarkYposBaseline{0.05\paperheight}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\phfsvn@doplace@manual}
% There is nothing to do for the |manual| placement, since the info is placed manually
% anyway. This macro is called by the package option treatment.
% \begin{macrocode}
\def\phfsvn@doplace@manual{}
% \end{macrocode}
% \end{macro}
%
%
%
% \subsection{Package Options \& Setup}
%
% \begin{macrocode}
\SetupKeyvalOptions{
family=phfsvn,
prefix=phfsvn@
}
% \end{macrocode}
%
% Setup code for a given ID method:
% \begin{macrocode}
\def\phfsvn@SetupForId#1{%
\ifcsname phfsvn@SetupForId@#1\endcsname%
\csname phfsvn@SetupForId@#1\endcsname%
\else%
\PackageError{phfsvn}{Unknown SvnId method: '#1'}%
\fi
}
\def\phfsvn@doincludesvn{}
\def\phfsvn@SetupForId@svn{
\message{phfsvn: Using SvnId method = svn}
\let\phfsvn@doincludesvn\phfsvn@doincludesvn@svn
\let\phfsvn@versionidtag@contents\phfsvn@versionidtag@contents@svn
}
\def\phfsvn@SetupForId@gitnotsvn{
\message{phfsvn: Using SvnId method = gitnotsvn}
\let\phfsvn@doincludesvn\phfsvn@doincludesvn@gitnotsvn
\let\phfsvn@versionidtag@contents\phfsvn@versionidtag@contents@gitnotsvn
}
\expandafter\def\csname phfsvn@SetupForId@svn-multi\endcsname{
\message{phfsvn: Using SvnId method = svn-multi}
\let\phfsvn@doincludesvn\phfsvn@doincludesvn@svnmulti
\let\phfsvn@versionidtag@contents\phfsvn@versionidtag@contents@svnmulti
}
\expandafter\def\csname phfsvn@SetupForId@svn-multi-currfile\endcsname{
\message{phfsvn: Using SvnId method = svn-multi-currfile}
\let\phfsvn@doincludesvn\phfsvn@doincludesvn@svnmulticurrfile
% redefine whole versionidtag, not only contents:
\let\phfsvn@versionidtag\phfsvn@versionidtag@for@svnmulticurrfile
}
\def\phfsvn@SetupForId@{% no ID method
\PackageWarning{phfsvn}{*** No SvnId method provided, no watermark will be displayed.}
\phfsvn@watermarkfalse
}
% \end{macrocode}
%
%
%
% Setup code for the placement:
% \begin{macrocode}
\def\phfsvn@SetupPlacement#1{%
\ifcsname phfsvn@doplace@#1\endcsname%
\csname phfsvn@doplace@#1\endcsname%
\else%
\PackageError{phfsvn}{Unknown placement method: '#1'}%
\fi
}
% \end{macrocode}
%
% Declare the |keyval| options:
%
% \begin{macrocode}
\DeclareStringOption[]{id}[svn]
\DeclareBoolOption[true]{watermark}
\DeclareStringOption[shipout]{placement}
\DeclareDefaultOption{%
% We provide the standard LaTeX error.
\@unknownoptionerror
}
% \end{macrocode}
%
%
% Process \& execute options:
% \begin{macrocode}
\ProcessKeyvalOptions*
% \end{macrocode}
%
%
% Now, take action according to the given options.
%
% Set up the correct ID method:
% \begin{macrocode}
\phfsvn@SetupForId{\phfsvn@id}
% \end{macrocode}
%
% Always include the relevant SVN package, so all files can have their meta-info tags
% regardless of whether the watermark is displayed or not:
% \begin{macrocode}
\phfsvn@doincludesvn
% \end{macrocode}
%
%
% Finish setting up, set up the watermark if we want it on.
% \begin{macrocode}
\ifphfsvn@watermark
\phfsvn@SetupPlacement{\phfsvn@placement}
\fi
% \end{macrocode}
%
%\Finale
\endinput
|