% \iffalse %% %% $Header: /usr3/users/latex3/design/consolidation/CURRENT/RCS/xinitials.dtx,v 1.7 2000/01/28 13:39:56 latex3 Exp $ %% %% (C) Copyright 1999-2000 Frank Mittelbach %% All rights reserved. %% %% Not for general distribution. In its present form it is not allowed %% to put this package onto CD or an archive without consulting the %% the authors. %% %<*dtx> \ProvidesFile{xinitials.dtx} % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{xinitials} %\ProvidesFile{xinitials.sig} %\ProvidesFile{xinitials.drv} % \fi % \ProvidesFile{xinitials.dtx} [2000/01/28 v0.1h templates for initials] % % \iffalse %<*driver> \documentclass{ltxdoc} \usepackage{textcomp} % \usepackage{ldcdoc} % next three definitions are big hacks to run the file % without the above packages % \newcommand\NoValue{\texttt{\textbackslash NoValue}} \makeatletter \newenvironment{TemplateInterfaceDescription}[1] {\subsection{The Template Type `#1'}% \begingroup \@beginparpenalty\@M \description \def\TemplateArgument##1##2{\item[Arg: ##1]##2\par}% \def\TemplateSemantics{\enddescription\endgroup \subsubsection*{Semantics:}}% } {\par\bigskip} \newenvironment{TemplateDescription}[2] {\subsection{The Template `#2' (type #1)}% \subsubsection*{Attributes:}% \begingroup \@beginparpenalty\@M \description \def\TemplateKey##1##2##3##4{\item[##1 (##2)]##3% \ifx\TemplateKey##4\TemplateKey\else % \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4% \hfill\penalty500\relax\qquad \hbox{}\hfill Default:~##4% \nobreak\hskip-\parfillskip\hskip0pt\relax \fi \par}% \def\TemplateSemantics{\enddescription\endgroup \subsubsection*{Semantics \& Comments:}}% } {\par\bigskip} \makeatother \newcommand\LaTeXplus{\LaTeXe$*$} \newcommand\key[1]{\textbf{#1}} \EnableCrossrefs \CodelineIndex \begin{document} \DocInput{xinitials.dtx} \PrintIndex \end{document} % % \fi % % \CheckSum{125} % % \GetFileInfo{xinitials.dtx} % % \title{The \textsf{xinitials} package\thanks{This file % has version number \fileversion, last % revised \filedate.}} % \author{FMi} % \date{\filedate} % \maketitle % % \tableofcontents % % \section{Introduction} % % This module implements an interface for producing initial % characters. It was originally written as an exercise for working % with the template interface of \LaTeXplus{} and survived many % internal changes of the new methods. % % % \section{Interfaces} % % The template implemented by this module uses absolute dimensions to % produce the initials, something which I found being a natural way to % achieve the desired results. There are other ways to specify how % such initials should look; for example there exists a \LaTeXe{} % package called \texttt{lettrine} by Daniel Flippo which makes the % specifications relative to the current font used for the initials. % It would be interesting to see his approach being reimplemented as % an alternative template to the one I called \texttt{std}. % % % \begin{TemplateInterfaceDescription}{initial} % % \TemplateArgument{1} % {Quote to the left of the initial (if any) or \NoValue} % % \TemplateArgument{2} % {Initial character} % % \TemplateArgument{3} % {Text following the initial that is handled specially, e.g., % set in small capitals (if any) or \NoValue } % % \TemplateSemantics % Typesets argument 2 as an initial character with argument 1 being % any special material typeset to the left of the initial (e.g., a % quote) and argument 3 being all material that is typeset in a % special fashion to the right of the initial. % % In typical document commands arguments 1 and 3 are most likely % implemented as optional, if implemented at all. % % \end{TemplateInterfaceDescription} % % % \begin{TemplateDescription}{initial}{std} % % \TemplateKey{initial-font}{f0} % {Font specification to use for the initial glyph itself.} % {None} % % \TemplateKey{initial-format}{f1} % {Action to be taken on the initial. % This action takes one argument: the initial glyph formated % using \key{initial-font} but not including % the left and right separation spaces from \key{quote-sep} and % \key{text-sep}. The result if this action is further % manipulated by other keys.} % {Process argument unchanged} % % \TemplateKey{text-format}{f1} % {Action to be take on the special text following % the initial. This action takes one argument: argument 3 of the % template if not \NoValue.} % {Produce Caps\&SmallCaps} % % \TemplateKey{quote-format}{f1} % {Action to be taken on a quotation glyph to the left of the % initial (i.e., argument 1 of the template, if not \NoValue). % This action takes one argument: the quote glyph.} % {Process argument unchanged} % % \TemplateKey{parshape-list}{f0} % {List of dimensions (separated by comma) specifying two things: % For how many lines the paragraph needs indentation due do the % initial, i.e., how far does it drop into the paragraph % (number of dimensions) and how much each line should % be indented in addition to the actual width of the initial % including its offsets from \key{text-sep} and \key{h-adjust} % (value of the individual dimension which % could be negative) --- because of the commas in the list the % whole list has to be surrounded by braces.} % {Initial does not drop: \texttt{0pt}} % % \TemplateKey{v-adjust}{l} % {Dimension used to adjust the initial (see above) % vertically (positive values raise it). Default value places % the initial at the baseline of the % last indented paragraph line.} % {\texttt{0pt}} % % \TemplateKey{h-adjust}{l} % {Dimension used to adjust the initial horizontally (positive % values move it to the right). Default value places the initial % flush left with the text margin.} % {\texttt{0pt}} % % \TemplateKey{quote-sep}{l} % {Dimension specifying the space between the initial % and any ``quote material'' on its left (see also % \key{initial-format}).} % {\texttt{0pt}} % % \TemplateKey{text-sep}{l} % {Dimension specifying the space between the initial % and the paragraph lines on the right (see also % \key{parshape-list}). This key is available for convenience, it % is equivalent of extending all values in \key{parshape-list} % by this amount.} % {\texttt{0pt}} % % \TemplateKey{nominal-height}{l} % {Dimension specifying the height of the initial as seen by % \TeX. If not specified, the height is calculated as the actual % dimension of the initial (after applying \key{initial-format}) % plus the value of \key{top-sep}.} % {Unspecified} % % \TemplateKey{top-sep}{l} % {Dimension specifying an extra separation from preceding % material by pretending that the initial larger (or smaller) % than it actually is (see also \key{nominal-height} for special % effects).} % {\texttt{0pt}} % % \TemplateSemantics % The template will raise an error if used in horizontal mode. It % will also complain if it finds that it is used with a special % |\parshape| in force (other than the one produced from list environments. % % \end{TemplateDescription} % % % % % \subsection{The Document Interface} % % The following two commands should be viewed as examples on how one % could set up a document interface for initials. % % \DescribeMacro\Initial % The |\Initial| command takes one mandatory argument which is the % initial character. It may be followed by an optional argument, % which, if present, denotes the portion of text following the initial % character that should be handled somewhat special (for example being % set in caps \& smallcaps). It can also take an optional argument % before the mandatory one, which, if present, contains material that % should be placed to the left of the initial (in the margin). It can % be used, for example, for placing quotes at this point. % % The mandatory argument can only contain a straight \textsc{ascii} % letter and not something like an accented character. The reason is % that the |\Initial| command tries to find a template instance using % the the argument as the potential name.\footnote{This is for % convenience only, if one often needs special initial one would better % define a different interface.} If it find such an instance it will % use it, otherwise it will use the instance with name % \texttt{default}. This scheme makes it possible to declare one % instance (\texttt{default}) with values being suitable for most % characters and define overwriting instances for those character % which need special treatment. % % % \DescribeMacro\ExtendedInitial % The |\ExtendedInitial| is an extension of the interface provided by % the |\Initial| command. It accepts a star in which case a following % optional argument is interpreted as the key/value specification for % the template \texttt{std} of type \texttt{initial} which is then % constructed on the fly. The remaining three arguments (optional, % mandatory, optional) are as in the case of |\Initial|. If no star is % present the first optional argument is interpreted as the name of % the template instance. If it is defined then it is used; if not the % instance with name \texttt{default} is used. This way the mandatory % argument is allowed to contain any \TeX{} code including accents and % the like. For example, %\begin{verbatim} % \ExtendedInitial [Uumlaut][``]{\"U}[ber den sieben Bergen] bei ... %\end{verbatim} % would use the instance with name \texttt{Uumlaut} (which would need % to be defined) to typeset the `\"U' as initial with a left double % quote on the left and the text `ber den sieben Bergen' handled % specially. % % \StopEventually{} % % \section{Implementation} % % \subsection{The template implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % For this module we need the galley support and of course the % template module. % \begin{macrocode} \RequirePackage{template,galley2} % \end{macrocode} % % Getting our private coding environment ready\ldots % \begin{macrocode} \IgnoreWhiteSpace \catcode`\:=11\relax % \end{macrocode} % % At some point below we need a register to do some calculations. We % could probably get away with a scratch one but here I allocated a % private one to avoid having to think about the implications :-) % \begin{macrocode} \newlength\initial@raise % \end{macrocode} % % We also need a box register to be able to measure the size of the % initial and its frills, again this could probably be done with a % general purpose register but\ldots % \begin{macrocode} \newbox\initial@box % \end{macrocode} % % % % \bigskip % % The \texttt{initial} template type has three arguments: % \begin{macrocode} \DeclareTemplateType{initial}{3} % \end{macrocode} % % % % \bigskip % % \begin{macrocode} \DeclareTemplate{initial}{std}{3}{ % \end{macrocode} % The font to be used for the initial does not have any default % value: it must be specified. % \begin{macrocode} initial-font =f0 \initial@font, % \end{macrocode} % All other keys have default values but we do not specify the here. % \begin{macrocode} h-adjust =L \initial@hadjust, initial-format =f1 \initial@charformat, nominal-height =L \initial@height, parshape-list =f0 \initial@parshape, quote-format =f1 \initial@quoteformat, quote-sep =L \initial@leftsep, text-format =f1 \initial@textformat, text-sep =L \initial@rightsep, top-sep =L \initial@topsep, v-adjust =L \initial@vadjust, } { % \end{macrocode} % Specifying the defaults here saves space, otherwise each instance would % contain them. % \begin{macrocode} \let\initial@vadjust\z@ \let\initial@hadjust\z@ \let\initial@leftsep\z@ \let\initial@rightsep\z@ \let\initial@height\maxdimen \let\initial@topsep\z@ \let\initial@parshape\z@ \let\initial@quoteformat\@firstofone \let\initial@charformat\@firstofone \let\initial@textformat\textsc \DoParameterAssignments % \end{macrocode} % % We first check if we are in vertical mode and if not raise an error. % \begin{macrocode} \ifvmode \else \PackageError{xinitials}{Initial~ inside~ paragraph} {Initials~ can~ only~ be~ used~ at~ the~ beginning~ of~ a~ paragraph} \par \fi % \end{macrocode} % We then typeset the initial character in a box to be able to % measure it. The purpose of this measurement is to determine the % width of the cutout, thus we have to include the specified % horizontal adjustments on the left and the right. % \begin{macrocode} \sbox\initial@box{ \kern\initial@hadjust \initial@charformat{ \initial@font #2 } \kern\initial@rightsep } % \end{macrocode} % We then prepare the cutout using |\setGALleftparshape:nnn| (see % the module \texttt{galley2} for an explanation of this command). % \begin{macrocode} \setGALleftparshape:nnn \z@ {\wd\initial@box} \initial@parshape % \end{macrocode} % It would be a problem if the paragraph containing the initial % would be split across the page, so we forbid paragraph splits % for the next paragraph. (We use the value |-3| which indicates % that it is allowed to break before the paragraph). % \begin{macrocode} \setGALbreak:n {-3} \noindent % \end{macrocode} % Next lines of code calculate the vertical dimension by which we % have to raise (normally lower in fact) the . The value of % |\parshape@linecnt| which is used in the formula was calculated % by |\setGALleftparshape:nnn|. % \begin{macrocode} \setlength\initial@raise{-\baselineskip*(\parshape@linecnt-2) -\initial@vadjust} % \end{macrocode} % % We then calculate the vertical space that the initial should % occupy (with respect to the first baseline of the paragraph). % If |\initial@height| is |\maxdimen|, i.e., was not set then the % effective height of the initial should be its real height % (|\height| reduced by the amount we drop (|\initial@raise|) plus % the extra space requested (|\initial@topsep|). If however the % value of |\initial@height| differs from |\maxdimen| we use that % value directly.\footnote{Writing the documentation for this I % notice that it might be better to change the logic here % completely: assume that the initial sticks out of the % paragraph. Now we have to account for this sticking out to avoid % that the initial bumps into the previous paragraph. However, if % we do it as it is currently implemented then this vertical extend % is actually a property of the initial character box. This means % that if we have a page break before the paragraph containing the % initial we do get a paragraph whose first line is far lower on % the page than in the care there would be a normal paragraph (in % other words the initial would not stick into the top margin but % be confined to the body text area). This may be what is intended, % on the other hand it may be not. So perhaps one need to allow to % contribute this vertical space to the inter-paragraph material.} % \begin{macrocode} \ifdim\initial@height=\maxdimen \def\initial@height{\height+\initial@raise+\initial@topsep} \fi % \end{macrocode} % % Now we about ready to typeset the initial. We put the whole thing % into an |\llap|. If we do have some material to the left of the % initial we set it in a way that its height and its width has no % influence. To prevent the width of the material effecting the % placement of the actual initial character we set the material in % an |\llap|. The right corner of this |\llap| will be at the left % paragraph boundary. But the initial might have been moved % horizontally so that we have to account for this space % (|-\initial@hadjust|). In addition there should be a separation % between the material and the initial of width % |\initial@leftsep|. Both spaces are added as |\kern|s to the % |\llap| box to provide the necessary separation. % \begin{macrocode} \llap{ \llap{\IfValueT{#1}{\smash{\initial@quoteformat{#1}}} \kern-\initial@hadjust \kern\initial@leftsep} % \end{macrocode} % Now we typeset the initial using |\raisebox| and the values we % have calculated above. We are as far as typesetting is concerned % at the place where the text following the initial would % start. Thus to be able to typeset the initial character we have % to first back off to the left margin. We do this by placing the % whole thing inside an |\rlap| so that we do not occupy any % horizontal space and add a kern of width % |\parshape@firstlineindent| inside it after the |\raisebox|. This % will push the initial to the left by the right amount and % afterwards we are still at the correct point to typeset the text % following the initial.\footnote{For those who find this % mysterious, please have a look at the implementation of % \texttt{\textbackslash parshape@setup} in \texttt{galley2}.} % \begin{macrocode} \rlap{ \raisebox{\initial@raise} [\initial@height] [\z@] {\box\initial@box} } \kern\parshape@firstlineindent } % \end{macrocode} % If there is any text that should be treated specially (in % argument \#3) then we typeset that now otherwise we are done. % \begin{macrocode} \IfValueT{#3} { \initial@textformat{#3} } } % \end{macrocode} % % \begin{macrocode} \catcode`\:=12\relax % % \end{macrocode} % % % % % \subsection{The document commands} % % \begin{macrocode} %<*signature> \RequirePackage{xinitials} \RequirePackage{xparse} \IgnoreWhiteSpace % \end{macrocode} % % % \begin{macro}{\Initial} % Default document command which takes one mandatory argument (the % initial) and two optional arguments (any ``quote material'' and % any text handled specially). % % It runs the instance \texttt{initial}/\meta{initial-char} (i.e., % a different instance per character) if defined or otherwise runs % the instance \texttt{initial/default}. Thus a class providing % this command has to define at least the latter instance. % \begin{macrocode} \DeclareDocumentCommand \Initial {omo} { \IfExistsInstanceTF{initial}{#2} {\UseInstance{initial}{#2}} {\UseInstance{initial}{default}} {#1}{#2}{#3} } % \end{macrocode} % \end{macro} % % % \begin{macro}{\ExtendedInitial} % An extension of the above document command is the following % version. This form of |\ExtendedInitial| will support a star % form, which, if used, expects an optional argument that contains % key value settings for the \texttt{std} template of type % \texttt{initial}. It is then followed by three more arguments % like in the case if the |\Initial| command. If no star is present % then the optional second argument is interpreted as an instance % name of type \texttt{initial}. If that instance exist it will be % used otherwise the instance with name \texttt{default} will be % used. This way it is possible to place into the mandatory % argument (argument 4) any character specification including % accents. % \begin{macrocode} \DeclareDocumentCommand \ExtendedInitial {so omo} { \IfBooleanTF{#1} {\UseTemplate{initial}{std}{#2}{#3}{#4}{#5}} {\IfExistsInstanceTF{initial}{#2} {\UseInstance{initial}{#2}} {\UseInstance{initial}{default}} {#3}{#4}{#5} } } % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \Finale %