% \iffalse meta-comment
%
% Copyright (C) 2004 by Philip G. Ratcliffe <philip.ratcliffe@uninsubria.it>
%
% This file may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, either version 1.2 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.2 or later is part of all distributions of LaTeX
% version 1999/12/01 or later.
%
% \fi
%
% \iffalse
%
%<package>\NeedsTeXFormat{LaTeX2e}[1995/12/01]
%<package>\ProvidesPackage{tensor}
%<package>   [2004/12/20 v2.1 tensor indices package (PGR)]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{tensor}
\providecommand\DescribeOther[1]{%
  \leavevmode
  \marginpar{\raggedleft\PrintDescribeEnv{#1}}%
  \index{#1|usage}%
}
\CodelineIndex
\EnableCrossrefs
\RecordChanges
%
\begin{document}
  \DocInput{tensor.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{269}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v1.0}{1996/06/03}{original version}
% \changes{v2.0}{2004/04/01}{extended \cs{tensor}, added \cs{indices} and
%   \cs{nuclide}, substituted \cs{DeclareRobustCommand} for \cs{newcommand} in
%   user commands, documented and packaged}
%
% \GetFileInfo{tensor.sty}
%
% \DoNotIndex{\CodelineIndex,\EnableCrossrefs,\RecordChanges}
%
% \title{
%   The \textsf{tensor}\relax
%   \thanks{
%     This file has version number \fileversion, and revision date \filedate.}
%   \thanks{
%     Based on and extending the original package of the same name by Mike Piff
%     (1996/06/03).}
%   \space
%   package for \LaTeX2e
% }
% \author{
%   Philip G. Ratcliffe\thanks{E-mail: \textsf{philip.ratcliffe@uninsubria.it}}
% \\
%   Dipartimento di Fisica e Matematica
% \\
%   Universit\`{a} degli Studi dell'Insubria---Como
% }
%
% \date{}
%
% \maketitle
%
% \begin{abstract}
% This is a complete revision and extension of Mike Piff's original |tensor|
% package; it defines two commands for typesetting tensors with mixed upper and
% lower indices in which the correct horizontal spacing must be observed.
% Various forms of alignment are available and spaces may be replaced by dots
% or other symbols. Correct preposing of indices is now made possible while
% backwards compatibility is maintained. A special-purpose command to typeset
% nuclides is also defined.
% \end{abstract}
%
% \section{Introduction}
%
% The use of tensors with mixed upper and lower indices, in which the relative
% horizontal positions and spacing are significant, is common in both
% physics and mathematics; for example,
% \begin{displaymath}
%   \Gamma\indices{^\mu_{\nu\rho}},\quad R\indices{^\mu_\nu^\rho_\sigma}
%   \quad\mathrm{or}\quad
%   \epsilon\indices{^\mu^\nu^\rho_\sigma}.
% \end{displaymath}
% The commands defined in this package automatically maintain the correct
% horizontal positioning. Another common need addressed by this
% package is the preposing of upper and lower indices, as in
% \begin{displaymath}
%   \tensor
%     [_{\rm H}]
%     {\langle q',t' \vert \mathcal{U}(t,t') \vert q,t\rangle}
%     {_{\rm H}}
%   \quad\mathrm{or}\quad
%   \nuclide[14][6]{C}.
% \end{displaymath}
% Note the correct spacing of the pre-index H in the above example. It should
% also be noted that constant vertical positioning is maintained for lone
% indices; consider the following (examine carefully the last lower index $o$):
% \begin{displaymath}
%   {\rm M}\indices*{^o_o} \vert \tensor[_o]{{\rm M}}{}
%   \quad\mbox{\emph{cf.}}\quad
%   {\rm M}^o_o \vert _o{\rm M},
% \end{displaymath}
% where the former group was typeset using \cs{indices} but the latter not.
%
% \section{Usage}
%
% Two robust math-mode commands, \cs{tensor} and \cs{indices}, are defined (the
% first of which remains backward compatible with Mike Piff's original
% definition). A new, robust text- and math-mode command, \cs{nuclide}, is also
% defined specifically for typesetting nuclides, as in the above example.
%
% \subsection{User commands}
%
% \DescribeMacro{\indices}
% To produce a mathematical expression (typically a tensor) with mixed upper
% and lower indices, simply enter
% \meta{object}|\indices{|\relax
%   |^|\meta{sup$_{\,1}$}|_|\meta{sub$_{\,1}$}\relax
%   |^|\meta{sup$_{\,2}$}|_|\meta{sub$_{\,2}$}\relax
% \dots|}|.
% Thus, in math mode it is sufficient to type, \emph{e.g.},
% \begin{center}
%   |M\indices{^a_b^{cd}_e}|\quad to obtain\quad
%   $M\indices{^a_b^{cd}_e}$.
% \end{center}
%
% \DescribeMacro{\tensor}
% This variant has been retained in a backward compatible form and considerably
% extended; the syntax for the previous expression is |\tensor{M}{^a_b^{cd}_e}|
% while the resulting output is identical. The extended form of \cs{tensor} now
% defined has an optional argument for indices to be placed \emph{before} the
% tensor, thus:
% \begin{center}
%   |\tensor[^a_b^c_d]{M}{^a_b^c_d}|\quad produces\quad
%   $\tensor[^a_b^c_d]{M}{^a_b^c_d}$
% \end{center}
% A fairly robust (if somewhat crude) attempt is made to ensure the correct
% spacing and skew of the preposed indices with respect to the tensor object
% itself.
%
% \DescribeMacro{\indices*}
% \DescribeMacro{\tensor*}
% The two commands have starred forms, which collapse the spacing (\emph{i.e.},
% return to standard form). While \cs{indices*} is clearly redundant (and is
% included merely for symmetry), \cs{tensor*} also \emph{right} justifies the
% \emph{pre}-index strings, so that, \emph{e.g.}, nuclides may be typeset as
% follows (though see below for a purpose-built command):
% \begin{center}
%   |\tensor*[^{14}_6]{\mathrm{C}}{}|\quad produces\quad
%   $\tensor*[^{14}_6]{\mathrm{C}}{}$.
% \end{center}
% For those familiar with the |amsmath| package, this is more-or-less a
% generalisation of (though \emph{not intended} as a substitute for) the
% \cs{sideset} command (which itself is \emph{only valid} for objects defined
% with \cs{mathop}). Note that to use \cs{tensor*} as a substitute for
% \cs{sideset}, it is necessary to insert a \cs{nolimits} command, thus:
% \begin{center}
%   |\tensor*[^*_*]{\prod\nolimits}{^*_*}|\quad produces\quad
%   $\displaystyle\tensor*[^*_*]{\prod\nolimits}{^*_*}$.
% \end{center}
% The output appears identical to that of |\sideset{_*^*}{_*^*}{\prod}|.
%
% \DescribeOther{* argument}
% The \cs{indices*} and \cs{tensor*} forms \emph{only}, allow a |*| to also be
% placed as the first entry in either index-list argument, causing alignment
% (\emph{left} justification) of the successive pairs of upper and lower
% indices. A warning is issued if a |*| appears in an argument string of either
% \emph{non}-starred commands. Thus,
% \begin{center}
%   |\tensor*{M}{*^{i_1}_{m_1}^{i_2}_{m_2}^{i_3}_{m_3}^{i_4}_{m_4}}|
% \\[2ex]
%   produces\hspace{\stretch{2}}
%   $\tensor*{M}{*^{i_1}_{m_1}^{i_2}_{m_2}^{i_3}_{m_3}^{i_4}_{m_4}}$\quad
%   (\emph{cf.} $M^{i_1i_2i_3i_4}_{m_1m_2m_3m_4}$).
%   \hspace*{\stretch{2}}
% \end{center}
% Note that \emph{no warning} is issued for improper pairing of successive
% indices.
%
% \DescribeMacro{\indexmarker}
% In analogy with the |tensind| package, the command \cs{indexmarker} (by
% default empty) may redefined (using \cs{renewcommand}) to introduce a visible
% place marker for the index spaces (though not all |tensind| functionality is
% reproduced here); a simple possibility is
% \begin{center}
% \vspace*{-2ex}
% |\renewcommand\indexmarker{\cdot}|,
% \\
%   after which,\hspace*{\stretch{2}}
% \\
%   |\tensor{M}{^a_b^c_d}|
% \\[2ex]
%   produces\hspace{\stretch{2}}
%   $\renewcommand\indexmarker{\cdot}\tensor{M}{^a_b^c_d}$\quad instead of\quad
%   $\tensor{M}{^a_b^c_d}$ \hspace*{3.5em}\hspace*{\stretch{2}}
% \end{center}
%
% \DescribeMacro{\nuclide}
% This command, available in both math and text modes, is defined with the same
% purpose and result as the \cs{isotope} command (from the package of the same
% name). The syntax is
% \begin{center}
%   |\nuclide[|\meta{mass no.}|][|\meta{atomic no.}|]{|\meta{symbol}|}|.
% \end{center}
% Thus, the earlier example of $\nuclide[14][6]{C}$ is obtained with
% |\nuclide[14][6]{C}| while |\nuclide[4][2]{\alpha}| gives
% $\nuclide[4][2]{\alpha}$. As indicated by the square brackets, the
% \meta{mass no.} and \meta{atomic no.} arguments are optional. Note that there
% is a little more space (|1mu|) between the numbers and the chemical symbol
% than appears in the example constructed manually with \cs{tensor*}.
%
% All the above-defined commands may be used recursively, \emph{i.e.}, a
% \cs{tensor} may occur as an index to another \cs{tensor} and should behave
% according to the current superscript--subscript level. Where useful, user
% commands are defined as `robust'; thus, they may appear as arguments to
% \cs{caption}, \cs{section} \emph{etc}.
%
% \DescribeMacro{\nuclideFont}
% By default, the font for \cs{nuclide} is \cs{mathrm}, but \cs{nuclideFont}
% may be reset with \cs{renewcommand} to \cs{mathsf}, \cs{mathbf}, \cs{mathtt}
% \emph{etc}., or simply \cs{relax} (this last has the chemical symbol font
% default to \cs{mathit} for correct spacing).
%
% \subsection{Caveats}
%
% Grouping of multi-token indices should be performed as normal (\emph{i.e.},
% via enclosure within a brace pair |{|\,|}|). Moreover, owing to the method by
% which index strings are parsed, any index constructs such as |\mathrm{H}|
% must also be entirely enclosed in braces, thus: |\indices{_{\mathrm{H}}^x}|.
%
% Spacing is not guaranteed to always appear absolutely perfect, especially
% between \emph{pre}-pended indices and the tensor object itself. Please also
% recall, however, that screen viewing often distorts small spaces owing to
% resolution effects.
%
% \subsection{External package requirements}
%
% No external packages are required.
%
% \subsection{Package conflicts}
%
% There are no known conflicts with any standard \LaTeX2e\ packages (a problem
% with the |color| package in the first version has now been corrected).
% However, there is obvious incompatibility with the similar |tensind| package.
%
% \StopEventually{\PrintChanges\PrintIndex}
%
% \section{Implementation}
%
% \subsection{User commands}
%
% The |tensor| package now defines three basic user commands:
% \begin{macro}{\tensor}
% The first takes three possible arguments (an optional index string to be
% \emph{preposed}, the tensor object, the index string) and also has a starred
% form, which suppresses spacing (it is backward compatible with Mike Piff's
% original version).
%    \begin{macrocode}
\DeclareRobustCommand\tensor{%
  \tnsr@Prp
  \@ifstar{\tnsr@Spcfalse\tnsr@Aux}{\tnsr@Spctrue\tnsr@Aux}%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\indices}
% The second command is a ``lightweight'' form, which is placed immediately
% \emph{following} the tensor object, takes just one argument (the index
% string) and also has a starred form (this command was \emph{not} present in
% the original package).
% \changes{v2.1}{2004/12/20}{added starred form, for symmetry with
%   \cs{tensor*}}
%    \begin{macrocode}
\DeclareRobustCommand\indices{%
  \tnsr@Prp
  \@ifstar{\tnsr@Spcfalse\ndcs@Aux}{\tnsr@Spctrue\ndcs@Aux}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\nuclide}
% This additional new command takes one direct argument (an optional mass
% number) and two indirect arguments (an optional atomic number, the chemical
% symbol---these last two are handled by auxiliary macros). Since usage is
% common in text, math mode is ensured.
%    \begin{macrocode}
\DeclareRobustCommand\nuclide[1][]{%
  \ncld@Mno{#1}%
  \ncld@Aux
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\nuclideFont}
% This sets the font for \cs{nuclide} (the default is \cs{mathrm}); it may be
% redefined as, \emph{e.g.}, \cs{mathsf}, \cs{mathbf}, \cs{mathtt}, \cs{mathit}
% \emph{etc}., or even simply \cs{relax} (this last has the chemical symbol
% font default to \cs{mathit} for correct spacing).
%    \begin{macrocode}
\newcommand\nuclideFont{\mathrm}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Internal token registers}
%
% \begin{macro}{\tnsr@Sps}
% \begin{macro}{\tnsr@Sbs}
% \begin{macro}{\tnsr@Spe}
% \begin{macro}{\tnsr@Sbe}
% The token registers that hold the upper and lower index strings, and the most
% recent upper and lower index elements respectively:
%    \begin{macrocode}
\newtoks\tnsr@Sps
\newtoks\tnsr@Sbs
\newtoks\tnsr@Spe
\newtoks\tnsr@Sbe
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\ncld@Mno}
% This token register temporarily holds the mass number for \cs{nuclide}.
%    \begin{macrocode}
\newtoks\ncld@Mno
%    \end{macrocode}
% \end{macro}
%
% \subsection{Internal switches}
%
% \begin{macro}{\iftnsr@Spc}
% The switch to select or suppress index element spacing.
%    \begin{macrocode}
\newif\iftnsr@Spc
%    \end{macrocode}
% \end{macro}
%
% \subsection{Internal macros}
%
% \begin{macro}{\tnsr@Prp}
% Here we simply reset token registers and the warning macro before commencing.
%    \begin{macrocode}
\newcommand\tnsr@Prp{%
  \tnsr@Sps{}%
  \tnsr@Sbs{}%
  \let\tnsr@Wrn\relax
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ndcs@Aux}
% This (lightweight) auxiliary macro for \cs{indices} takes one argument (an
% index string); it calls \cs{tnsr@Set}, prints the indices and then issues any
% warnings.
%    \begin{macrocode}
\newcommand\ndcs@Aux[1]{%
  \def\tnsr@Obj{}
  \tnsr@Set{#1}%
  \tnsr@Fin
  \tnsr@Wrn
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Aux}
% This auxiliary macro for \cs{tensor} takes three possible arguments (an
% optional pre-index string, the tensor object, the post-index string) and
% passes everything via \cs{mathpalette} to \cs{tnsr@Plt}.
%    \begin{macrocode}
\newcommand\tnsr@Aux[3][]{%
  \mathpalette{\tnsr@Plt{#1}{#3}}{#2}%
  \tnsr@Wrn
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Plt}
% This takes four arguments (the pre-index string---may be empty, the
% post-index, the current math style, the tensor object) and calls
% \cs{tnsr@Set} separately for both pre- and post-index strings.
%    \begin{macrocode}
\newcommand\tnsr@Plt[4]{%
  \def\tnsr@Obj{#3#4}
  \def\reserved@a{#1}%
  \ifx\reserved@a\@empty\else
    \tnsr@Set{#1}%
    \hphantom{{}\tnsr@Fin}%
    \tnsr@Sps\expandafter{%
      \expandafter\tnsr@Krn\expandafter{\the\tnsr@Sps}%
    }%
    \tnsr@Sbs\expandafter{%
      \expandafter\tnsr@Krn\expandafter{\the\tnsr@Sbs}%
    }%
  \fi
  \tnsr@Set{#2}%
  #4\tnsr@Fin
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Set}
% This takes one argument (a pre- or post-index string) and starts processing.
%    \begin{macrocode}
\newcommand\tnsr@Set[1]{%
  \let\tnsr@Swx\relax
  \tnsr@Pro#1\tnsr@Err
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Krn}
% This has one argument (a processed index string) and inserts the necessary
% offsets.
% \changes{v2.1}{2004/12/20}{altered spacing slightly}
%    \begin{macrocode}
\newcommand\tnsr@Krn[1]{%
  \settowidth\@tempdima{$\m@th\tnsr@Obj^{#1}\mkern-1mu$}%
  \kern-\@tempdima
  #1
  \settowidth\@tempdima{$\m@th\tnsr@Obj$}%
  \kern\@tempdima
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Pro}
% This is the index-string processing macro, it takes one argument (an index
% string):
%    \begin{macrocode}
\newcommand\tnsr@Pro[1]{%
  \ifx#1\tnsr@Err
    \let\tnsr@Nxt\relax
  \else
    \ifx#1*
      \iftnsr@Spc
        \gdef\tnsr@Wrn{%
          \PackageWarning{tensor}{%
            `*' not allowed in argument here, I am ignoring it,%
            \MessageBreak remove it or use `\string\tensor*',%
          }%
        }%
      \else
        \let\tnsr@Swx\tnsr@Swa
      \fi
      \let\tnsr@Nxt\tnsr@Pro
    \else
      \ifx#1^
        \def\tnsr@Nxt{\tnsr@Add{\tnsr@Sps}{\tnsr@Sbs}{\tnsr@Spe}}%
      \else
        \ifx#1_
          \def\tnsr@Nxt{\tnsr@Add{\tnsr@Sbs}{\tnsr@Sps}{\tnsr@Sbe}}%
        \else
          \tnsr@Err
          \let\tnsr@Nxt\tnsr@Pro
        \fi
      \fi
    \fi
  \fi
  \tnsr@Nxt
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Swa}
% Here we flip the state of \cs{tnsr@Swx} to \cs{tnsr@Swb}.
%    \begin{macrocode}
\newcommand\tnsr@Swa{\let\tnsr@Swx\tnsr@Swb}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Swb}
% Here we flip the state of \cs{tnsr@Swx} to \cs{tnsr@Swa} then calculate and
% insert the necessary padding for index alignment.
%    \begin{macrocode}
\newcommand\tnsr@Swb{%
  \let\tnsr@Swx\tnsr@Swa
  \settowidth\@tempdima{$\m@th\tnsr@Obj{}^{\the\tnsr@Spe}$}%
  \settowidth\@tempdimb{$\m@th\tnsr@Obj{}_{\the\tnsr@Sbe}$}%
  \addtolength\@tempdima{-\@tempdimb}%
  \ifdim\@tempdima=\z@\else
    \ifdim\@tempdima>\z@
      \tnsr@Sbs\expandafter\expandafter\expandafter{%
        \expandafter\the\expandafter\tnsr@Sbs
        \expandafter\kern\the\@tempdima
      }
    \else
      \@tempdima=-\@tempdima
      \tnsr@Sps\expandafter\expandafter\expandafter{%
        \expandafter\the\expandafter\tnsr@Sps
        \expandafter\kern\the\@tempdima
      }
    \fi
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Add}
% This macro takes four arguments (the token-register target for the next index
% token, the token-register target for the phantom element, the token-register
% target for the most-recent element, the next index token). It adds the next
% index token to the upper or lower string and (if spacing is \emph{on}) a
% place-holder (\cs{tnsr@Hph}) of the same size to the lower or upper string,
% respectively. It also calls \cs{tnsr@Swx} to flip state (if activated). The
% use of \cs{leavevmode} is necessary to avoid conflict with the |color|
% package.
% \changes{v2.1}{2004/12/20}{added \cs{leavevmode}, to avoid \textsf{color}
%   package conflict}
%    \begin{macrocode}
\newcommand\tnsr@Add[4]{%
  #1\expandafter{\the#1\leavevmode{#4}}%
  \iftnsr@Spc
    #2\expandafter{\the#2\tnsr@Hph{#4}}%
  \fi
  #3{\leavevmode{#4}}%
  \tnsr@Swx
  \tnsr@Pro
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Hph}
% The place-holder macro, uses \cs{mathpalette} to call the contents
% \cs{tnsr@Mph}:
%    \begin{macrocode}
\newcommand\tnsr@Hph{\expandafter\mathpalette\expandafter\tnsr@Mph}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Mph}
% The place-holder macro contents:
% \changes{v2.1}{2004/12/20}{substituted \cs{hbox} with \cs{makebox}}
%    \begin{macrocode}
\newcommand\tnsr@Mph[2]{%
  \settowidth\@tempdima{$\m@th#1{#2}$}%
  \makebox[\@tempdima][c]{$\m@th#1\indexmarker$}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\indexmarker}
% The default (blank) placeholder for index spacing:
% \changes{v2.1}{2004/12/20}{added capability to insert place holders}
%    \begin{macrocode}
\newcommand\indexmarker{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Fin}
% Finally, we put the index strings into place:
%    \begin{macrocode}
\newcommand\tnsr@Fin{^{\the\tnsr@Sps}_{\the\tnsr@Sbs}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ncld@Aux}
% This auxiliary macro takes two arguments (an optional atomic number, a
% chemical symbol). The mass number is passed via \cs{ncld@Mno}. Math mode is
% ensured since usage is common in text. The spacing is increased by |1mu| for
% better appearance.
%    \begin{macrocode}
\newcommand\ncld@Aux[2][]{%
  \ensuremath{%
    \tensor*[^{\nuclideFont{\the\ncld@Mno}}_{\nuclideFont{#1}}]%
      {\mkern1mu{\mathit{\nuclideFont{#2}}{}}}{}%
  }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tnsr@Err}
% This is invoked in the only error situation considered.
%    \begin{macrocode}
\newcommand\tnsr@Err{%
  \PackageError{tensor}{%
    Sub/Superscript items out of order\on@line,
    \MessageBreak some index tokens may now have been lost%
  }{An index string has an extra or missing `^' or `_' token.}%
}
%    \end{macrocode}
% \end{macro}
%
% \Finale
%
\endinput
%%
%% End of file `tensor.dtx'.