% \iffalse meta-comment % % Copyright (C) 2004 by Philip G. Ratcliffe % % 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 % %\NeedsTeXFormat{LaTeX2e}[1995/12/01] %\ProvidesPackage{tensor} % [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} % % \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'.