% $StyleId: rcs.doc,v 2.9 1995/08/02 12:09:07 schrod Exp $ %---------------------------------------------------------------------- % Written by Joachim Schrod . % Copyright conditions see below. % % LaTeX package rcs % to use RCS tag values in one's document, and typeset revision logs % % [LaTeX in MAKEPROG] % (history at end) % If you have received this style file without the user manual (in the % file rcs-user.tex or the respective DVI file), it's incomplete and % near to useless. If it was given to you as something that you shall % use as an author -- complain bitterly to your provider. You need the % documentation and you have a right on it! (Below you can find info % where to get the reference version.) %%%% %%%% %%%% These TeX macros were documented with the documentation system %%%% MAKEPROG and automatically converted to the current form. %%%% If you have MAKEPROG available you may transform it back to %%%% the original input: Remove every occurence of three percents %%%% and one optional blank from the beginning of a line and remove %%%% every line which starts with four percents. The following lex %%%% program will do this: %%%% %%%% %% %%%% %%%% ^%%%\ ? ; %%%% ^%%%%.*\n ; %%%% %%%% If you just want to print the documentation you may fetch %%%% the archive print-makeprog.tar.Z from ftp.th-darmstadt.de (directory %%%% pub/tex/latex). It contains *all* used styles -- but beware, they %%%% may not be in a documented form... %%%% %%%% %%% \documentclass{progltx} %%% \usepackage{rcs-doc} %%% \usepackage{alltt} %%% \usepackage{fullpage} %%% \RCS $StyleDate: 1995/08/02 12:09:07 $ %%% \begin{document} %%% \title{The \texttt{rcs} Package\\ %%% {\large (Implementation)}% %%% } %%% \author{% % LaTeX does not discard unnecessary glue... %%% Joachim Schrod% %%% \thanks{% %%% \protect\raggedright %%% TU~Darmstadt, Computer Science Department, WG Systems Programming, %%% Alexanderstr.~10, D-64283~Darmstadt, Germany. %%% Email: \texttt{schrod@iti.informatik.th-darmstadt.de}% %%% }% %%% } %%% \date{% %%% Revision \RCSStyleRevision\\ %%% (as of \RCSStyleDate)% %%% } %%% \maketitle %%% % ------------------------------------------------------------ %%% % %%% % subdocument: The user interface of rcs.sty %%% % %%% \input{rcs-user} %%% % %%% % ------------------------------------------------------------ %%% % %%% % subdocument: The internal interface %%% % %%% \input{rcs-conf} %%% % %%% % ------------------------------------------------------------ %%% \chap Implementation. %%% This module reserves the namespace |rcs|. %%% \beginprog \ifx \rcs@loaded\undefined \def\rcs@loaded{$StyleRevision: 2.9 $} \else \PackageWarningNoLine{rcs}% {Some other package already uses namespace `rcs'} \fi %%% \endprog %%% \sect Let's identify this package. %%% Now I'm caught in a catch-22 situation. The code below---part of my %%% standard templates for \LaTeX{} packages---uses principles that are %%% explained later in this document. In particular, the explanation how %%% the information from the following RCS fields are gathered starts at %%% chunk~\ref{chunk:value-split}. %%% There you'll find also the explanation for the funny strings behind %%% the RCS fields. Actually, I would not need them any more, they make %%% the initial document (before the first check-in) work. But they won't %%% be discarded in this package source, as they'll demonstrate another %%% utilization of RCS at work. %%% \beginprog \begingroup \def\RCSPackage#1#2 $#3: #4 #5\endRCS $#6: #7 #8\endRCS{% \def\date{#4}\def\id{v#7}% \ProvidesPackage{#1}[\date\space\id\space #2]% } \RCSPackage{rcs}{typeset info from RCS fields} $StyleDate: 1995/08/02 12:09:07 $: 9999/00/00 \endRCS $StyleRevision: 2.9 $: 0.0 \endRCS \endgroup %%% \endprog %%% \sect This module is supported. Send bug reports, comments, and %%% repairs. %%% The reference version may be retrieved via anonymous ftp from %%% |ftp.th-darmstadt.de| [130.83.47.112], directory |pub/tex/latex|. It's %%% placed there as a gzipped tar file. (The information on the %%% IP~number is dated August~2,~1995. %%% It might have changed, although this is very unlikely. Use your %%% friendly nameserver.) %%% \sect This is freely distributable software; you can redistribute it %%% and/or modify it under the terms of the GNU General Public License as %%% published by the Free Software Foundation; either version~2 of the %%% License, or (at your option) any later version. %%% This software is distributed in the hope that it will be useful, but %%% \textbf{without any warranty}; without even the implied warranty of %%% \textbf{merchantability} or \textbf{fitness for a particular purpose}. %%% See the GNU General Public License for more details. %%% You should have received a copy of the GNU General Public License in %%% the file |License| along with this package; if not, write to the Free %%% Software Foundation, Inc., 675~Mass Ave, Cambridge, MA~02139,~USA. %%% \sect Before we start we declare some shorthands for category codes. %%% By declaring the underscore~`(|_|)' as letter we can use it in our %%% macros. (I agree with {\sc D.~Knuth} that %%% |\identifier_several_words_long| is more readable than %%% |\IdentifierSeveralWordsLong| and in every case better than %%% |\p@@@s|.) As this is a \LaTeX{} style option the at sign is a letter %%% anyhow; so we can use the ``private'' Plain and \LaTeX{} macros; and %%% with the underscore we can make our own macros more readable. But as %%% we have to restore this category code at the end of this macro file %%% we store its former value in the control sequence |\CatUsCode|. This %%% method is better than to use a group because not all macros have to %%% be defined global this way. %%% \beginprog \ifx \CatEscape\undefined \chardef\CatEscape=0 \chardef\CatOpen=1 \chardef\CatClose=2 \chardef\CatIgnore=9 \chardef\CatLetter=11 \chardef\CatOther=12 \chardef\CatActive=13 \chardef\CatUsCode=\catcode`\_ \fi \catcode`\_=\CatLetter % top level macro file %%% \endprog %%% \chap Parsing RCS fields. %%% Each RCS field consists of a keyword and an optional value. The value %%% is delimited by `\verb*|: |' from the keyword, this delimiter is %%% missing if no value does exist. At the end of a value there's always %%% a space. I.e., the possible input looks like one of the two following %%% lines: %%% % %%% \begin{quote} %%% \itshape %%% |\RCS $|Keyword\/|$|\\ %%% |\RCS $|Keyword\/\verb*|: |value\/\verb*| $| %%% \end{quote} %%% % %%% where \textit{Keyword} and \textit{value} may be arbitrary strings. In %%% fact, we assume that \textit{Keyword} is a sequence of letters---only %%% then the creation of a cseq |\RCS|\textit{Keyword} is sensible. Our %%% implementation will not produce an error with an obscure keyword, but %%% the result will not be of use for the author. %%% We must not depend on a fixed set of keywords, this style shall be %%% usable with a configurable RCS version. In such a version one can %%% bind arbitrary keywords to the information available in RCS\@. This %%% means we will parse all RCS fields with the same macro, %%% |\rcs_split_field|. This macro will place its results in two macros: %%% |\RCS_keyword| and |\RCS_value|. Afterwards we can bind the expansion %%% of |\RCS_value| to the target cseq. %%% \sect |\RCS_value| will be set to the expansion of |\RcsEmptyValue| %%% if there was no RCS value available, i.e., if the field was not %%% processed by RCS yet. This way the values of non-expanded RCS fields %%% can be configured. The default value is the empty token list. %%% \beginprog \def\RcsEmptyValue{} %%% \endprog %%% \sect For those fields where a special handling is demanded, a cseq %%% |\RcsHandle|\textit{Keyword} must exist. This cseq must handle the %%% parsing of the value. Usually this means that it will create a macro %%% named |\RCS|\textit{Keyword} with a transformed (or filtered) value. %%% If you happen to write a handler you might want to look at the %%% definition of |\RcsHandleDate| starting at section~\ref{sec:date} %%% If a special handler for a field exists, the original value is %%% placed automatically in the macro |\RCSRaw|\textit{Keyword}. This is done %%% before the handler is called. %%% \sect \label{chunk:value-split} The macro %%% |\rcs_split_field| will split the field into |\RCS_keyword| and %%% |\RCS_value|. This split is done by the argument parsing capability %%% of \TeX{}: We can separate parameters by token lists and \TeX{} will %%% use a shortest pattern match to determine the arguments. %%% Let's look what kind of pattern we can use. As an example we use the %%% RCS field `\verb*|$Revision: 1.1 $|', i.e., the unexpanded field is %%% `|$Revision$|'. The macro |\RCS| will use dollars to delimit its %%% argument, we don't need to worry for them. Eventually we'll have to %%% discard the space of the expanded field's value---after all, %%% |\RCSRevision| shall expand to `1.1', not to `1.1~'. %%% First, we can see that the token list $\it (colon, space)$ may be used %%% as the seperator of keyword and value: %%% % %%% \begin{quote} %%% \macroCall{\\rcs_split_field \[Revision\(: \)1.1 \]\\end_value} %%% \end{quote} %%% % %%% ($d_i$ is the separating token list between parameter $i$ and~$i+1$. %%% |#1| denotes the argument of |\RCS|. |\end_value| is a stop token, %%% used to delimit the last parameter; we have to supply this token at %%% the call. In fact, all tokens marked by $s$ and the dotted %%% line---i.e., those after |#1|---are supplied by us.) %%% When we want this token list as a separator, we have to supply it for %%% the unexpanded field, since there is no $\it (colon, space)$ in there: %%% % %%% \begin{quote} %%% \macroCall{\\rcs_split_field \[Revision\]\(: \)\\end_value} %%% \end{quote} %%% % %%% Then the call with the expanded field gets %%% % %%% \begin{quote} %%% \macroCall{\\rcs_split_field \[Revision\(: \)1.1 \]: \\end_value} %%% \end{quote} %%% Well, we want neither the space nor the colon and the other space %%% after the value---we have to get rid of them. We can utilize the fact %%% that no RCS field will ever have the token list $\it (space, colon)$ %%% in it. This means we can use it as a terminator for the RCS value: %%% % %%% \begin{quote} %%% \macroCall{\\rcs_split_field \[Revision\(: \)1.1\( \]:\) \\end_value} %%% \end{quote} %%% % %%% Please note, one token of the delimiter~$d_2$ comes from the %%% |#1|~argument, the other from the tokens we'll add at the call. %%% Let's check our unexpanded field again---we don't have $d_2$ there. We %%% have to add it by the caller: %%% % %%% \begin{quote} %%% \macroCall{\\rcs_split_field \[Revision\]\(: \)\{\}\( :\)\\end_value} %%% \end{quote} %%% % %%% (Without the empty group the two spaces would be combined into one %%% token.) Going back to the expanded field, we notice that these %%% additional tokens do not harm us---we'll ignore everything after $d_2$ %%% anyhow. %%% % %%% \begin{quote} %%% \macroCall{\\rcs_split_field \[Revision\(: \)1.1\( \]:\) \{\} :\\end_value} %%% \end{quote} %%% We can take another look at the whole affair and point out the %%% parameters we get for the split. Remember, that spaces after a control %%% word belong to this word. First, the expanded field: %%% % %%% \begin{quote} %%% \macroCall %%% [p]{\\rcs_split_field \[\(Revision\): \(1.1\) \]:\( \{\} :\)\\end_value} %%% \end{quote} %%% % %%% Then the unexpanded one: %%% % %%% \begin{quote} %%% \macroCall[p]{\\rcs_split_field \[\(Revision\)\]: \(\{\}\) :\(\|\)\\end_value} %%% \end{quote} %%% % %%% ($p_3$, the third parameter will be empty in this case.) %%% \medskip %%% \noindent As explained above: if the value does not exist, a default %%% value is supplied. %%% \beginprog \def\rcs_split_field #1: #2 :#3\end_value{% \def\RCS_keyword{#1}% \def\RCS_value{#2}% \ifx \RCS_value\empty \let\RCS_value\RcsEmptyValue \fi } %%% \endprog %%% \sect |\RCS| triggers the split. After it has occured, we can bind the %%% expansion of |\RCS_value| to a new name. This name is constructed from %%% the prefix |RCS|, the string |Raw| iff a handle for this field exists, %%% and the keyword itself. %%% Afterwards we call the handle, on non-existance this will be a no-op. %%% \beginprog \def\RCS $#1${% \rcs_split_field #1: {} :\end_value \expandafter\let \csname RCS\rcs_raw_if_handle\RCS_keyword\endcsname \RCS_value \csname RcsHandle\RCS_keyword\endcsname } \def\rcs_raw_if_handle{% \@ifundefined{RcsHandle\RCS_keyword}{}{Raw}% } %%% \endprog %%% \chap Transforming the value of \Date{} fields. %%% \label{sec:date} %%% When we implement the special handling for the \Date{} field, we take %%% care that we don't rely on the fact that the keyword is |Date|. %%% Certain RCS versions (one of them created at our site) allow the %%% configuration of the used keywords. I.e., there might be another %%% keyword used for this field, but we still want to use the %%% functionality provided here. %%% For example, let's assume the keyword of the \Date{} field is %%% |StyleDate|. Then the assignment %%% % %%% \begin{quote} %%% |\let\RcsHandleStyleDate=\RcsHandleDate| %%% \end{quote} %%% % %%% is all that's needed to turn on the `date special handling' for this %%% field. (In fact, that's done in this style file you're reading.) %%% \sect The special handler for \Date{} fields sets up %%% |\RCS|\textit{Keyword} (|\RCSDate| usually) to produce a textual %%% representation of the date part of the \Date{} value in a %%% |\today|-like format. Thus the constructed tag can be used in many %%% circumstances, e.g., as the argument of the |\date| tag on the %%% titlepage. %%% In addition, |\RCSTime| is defined; it expands to the checkin time. %%% If the value is empty, i.e., if there's no \Date{} value from RCS %%% available, we use the current date. Later we might supply the current %%% time, too---currently |\RCSTime| expands to an empty token list in %%% such a case. %%% Of course, this whole special handling is only done if |\today| is %%% defined in some way; otherwise we just handle the \Date{} field like %%% every other RCS field: The value is stored unfiltered in %%% |\RCS|\textit{Keyword}. %%% \beginprog \def\RcsHandleDate{% \ifx \today\undefined \expandafter\let \csname RCS\RCS_keyword\endcsname \RCS_value \else \ifx \RCS_value\RcsEmptyValue \@namedef{RCS\RCS_keyword}{\today}% \let\RCSTime\empty \else \expandafter\rcs_set_date \RCS_value\end_date \fi \fi } %%% \endprog %%% \sect If the value is not empty we split it using the argument parsing %%% mechanism of \TeX{}. Then we'll define the value using the current %%% definition of |\today|. This way language-specific styles (e.g., from %%% the \textsf{babel} system) may supply their own way to present a date. %%% \beginprog \def\rcs_set_date #1/#2/#3 #4\end_date{% \begingroup \day #3 % <-- space! \month #2 % <-- space! \year #1 % <-- space! \expandafter\xdef \csname RCS\RCS_keyword\endcsname {\today}% \endgroup \def\RCSTime{#4}% } %%% \endprog %%% \chap Typesetting revision logs. %%% If a revision log is to be typeset, we demand a special format. %%% Namely, it is to be enclosed in the |rcslog| environment. This %%% environment has an optional parameter, the configuration tokens. The %%% contents of the environment is the \Log{} field followed by a list of %%% revision entries. The \Log{} field must be on a line of its own. Each %%% revision entry is introduced by a line consisting of the tag %%% |\Revision|, the revision number, the checkin date, the checkin time, %%% and the author's user id. %%% I.e., the input looks like the following example sketch, where italic %%% material is substituted by current values. %%% % %%% \begin{quote} %%% \chardef\\=`\\ % just for the example %%% \chardef\{=`\{ %%% \chardef\}=`\} %%% \begin{alltt}\frenchspacing %%% \\begin\{rcslog\} %%% $Log: {\it filename},v $ %%% \\Revision {\it revision date time uid} %%% \qquad {\it log text\/} %%% \quad \([\,\ldots\) {\it perhaps more entries\/} \(\ldots\,]\) %%% \\end\{rcslog\} %%% \end{alltt} %%% \end{quote} %%% We typeset the revision log similar to a |description| environment. %%% Each revision entry is an item. %%% \sect The tag for the log intro is implemented as a token register. In %%% fact, |\rcsLogIntro| is a hook. %%% \beginprog \newtoks\rcsLogIntro \rcsLogIntro={} %%% \endprog %%% \sect The author names are stored in a table named |rcs_author|. We %%% supply the lookup macro |\RCS_get_author|, which expands to the table %%% value or to the table key itself. %%% \beginprog \def\rcsAuthor#1#2{\@namedef{rcs_author:#1}{#2}} \def\RCS_get_author#1{% \@ifundefined{rcs_author:#1}{#1}{\@nameuse{rcs_author:#1}}% } %%% \endprog %%% \sect Since this style option shall be usable with many styles, we %%% must provide means to configure its behaviour. In particular, it must %%% be possible to configure the layout. What remains fixed, is the layout %%% of the log like a |description| list. I might add this flexibility if %%% there is enough interest (or if somebody sends me tested changes). %%% The first thing to parametrize is the overall layout and the header. %%% This is set up by |\RcsLogStyle|. This cseq \emph{must} define %%% |\RcsLogHeading|, which is the macro to set the header. E.g., here %%% one could insert a |\newpage| to start a new page for the revision log. %%% In addition, we reduce the base size of the log. That's the reason why %%% these two configurations are combined in one macro---if you change %%% one, you also have to consider to change the other. %%% \beginprog \def\RcsLogStyle{% \def\RcsLogHeading{\subsubsection*}% \footnotesize } %%% \endprog %%% \sect The header itself is created by |\rcs_log_hdr|, which is called %%% with the expanded \Log{} value as its argument, terminated by %%% |\end_value|. We use \TeX{}'s parameter parsing mechanism to chop off %%% the tail of the value---if the value exists, it always ends in~`|,v|'. %%% Since only an existing value ends in~`|,v|', we have to supply a %%% fitting empty value. We will use |\rcs_empty_log_value| for that. %%% The empty log value gets a bit more complicated: If we have an empty %%% \Log{} value, we will not have any revision entries. (Well, except in %%% pathological cases. Then we will produce spurious text.) Missing %%% revision entries are missing items; since \LaTeX{} will complain %%% about a missing |\item|, we must provide one to stop it from doing %%% so. But here is no place for such tokens, the list environment hasn't %%% started yet. We will set the flag |@rcs_empty_log@| and check this %%% flag after we invoked the list. %%% \beginprog \def\rcs_log_hdr#1,v\end_value{% \@rcs_empty_log@false \RcsLogHeading{\RcsLogHeadingName #1}% \the\rcsLogIntro } \def\rcs_empty_log_value{% \global\@rcs_empty_log@true % that's most probably in a group! \RcsUnknownFile % text for unknown file name ,v% % assert calling env } \newif\if@rcs_empty_log@ %%% \endprog %%% \sect The user might want to adapt the text output. He can do so by %%% redefining |\RcsLogHeadingName|, |\RcsUnknownFile|, and |\RcsEmptyLog|. %%% \beginprog \def\RcsLogHeadingName{Revision Log for \tt} % file name in monospace \def\RcsUnknownFile{\rm $\langle\,$Unknown file name$\,\rangle$} \def\RcsEmptyLog{{\itshape No log entries available.}} %%% \endprog %%% \sect OK, we have fixed the header, let's address the entries. Each %%% entry is typeset by |\RcsLogRevision| which is called with four %%% arguments: (1)~the revision number, (2)~the checkin date, (3)~the %%% checkin time, and (4)~the uid of the author. %%% Such an entry is inserted as an item in the list. The uid is %%% transformed to an author name, if the respective information is %%% available. The checkin timestamp is mapped to a neater appearance by %%% |\RcsLogDate| and |\RcsLogTime|. %%% \beginprog \def\RcsLogRevision#1#2#3#4{% \item [Revision #1]% (created at \RcsLogDate #2\endDate\space \RcsLogTime{#3} % <-- space! by \RCS_get_author{#4})\\\relax } %%% \endprog %%% \sect |\RcsLogDate| sets the date. We can use \TeX{}'s parameter parsing %%% mechanism to separate the date value (passed as the argument) in its %%% sub-values. The code is very similar to |\rcs_set_date|. %%% |\RcsLogTime| sets the time. As explained in the user manual, the time %%% is ignored usually. (I don't think that this info is relevant in a %%% printout.) Here we assume something about the context it's expanded %%% in: Spaces will be before and after the tag. One of them must be %%% discarded. The user option |\settime| is implemented here as a %%% private macro, too. %%% \beginprog \def\RcsLogDate #1/#2/#3\endDate{% \begingroup \day #3 % <-- space! \month #2 % <-- space! \year #1 % <-- space! \today \endgroup } \def\RcsLogTime#1{\ignorespaces} \def\rcs_settime{% \def\RcsLogTime##1{[##1]}% } %%% \endprog %%% \sect Well, that are all possibilities to configure the revision log. %%% Let's put together the pieces. Within the |rcslog| environment the %%% tags |\Revision| and |\settime| are used, they are implemented in %%% the |rcs| namespace. %%% At the start, we use the optional argument of the environment to %%% configure it. |\settime| might be placed here, or font switches, etc. %%% The next entity shall be the \Log{} field. In fact, it shall be on %%% the next line. If an optional environment argument was there, the %%% newline is still in the input and must be discarded before we can use %%% |\RCS| to parse the field. %%% \beginprog \def\rcslog{% \@ifnextchar[% % ] (Emacs) \rcslog_configure {\rcslog_configure[]}% } \def\rcslog_configure[#1]{% \let\Revision\rcslog_revision \let\settime\rcs_settime \RcsLogStyle #1% \afterassignment\rcslog_skipcr \let\next } %%% \endprog %%% \sect There are users---programmer's life would be so nice without %%% them. An empty line (i.e., a |\par|) might have been inserted between %%% |\begin{rcslog}| and the \Log{} field. There might be even other %%% garbage between them. We have to check these possibilities and provide %%% proper responses. %%% \beginprog \def\rcslog_skipcr{% \ifx \next $% \def\next{\rcslog_field $}% \else\ifx \next\par \let\next\rcslog_field \else \PackageError{rcs}{Missing RCS Log field in environment}{% The RCS Log field must be the very first text in the rcslog\MessageBreak environment. I will discard the rest of your input line and try to\MessageBreak recover then. If you think this won't work, exit now.\MessageBreak Otherwise press and cross your fingers!} \let\next\rcslog_discard_line \fi\fi \next } %%% \endprog %%% \sect This is the code for the luser. He provided tokens we didn't %%% wait for---we discard them and check anew if we've got it right now. %%% (Remember, we're waiting for the `|$|' of the \Log{} field.) %%% \beginprog \def\rcslog_discard_line{% \begingroup \obeylines \rcslog_gobble_line } \begingroup \obeylines \gdef\rcslog_gobble_line #1^^M{% \endgroup% \afterassignment\rcslog_skipcr% \let\next% } \endgroup %%% \endprog %%% \sect Yep, we've reached a dollar; let's hope that it's our \Log{} %%% field. It must be on one line, this line is fetched first and then %%% analyzed. %%% \beginprog \def\rcslog_field{% \begingroup \obeylines \rcslog_get_field } \begingroup \obeylines \gdef\rcslog_get_field #1^^M{% \endgroup% \rcslog_set_field{#1}% } \endgroup %%% \endprog %%% \sect When we analyze the \Log{} field, we must supply the default %%% value. Within the log list there will be no other RCS fields, %%% therefore we can redefine |\RcsEmptyValue| in this environment. %%% The header gets passed the expanded \Log{} value, as explained above. %%% We use |\RCS_value| instead of |\RCSLog| since we don't know which %%% RCS keyword is used. %%% At last, we start the list and check the |@rcs_empty_log@| flag, %%% perhaps we have to supply a dummy |\item|. %%% \beginprog \def\rcslog_set_field#1{% \let\RcsEmptyValue\rcs_empty_log_value \RCS #1% \expandafter\rcs_log_hdr \RCS_value\end_value \list{}\RcsLogListStyle % empty label, layout configurable \if@rcs_empty_log@ \item []\RcsEmptyLog % supply missing item \fi } %%% \endprog %%% \sect The setup of the log list is done by a macro from the protected %%% interface, the user shall be able to change it. In the default %%% supplied, there is no skip between paragraphs, but a quad indentation. %%% |rcslog| is here no list environment in the sense like |itemize| or %%% |enumerate|, therefore a usage of these environments within an entry %%% shall result in top-level item markers. %%% \textbf{Caveat}:\quad Since we globally set |\@listdepth| at the start %%% of the environment, we must not execute |\endlist| that decrements it. %%% Instead we use |\endtrivlist| for the termination of the |rcslog| %%% environment. It might be, that this must be changed if %%% |\RcsLogListStyle| is changed. %%% \beginprog \def\RcsLogListStyle{% \global\@listdepth\z@ \labelwidth\z@ % item label w/o fixed size \itemindent -\leftmargin % move label before start of line \advance\itemindent \labelsep % label was moved too much \def\makelabel##1{\bf ##1}% % how to typeset labels \parsep\z@skip % no space between pars in items \listparindent 1em % <-- space! indent pars in items }% \let\endrcslog\endtrivlist %%% \endprog %%% \sect The arguments of |\Revision| are separated by spaces and %%% terminated by the end of the line. We have to fetch them, then we can %%% pass them to |\RcsLogRevision| which does the real work. %%% \beginprog \def\rcslog_revision{% \begingroup \obeylines \rcslog_get_revinfo } \begingroup \obeylines \gdef\rcslog_get_revinfo #1 #2 #3 #4^^M{% \endgroup% \RcsLogRevision{#1}{#2}{#3}{#4}% } \endgroup %%% \endprog %%% \chap Convenience tags. %%% As a shortcut we %%% support the direct supply of the checkin date for the titlepage %%% material. Here we also take care not to depend on the keyword. %%% \beginprog \def\RCSdate $#1${% \RCS $#1$% \expandafter\date \expandafter{\csname RCS\RCS_keyword\endcsname}% } %%% \endprog %%% \sect |\RCSID| parses the RCS field and redefines the footline. This %%% tag is from Nelson's |rcs| style. In his style he defines that the RCS %%% field is passed as an argument to the macro. To be upward compatible, %%% we have to support this as well: We look at the next token, if it is %%% an opening brace we fetch the param and trigger the `real' invocation %%% by |\rcs_id|. If no brace follows, we call |\rcs_id| immediately. %%% \beginprog \def\RCSID{% \@ifnextchar\bgroup \rcsid_get_field \rcs_id } \def\rcsid_get_field#1{\rcs_id #1} %%% \endprog %%% \sect As a side effect, we'll produce the normal value tags. When we %%% define the footline, we must assert that |\RCS_keyword| and %%% |\RCS_value| are expanded. (They will get new bindings at the next %%% invocation of |\RCS|.) All other macros must not be expanded, they %%% shall be used in the context of the footline, not in our definition %%% context. We utilize |\protect| for that, |\framebox| is the only macro %%% that must be protected. %%% \beginprog \def\rcs_id $#1${% \RCS $#1$% \begingroup \let\protect\noexpand \xdef\@oddfoot{% \reset@font \protect\framebox[\textwidth]{\RCS_keyword: \RCS_value}% }% \endgroup \global\let\@evenfoot\@oddfoot } %%% \endprog %%% \sect |\RCSdef| just outputs its parameter before it's passed to %%% |\RCS|. This tag is from Tom Verhoeff's |rcs| style. In fact, we're %%% not fully compatible: Tom did output `RCS keyword string'. I %%% substitute this by `RCS field', this is consistent with the rest of %%% this style's description. %%% \beginprog \def\RCSdef $#1${% \typeout{RCS field: $#1$}% \RCS $#1$% } %%% \endprog %%% \chap The end. %%% Well, after all we're finished with this style. We must not forget to %%% restore the underscore catcode. %%% \beginprog \catcode`\_=\CatUsCode \endinput %%% \endprog %%% \sect I would like to thank those who helped me to improve this style. %%% % In particular, XXX provided XXXsubstantial parts of the code. %%% \textsc{Marcus Speh} pointed out that Nelson's style option exists. %%% \textsc{Lee Wittenberg} pointed out that Tom style option exists---Tom %%% posted the style option on |comp.programming.literate| afterwards. I %%% borrowed the idea of appending a second colon to the call of %%% |\rcs_split_field| from Tom's style. \textsc{Harald Fuchs} asked for the %%% possibility to configure the log list layout. %%% \textsc{Dave Love} brought the problem with the |-kv| option of |co| to %%% my attention. It's a pitty that I haven't found a solution yet. (I %%% mean, one that convinces me.) %%% \textsc{Christine Detig} told me where my documentation was %%% uncomprehensible. In particular, you won't have the visual explanation %%% of |\rcs_split_field| without her. barbara beeton proofread the user %%% manual. In addition, she pointed out where a non-programmer does not %%% understand it. %%% \vskip \PltxPreSectSkip %%% \rcsLogIntro{Of course, we shouldn't stop without the RCS log of this %%% style file.} %%% \begin{rcslog} %%% $StyleLog: rcs.doc,v $ %%% \Revision 2.9 1995/08/02 12:09:07 schrod %%% Transformed this style option into a \LaTeXe{} package. %%% Updated to \LaTeXe{}. %%% \Revision 2.8 1993/11/10 12:29:49 schrod %%% Added acknowledgement of barbara. %%% \Revision 2.7 1993/11/08 20:15:15 schrod %%% Added possibility to configure the layout of the log list %%% (|\RcsLogListStyle|). %%% Now the log list is on level~0. Thereby item lists or enumerations in %%% revision entries get first-level labels. This has consequences for %%% the configuration, this implementation strategy must therefore be %%% specified in the internal interface description. %%% \Revision 2.6 1993/11/03 20:04:57 schrod %%% Cleaned up for distribution: Added email address to each document, %%% added copyright info to |rcs.doc|, added acknowledgements. Checked my %%% English and the spacing. %%% Explained the restriction concerning the |-kv| option of |co|. %%% Rewrote the explanation to |\rcs_split_field|. Added the visual clues %%% to explain the (mis?)usage of macro expansion and pattern matching. %%% \Revision 2.5 1993/11/02 20:02:51 schrod %%% Implemented |\RCSdef|. %%% Deleted unnecessary macro that did discard the space of an RCS value. %%% Moved this in the parameter context of |\rcs_split_field|. Added an %%% explanation to |\RCS| where it is called. %%% \Revision 2.4 1993/11/02 18:44:49 schrod %%% Implemented |\RCSID|.\\ %%% Need |\reset@font| now, for the definition of the footline in |\RCSID|. %%% Paragraphs in revision logs are not separated by vertical space any %%% more. They are indented instead. I use the ``classic'' indentation of %%% one quad. %%% \Revision 2.3 1993/11/01 19:49:49 schrod %%% Added subdocument about the internal interface. %%% Cleaned the cseq names: All public names start with `|RCS|' or %%% `|rcs|', protected names start with `|Rcs|', both have only letters. %%% Observer names start with `|RCS|', internal names with `|rcs|', both %%% feature non-letters in the names. %%% \Revision 2.2 1993/11/01 19:20:58 schrod %%% Cleaned up the documentation. The enhancement of the |rcslog| %%% environment was just appended, now it's integrated in the whole %%% document. Improved the explanation of the implementation: the valid %%% input is now explained more clearly. %%% Use |rcs-doc.sty| for documentation of |rcs| style. It does not only %%% load style options, but does also define |\RCSStyleRevision| for %%% access of the style's revision. %%% Added hint that the user manual is urgently needed.\\ %%% The load tag is now in the protected interface.\\ %%% Commented out section with definition of |\reset@font|, that cseq is %%% not needed in the implementation.\\ %%% OALD tells me to use ``heading'' instead of ``header.'' %%% \Revision 2.1 1993/10/29 19:07:38 schrod %%% Reorganized the source structure---the style gets too large to keep %%% everything in one directory. I use the usual setup for my larger %%% styles. %%% Changed the RCS keywords. All keywords in use now start with %%% `|Style|'. Stuff in the text which looks like RCS fields, but where %%% the keywords do not start with `|Style|', are examples! %%% \Revision 1.3 1993/10/29 18:08:19 schrod %%% Each field value supplied by RCS ends with a space; this space is %%% discarded. %%% Supports the typesetting of revision logs. The overall documentation %%% is not yet fully integrated. Of course, our own revision log is %%% typeset at the end, too.\\ %%% But we'll have to use other RCS keywords for this document in the %%% future. E.g., I can't use original RCS keywords currently in the %%% examples without much hassle. %%% An hook for the configuration of this style option is provided. %%% \Revision 1.2 1993/09/08 15:49:00 schrod %%% Use canonical names for category codes. %%% \Revision 1.1 1993/09/03 21:01:29 schrod %%% Re-implemented |rcs| style option. Made it a documented option. %%% \end{rcslog} %%% \end{document} %%% %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Local Variables: %%% mode: LaTeX %%% TeX-brace-indent-level: 4 %%% indent-tabs-mode: t %%% TeX-auto-untabify: nil %%% TeX-auto-regexp-list: LaTeX-auto-regexp-list %%% End: