% \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
