% \iffalse meta-comment % %% File: tensor.dtx %% % Copyright (C) 2023 Philip G. Ratcliffe % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file % % http://www.latex-project.org/lppl.txt % % This file is part of the "tensor package" (the Work in LPPL) % and all files in that package must be distributed together. % % The released version of this package is available from CTAN. % % This package has the LPPL maintenance status "maintained". % % The current maintainer of this package is Philip G. Ratcliffe. % % \fi % % \iffalse % %\NeedsTeXFormat{LaTeX2e}[1995/12/01] %\ProvidesPackage{tensor} % [2023/07/18 v2.2 tensor indices package (PGR)] % %<*driver> \documentclass{ltxdoc} \usepackage{tensor} \NewDocElement[macrolike=false]{Argument}{argument} \NewDocElement[macrolike=false]{Option}{option} % \CodelineIndex \EnableCrossrefs \RecordChanges \DoNotIndex{\let,\def,\gdef,\newcommand,\renewcommand} \DoNotIndex{\if,\else,\fi,\ifx,\fi,\iffalse,\fi,\iftrue,\fi} \DoNotIndex{\@empty,\expandafter,\makebox,\relax,\string,\the,\z@} \DoNotIndex{\MessageBreak,\on@line} % \begin{document} \DocInput{tensor.dtx} \end{document} % % \fi % % \CheckSum{342} % % \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{newcommand} with \cs{DeclareRobustCommand} in % user commands, documented and packaged} % % \GetFileInfo{tensor.sty} % % \DoNotIndex{\CodelineIndex,\EnableCrossrefs,\RecordChanges} % % \title{% % The \textsf{tensor}\relax % \,\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\relax % \,\thanks{E-mail: \textsf{philip.ratcliffe@uninsubria.it}} % \\ % Dipartimento di Scienza e Alta Tecnologia % \\ % Universit\`a degli Studi dell'Insubria---Como % } % % \date{(\fileversion, last revision \filedate)} % % \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. Consistent 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} % % It is common in both physics and mathematics to use tensors with mixed upper % and lower indices in which the relative horizontal positions and spacing are % significant, 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 macros defined in this package automatically maintain consistent % horizontal positioning. Another common need addressed 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$ % on the right): % \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}, the latter using `|_|' % and `|^|'. % % \section{Usage} % % Two robust math-mode commands, \cs{tensor} and \cs{indices}, are defined (the % first of which remains backwards 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{|% % |^|\meta{sup$_{\,1}$}|_|\meta{sub$_{\,1}$}% % |^|\meta{sup$_{\,2}$}|_|\meta{sub$_{\,2}$}% % \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 completely backwards compatible form % while also being considerably extended; the syntax for the previous % expression is |\tensor{M}{^a_b^{cd}_e}|, for which the resulting output is % identical. The extended form of \cs{tensor} defined here has an optional % argument for indices to be placed \emph{before} the tensor, thus: % \begin{center} % |\tensor[^a_b^c_d]{M}{^e_f^g_h}|\quad produces\quad % $\tensor[^a_b^c_d]{M}{^e_f^g_h}$. % \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. % % Note that also \cs{sb} and \cs{sp} may be used in place of `|_|' and `|^|' % respectively for both the above macros. % % \DescribeMacro{\indices*} % \DescribeMacro{\tensor*} % These two macros 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}|. % % \DescribeArgument{*} % The \cs{indices*} and \cs{tensor*} forms \emph{alone}, 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}| % \\[1ex] % produces\hspace*{\stretch{2}}\null % \\ % $\renewcommand\indexmarker{\cdot}\tensor{M}{^a_b^c_d}$\quad instead of\quad % $\tensor{M}{^a_b^c_d}$\,. % \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. The user commands are % defined here as `robust'; they may thus appear as so-called moving arguments, % \emph{i.e.} to \cs{caption}, \cs{section} \emph{etc}. % % \DescribeMacro{\nuclideFont} % \DescribeMacro{\massnumFont} % By default, the fonts used in \cs{nuclide} for the chemical symbol, mass and % atomic numbers are \cs{mathrm}; \emph{i}.\emph{e}., \cs{nuclideFont} (for the % chemical symbol) is initially defined as \cs{mathrm} and \cs{massnumFont} % (for the mass/atomic numbers) as \cs{nuclideFont} (for backwards % compatibility). This then now allows for independent font variation of the % chemical symbol and mass/atomic numbers. Both macros may be reset with % \cs{renewcommand} to \cs{mathsf}, \cs{mathbf}, \cs{mathtt} \emph{etc}., or % simply \cs{relax} (this last for \cs{nuclideFont} has the chemical symbol % font default to \cs{mathit} for correct spacing, while for \cs{massnumFont} % the mass and atomic numbers revert to standard math font). % % \subsection{Package options} % % As of v2.2, the package includes four options relating to the vertical % alignment of indices. \LaTeX's behaviour in this regard is not always optimal % or what the user may desire. Consider the following output (constructed using % `|_|' and `|^|'.): % \begin{displaymath} % \epsilon\indices{^\mu_\rho^\nu_{\tilde\lambda}} \; % g\indices{^\mu^\nu} \,. % \end{displaymath} % While the indices within each single mathematical object are mutually % vertically aligned correctly, between separate objects they may not be. This % is because \LaTeX\ sets the baseline according to the height and depth of the % given indices on a per-object basis. To obviate such behaviour, this package % takes the simplest route of using \cs{smash} to hide the height and depth of % each superscript and subscript string so that they are always set with the % same baselines. This naturally leads to a somewhat cramped form (superscripts % are set a little too low and subscripts high) and so a specially defined % \cs{strut} is included, which slightly raises superscripts and lowers % subscripts; by default, this is only implemented in displayed math, as the % impact on inline text may be too disruptive. % % \DescribeOption{align} % \DescribeOption{text} % \DescribeOption{nosmash} % \DescribeOption{nostrut} % The options thus introduced are |align|, |text|, |nosmash| and |nostrut|. The % first implements both \cs{smash} and a \cs{strut} as outlined above, with % |text| extending the implementation of the \cs{strut} to inline text, while % |nosmash| and |nostrut| cancel the single effects (using both entirely % negates |align|). Option ordering is irrelevant and the last three are % inoperative without the first. % % The desired effects are implemented via two internal commands, which may also % be redefined by the user. % \DescribeMacro{\tensorSmash} % The first, \cs{tensorSmash}, is set equal to \cs{smash}, which then takes each % index string as an argument. % \DescribeMacro{\tensorStrut} % The second, \cs{tensorStrut}, is set equal to the height of `|l|' and depth % of `|j|' in the relevant font, (by default though only inside displayed math % environments) and is appended to each \cs{smash}'ed index string. % % \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 optimal, especially when between % \emph{pre}-pended indices and the tensor object itself. Recall too that % screen viewing often distorts small spaces owing to resolution effects. % % \subsection{External package requirements} % % No external packages are required or called. % % \subsection{Package conflicts} % % There are few conflicts with standard \LaTeX2e\ packages; a problem with the % |color| package in the first version has now been corrected, as too a % recently flagged problem with the |underscore| package. % % However, the macros defined here fail as arguments of \cs{bm} from the |bm| % package (due to parsing conflicts) or, consequently, of macros defined by the % \cs{maybebm} package. A work around for, say, a chapter or section header is % \begin{center} % |{\let\nuclideFont\maybebm \nuclide[4][2]{\textup{He}}}|, % \end{center} % which should render \nuclide[\mathbf4][\mathbf2]{\textbf{He}} in the header, % but \nuclide[4][2]{\textup{He}} in the contents listing. % % \StopEventually{\PrintChanges\PrintIndex} % % \section{Implementation} % % \subsection{User options} % % First, the package options with their related \cs{if}\dots\ conditionals are % defined and processed. % \begin{macrocode} \newif\iftnsr@Aln \DeclareOption{align}{\tnsr@Alntrue} \newif\iftnsr@Txt \DeclareOption{text}{\tnsr@Txttrue} \newif\iftnsr@Sma \tnsr@Smatrue \DeclareOption{nosmash}{\tnsr@Smafalse} \newif\iftnsr@Str \tnsr@Strtrue \DeclareOption{nostrut}{\tnsr@Strfalse} \ProcessOptions % \end{macrocode} % % \subsection{User commands} % % The |tensor| package 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 backwards 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 is a `\emph{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 form was \emph{not} however 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 an auxiliary macro). 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} % \begin{macro}{\massnumFont} % These set the fonts for \cs{nuclide}; the defaults are \cs{mathrm} for both % \cs{nuclideFont} and \cs{massnumFont}. They may be redefined as \emph{e.g.} % \changes{v2.2}{2023/07/18}{added independent mass/atomic-no.\ font control} % \cs{mathsf}, \cs{mathbf}, \cs{mathtt}, \cs{mathit} \emph{etc}., or even % simply \cs{relax} or \cs{renewcommand}\cs{nuclideFont}|{}|. % \begin{macrocode} \newcommand\nuclideFont{\mathrm} \newcommand\massnumFont{\nuclideFont} % \end{macrocode} % \end{macro} % \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} % \begin{macro}{\tnsr@Wrn} % Here we simply reset token registers and the warning macro before commencing. % \begin{macrocode} \newcommand\tnsr@Wrn{} \newcommand\tnsr@Prp{% \tnsr@Sps{}% \tnsr@Sbs{}% \def\tnsr@Wrn{} } % \end{macrocode} % \end{macro} % \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]{% \tnsr@Erx \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][]{% \tnsr@Erx \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\tnsr@Tmp{#1}% \ifx\tnsr@Tmp\@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}{slightly altered spacing} % \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): % \changes{v2.2}{2023/07/18}{substituted \cs{ifx} with \cs{if} to avoid % \textsf{underscore} package conflict} % \begin{macrocode} \newcommand\tnsr@Pro[1]{% \ifx#1\tnsr@Err \let\tnsr@Nxt\relax \else \if#1* \iftnsr@Spc \gdef\tnsr@Wrn{% \PackageWarning{tensor}{% '*' not allowed in argument here; I shall ignore it.% \MessageBreak Either remove it or use '\string\tensor*'% }% }% \else \let\tnsr@Swx\tnsr@Swa \fi \let\tnsr@Nxt\tnsr@Pro \else \if#1^ \def\tnsr@Nxt{\tnsr@Add{\tnsr@Sps}{\tnsr@Sbs}{\tnsr@Spe}}% \else \if#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 horizontal 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} avoids 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: % \changes{v2.2}{2023/07/18}{added vertical alignment capability} % \begin{macrocode} \newcommand\tnsr@Fin{% ^{\tensorSmash{\the\tnsr@Sps}\tnsr@Str}% _{\tensorSmash{\the\tnsr@Sbs}\tnsr@Str}% } % \end{macrocode} % \end{macro} % \begin{macro}{\tensorSmash} % Initialise \cs{tensorSmash} as \cs{relax} and then conditionally set it equal % to \cs{smash} (it is user redefinable). % \begin{macrocode} \let\tensorSmash\relax \iftnsr@Aln \iftnsr@Sma \let\tensorSmash\smash \fi \fi % \end{macrocode} % \end{macro} % \begin{macro}{\tensorStrut} % \begin{macro}{\tnsr@Str} % Initialise \cs{tensorStrut} as \cs{relax} and then conditionally set it to % the height and depth of `|jl|'. By default, it is only applied to displayed % math environments (passed on via \cs{tnsr@Str}, which is \cs{def}'ed as % \cs{tensorStrut} to be user redefinable), but always (\emph{i.e.} extended to % inline text) if the package option |text| is present. % \begin{macrocode} \newcommand\tensorStrut{} \let\tnsr@Str\relax \iftnsr@Aln \iftnsr@Str \renewcommand\tensorStrut{\vphantom{jl}} \iftnsr@Txt \def\tnsr@Str{\tensorStrut} \else \everydisplay\expandafter{\the\everydisplay\let\tnsr@Str\tensorStrut} \fi \fi \fi % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\ncld@Aux} % This auxiliary macro takes two arguments (an optional atomic number and the % chemical symbol). The mass number is passed on 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*[^{\massnumFont{\the\ncld@Mno}}_{\massnumFont{#1}}]% {\mkern1mu{\mathit{\nuclideFont{#2}}{}}}{}% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\tnsr@Err} % This is invoked in the only error situations considered. % \begin{macrocode} \newcommand\tnsr@Err{} \newcommand\tnsr@Erx{% \def\tnsr@Err{% \global\let\tnsr@Err\relax \PackageError{tensor}{% Misordered sub/superscript items\on@line; \MessageBreak index tokens may have been lost. \MessageBreak Press and I shall try to continue% }{Index string probably has extra/missing '^' or '_'.}% }% } % \end{macrocode} % \end{macro} % % \Finale % \endinput %% %% End of file 'tensor.dtx'.