% \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}
%</dtx>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{xinitials}
%<signature>\ProvidesFile{xinitials.sig}
%<driver>\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}
%</driver>
% \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
%</package>
%    \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}
%</signature>
%    \end{macrocode}
%
% \Finale
%
