summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/tensor/tensor.dtx
blob: edbf571b56631a9230b748d720f6bff67f37c1c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
% \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'.