% \iffalse meta-comment % Copyright (C) 2009 by Martin Scharrer % http://www.scharrer-online.de/latex/ % ----------------------------------------------------------------- % % This work 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. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Martin Scharrer. % % This work consists of the file rcs-multi.dtx and the derived file % rcs-multi.sty. % $Id: rcs-multi.dtx 638 2009-03-23 19:21:36Z martin $ % \fi % \iffalse %<*package|driver|wrapper> \def\filedate$#1: #2 #3 #4-#5-#6 #7 ${% \year#4\month#5\day#6\relax \def\filedate{#4/#5/#6}% \def\filerev{#3}% } \filedate$Id: rcs-multi.dtx 638 2009-03-23 19:21:36Z martin $ \def\fileversion{v0.1} % %<*driver> \ProvidesFile{rcs-multi.dtx} [\filedate\space\fileversion\space RCS Keywords for multi-file LaTeX documents] \documentclass{ltxdoc} \usepackage{rcs-multi} \usepackage{booktabs} \usepackage{ifpdf} \ifpdf % use hypdoc if you have it, hyperref else \IfFileExists{hypdoc.sty} {\usepackage{hypdoc}} {\usepackage{hyperref}} \else \let\url\texttt \fi \usepackage{xspace} \newcommand{\ie}{i.e.\@\xspace} \newcommand{\eg}{e.g.\@\xspace} \iffalse \let\css=\cs \let\op=\cs \let\DescribeOption\DescribeMacro \let\DescribeScript\DescribeOption \else % crossreference of macros in documentation \makeatletter \usepackage{xspace} \@namedef{seen@package@latex}{1} %^^A avoid footnotes for 'latex' \newcommand*{\pkg}[1]{% \href{http://tug.ctan.org/pkg/#1}{\texttt{#1}}% % URL footnote (for print-out) on first appearance: \@ifundefined{seen@package@#1}{% \footnote{CTAN: \url{http://tug.ctan.org/pkg/#1}}% \@namedef{seen@package@#1}{1}% }{}% \xspace } \newcommand*{\rcsmulti}{% \texttt{rcs-multi}\xspace% } % link \cs to macro definitions \let\origmacro\macro \let\origendmacro\endmacro \let\origStopEventually\StopEventually \let\origPrintDescribeMacro\PrintDescribeMacro \usepackage{xcolor} \definecolor{darkred}{rgb}{0.333.0.0,0.0} \hypersetup{colorlinks=true,linkcolor=darkred,urlcolor=darkred} \definecolor{macrodesccolor}{rgb}{0.0,0.0,0.8} \definecolor{macroimplcolor}{rgb}{0.0,0.0,0.4} \definecolor{metacolor}{rgb}{0.0,0.4,0.4} \definecolor{scriptcolor}{rgb}{0.2,0.6,0.2} \definecolor{optioncolor}{rgb}{0.3.0.2,0} \let\macroline\\ \newlength{\macrosep} \setlength{\macrosep}{-3em} \renewcommand{\meta@font@select}{\color{metacolor}\itshape} \newcommand{\macroformat}[1]{\textbf{\ttfamily #1}} \newcommand{\optionformat}[1]{\textbf{\sffamily #1}} \newcommand{\scriptformat}[1]{\textbf{\ttfamily #1}} \newcommand{\macroargformat}[1]{\texttt{#1}} \newcommand{\scriptargformat}[1]{\textbf{#1}} \newcommand{\macrohlinkprefix}{desc} \newcommand{\macrolink}{} \usepackage[T1]{fontenc} \usepackage{lmodern} \def\DescribeMacro{\@ifnextchar*{\DescribeMacroS}{\DescribeMacroN}} \def\DescribeMacroN{% \bigskip\pagebreak[3]\par\noindent\DescribeMacroS*% } \def\DescribeMacroS*#1#2{% \begingroup \g@namedef{href@desc@#1}{}% \immediate\write\@mainaux{% \noexpand\g@namedef{href@desc@#1}{}% }% \@ifundefined{href@impl@#1}% {\let\macrolink\relax}% {\def\macrolink{\hyperlink{impl@#1}}}% \hypersetup{linkcolor=macrodesccolor}% \hspace*{\macrosep}% \raisebox{\baselineskip}[\baselineskip]{\hypertarget{desc@#1}{}}% \macrolink{\macroformat{\textcolor{macrodesccolor}{\textbackslash #1}}}% \noindent\mbox{}\macroargformat{#2}\nopagebreak \macroline*[0.2\baselineskip]% \endgroup \nopagebreak \ignorespaces } \def\DescribeScript{\@ifnextchar*{\DescribeScriptS}{\DescribeScriptN}} \def\DescribeScriptN{% \bigskip\par\pagebreak[2]\noindent\DescribeScriptS*% } \def\DescribeScriptS*#1#2{% \hspace*{\macrosep}% \raisebox{\baselineskip}[\baselineskip]{\hypertarget{script@#1}{}}% \scriptformat{\textcolor{scriptcolor}{#1}}% \noindent\mbox{}\scriptargformat{\ {#2}}\macroline*[0.2\baselineskip]% \nopagebreak } \def\DescribeOption{\@ifnextchar*{\DescribeOptionS}{\DescribeOptionN}} \def\DescribeOptionN{% \bigskip\par\noindent\DescribeOptionS*% } \def\DescribeOptionS*#1{% \hspace*{\macrosep}% \raisebox{\baselineskip}[\baselineskip]{\hypertarget{option@#1}{}}% \optionformat{\textcolor{optioncolor}{#1}}% \noindent\mbox{}\macroline*[0.2\baselineskip]% \nopagebreak } \newcounter{macrolevel} \renewenvironment{macro}[1]{% \addtocounter{macrolevel}{1}% \expandafter\macroX\expandafter{\expandafter\@gobble\string#1}% }{% \addtocounter{macrolevel}{-1}% } \providecommand*{\g@namedef}[1]{% \expandafter\gdef\csname #1\endcsname } \newcommand*{\macroX}[1]{% \ifnum\c@macrolevel<2 \smallskip \fi \par\noindent \g@namedef{href@impl@#1}{}% \immediate\write\@mainaux{% \noexpand\g@namedef{href@impl@#1}{}% }% \@ifundefined{href@desc@#1}% {\let\macrolink\relax}% {\def\macrolink{\hyperlink{desc@#1}}}% \hspace*{\macrosep}% \raisebox{\baselineskip}[\baselineskip]{\hypertarget{impl@#1}{}}% \macrolink{\macroformat{% \textcolor{macroimplcolor}{\textbackslash #1}}}% \\*[\smallskipamount]% \@ifnextchar\begin{\vspace*{-\baselineskip}}{\imacroarg}% } \newcounter{macroargs} \newcounter{nmacroarg} \newcommand*{\imacroarg}[1][0]{% \setcounter{macroargs}{#1}% \setcounter{nmacroarg}{1}% \ifnum\c@macroargs>0 \expandafter\imacroargX \fi } \newcommand*{\aftermacroargs}{% \@ifnextchar\begin {\\*[-2ex]\ignorespaces}% {\\*[\smallskipamount]\ignorespaces}% } \newcommand*{\imacroargX}[1]{% \hspace*{-1em}\texttt{\#\thenmacroarg:} #1\relax \ifnum\c@macroargs>1 \newline \fi \addtocounter{nmacroarg}{1}% \addtocounter{macroargs}{-1}% \ifnum\c@macroargs>0 \expandafter\imacroargX \else \expandafter\aftermacroargs \fi } \def\karg#1{\{\$\textcolor{metacolor}{#1}\$\}} \def\kmarg#1{\{\$\meta{#1}\$\}} \DeclareRobustCommand{\csi}[1]{% \begingroup \hypersetup{linkcolor=macroimplcolor}% \renewcommand{\macrohlinkprefix}{impl}% \@ifundefined{href@impl@#1}% {\let\macrolink\relax}% {\def\macrolink{\hyperlink{impl@#1}}}% \csX{#1}% \endgroup } \DeclareRobustCommand{\csd}[1]{% \begingroup \hypersetup{linkcolor=macrodesccolor}% \renewcommand{\macrohlinkprefix}{macro}% \@ifundefined{href@desc@#1}% {\let\macrolink\relax}% {\def\macrolink{\hyperlink{desc@#1}}}% \csX{#1}% \endgroup } \DeclareRobustCommand{\csX}[1]{% \begingroup \macrolink{\texttt{\textbackslash#1}}% \endgroup } \let\cs\csd \DeclareRobustCommand{\css}[1]{\texttt{\textbackslash#1}} \DeclareRobustCommand{\op}[1]{% \begingroup \hypersetup{linkcolor=optioncolor}% \hyperlink{option@#1}{\textbf{\sffamily #1}}% \endgroup } \DeclareRobustCommand{\scr}[1]{% \begingroup \hypersetup{linkcolor=scriptcolor}% \hyperlink{script@#1}{\scriptformat{#1}}% \endgroup } \def\StopEventually#1{\origStopEventually{#1}% \let\cs\csi } \fi \usepackage{graphicx} \EnableCrossrefs %\DisableCrossrefs \CodelineIndex %\PageIndex \RecordChanges %\OnlyDescription \widowpenalty=500 \clubpenalty=500 \begin{document} \DocInput{rcs-multi.dtx}% \PrintChanges %\clearpage \PrintIndex \end{document} % %<*package> % \fi % % \CheckSum{616} % % {\makeatother % \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{v0.1}{2009/03/23}{Initial version forked from rcs-multi v2.0} % % ^^A \GetFileInfo{rcs-multi.dtx} % % \DoNotIndex{\newcommand,\newenvironment,\AtBeginDocument,\AtEndDocument} % \DoNotIndex{\def,\let,\edef,\xdef,\item,\space,\write,\jobname,\relax,\!} % \DoNotIndex{\closeout,\csname,\DeclareRobustCommand,\else,\empty,\newwrite} % \DoNotIndex{\endcsname,\expandafter,\fi,\Hurl,\hyper@normalise,\@ifnextchar} % \DoNotIndex{\ifnum,\@ifundefined,\ifx,\immediate,\InputIfFileExists,\ } % \DoNotIndex{\newcount,\noexpand,\openout,\PackageWarning,\@percentchar} % \DoNotIndex{\@sanitize,\@makeother,\@iwrcs,\%,\_,\&,\^,\$,\#,\ ,\\,\if@filesw} % \DoNotIndex{\gdef,\begingroup,\endgroup,\catcode} % \DoNotIndex{\^,\ ,\_,\(,\),\$,\&,\#,\@ampersamchar,\AtEndOfPackage} % \DoNotIndex{\@backslashchar,\begin,\bgroup,\chapter,\day} % \DoNotIndex{\DeclareOption,\do,\dospecials,\@dottedtocline,\egroup} % \DoNotIndex{\end,\ExecuteOptions,\filedate,\fileversion,\@for} % \DoNotIndex{\futurelet,\g@addto@macro,\global,\@gobbletwo,\hline} % \DoNotIndex{\hspace,\if@restonecol,\if@twocolumn,\ignorespaces} % \DoNotIndex{\makeatletter,\MakeUppercase,\@mkboth,\month,\@namedef} % \DoNotIndex{\NeedsTeXFormat,\newif,\onecolumn,\orig@fink@prepare} % \DoNotIndex{\orig@fink@restore,\PackageError,\ProcessOptions} % \DoNotIndex{\ProvidesPackage,\renewcommand,\RequirePackage} % \DoNotIndex{\@restonecolfalse,\@restonecoltrue,\section,\strut} % \DoNotIndex{\tableofcontents,\tableofrevisions,\texttt,\today} % \DoNotIndex{\twocolumn,\@undefined,\url,\year} % \DoNotIndex{\textwidth,\the,\string,\raggedright,\providecommand,\small,\toks@} % \DoNotIndex{\medskipamount,\long,\leftskip,\clearpage,\advance,\addtolength} % \DoNotIndex{\DeclareBoolOption,\DeclareStringOption,\DeclareVoidOption} % \DoNotIndex{\ProcessKeyvalOptions,\SetupKeyvalOptions} % \DoNotIndex{\@firstoftwo,\@secondoftwo,\@gobble} % % \title{The \textsf{rcs-multi} package} % \author{Martin Scharrer \\ \url{martin@scharrer-online.de} \\ % \url{http://www.scharrer-online.de/latex/rcs-multi}\\ % CTAN: \url{http://tug.ctan.org/pkg/rcs-multi}} % \date{Version \expandafter\@gobble\fileversion\\[0.5ex]\today} % % \ifpdf % \hypersetup{% % pdfauthor = {Martin Scharrer }, % pdftitle = {The rcs-multi package, \fileversion, r\filerev\ from % \filedate}, % pdfsubject = {Documentation of LaTeX package rcs-multi which allows the % typesetting of RCS keywords in multi-file LaTeX documents}, % pdfkeywords = {rcs-multi, LaTeX, RCS, multiple files, keywords, Version % Control, Id} % }% % \fi % \maketitle % % \section{Introduction} % This package allows to typeset version control (VC) information provided by % RCS\footnote{RCS homepage: \url{http://www.gnu.org/software/rcs/}} keywords % (\eg |$||Id: ... $|) in \LaTeX\ documents which can contain of multiple |.tex| % files included using |\include| or |\input|. It is based on the % \pkg{svn-multi} which macros have been renamed and modified to support RCS. % % This package reads the keywords of all files and provides the VC information % of of the most recent changed file of the document to the user through a set % of macros. This information is written to the auxiliary |.aux| file during the % first \LaTeX\ run and read back at the next which introduces the same delay % known from the table of contents. The standard \LaTeX{} switch |\nofiles| can % be used to suppress the file generation. % % \subsection{Scope of Keywords} % This package provides the RCS keyword data in two different scopes: % document-global and file-local. % % \subsubsection*{Document Global} % The document global macros, like \cs{rcsrev}, return the latest version % control information (keyword data) for the whole multi-file document, \ie the % information of the latest changed file of the document. To collect, sort and % provide this information is the main functionality of this package. % % \subsubsection*{Local to Current File} % There are also file-local macros, \eg \cs{rcsfilerev}, which return the % version control information of the current file, \ie the file they are used % in. It is assumed here that every file using this macros calls first the macro % \cs{rcsid}. See section~\ref{sec:usage:id} for more details about this macro. % Please note that the file-local macros technically actually return the % \emph{last registered} information from the last \cs{rcsid}. % % % \section{Usage} % The version control information are provided by RCS keywords which % first need to be read in by dedicated macros and can then be typeset using % different macros. % % \subsection{Including RCS Keywords}\label{sec:usage:id} % RCS keywords are included using \cs{rcsid}. This macro should be written very % early in each file, \ie in the preamble of the main document soon after % |\documentclass| and |\usepackage{rcs-multi}| and as first in \emph{every} % subfile before an |\chapter| or similar macro. It does not create any output. % See section~\ref{sec:kwaccess} to learn how to typeset the keyword values. % % \DescribeMacro{rcsid}{\karg{Id}} % \DescribeMacro*{rcsid}{\karg{Header}} % The macro is for the |Id| keyword and must be written like shown. A trailing % colon with or without spaces after the keyword name (`|Id|') is also valid but % \textbf{everything else} except a valid RCS string will cause a \TeX{} parse % error. The difference between |Id| and |Header| is that the latter includes % the full URL/path and not only the filename. % % \DescribeMacro{rcs}{\kmarg{keyword}} % This macro let you typeset rcs keywords directly. The dollars will be stripped % and the rest is typeset as normal text. % % \DescribeMacro{rcskwsave}{\kmarg{keyword}} % This macro lets you include and save any keyword you like. The keyword can be % already expanded or not (no value and only ``|:|'' or nothing after the key % name). This macro is also used internally and does not create any output. % Please note that the argument is read verbatim and that there should be no % space between the macro and the argument's left brace. % % % \subsection{Typesetting the Keyword Values}\label{sec:kwaccess} % The following macros can be used to typeset the keyword values anywhere in the % document. Please note that not all \LaTeX{} fonts have all special % characters, \eg `|_|' is not provided in the standard roman font. To proper % typeset file names and URLs containing these letters you can use either % teletype font (|\texttt|) or use |{\urlstyle{rm}\rcsnolinkurl{...}}| which % requires the \pkg{hyperref} package. % % \DescribeMacro{rcsrev}{} % \DescribeMacro*{rcsdate}{} % \DescribeMacro*{rcsauthor}{} % These macros hold the keyword values of the whole document, \ie of the most % recent revision. They can be used everywhere in every file of the \LaTeX{} % document, after |\usepackage{rcs-multi}| of course. Please see % section~\ref{sec:date} how to typeset parts of the date. % % \DescribeMacro{rcsfilerev}{} % \DescribeMacro*{rcsfiledate}{} % \DescribeMacro*{rcsfileauthor}{} % These macros hold the keyword values of the current \LaTeX{} file, but only if % it contains a \cs{rcsid} or \cs{rcsidlong} macro. Otherwise the macros hold % either zero values or the values of the last file dependent on whether an % option is enabled which enabled the \pkg{fink} package. Please see % section~\ref{sec:date} how to typeset parts of the date. See \cs{rcskw} below % for all other keywords. % % \DescribeMacro{rcsmainfilename}{} % The macro \cs{rcsmainfilename} hold the filename of the main \LaTeX{file}. % It can be used to typeset this information anywhere in the document which % might be more descriptive as the name of the current file (which can be % typeset with \cs{rcskw}|{HeadURL}| or \cs{rcskw}|{Filename}| after \cs{rcsid} % or \cs{rcsidlong}, respectively). ^^A TODO: Change to correct names! % % \DescribeMacro{rcssetmainfile}{} % This will declare the current file as the main LaTeX file by defining the % above macros. It will automatically be called at the end of the preamble so % the user normally doesn't have to use it by him- or herself as long it isn't % needed in the preamble.\par Please note that this macro changes the definition % of \cs{rcsmainfilename} directly without going over the auxiliary file. % Calling it in several files will make this two macros inconsistent. % % \DescribeMacro{rcskw}{\marg{keyword name}} % All keywords saved with \cs{rcsid} or \cs{rcskwsave} can be typeset by this % macro which is a holdover from a very early version of this % package when multiple files where not supported. It takes one argument which % must be a RCS keyword name. It then returns the current value of this % keyword or nothing (|\relax|) when the keyword was not set yet. % Examples:\\ % \indent\indent |\textsl{Revision: \rcskw{Revision}}|\\ % \indent\indent |URL: \url{\rcskw{HeadURL}}|\\ ^^A TODO: Change name! % In the second example |\url| (\pkg{hyperref} package) is used to add a hyperlink % and to avoid problems with underscores (|_|) inside the URL. \rcsmulti is % also providing a macro \cs{rcsnolinkurl} which works like |\url| but doesn't % adds an hyperlink. See the description of this macro for more details. % % If the given keyword doesn't exists a package warning is given to allow % spelling errors to be tracked down. This doesn't work well when \cs{rcskw} is % used inside |\url|. In this case the warning code will be typeset(!) verbatim % into the document by |\url|. % % \DescribeMacro{rcskwdef}{\marg{keyword name}\marg{value}} % This macro is used to define the keyword values. This is normally only called % internally but could be used by the user to override single keywords. The % values can then be typeset by \cs{rcskw}. Note that this macro has no % influence on the calculation of the latest revision. % % \subsection{Accessing Date Values}\label{sec:date} % \begin{tabular}{@{}l@{\hspace{-2\macrosep}}ll@{}}\\ % \DescribeMacro*{rcsyear}{}& % \DescribeMacro*{rcsfileyear}{}\\ % \DescribeMacro*{rcsmonth}{}& % \DescribeMacro*{rcsfilemonth}{}\\ % \DescribeMacro*{rcsday}{}& % \DescribeMacro*{rcsfileday}{}\\ % \DescribeMacro*{rcshour}{}& % \DescribeMacro*{rcsfilehour}{}\\ % \DescribeMacro*{rcsminute}{}& % \DescribeMacro*{rcsfileminute}{}\\ % \DescribeMacro*{rcssecond}{}& % \DescribeMacro*{rcsfilesecond}{}\\ % \end{tabular} % \\*[\medskipamount] % Whenever the date information is read, \ie by % \cs{rcskwsave}|{Date}| or \cs{rcsid}, the following macros are set to the % appropriate date parts for the % current file (the |\rcsfile...| versions) and for the whole document. % % % \DescribeMacro{rcstime}{} % \DescribeMacro*{rcsfiletime}{} % This macros return the time part of the date only and simply return the % corresponding hour, minute and second macros with a colon as separator. % % \DescribeMacro{rcspdfdate}{} % Returns the last changed date of the whole document in a format needed for % |\pdfinfo|. Can be used like this:\\ % \hbox{}\hfill|\pdfinfo{ /CreationDate (D:\rcspdfdate) }|\hfill\hbox{}\\ % to set the PDF creation date to the last changed date if you use |pdflatex| to % compile your \LaTeX{} document. % % \DescribeMacro{rcstoday}{} % \DescribeMacro*{rcsfiletoday}{} % These macros typeset the document-global or current-file, respectively, using % the format of |\today| which depends on the used language. % To adjust the language of your document use the \pkg{babel} package. % % \subsection{Using Full Author Names} % If you like to have the full author\footnote{This means RCS authors, % \eg the persons who commit changes into the rcs repository.} names, not only % the usernames, in your document you can use the following macros. First you % have to register all authors of the document with \cs{rcsRegisterAuthor} and % then you can write \eg |\rcsFullAuthor{\rcsauthor}| or % |\rcsFullAuthor{\rcsfileauthor}|. % % \DescribeMacro{rcsRegisterAuthor}{\marg{author}\marg{full name}} % This macro registers \meta{full name} as full name for \meta{author} (a % RCS username) for later use with \cs{rcsFullAuthor}. % % \DescribeMacro{rcsFullAuthor}{\marg{author name or macro}} % \DescribeMacro*{rcsFullAuthor*}{\marg{author name or macro}} % Takes the username as argument and returns the full name if it was registered % first with \cs{rcsRegisterAuthor}, otherwise it returns the given username. % The star version returns the username in parentheses after the full name. % This is normally used in one of the following forms:\\ % \hspace*{3em}\cs{rcsFullAuthor}|{|\cs{rcsauthor}|}|\\ % \hspace*{3em}\cs{rcsFullAuthor}|{|\cs{rcsfileauthor}|}|\\ % % \subsection{Using Full Revision Names} % Like the author's also revision names/tags can be registered and used later. % These macros were implemented on user request and have the drawback that you % have to guess the next revision number of your document in order to get % correct results when you like to tag the to-be-checked-in revision. Please % note that this has nothing to do with the normal tagging. % % \DescribeMacro{rcsRegisterRevision}{\marg{revision number}\marg{tag name}} % This registers \meta{tag name} as tag name for \meta{revision number} for % later use with \cs{rcsFullRevision}. % % \DescribeMacro{rcsFullRevision}{\marg{revision number or macro}} % \DescribeMacro*{rcsFullRevision*}{\marg{revision number or macro}} % Takes a revision number coming from a macro like \cs{rcsrev}, \cs{rcsfilerev} % or a number as argument and returns the full name if it was registered first % with \cs{rcsRegisterRevision}, otherwise it returns ``Revision \meta{revision % number}''. The star version returns also the revision number leaded by `r' in % parentheses after the tag name, \eg |Name (1.2)|. % % \subsection{Verbatim URLs with and without Hyperlinks} % \vspace{-\baselineskip} % \DescribeMacro{rcsnolinkurl}{\marg{macro with returns special text}} % This macro allows you to write |\rcsnolinkurl{\rcskw{HeadURL}}| and get the % Head URL typeset verbatim. However |\url{|\cs{rcskw}|{HeadURL}}| % (\pkg{hyperref} package) gives you the same result with a hyperlink. Both % macros require the \pkg{hyperref} package which is not automatically loaded by % \rcsmulti. Please load it manually when you like to use \cs{rcsnolinkurl}. % % Please note that you can't use \pkg{hyperref}'s |\nolinkurl| because it won't % expand \cs{rcskw}. % % \StopEventually{} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Implementation} % \subsection{Package Header} % \begin{macrocode} \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{rcs-multi} [\filedate\space\fileversion\space RCS Keywords for multi-file LaTeX documents] % \end{macrocode} % \subsection{General Internal Macros} % Some internal used macro which don't fit in any other section. % % \begin{macro}{\rcs@ifempty}[1]{string} % Tests if the given argument is empty. If so the first of the next two token % will be expanded, the second one otherwise. % \begin{macrocode} \def\rcs@ifempty#1{% \begingroup \edef\rcs@temp{#1}% \ifx\rcs@temp\empty \endgroup \expandafter \@firstoftwo \else \endgroup \expandafter \@secondoftwo \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@ifequal}[2]{string a}{string b} % Tests if the given arguments are identical, \eg same strings. If so the first % of the next two token will be expanded, the second one otherwise. % \begin{macrocode} \def\rcs@ifequal#1#2{% \begingroup \edef\rcs@stringa{#1}% \edef\rcs@stringb{#2}% \ifx\rcs@stringa\rcs@stringb \endgroup \expandafter \@firstoftwo \else \endgroup \expandafter \@secondoftwo \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@ifvalidrev}[1]{macro name} % Checks if the given macro (by name) is a valid revision, \ie defined and % greater than zero. % \begin{macrocode} \def\rcs@ifvalidrev#1{% \begingroup \@ifundefined{#1}% {\def\rcs@temp{-1}}% {\expandafter\edef \expandafter\rcs@temp\expandafter{\csname #1\endcsname}}% \ifnum\rcs@temp>-1\relax \endgroup \expandafter \@firstoftwo \else \endgroup \expandafter \@secondoftwo \fi } % \end{macrocode} % \end{macro} % \subsection{Definition of init values} % \begin{macrocode} % Init values \def\rcsrev{0.0} \def\@rcs@rev{0.0} \def\rcsdate{} \def\@rcs@date{} \def\rcsauthor{} \def\@rcs@author{} \def\rcsyear{0000} \def\@rcs@year{0000} \def\rcsmonth{00} \def\@rcs@month{00} \def\rcsday{00} \def\@rcs@day{00} \def\rcshour{00} \def\@rcs@hour{00} \def\rcsminute{00} \def\@rcs@minute{00} \def\rcssecond{00} \def\@rcs@second{00} \def\rcsname{} \def\@rcs@name{} \def\rcsurl{} \def\@rcs@url{} \def\rcsmainfilename{} \def\rcsmainurl{\rcsmainfilename} \def\rcs@temp{} \def\rcs@lastkw{} \def\rcsfilerev{0.0} \def\rcsfiledate{} \def\rcsfileauthor{} \def\rcsfileyear{0000} \def\rcsfilemonth{00} \def\rcsfileday{00} \def\rcsfilehour{00} \def\rcsfileminute{00} \def\rcsfilesecond{00} \def\rcsfileurl{} \def\rcsfilename{} % \end{macrocode} % % \subsection{Time and \textit{Today} macros} % % \begin{macro}{\rcstime} % \begin{macro}{\rcsfiletime} % This macros simple use the hour, minute and second macros. % \begin{macrocode} \def\rcstime{\rcshour:\rcsminute:\rcssecond} \def\rcsfiletime{\rcsfilehour:\rcsfileminute:\rcsfilesecond} % \end{macrocode} % \end{macro} % \end{macro} % These macros use the |\today| macro to typeset the current date using the % local language settings. Thanks and credit goes to Manuel P\'egouri\'e-Gonnard % for suggesting this feature and for providing some code. % \begin{macro}{\rcstoday} % \begin{macrocode} \newcommand*{\rcstoday}{% \begingroup \year\rcsyear \month\rcsmonth \day\rcsday \relax \today \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\rcsfiletoday} % \begin{macrocode} \newcommand*{\rcsfiletoday}{% \begingroup \year\rcsfileyear \month\rcsfilemonth \day\rcsfileday \relax \today \endgroup } % \end{macrocode} % \end{macro} % \subsection{Id macro} % \begin{macro}{\rcsid} % Calls \cs{rcskwsave} with |\@rcsidswtrue| so that the Id keyword will be % parsed at the end of \cs{rcskwsave}. % \begin{macrocode} \newcommand*{\rcsid}{% \@rcsidswtrue \rcskwsave } \newif\if@rcsidsw \@rcsidswfalse % \end{macrocode} % \end{macro} % % \begin{macro}{\rcs@scanId}[6]{file name}{revision}{date (YYYY-MM-DD)}{time % (HH:MM:SS)}{author (username)}{rest} % Scans rcs Id (after it got parsed by \cs{rcskwsave}). Awaits only Id value % without leading `|Id:|' and a trailing |\relax| as end marker. It calls % \cs{@rcs@scandate} to extract the date information and \cs{@rcs@updateid} to % update global Id values and also sets the appropriate keywords. % \begin{macrocode} \def\rcs@scanId#1,v #2 #3 #4 #5 #6\relax{% \@rcs@scandate{#3 #4}% \@rcs@updateid{#2}{#3 #4}{#5}{#1}% \rcskwdef{Filename}{#1}% \rcskwdef{Date}{#3 #4}% \rcskwdef{Revision}{#2}% \rcskwdef{Author}{#5}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\@rcs@updateid}[4]{rev}{date}{author (username)}{url} % We first define the expanded arguments to variables for the user. The % expansion is needed because the arguments content is mostly generic like % |\rcs@value| which can change very soon after this macro. % \begin{macrocode} \def\@rcs@updateid#1#2#3#4{% \xdef\rcsfilerev{#1}% \xdef\rcsfiledate{#2}% \xdef\rcsfileauthor{#3}% \xdef\rcsfileurl{#4}% \rcs@getfilename\rcsfileurl % \end{macrocode} % Then we check if the revision is non-empty (not yet expanded by RCS?) % and larger then the current maximum value |\@rcs@rev|. If yes we save all % value to save them in the .aux-file later. % \begin{macrocode} \ifx\rcsfiledate\empty\else \begingroup \edef\@tempa{\@rcs@year\@rcs@month\@rcs@day} \edef\@tempb{\rcsfileyear\rcsfilemonth\rcsfileday} \ifnum\@tempa<\@tempb \rcs@update \else\ifnum\@tempa=\@tempb \edef\@tempa{\@rcs@hour\@rcs@minute\@rcs@second} \edef\@tempb{\rcsfilehour\rcsfileminute\rcsfilesecond} \ifnum\@tempa<\@tempb \rcs@update \fi \fi\fi \endgroup \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\rcs@updateid} % Updates the max-hold macros with the values of the current file VC % information. % \begin{macrocode} \def\rcs@update{% \xdef\@rcs@rev{\rcsfilerev}% \xdef\@rcs@date{\rcsfiledate}% \xdef\@rcs@author{\rcsfileauthor}% \xdef\@rcs@year{\rcsfileyear}% \xdef\@rcs@month{\rcsfilemonth}% \xdef\@rcs@day{\rcsfileday}% \xdef\@rcs@hour{\rcsfilehour}% \xdef\@rcs@minute{\rcsfileminute}% \xdef\@rcs@second{\rcsfilesecond}% \xdef\@rcs@name{\rcsfilename}% \xdef\@rcs@url{\rcsfileurl}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\rcs@catcodes} % Changes all \TeX-special character to category ``other''. The newline aka % return is changed to category ``ignore'' so line breaks are not taken as part % of the verbatim arguments. % \begin{macrocode} \def\rcs@catcodes{% \let\do\@makeother \dospecials \catcode`\^^M9 \catcode`\ 10 \catcode`\{1 \catcode`\}2 } % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@gdefverb}[1]{macro} % \begin{macrocode} \def\rcs@gdefverb#1{% \begingroup \def\rcs@temp{#1}% \begingroup \rcs@catcodes \rcs@gdefverb@ } % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@defverb@}[1]{verbatim stuff} % \begin{macrocode} \def\rcs@gdefverb@#1{% \endgroup \expandafter\gdef\rcs@temp{#1}% \endgroup } % \end{macrocode} % \end{macro} % \subsection{Keyword Macros} % \begin{macro}{\rcskwsave} % Enabled verbatim mode and uses a sub macro to read the arguments afterwards. % \begin{macrocode} \def\rcskwsave{% \begingroup \rcs@catcodes \rcskwsave@readargs } % \end{macrocode} % \end{macro} % \begin{macro}{\rcskwsave@readargs}[1]{\$kw: value\$} % Reads full argument, calls parse submacro and ends catcode changes. % If \cs{rcskwsave} was called by \cs{rcsid} scans the id keyword by calling the % scan macro. % \begin{macrocode} \gdef\rcskwsave@readargs#1{% \rcskwsave@read#1\relax \endgroup \if@rcsidsw \rcs@ifequal{\rcs@lastkw}{Id}% {\ifx\rcskwId\empty\else \expandafter \rcs@scanId\rcskwId\relax \@rcsidswfalse \fi}{% \rcs@ifequal{\rcs@lastkw}{Header}% {\ifx\rcskwHeader\empty\else \expandafter \rcs@scanId\rcskwHeader\relax \@rcsidswfalse \fi}{}% }% \fi \ignorespaces } % \end{macrocode} % \end{macro} % \begin{macro}{\rcskwsave@read}[1]{keyword line without surrounding \$ \$} % Reads the full keyword and strips the dollars. % \begin{macrocode} \begingroup \catcode`\$=12 \gdef\rcskwsave@read $#1$\relax{% \rcs@checkcolon#1:\relax } \endgroup % \end{macrocode} % \end{macro} % \begin{macro}{\rcskwsave@parse}[2]{key}{value} % Parse the keyword and save it away. % \begin{macrocode} \begingroup \catcode`\$=11 \gdef\rcskwsave@parse$#1:#2${% \expandafter\xdef\csname rcskw#1\endcsname{#2}% }% \endgroup % \end{macrocode} % \end{macro} % \begin{macro}{\rcskwdef}[2]{key}{value} % \begin{macrocode} \newcommand{\rcskwdef}[2]{% \gdef\rcs@lastkw{#1}% \expandafter\xdef\csname rcskw#1\endcsname{#2}% } % \end{macrocode} % Example: |\rcskwdef{Rev}{2.3}| will define |\rcskwRev| as `|2.3|'. % \end{macro} % We define default values for normal keywords. Keyword |Filename| is the name % given by |Id| and not a real keyword. % \begin{macrocode} ^^A TODO: check if needed \rcskwdef{Rev}{0.0} \rcskwdef{Date}{} \rcskwdef{Author}{} \rcskwdef{Filename}{} \rcskwdef{HeadURL}{} % \end{macrocode} % \begin{macro}{\rcskw}[1]{keyword name} % Macro to get keyword value. Just calls \cs{rcskw}\meta{ARGUMENT} where % the argument interpreted as text. So \eg |\rcskw{Date}| is the same as % |rcskwDate| but this could be changed later so always use this interface % to get the keyword values. % % \changes{v1.2}{2007/06/22}{Added warning when a wrong, maybe % misspelled, keyword is given.} % \begin{macrocode} \newcommand{\rcskw}[1]{% \@ifundefined{rcskw#1}% {\PackageWarning{rcs-multi}{RCS keyword '#1' not defined (typo?)}}% {\csname rcskw#1\endcsname}% }% % \end{macrocode} % \end{macro} % % \subsection{Keyword check and strip macros} % The following macros are used to test whether the given keywords are fully % expanded or not. % RCS supports unexpanded keywords as input with or without colon and % with or without trailing space(s), \ie a:~|$KW$|, b:~|$KW:$| or c:~|$KW: $|. % To avoid \LaTeX{} syntax errors in this pre-commit state the keyword is % checked by the following macros. Unexpanded keywords result in an empty value. % Also leading and trailing spaces are removed. % % \begin{macro}{\rcs@checkcolon}[2]{key}{potential value, might be empty} % Checks if the keyword contains a colon. It is called by \cs{rcskwsave@read} % with a trailing |:\relax| so that \#2 will be empty if there is no earlier % colon or will hold the value with this trailing colon otherwise. % The first case means that the keyword is unexpanded without colon (case a) % which leads to an empty value. In the second case \cs{rcs@stripcolon} is % called to strip the colon and surrounding spaces. The final value is % returned by |\rcs@value|. % \begin{macrocode} \def\rcs@checkcolon#1:#2\relax{% \rcs@ifempty{#2}% {\rcskwdef{#1}{}}% {\rcs@stripcolon#2\relax\rcskwdef{#1}{\rcs@value}}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@stripcolon}[1]{potential value} % Strips the previous added colon (for \cs{rcs@checkcolon}). % The remaining argument is checked if it's empty (case b) or only a space % (case c). Otherwise the keyword is expanded and \cs{rcs@stripspace} is % called to strip the spaces. % \begin{macrocode} \def\rcs@stripcolon#1:\relax{% \rcs@ifempty{#1}% {\gdef\rcs@value{}}% {\rcs@ifequal{#1}{ }% {\gdef\rcs@value{}}% {\rcs@stripspace#1\relax\relax}% }% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@stripspace}[2]{first character}{rest of string} % Strips leading space if present and calls \cs{rcs@striptrailingspace} to % strip the trailing space. % \begin{macrocode} \def\rcs@stripspace#1#2\relax{% \rcs@ifequal{#1}{ }% {\gdef\rcs@value{#2}}% {\rcs@striptrailingspace#1#2\relax}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@striptrailingspace}[1]{string} % Strips trailing space using the macros parameter text. Must be called with % |\relax| as end marker. % \begin{macrocode} \def\rcs@striptrailingspace#1 \relax{% \gdef\rcs@value{#1}% } % \end{macrocode} % \end{macro} % \subsection{Date Macros} % \begin{macro}{\@rcs@scandate}[1]{date} % Scans data information in Id keyword and saves them in macros. % \begin{macrocode} \def\@rcs@scandate#1{\@rcs@scandate@#1\empty\relax} \def\@rcs@scandate@#1/#2/#3 #4:#5:#6#7#8\relax{% \gdef\rcsfileyear{#1}% \gdef\rcsfilemonth{#2}% \gdef\rcsfileday{#3}% \gdef\rcsfilehour{#4}% \gdef\rcsfileminute{#5}% \gdef\rcsfilesecond{#6#7}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcspdfdate} % Returns date in a format needed for |\pdfinfo|. % \begin{macrocode} \def\rcspdfdate{% \rcsyear\rcsmonth\rcsday \rcshour\rcsminute\rcssecond00'00'% } % \end{macrocode} % \end{macro} % \subsection{Mainfile Makros} % \begin{macro}{\rcssetmainfile} % Saves the current filename and URL to macros. % Will be called automatically in the preamble. % \changes{v1.2}{2007/06/22}{New macro} % \begin{macrocode} \newcommand{\rcssetmainfile}{% \xdef\rcsmainfilename{\rcsfilename}% \xdef\rcsmainfileurl{\rcsfileurl}% } \AtBeginDocument{\rcssetmainfile} % \end{macrocode} % \end{macro} % \subsection{Register and FullName Macros} % \begin{macro}{\rcsRegisterAuthor}[2]{author username}{Full Name} % Saves the author's name by defining |rcs@author@|\meta{username} to it. % \begin{macrocode} \newcommand{\rcsRegisterAuthor}[2]{% \expandafter\def\csname rcs@author@#1\endcsname{#2}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcsFullAuthor} % \begin{macro}{\rcsFullAuthor*} % We test if the starred or the normal version is used and call the % appropriate submacro |rcsFullAuthor@star| or |rcsFullAuthor@normal|. % \changes{v1.2}{2007/06/22}{Macro now returns the username if the full name % was not registered.} % \begin{macrocode} \newcommand{\rcsFullAuthor}{% \@ifnextchar{*}% {\rcsFullAuthor@star}% {\rcsFullAuthor@normal}% }% % \end{macrocode} % \end{macro} % \end{macro} % \begin{macro}{\rcsFullAuthor@star}[1]{username} % Both submacros are calling |rcsFullAuthor@| but with different arguments. % The star macro also removes the star of course. % \begin{macrocode} \def\rcsFullAuthor@star*#1{% \edef\rcs@temp{#1}% \rcsFullAuthor@{\rcs@temp}{~(\rcs@temp)}% }% % \end{macrocode} % \end{macro} % \begin{macro}{\rcsFullAuthor@normal}[1]{username} % \begin{macrocode} \def\rcsFullAuthor@normal#1{% \edef\rcs@temp{#1}% \rcsFullAuthor@{\rcs@temp}{}% }% % \end{macrocode} % \end{macro} % \begin{macro}{\rcsFullAuthor@}[2]{username}{previous defined trailing string} % |rcsFullAuthor@| now sets the author's full name. Note that |#2| is empty % when the normal version is called. % \begin{macrocode} \def\rcsFullAuthor@#1#2{% \@ifundefined{rcs@author@#1}% {#1}% {\csname rcs@author@#1\endcsname #2}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcsRegisterRevision}[2]{revision number}{tag name} % Saves the revision's name or tag by defining % |rcs@revision@|\meta{revisionnumber} to it. % \changes{v1.2}{2007/06/22}{New macro} % \begin{macrocode} \newcommand{\rcsRegisterRevision}[2]{% \expandafter\def\csname rcs@revision@#1\endcsname{#2}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcsFullRevision} % \begin{macro}{\rcsFullRevision*} % We test if the starred or the normal version is used and call the % appropriate submacro |rcsFullRevision@star| or |rcsFullRevision@normal|. % \changes{v1.2}{2007/06/22}{New macro} % \begin{macrocode} \newcommand{\rcsFullRevision}{% \@ifnextchar{*}% {\rcsFullRevision@star}% {\rcsFullRevision@normal}% } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\rcsFullRevision@star}[1]{revision number} % Both submacros are calling |rcsFullRevision@| but with different arguments. % The star macro also removes the star of course. % \begin{macrocode} \def\rcsFullRevision@star*#1{% \edef\rcs@temp{#1}% \rcsFullRevision@{\rcs@temp}{~(r\rcs@temp)}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcsFullRevision@normal}[1]{revision number} % \begin{macrocode} \def\rcsFullRevision@normal#1{% \edef\rcs@temp{#1}% \rcsFullRevision@{\rcs@temp}{}% } % \end{macrocode} % \end{macro} % \begin{macro}{\rcsFullRevision@}[2]{revision number}{previous defined trailing % string} % |rcsFullRevision@| now sets the revision name. Note that |#2| is empty % when the normal version is called. % \begin{macrocode} \def\rcsFullRevision@#1#2{% \@ifundefined{rcs@revision@#1}% {Revision #1}% {\csname rcs@revision@#1\endcsname #2}% } % \end{macrocode} % \end{macro} % \subsection{Other macros} % This section contains macros which don't fit in any other section. % % \begin{macro}{\rcs} % Strips the |$ $| around the keyword. A space must be before the final dollar. % \begin{macrocode} \providecommand{\rcs}[1]{\@revs#1} \def\@rcs$#1 ${#1} % \end{macrocode} % \end{macro} % \begin{macro}{\rcsnolinkurl}[1]{URL} % This code is taken from the \pkg{hyperref} package and is the definition of % |\url| just without the part which creates the actual hyperlink. This needs % of course the \pkg{hyperref} package. A warning is given if it isn't loaded. % \changes{v1.2}{2007/06/22}{New macro} % \begin{macrocode} %% Adapted from the \url macro of the `hyperref` package. \DeclareRobustCommand*{\rcsnolinkurl}{% \@ifundefined{hyper@normalise}% {\PackageWarning{rcs-multi}{Package hyperref is needed for \noexpand \rcsnolinkurl.}}% {\hyper@normalise\rcsnolinkurl@}% }% \def\rcsnolinkurl@#1{\Hurl{#1}}% % \end{macrocode} % \end{macro} % \begin{macro}{\rcs@getfilename}[1]{URL} % This macro expands the content using the temporary macro and sets it in front % of the \csi{rcs@getfilename} sub-macro together with |/{}| to make sure the % macro does not break at values without directories. A |\relax| is used as % end marker. % \begin{macrocode} \def\rcs@getfilename#1{% \begingroup \edef\rcs@temp{#1}% \expandafter\@rcs@getfilename\rcs@temp/{}\relax }% % \end{macrocode} % \end{macro} % \begin{macro}{\@rcs@getfilename}[2]{URL part before first slash}{URL part after % first slash} % Splits the content at the first slash (|/|) and checks if the remainder is % empty. If so the end marker got reached and the part before the slash is the % filename which is returned. Otherwise the macro recursively calls itself to % split the remainder. % \begin{macrocode} \def\@rcs@getfilename#1/#2\relax{% \rcs@ifempty{#2}% {\endgroup\gdef\rcsfilename{#1}}% {\@rcs@getfilename#2\relax}% }% % \end{macrocode} % \end{macro} % \subsection{Write to Auxiliary file} % % \begin{macro}{\rcs@writeaux} % This macro writes the |.aux| auxiliary file and is called from a % |\AtEndDocument| macro later on. % \begin{macrocode} \def\rcs@writeaux{% \immediate\write\@mainaux{^^J% \noexpand\gdef\noexpand\rcsrev{\@rcs@rev}^^J% \noexpand\gdef\noexpand\rcsdate{\@rcs@date}^^J% \noexpand\gdef\noexpand\rcsauthor{\@rcs@author}^^J% \noexpand\gdef\noexpand\rcsyear{\@rcs@year}^^J% \noexpand\gdef\noexpand\rcsmonth{\@rcs@month}^^J% \noexpand\gdef\noexpand\rcsday{\@rcs@day}^^J% \noexpand\gdef\noexpand\rcshour{\@rcs@hour}^^J% \noexpand\gdef\noexpand\rcsminute{\@rcs@minute}^^J% \noexpand\gdef\noexpand\rcssecond{\@rcs@second}^^J% \noexpand\rcs@gdefverb\noexpand\rcsname{\@rcs@name}^^J% \noexpand\rcs@gdefverb\noexpand\rcsurl{\@rcs@url}^^J% }% } % \end{macrocode} % \end{macro} % At the end of document the values are written to the auxiliary file. % \begin{macrocode} \AtEndDocument{% \if@filesw \ifx\@rcs@date\empty\else \rcs@writeaux \fi \fi } % \end{macrocode} % % \Finale \endinput