% \iffalse meta-comment % % Copyright (C) 2016 by Philippe Faist % ------------------------------------------------------- % % 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} % %\NeedsTeXFormat{LaTeX2e}[2005/12/01] %\ProvidesPackage{phfsvnwatermark} %<*package> [2016/08/15 v1.0 phfsvnwatermark 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} % % \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