texlive[42225] Master: spalign (7oct16)

commits+karl at tug.org commits+karl at tug.org
Sat Oct 8 00:24:58 CEST 2016


Revision: 42225
          http://tug.org/svn/texlive?view=revision&revision=42225
Author:   karl
Date:     2016-10-08 00:24:58 +0200 (Sat, 08 Oct 2016)
Log Message:
-----------
spalign (7oct16)

Modified Paths:
--------------
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/spalign/
    trunk/Master/texmf-dist/doc/latex/spalign/README.md
    trunk/Master/texmf-dist/doc/latex/spalign/spalign.pdf
    trunk/Master/texmf-dist/source/latex/spalign/
    trunk/Master/texmf-dist/source/latex/spalign/spalign.dtx
    trunk/Master/texmf-dist/source/latex/spalign/spalign.ins
    trunk/Master/texmf-dist/tex/latex/spalign/
    trunk/Master/texmf-dist/tex/latex/spalign/spalign.sty
    trunk/Master/tlpkg/tlpsrc/spalign.tlpsrc

Added: trunk/Master/texmf-dist/doc/latex/spalign/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/spalign/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/spalign/README.md	2016-10-07 22:24:58 UTC (rev 42225)
@@ -0,0 +1,37 @@
+spalign version dated 2016-10-05
+================================
+
+The purpose of this package is to decrease the number of keystrokes needed to
+typeset small amounts of aligned material (matrices, arrays, etc.).  For
+instance, it is inconvenient to type (using the `amsmath` package)
+```latex
+\[\begin{matrix}
+   1 & 12 & -3 \\
+  24 & -2 &  2 \\
+   0 &  0 &  1
+  \end{matrix}\]
+```
+in a document where several hundred such matrices must be typeset.  Of course
+one can always define a macro `\mat` which puts its argument inside a `matrix`
+environment, but it is still necessary to type the align character `&` and the
+end-of-row control sequence `\\` many times for each matrix.
+
+This package provides a facility for typesetting matrices, and for using other
+alignment environments and macros, with spaces as the alignment delimiter and
+semicolons (by default) as the end-of-row indicator.  So the above matrix could
+be produced using the command:
+```latex
+\[ \spalignmat{1 12 -3; 24 -2 2; 0 0 1} \]
+```
+This package also contains utility macros for typesetting augmented matrices,
+vectors, arrays, systems of equations, and more, and is easily extendable to
+other situations that use alignments.
+
+
+## License
+
+Copyright (C) 2016 by Joseph Rabinoff
+
+This material is subject to the 
+[LaTeX Project Public License v1.3](http://www.latex-project.org/lppl.txt)
+


Property changes on: trunk/Master/texmf-dist/doc/latex/spalign/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/spalign/spalign.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/spalign/spalign.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/spalign/spalign.pdf	2016-10-07 22:24:15 UTC (rev 42224)
+++ trunk/Master/texmf-dist/doc/latex/spalign/spalign.pdf	2016-10-07 22:24:58 UTC (rev 42225)

Property changes on: trunk/Master/texmf-dist/doc/latex/spalign/spalign.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/spalign/spalign.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/spalign/spalign.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/spalign/spalign.dtx	2016-10-07 22:24:58 UTC (rev 42225)
@@ -0,0 +1,1211 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2016 by Joseph Rabinoff <rabinoff at math.gatech.edu>
+% -------------------------------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{spalign.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[2005/12/01]
+%<package>\ProvidesPackage{spalign}
+%<*package>
+    [2016/10/05 aligns delimited by spaces]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{spalign}[2016/10/05]
+\usepackage[charter,sfscaled,ttscaled,cal=cmcal]{mathdesign}
+\usepackage{amsmath}
+
+\def\usage#1#2{\textbf{Usage:} \texttt{\string#1} #2\vadjust{\vskip 1ex}\\}
+
+\newdimen\poptskip\poptskip=1.3cm
+\advance\poptskip by 1ex
+\def\poption #1:{%
+  \hangindent=\poptskip\hangafter=1%
+  \noindent\hbox to 1.3cm{\hfil\bf#1:}\hskip 1ex%
+  }
+\def\endopt{\par\vskip2pt}
+
+\let\tvs=\textvisiblespace
+
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\begin{document}
+  \DocInput{spalign.dtx}
+  \PrintChanges
+  \PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \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}{2016/10/05}{Initial version}
+%
+% \GetFileInfo{spalign.dtx}
+%
+% \DoNotIndex{\newcommand,\newenvironment}
+%
+%
+% \title{The \textsf{spalign} package\thanks{This document
+%   corresponds to the version of \textsf{spalign} dated \filedate.}}
+% \author{Joseph Rabinoff \\ \texttt{rabinoff at math.gatech.edu}}
+%
+% \maketitle
+%
+% \section{Introduction}
+%
+% The purpose of this package is to decrease the number of keystrokes needed to
+% typeset small amounts of aligned material (matrices, arrays, etc.).  For
+% instance, it is inconvenient to type (using the \textsf{amsmath} package)
+% \begin{verbatim}
+%    \[ \begin{matrix}
+%          1 & 12 & -3 \\
+%         24 & -2 &  2 \\
+%          0 &  0 &  1
+%       \end{matrix} \]\end{verbatim}
+% in a document where several hundred such
+% matrices must  be typeset.  Of course
+% one can always define a macro |\mat| which puts its argument inside a
+% |matrix| environment, but it is still necessary to type the align character
+% |&| and the end-of-row control sequence |\\| many times for each matrix.
+%
+% This package provides a facility for typesetting matrices, and using other
+% alignment environments and macros, with spaces as the
+% alignment delimiter and semicolons (by default) as the end-of-row indicator.  So
+% the above matrix could be produced using the command:
+% \begin{verbatim}
+%    \[ \spalignmat{1 12 -3; 24 -2 2; 0 0 1} \]\end{verbatim}
+% This package also contains utility macros for typesetting augmented matrices,
+% vectors, arrays, and more, and is easily extendable to other situations that use
+% alignments.
+%
+% \section{Usage}
+%
+% In~\S\ref{sec:alignment} the simplified alignment format used by arguments to
+% macros in this package is described.  In~\S\ref{sec:utility} the utility
+% macros provided by the \textsf{spalign} package are presented; these are the
+% macros that most users will need.  Section~\ref{sec:options} contains the
+% package options.  The macros designed to allow the user to adapt the
+% \textsf{spalign} package to other situations are presented
+% in~\S\ref{sec:general}.
+%
+% \subsection{Alignment format}\label{sec:alignment}
+% The core functionality of the \textsf{spalign} package is to convert spaces to
+% alignment characters `|&|' and semicolons to end-of-row control sequences
+% `|\\|'.  This process is called \textit{retokenization}.  The retokenization
+% procedure is designed to work more or less how one would expect.
+% Retokenization of a string \meta{text} proceeds as follows.
+% \begin{enumerate}
+% \item Spaces at the beginning and end of \meta{text} are ignored, as are
+%   spaces at the beginning and end of a line, and spaces before and after a
+%   semicolon or a comma.
+% \item Multiple spaces are combined into one space.
+% \item Spaces between non-space characters are converted to |&| (really, to
+%   the contents of |\spalignaligntab|).
+% \item Commas (really, the contents of |\spalignseparator|) are also converted to
+% |&|.
+% \item Semicolons (really, the contents of |\spalignendofrow|) are
+%   converted to |\\| (really, to the contents of |\spalignendline|).
+% \item Text in braces |{...}| is treated as a unit: the contents are not
+%   retokenized, and the braces are preserved.
+% \end{enumerate}
+% These rules are best understood by example.
+%
+% \medskip\noindent\textbf{Example.} The command
+% \begin{verbatim}
+%    \[ \spalignmat{ 1
+%         -2 3 ; 4
+%         55 2^3;
+%         \frac{1 1}2 {1
+%         3} {1 0 1} } \]\end{verbatim}
+% produces
+% \[\spalignmat{ 1
+%        -2 3 ; 4
+%        55 2^3 ;
+%        \frac{1 1}2 {1
+%        3} {1 0 1} }.
+% \]
+%
+% \medskip\noindent\textbf{Example.} The command
+% \begin{verbatim}
+%    \[ \spalignmat{ \cos\theta, \sin\theta;
+%       -\sin\theta, \cos\theta} \]\end{verbatim}
+% produces
+% \[\spalignmat{ \cos\theta, \sin\theta;
+%      -\sin\theta, \cos\theta}.
+% \]
+% Here the commas are necessary: \TeX\ will not tokenize spaces following a
+% command sequence, so
+% \begin{verbatim}
+%    \[ \spalignmat{ \cos\theta \sin\theta;
+%       -\sin\theta \cos\theta} \]\end{verbatim}
+% produces the (presumably unexpected) result
+% \[\spalignmat{ \cos\theta \sin\theta;
+%      -\sin\theta \cos\theta}.
+% \]
+% Instead of commas, one could also type, for instance,
+% \begin{verbatim}
+%    \[ \spalignmat{ \cos\theta{} \sin\theta;
+%       -\sin{\theta} \cos\theta} \]\end{verbatim}
+% 
+% \medskip\noindent\textbf{Example.} The fact that expressions between braces
+% |{...}| are not retokenized allows for arbitrarily complex entries in
+% \textsf{spalign} macros---although these macros are probably not terribly
+% useful in such cases.  The \textsf{spalign} macros can even be nested: for
+% instance, 
+% \begin{verbatim}
+%    \[ \spalignmat{ \spalignmat{a b; c d} \spalignmat{a' b'; c' d'};
+%         \spalignmat{d e; f g} \spalignmat{d' e'; f' g'} } \] \end{verbatim}
+% produces
+% \[ \spalignmat{ \spalignmat{a b; c d} \spalignmat{a' b'; c' d'};
+%       \spalignmat{d e; f g} \spalignmat{d' e'; f' g'} }. \]
+% 
+%
+% \subsection{Utility macros}\label{sec:utility}
+% Most math-mode utility macros use the |array| environment internally.  This
+% can be the vanilla \LaTeX\ |array| environment, or the one from the
+% \textsf{array} package; it makes no difference.  All math-mode utility macros
+% have an un-starred version and a starred version.  The un-starred version
+% produces arrays with the delimiters defined by the package options
+% (see~\ref{sec:options}), and the starred version omits the delimiters (and the
+% glue between the delimiters and the array).
+%
+% As the only purpose of this package is to save keystrokes, the user may want
+% to put
+% \begin{verbatim}
+%    \let\mat=\spalignmat
+%    \let\amat=\spalignaugmat
+%    \let\vec=\spalignvector\end{verbatim}
+% or something similar after |\usepackage{spalign}|.  Note that |\mat*| will now
+% also be synonymous with |\spalignmat*|, etc.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignarray}
+% \DescribeMacro{\spalignarray*}
+% \usage\spalignarray{\marg{alignment specifier}\marg{text}}
+% Produces a (potentially delimited) |array| environment, passing it
+% \meta{alignment specifier}, after retokenizing \meta{text}.  This is exactly
+% like the matrix environments below, except that it is possible to specify the
+% alignment of each column separately, add vertical bars, etc.
+% For example,
+% \begin{verbatim}
+%    \[ \spalignarray{l|c|r}{1 1 1; 100 100 100} \]\end{verbatim}
+% produces
+% \[ \DeleteShortVerb{\|}
+%    \spalignarray{l|c|r}{1 1 1; 100 100 100}. 
+%    \MakeShortVerb{\|}
+% \]
+% Note that |\spalignarray*| simply produces an |array| environment surrounding
+% the retokenized \meta{text}.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignmat}
+% \DescribeMacro{\spalignmat*}
+% \usage\spalignmat{\oarg{column alignment}\marg{text}}
+% Produces a matrix whose columns are aligned according to the
+% \meta{column alignment}, after retokenizing \meta{text}.  The \meta{column alignment}
+% is an array environment alignment specifier for a single column (usually |l|,
+% |c|, or |r|), which is used for each column.  The default is |c|.  For example,
+% \begin{verbatim}
+%    \[ \spalignmat[l]{1 1 1; 100 100 100} \]\end{verbatim}
+% produces
+% \[ \spalignmat[l]{1 1 1; 100 100 100}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignvector}
+% \DescribeMacro{\spalignvector*}
+% \usage\spalignvector{\oarg{column alignment}\marg{text}}
+% Produces a matrix with one column.  Spaces, commas, and semicolons are all
+% retokenized to the end-of-row control sequence `|\\|'.  The
+% \meta{column alignment} is interpreted as in |\spalignmat|; the default is
+% |c|.  For example,
+% \begin{verbatim}
+%    \[ \spalignvector[r]{1 100 1000} \]\end{verbatim}
+% produces
+% \[ \spalignvector[r]{1 100 1000}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignaugmatn}
+% \DescribeMacro{\spalignaugmatn*}
+% \usage\spalignaugmatn{\oarg{column alignment}\marg{augmented columns}\marg{text}}
+% Produces a matrix with a vertical divider located \meta{augmented columns} from the
+% right side of the matrix.  The \meta{column alignment} is interpreted as in
+% |\spalignmat|; the default is |r|.  For example,
+% \begin{verbatim}
+%    \[ \spalignaugmatn[c]{3}{1 2 3 4; 10 20 30 40} \]\end{verbatim}
+% produces
+% \[ \spalignaugmatn[c]{3}{1 2 3 4; 10 20 30 40}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignaugmat}
+% \DescribeMacro{\spalignaugmat*}
+% \usage\spalignaugmat{\oarg{column alignment}\marg{text}}
+% This is the same as |\spalignaugmatn|, with \meta{augmented columns} equal to
+% $1$.  For example,
+% \begin{verbatim}
+%    \[ \spalignaugmat{1 2 3 4; 10 20 30 40} \]\end{verbatim}
+% produces
+% \[ \spalignaugmat{1 2 3 4; 10 20 30 40}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignaugmathalf}
+% \DescribeMacro{\spalignaugmathalf*}
+% \usage\spalignaugmathalf{\oarg{column alignment}\marg{text}}
+% This is the same as |\spalignaugmatn|, with \meta{augmented columns} equal to
+% the largest integer less or equal to half of the total number of columns
+% parsed from \meta{text}.  For example,
+% \begin{verbatim}
+%    \[ \spalignaugmathalf[l]{1 2 3 4; 10 20 30 40} \]\end{verbatim}
+% produces
+% \[ \spalignaugmathalf[l]{1 2 3 4; 10 20 30 40}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignsys}
+% \DescribeMacro{\spalignsys*}
+% \usage\spalignsys{\marg{text}}
+% Typesets systems of simple equations so that binary operators and relations
+% are aligned vertically, and variables are right-justified.  This macro assumes
+% that variables are in odd columns and that binary operators and relations are
+% in even columns.  For example,
+% \begin{verbatim}
+%    \[ \spalignsys{2x + y = 4; x - 3y = -17} \]\end{verbatim}
+% produces
+% \[ \spalignsys{2x + y = 4; x - 3y = -17\rlap.} \]
+% Within \marg{text} the macro |\+| is defined to be an empty box with the size
+% and spacing of a binary operator, the macro |\=| is defined to be an empty box
+% with the size and spacing of a relation, and the macro |\.| is defined to be
+% empty.  (Ordinarily, the latter two macros produce th\=ese acc\.ents, but they
+% cannot be used in math mode.)  This allows one to deal with empty columns in
+% an easy-to-read way: for example,
+% \begin{verbatim}
+%    \[ \spalignsys{
+%         2x \+ \. - 3z =  1; 
+%         \. \+ 4y +  z = -4}
+%    \]\end{verbatim}
+% produces
+%    \[ \spalignsys{
+%         2x \+ \. - 3z = 1; 
+%         \. \+ 4y +  z = -4\rlap.} 
+%    \]
+% As with the matrix macros, delimiters can be changed with the package options.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spaligntabular}
+% \usage\spaligntabular{\marg{alignment specifier}\marg{text}}
+% Produces an (undelimited) |tabular| environment, passing it
+% \meta{alignment specifier}, after retokenizing \meta{text}.  This macro may be
+% used outside of math mode, and therefore is undelimited.
+% For example,
+% \begin{verbatim}
+%    \spaligntabular{lrc}{a b c; aa bb cc}\end{verbatim}
+% produces
+% \[ \spaligntabular{lcr}{a b c; aa bb cc} \]
+%
+% \subsection{Package options}\label{sec:options}
+% The following package options can be specified as key-value pairs when the
+% package is loaded, as in
+% \begin{verbatim}
+%    \usepackage[sep={,},endofrow=;]{spalign} \end{verbatim}
+% They can also be set directly with macros, which are described as well.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{delims}
+% \DescribeMacro{\spaligndelims}
+% \poption Use: Specifies the delimiters used by all matrix macros.\endopt
+% \poption Format: Must contain exactly two delimiter tokens, the first for the left
+%   delimiter, the second for the right.\endopt
+% \poption Default: |delims=()|\endopt
+% \poption Macro: |\spaligndelims|\marg{left-delim}\marg{right-delim}\endopt
+% \smallskip
+% It is easier to specify |\{\}| as delimiters using the macro form.
+% For example,
+% \begin{verbatim}
+%    \[ \spaligndelims\vert\vert \spalignmat{a b; c d} \]\end{verbatim}
+% produces
+% \[ \spaligndelims\vert\vert \spalignmat{a b; c d}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{sysdelims}
+% \DescribeMacro{\spalignsysdelims}
+% These function the same way as |delims| and |\spaligndelims|, except they
+% apply only to the |\spalignsys| macro.  The default is |\spalignsysdelims\{.|,
+% i.e., left brace and no right delimiter.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{matdelimskip}
+% \DescribeMacro{\spalignmatdelimskip}
+% \poption Use: Specifies the glue to insert between delimiters and the internal
+%   |array| environment in (un-starred) math-mode matrix macros, i.e., all
+%   math-mode utility macros except |\spalignvector|.\endopt
+% \poption Format: Should either be empty, or expand to a legal |\hskip|,
+%   |\mskip|, or |\kern| command.  (Really any sequence of tokens can be
+%   specified; they will dutifully be inserted between the delimiters and the
+%   |array|, but this behavior may change in future versions.)\endopt
+% \poption Default: |matdelimskip=\,|\endopt
+% \poption Macro: |\def\spalignmatdelimskip|\marg{skip}\endopt
+% \smallskip
+% Actually, an additional skip of |\hskip-\arraycolsep| is always added; the
+% effect is that if |matdimskip| is empty, then there is no extra space between
+% the outer columns of the |array| and the delimiters.  This is how the
+% \textsf{amsmath} package's |matrix| environment is defined.  It is this
+% package author's opinion that matrices look better when a thin space is added
+% between the outer columns of the |array| and the delimiters.  To keep the
+% original array spacing inside the delimiters, specify
+% |matdelimskip=\hskip\arraycolsep|.
+%
+% Here are four matrices typeset, respectively, with |matdelimskip|
+% set to |{}|, |\,|, |\;|, and |{\hskip\arraycolsep}|.
+% \[ \def\spalignmatdelimskip{}   \spalignmat{10 20; 30 40} \quad
+%    \def\spalignmatdelimskip{\,} \spalignmat{10 20; 30 40} \quad
+%    \def\spalignmatdelimskip{\;} \spalignmat{10 20; 30 40} \quad
+%    \def\spalignmatdelimskip{\hskip\arraycolsep} \spalignmat{10 20; 30 40}
+%  \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{vecdelimskip}
+% \DescribeMacro{\spalignvecdelimskip}
+% These function the same way as |matdelimskip| and |\spalignmatdelimskip|,
+% except they apply only to the |\spalignvector| macro.  The default is no extra
+% skip in vectors, i.e., |vecdelimskip={}|.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{sysdelimskip}
+% \DescribeMacro{\spalignsysdelimskip}
+% These function the same way as |matdelimskip| and |\spalignmatdelimskip|,
+% except they apply only to the |\spalignsys| macro.  The default is
+% |sysdelimskip=\,|.
+%
+% Actually there is a slight difference: the |\halign| primitive used in the
+% |\spalignsys| macro does not put glue on the outsides of the columns, so that
+% it is unnecessary to subtract any |\arraycolsep| glue.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{systabspace}
+% \DescribeMacro{\spalignsystabspace}
+% \poption Use: Specifies the amount of glue between columns in
+%   |\spsysalign|.\endopt 
+% \poption Format: Must be a legal glue specification.\endopt
+% \poption Default: |systabspace=1pt|\endopt
+% \poption Macro: |\spalignsystabspace=|\meta{glue}\endopt
+% \smallskip
+% Equations with operators, relations, and variables all aligned look a 
+% better with a bit of extra spacing between these three.  Setting |systabspace|
+% to zero will cause the equations to use their natural spacing, subject to
+% the alignment. For example, the following systems of equations were typeset,
+% respectively, with |systabspace| set to |0pt|, |1pt|, and |5pt|.
+%   \[ 
+%      \spalignsystabspace=0pt \spalignsys{2x + y = 4; x - 3y = -17} \qquad
+%      \spalignsystabspace=1pt \spalignsys{2x + y = 4; x - 3y = -17} \qquad
+%      \spalignsystabspace=5pt \spalignsys{2x + y = 4; x - 3y = -17\rlap.}
+%   \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{endofrow}
+% \DescribeMacro{\spalignendofrow}
+% \poption Use: Specifies the token to convert into the end-of-row
+%   control sequence |\\| (really into the contents of |\spalignendline|) during
+%   retokenization.\endopt
+% \poption Format: Must consist of a single token.\endopt
+% \poption Default: |endofrow=;|\endopt
+% \poption Macro: |\def\spalignendofrow|\marg{token}\endopt
+% \smallskip
+% For example,
+% \begin{verbatim}
+%   \[ \def\spalignendofrow{|} 
+%      \spalignmat{1;2 3;4 | 5;6 7;8} \]\end{verbatim}
+% produces
+% \[ \def\spalignendofrow{|} \spalignmat{1;2 3;4 | 5;6 7;8}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{separator}
+% \DescribeMacro{\spalignseparator}
+% \poption Use: Specifies a token (in addition to space tokens) to convert into
+%   the alignment character `|&|' (really the contents of |\spalignseparator|)
+%   during  retokenization.\endopt
+% \poption Format: Must consist of a single token.\endopt
+% \poption Default: |separator={,}|\endopt
+% \poption Macro: |\def\spalignseparator|\marg{token}\endopt
+% \smallskip
+% For example,
+% \begin{verbatim}
+%   \[ \def\spalignseparator{|} 
+%      \spalignmat{(1,2)|(3,4);(5,6)|(7,8)} \]\end{verbatim}
+% produces
+%   \[ \def\spalignseparator{|} \spalignmat{(1,2)|(3,4);(5,6)|(7,8)}. \]
+%
+% \bigskip
+% The following commands can be redefined to affect the behavior of the package,
+% but cannot be specified as key-value pairs when the package is loaded.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignendline}
+% \poption Use: The end-of-row token is replaced by the top-level expansion of
+%   this macro during retokenization.\endopt
+% \poption Format: May contain any tokens.\endopt
+% \poption Default: |\def\spalignendline{\\}|\endopt
+% \smallskip
+% This is useful, for instance, when using \textsf{spalign} in conjunction with
+% plain \TeX-style alignment macros that use |\cr| as the end-of-row token.
+% See the documentation for |\spalignrun| in~\S\ref{sec:general} and the
+% implementation of |\spalignsys| for examples.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignaligntab}
+% \poption Use: Spaces and the contents of |\spalignseparator| are replaced by the
+%   top-level expansion of this macro during retokenization.\endopt
+% \poption Format: May contain any tokens.\endopt
+% \poption Default: |\def\spalignaligntab{&}|\endopt
+% \smallskip
+% This is useful, for instance, in one-column alignments.  For example,
+% \begin{verbatim}
+%   \[ \def\spalignaligntab{\\} \spalignmat{12 1 2 13} \]\end{verbatim}
+% produces
+%   \[ \def\spalignaligntab{\\} \spalignmat{12 1 2 13}. \]
+% The |\spalignvector| macro is defined in this way.
+%
+%
+% \subsection{General macros}\label{sec:general}
+% The following macros are meant to make it easy to make new utility macros
+% in different situations using \textsf{spalign}.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignretokenize}
+% \usage\spalignretokenize{\marg{text}}
+% Applies the retokenization procedure to \meta{text}, and expands to the
+% retokenized version.  For instance, |\spalignretokenize{1 2; 3 4}| expands to
+% |1&2\\3&4|.  
+% For example, using the |split| environment from the
+% \textsf{amsmath} package,
+% \begin{verbatim}
+%    \[ \begin{split}
+%         \spalignretokenize{f_0 =1; f_1 =1; f_{n+2} =f_n+f_{n+1}}
+%       \end{split} \]\end{verbatim}
+% produces
+%    \[ \begin{split}
+%         \spalignretokenize{f_0 =1; f_1 =1; f_{n+2} =f_n+f_{n+1}}.
+%       \end{split} \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignrun}
+% \usage\spalignrun{\marg{tokens}\marg{text}}
+% Applies the retokenization procedure to \meta{text}, saving the result into
+% the token register |\spaligntoks| (see below).  Then executes \meta{tokens},
+% which presumably makes reference to |\spaligntoks|.  For example,
+% \begin{verbatim}
+%    \[ \def\spalignendline{\cr}
+%       \spalignrun{\bordermatrix{\the\spaligntoks}}
+%           {, x y; u 1 2; v 3 4} \]\end{verbatim}
+% produces
+%    \[ \def\spalignendline{\cr}
+%       \spalignrun{\bordermatrix{\the\spaligntoks}}
+%           {, x y; u 1 2; v 3 4}. \]
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignenv}
+% \usage\spalignenv{\marg{before-tokens}\marg{after-tokens}\marg{text}}
+% Convenience macro that expands to 
+% \[ \hbox{|\spalignrun{|\meta{before-tokens}
+%    |\the\spaligntoks| \meta{after-tokens}|}{|\meta{text}|}|.} \]
+% For example, using the |align*| environment from the
+% \textsf{amsmath} package,
+% \begin{verbatim}
+%    \spalignenv{\begin{align*}}{\end{align*}}%
+%      {x =y x' =y'; z =w z' =w'.}\end{verbatim} 
+% produces
+%    \spalignenv{\begin{align*}}{\end{align*}}%
+%      {x =y x' =y'; z =w z' =w'.} 
+%
+% \bigskip
+% The \meta{tokens} arguments of |\spalignrun| and |\spalignenv| have access to
+% the following registers, which are defined locally in a group inside
+% |\spalignrun| and |\spalignenv|.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spaligntoks}
+% A tokens register that contains the result of the retokenizing procedure.
+%
+% \bigskip
+% \noindent
+% \DescribeMacro{\spalignmaxcols}
+% A count register that contains the maximum number of columns in any given row,
+% as parsed by the retokenizer.  This is used in |\spalignmat| and in the
+% |\spalignaugmat| family of macros.
+
+% \StopEventually{}
+%
+% \section{Implementation}
+% 
+% \subsection{Options processing}
+%
+%    \begin{macrocode}
+\makeatletter
+
+\RequirePackage{kvoptions}
+%    \end{macrocode}
+% With the following options, the key |foo| gets stored as |\spalign at foo|.
+%    \smallskip
+%    \begin{macrocode}
+\SetupKeyvalOptions{family=spalign,prefix=spalign@}
+
+\DeclareStringOption[()]{delims}
+\DeclareStringOption[\{.]{sysdelims}
+\DeclareStringOption[\,]{matdelimskip}
+\DeclareStringOption[]{vecdelimskip}
+\DeclareStringOption[\,]{sysdelimskip}
+\DeclareStringOption[1pt]{systabspace}
+\DeclareStringOption[;]{endofrow}
+\DeclareStringOption[,]{separator}
+
+\ProcessLocalKeyvalOptions*
+
+\def\spaligndelims#1#2{%
+  \def\spalign at leftdelim{#1}\def\spalign at rightdelim{#2}}
+\expandafter\spaligndelims\spalign at delims
+\def\spalignsysdelims#1#2{%
+  \def\spalign at sysleftdelim{#1}\def\spalign at sysrightdelim{#2}}
+\expandafter\spalignsysdelims\spalign at sysdelims
+\let\spalignmatdelimskip=\spalign at matdelimskip
+\let\spalignvecdelimskip=\spalign at vecdelimskip
+\let\spalignsysdelimskip=\spalign at sysdelimskip
+\newdimen\spalignsystabspace
+\spalignsystabspace=\spalign at systabspace
+\let\spalignendofrow=\spalign at endofrow
+\let\spalignseparator=\spalign at separator
+\def\spalignendline{\\}
+\def\spalignaligntab{&}
+%    \end{macrocode}
+%
+% \bigskip
+% \subsection{Main retokenizing code}
+% The retokenizer processes the input token list one ``item'' at a time,
+% performing replacements as necessary, and saving the resulting tokens in
+% |\spaligntoks|.  The difficulties arise because of the special treatment that
+% \TeX\ gives to spaces and braces.  First let's review the rules of the game:
+% \begin{enumerate}\itemsep=1\jot\parskip=0pt
+% \item Spaces after a control sequence are not tokenized.
+% \item Multiple spaces are tokenized into a single space.
+% \item Space tokens between a control sequence and its argument are ignored:
+%   undelimited spaces are never interpreted as a macro argument.
+% \item Braces around a macro argument are stripped.
+% \item The |\futurelet|\meta{control sequence}\meta{token1}\meta{token2} syntax
+%   will |\let| the specified \meta{control sequence} be \meta{token2}, nomatter
+%   what kind of token \meta{token2} is.
+% \end{enumerate}
+% Consider then a macro |\retokenize#1{...}| and the token sequence
+% \[ \hbox{|\retokenize |\tvs|{\bf a}b|} \]
+% The |\retokenize| macro needs to recognize both the space (as it should be
+% replaced by an align token, if other non-space tokens have just been processed),
+% and the braces (so |{\bf a}b| is not replaced by |\bf ab|).  However, the
+% argument to |\retokenize| will be |\bf a|; the space and braces are ignored.
+%
+% The solution, of course, is judicious use of |\futurelet|.  (One could
+% conceivably use |\let| and |\futurelet| exclusively, except then one would
+% have the opposite problem: we \emph{want} the retokenizer to swallow whole
+% arguments in braces.)  This is still somewhat tricky:
+% \[ \hbox{|\futurelet\next\retokenize |\tvs|{\bf a}b|} \]
+% will expand |\retokenize| with the argument set to |\bf a| and |\next|
+% behaving like \tvs, but the braces will still disappear.  Hence one has to use
+% the |\futurelet| in a macro which does not take any arguments.
+%
+% Here is the outline of the solution to the problem used in this package.  The
+% |\spalign at gobble@spaces| macro has the effect of deleting the subsequent
+% sequence of space tokens and replacing them with the token
+% |\spalign at parsetoks|.  It sets |\spalign at saw@spacetrue| if it ate at least
+% one space token, and in any case it sets |\spalign at nexttok| to the following
+% token.  The |\spalign at parsetoks| macro takes one argument.  When it is
+% executed, |\spalign at nexttok| represents a non-space token.  Now
+% |\spalign at parsetoks| knows if the token beginning its argument is a brace, and
+% it knows if there was a space preceding the brace as well, using
+% |\ifspalign at saw@space|.  It can proceed to parse its argument in a
+% straightforward manner, eventually expanding back into
+% |\splign at gobble@spaces|, unless it sees |\spalign at end|, which signifies the
+% end of input.
+%
+% See Appendix~D in the {\TeX}book for a discussion of these kinds of tricks.
+%
+% \begin{macro}{\spalign at makespace}
+%   This macro expands to a single space token.  It is mildly tricky to
+%   construct, since \TeX\ allows one optional space token after |\let\foo| or
+%   |\let\foo=|, but multiple spaces are combined into one space token.  Here is
+%   one trick for producing two consecutive space tokens.  See Exercise~24.6 in
+%   the {\TeX}book.
+%    \begin{macrocode}
+\begingroup
+\def\\{\global\let\spalign at space= } \\ %
+\endgroup
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at end}
+%   Sentinel macro that is used to mark the end-of-input for
+%   |\spalign at parsetoks|.  Defining it recursively like this has the
+%   disadvantage that \LaTeX\ will hang if it tries to expand |\spalign at end|.
+%   On the other hand, one can test whether a token is |\spalign at end| using
+%   |\ifx| without using some other sentinel expansion of the macro, and the
+%   only reason |\spalign at end| would be executed is if there is a bug in this
+%   package. 
+%    \begin{macrocode}
+\def\spalign at end{\spalign at end}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at bgroup}
+%   This is just used to test whether a token is a literal |\bgroup| (as opposed
+%   to an actual open brace |{|) using |\ifx|.
+%    \begin{macrocode}
+\def\spalign at bgroup{\bgroup}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at curcols}
+%   This counter keeps track of how many columns are in the current row.
+%    \begin{macrocode}
+\newcount\spalign at curcols
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ifspalign at ignorespaces}
+%   Boolean variable which keeps track of whether spaces should be ignored in
+%   the current state, like after an end-of-row token.
+%    \begin{macrocode}
+\newif\ifspalign at ignorespaces
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\ifspalign at saw@space}
+%   Boolean variable which is true if the argument to |\spalign at parsetoks| was
+%   preceded by at least one space token.
+%    \begin{macrocode}
+\newif\ifspalign at saw@space
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at gobble@spaces}
+%   This macro has the effect of deleting any subsequent space tokens, replacing
+%   them with |\spalign at parsetoks|.  It sets |\spalign at nexttok| to the next
+%   (non-space) token, and sets |\spalign at saw@spacetrue| if it ate at least one
+%   space.  The boolean variable |\ifspalign at saw@space| should be false before
+%   |\spalign at gobble@spaces| is first executed.
+%
+%   The macro |\spalign at gobble@next| has the effect of replacing the following
+%   token with |\spalign at gobble@spaces|.
+%    \begin{macrocode}
+\def\spalign at gobble@next{%
+  \afterassignment\spalign at gobble@spaces\let\spalign at atoken= }
+\def\spalign at check@space{%
+  \ifx\spalign at nexttok\spalign at space%
+    \spalign at saw@spacetrue%
+    \let\spalign at next=\spalign at gobble@next%
+  \else%
+%    \end{macrocode}
+%   Don't set |\spalign at saw@spacefalse| here: eventually we will run
+%   into a non-space token.
+%    \begin{macrocode}
+    \let\spalign at next=\spalign at parsetoks%
+  \fi%
+  \spalign at next%
+  }
+\def\spalign at gobble@spaces{%
+  \futurelet\spalign at nexttok\spalign at check@space}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at append}
+%   Convenience macro that appends its argument, unexpanded, onto the token
+%   register |\spaligntoks|.
+%    \begin{macrocode}
+\def\spalign at append#1{%
+  \begingroup%
+  \toks255={#1}%
+%    \end{macrocode}
+%   The |\edef| and |\xdef| macros do not expand tokens obtained by expanding a
+%   token register.
+%    \begin{macrocode}
+  \xdef\spalign at settok{%
+    \spaligntoks={\the\spaligntoks\the\toks255}}%
+  \endgroup%
+  \spalign at settok%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at addcol}
+%   Convenience macro to take care of housekeeping when an align column has been
+%   parsed but the row is not complete.  Note that it appends the top-level
+%   expansion of |\spaligntab| to |\spaligntoks|, not the token |\spaligntab|
+%   itself.
+%    \begin{macrocode}
+\def\spalign at addcol{%
+  \expandafter\spalign at append\expandafter{\spalignaligntab}%
+  \advance\spalign at curcols by 1 %
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at endrow}
+%   Convenience macro to take care of housekeeping when a row has been ended,
+%   either by an end-of-row token or an end-of-input token.
+%    \begin{macrocode}
+\def\spalign at endrow{%
+  \advance\spalign at curcols by 1 %
+  \ifnum\spalign at curcols>\spalignmaxcols%
+    \spalignmaxcols=\spalign at curcols%
+  \fi%
+  \spalign at curcols=0%
+  \spalign at ignorespacestrue%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at normaltok}
+%   Convenience macro to take care of housekeeping when a non-special token (not
+%   a space, end-of-row token, separator token, or end-of-input token) has been
+%   parsed.  The boolean variable |\ifspalign at saw@space| will be true if the token
+%   preceding the non-special token was a space.
+%    \begin{macrocode}
+\def\spalign at normaltok{%
+  \ifspalign at saw@space%
+    \ifspalign at ignorespaces%
+    \else%
+      \spalign at addcol%
+    \fi%
+  \fi%
+  \spalign at ignorespacesfalse%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at parsetoks}
+%   This is the main retokenizing routine.  It is only called by
+%   |\spalign at gobble@spaces|.  When it is expanded, |\spalign at nexttok| is the
+%   token that immediately follows the |\spalign at parsetoks| token itself; this
+%   is not a space.  The value of the boolean variable |\ifspalign at saw@space| is
+%   true if there was a space before the argument of |\spalign at parsetoks| in the
+%   token list.
+%    \begin{macrocode}
+\def\spalign at parsetoks#1{%
+  \let\spalign at next=\spalign at gobble@spaces%
+%    \end{macrocode}
+%   This is for |\ifx| comparisons:
+%    \begin{macrocode}
+  \def\spalign at arg{#1}%
+%    \end{macrocode}
+%   Anything in braces is passed through untouched:
+%    \begin{macrocode}
+  \ifx\spalign at nexttok\bgroup%
+    \spalign at normaltok%
+    \ifx\spalign at arg\spalign at bgroup%
+%    \end{macrocode}
+%   The argument is a literal |\bgroup|, not a brace.
+%    \begin{macrocode}
+      \spalign at append{#1}%
+    \else%
+%    \end{macrocode}
+%   Re-wrap the argument in braces and append.
+%    \begin{macrocode}
+      \spalign at append{{#1}}%
+    \fi%
+  \else%
+%    \end{macrocode}
+%   The argument is not wrapped in braces.
+%    \begin{macrocode}
+    \ifx\spalign at arg\spalignendofrow%
+%    \end{macrocode}
+%   End-of-row token.  Append the top-level expansion of |\spalignendline|.
+%   (Ignore previous spaces.)
+%    \begin{macrocode}
+      \expandafter\spalign at append\expandafter{\spalignendline}%
+      \spalign at endrow%
+    \else%
+      \ifx\spalign at arg\spalignseparator%
+%    \end{macrocode}
+%   Separator token.  (Ignore previous spaces.)
+%    \begin{macrocode}
+        \spalign at addcol%
+        \spalign at ignorespacestrue%
+      \else%
+        \ifx\spalign at arg\spalign at end%
+%    \end{macrocode}
+%   End-of-input token.  End the current row to record |\spalign at maxcols|.
+%   (Ignore previous spaces.)
+%    \begin{macrocode}
+          \let\spalign at next=\relax%
+          \spalign at endrow%
+        \else%
+%    \end{macrocode}
+%   Non-special token.
+%    \begin{macrocode}
+          \spalign at normaltok%
+          \spalign at append{#1}%
+        \fi%
+      \fi%
+    \fi%
+  \fi%
+%    \end{macrocode}
+%   Reset |\ifspalign at saw@space| for the next |\spalign at gobble@spaces|.
+%    \begin{macrocode}
+  \spalign at saw@spacefalse%
+  \spalign at next%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at process}
+%   This is a wrapper for |\spalign at parsetoks|.  It initializes registers and
+%   boolean variables, then starts the parsing routine with
+%   |\spalign at gobble@spaces|.  It should be run in a local group.  It stops
+%   processing at |\spalign at end|.  It fills |\spalignmaxcols| and |\spaligntoks|
+%   with the results of the retokenization.  It replaces everything in the token
+%   list up through |\spalign at end| with |\relax|.
+%    \begin{macrocode}
+\def\spalign at process{%
+  \spaligntoks={}%
+  \spalignmaxcols=0%
+  \spalign at curcols=0%
+  \spalign at ignorespacestrue%
+  \spalign at saw@spacefalse%
+  \spalign at gobble@spaces%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Poor man's starred commands}
+% There are several excellent packages that allow for flexible command
+% specifications.  However, the needs of this package are minimal as regards
+% starred commands, so in order to reduce dependencies, this package contains
+% its own simple implimentation.
+%
+% \begin{macro}{\ifspalign at star}
+%   Boolean variable which records whether or not the current command has a star
+%   on it.
+%    \begin{macrocode}
+\newif\ifspalign at star
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at def@star}
+%   Used like |\def|, the command |\spalign at def@star\foo{...}| defines a macro
+%   |\foo| which can be called as |\foo| or |\foo*|.  In the body of |\foo|,
+%   the boolean variable |\ifspalign at star| indicates whether the command was
+%   called with a star.
+%
+%   This command actually defines three commands: |\foo|, |\foo at x|, and
+%   |\foo at star|.  The first calls the second with |\spalign at nexttok| defined via
+%   |\futurelet| to the token following |\foo|.  The command |\foo at x| checks
+%   whether or not the next token is a star, and if it is, it is removed from
+%   the token list.  It then sets |\ifspalign at star| appropriately and calls
+%   |\foo at star|, which contains the original command definition.  Of course,
+%   |\foo at star| can then be redefined, for instance using |\newcommand|, to take
+%   advantage of \LaTeX's optional argument parsing.
+%    \begin{macrocode}
+\def\spalign at gobble@one#1{}
+
+\def\spalign at def@star#1{%
+%    \end{macrocode}
+%   If |#1| is |\foo|, then |\spalign at cmd| expands to |\foo|,
+%   |\spalign at cmd@x| expands to |\foo at x|, and |\spalign at cmd@star| expands to
+%   |\foo at star|.
+%    \begin{macrocode}
+  \def\spalign at cmd{#1}%
+  \edef\spalign at cmd@x{%
+    \csname\expandafter\spalign at gobble@one\string#1 at x\endcsname}%
+  \edef\spalign at cmd@star{%
+    \csname\expandafter\spalign at gobble@one\string#1 at star\endcsname}%
+%    \end{macrocode}
+%   Make |\foo at x| unexpandable.  (The |\csname...\endcsname| construction
+%   already does this, but only if |\foo at x| was previously undefined.)  This
+%   makes it easier to define |\foo|.
+%    \begin{macrocode}
+  \expandafter\let\spalign at cmd@x=\relax
+  \expandafter\edef\spalign at cmd{%
+    \futurelet\noexpand\spalign at nexttok\spalign at cmd@x}%
+%    \end{macrocode}
+%   I don't know a less annoying but still short way of defining a token list
+%   where only one token in the middle is to be expanded, and that one token only
+%   once (not recursively).
+%    \begin{macrocode}
+  \def\spalign at mkcmd##1{%
+    \expandafter\def\spalign at cmd@x{%
+      \ifx\spalign at nexttok*%
+        \spalign at startrue%
+        \let\spalign at next=\spalign at gobble@one%
+      \else%
+        \spalign at starfalse%
+        \def\spalign at next{}%
+      \fi%
+%    \end{macrocode}
+%   Expanding |\spalign at gobble@one| before |##1| (which is |\foo at star|) eats the
+%   star before parsing the arguments for |\foo at star|.
+%    \begin{macrocode}
+      \expandafter##1\spalign at next%
+      }%
+    }%
+  \expandafter\spalign at mkcmd\spalign at cmd@star%
+  \expandafter\def\spalign at cmd@star%
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{General macros}
+%
+% Here are the definitions of the macros presented in~\S\ref{sec:general}.
+%    \begin{macrocode}
+\newtoks\spaligntoks
+\newcount\spalignmaxcols
+%    \end{macrocode}
+% \begin{macro}{\spalignrun}
+%   Calls |\spalign at process| on |#2|, then inserts |#1|, in a group.
+%   Presumably |#1| will refer to |\spaligntoks| and/or |\spalignmaxcols|.
+%    \begin{macrocode}
+\def\spalignrun#1#2{%
+  \begingroup%
+  \spalign at process#2\spalign at end%
+  %\showthe\spaligntoks%  For debugging
+  #1%
+  \endgroup%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignenv}
+%   This effectively calls |\spalign at process| on |#3|, then puts the resulting
+%   token list between |#1| and |#2|.  Both |#1| and |#2| have access to
+%   |\spaligntoks| and |\spalignmaxcols|.
+%    \begin{macrocode}
+\def\spalignenv#1#2{%
+  \spalignrun{%
+    #1%
+    \the\spaligntoks%
+    #2%
+    }%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignretokenize}
+%   This calls |\spalign at process| on |#1|, then expands to |\the\spaligntoks|.
+%    \begin{macrocode}
+\def\spalignretokenize#1{%
+  \begingroup%
+  \spalign at process#1\spalign at end%
+  \expandafter\endgroup\the\spaligntoks%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spaligntabular}
+%   Tabular utility macro.
+%    \begin{macrocode}
+\def\spaligntabular#1#2{%
+  \begin{tabular}{#1}\spalignretokenize{#2}\end{tabular}}
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at maybedelim}
+%   This is like |\spalignenv|, but it adds delimiters and the glue specified in
+%   |#3| before |#1| and after |#2|, if |\ifspalign at star| is false.
+%    \begin{macrocode}
+\def\spalign at maybedelim#1#2#3{%
+  \spalignenv%
+    {\ifspalign at star\else\left\spalign at leftdelim#3\fi#1}%
+    {#2\ifspalign at star\else#3\right\spalign at rightdelim\fi}%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignarray}
+%   Array utility macro with delimiters.
+%    \begin{macrocode}
+\spalign at def@star\spalignarray#1{%
+  \spalign at maybedelim%
+    {\begin{array}{#1}}%
+    {\end{array}}%
+    {\hskip-\arraycolsep\spalignmatdelimskip}%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignvector}
+%   Vector utility macro: an array with one column, with |\spaligntab| set to
+%   |\\| so that spaces produce new rows.
+%    \begin{macrocode}
+\spalign at def@star\spalignvector{}
+\renewcommand\spalignvector at star[2][c]{%
+  \begingroup%
+  \def\spalignaligntab{\\}%
+  \spalign at maybedelim%
+    {\begin{array}{#1}}%
+    {\end{array}}%
+%    \end{macrocode}
+%   Note the use of |\spalignvecdelimskip| here.
+%    \begin{macrocode}
+    {\hskip-\arraycolsep\spalignvecdelimskip}%
+    {#2}%
+  \endgroup%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalign at repeat}
+%   Sets |\spalign at repeated| to |#1|, repeated |#2| times.  Used for
+%   auto-constructing |array| alignment specifications from |\spalignmaxcols|.
+%    \begin{macrocode}
+\def\spalign at repeat#1#2{%
+  \begingroup%
+  \count255=0 %
+  \toks255={}%
+  \loop\ifnum\count255<#2%
+    \edef\spalign at settok{\toks255={\the\toks255 #1}}%
+    \spalign at settok%
+    \advance\count255 by 1 %
+  \repeat%
+  \xdef\spalign at repeated{\the\toks255}%
+  \endgroup
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignmat}
+%   Matrix utility macro.  Uses |\spalignmaxcols| and |\spalign at repeat| to
+%   construct the |array| align specification.
+%    \begin{macrocode}
+\spalign at def@star\spalignmat{}
+\renewcommand\spalignmat at star[1][c]{%
+  \spalign at maybedelim{%
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \edef\spalign at barray{\noexpand\begin{array}{%
+        \spalign at repeated}}%
+    \spalign at barray%
+    }{\end{array}%
+    }{\hskip-\arraycolsep\spalignmatdelimskip}%
+  }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignaugmatn}
+%   Augmented matrix with |#2| columns on the right of the vertical bar.  Uses
+%   |\spalignmaxcols| and |\spalign at repeat| to construct the |array| align
+%   specification.
+%    \begin{macrocode}
+\spalign at def@star\spalignaugmatn{}
+\renewcommand\spalignaugmatn at star[2][r]{%
+  \spalign at maybedelim{%
+    \advance\spalignmaxcols by -#2 %
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \let\spalign at repeated@one=\spalign at repeated%
+    \spalign at repeat{#1}{#2}%
+    \let\spalign at repeated@two=\spalign at repeated%
+    \edef\spalign at barray{\noexpand\begin{array}{%
+        \spalign at repeated@one|\spalign at repeated@two}}%
+    \spalign at barray%
+    }{\end{array}%
+    }{\hskip-\arraycolsep\spalignmatdelimskip}%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignaugmat}
+%   Augmented matrix with one column on the right of the vertical bar.
+%    \begin{macrocode}
+\spalign at def@star\spalignaugmat{}
+\renewcommand\spalignaugmat at star[1][r]{%
+  \spalignaugmatn at star[#1]{1}%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignaugmathalf}
+%   Augmented matrix with (ceiling of) half the columns on the right.
+%    \begin{macrocode}
+\spalign at def@star\spalignaugmathalf{}
+\renewcommand\spalignaugmathalf at star[1][r]{%
+  \spalign at maybedelim{%
+    \count255=\spalignmaxcols%
+    \divide\spalignmaxcols by 2 %
+    \advance\count255 by -\spalignmaxcols%
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \let\spalign at repeated@one=\spalign at repeated%
+    \spalignmaxcols=\count255%
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \let\spalign at repeated@two=\spalign at repeated%
+    \edef\spalign at barray{\noexpand\begin{array}{%
+      \spalign at repeated@one|\spalign at repeated@two}}%
+    \spalign at barray%
+    }{\end{array}%
+    }{\hskip-\arraycolsep\spalignmatdelimskip}%
+  }%
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\spalignsys}
+%   System of equations with aligned operators and variables.
+%    \begin{macrocode}
+\spalign at def@star\spalignsys#1{%
+  \ifspalign at star\else%
+    \left\spalign at sysleftdelim\spalignsysdelimskip%
+  \fi%
+  \vcenter{%
+    \def\spalignendline{\cr}%
+    \openup1pt%
+    \tabskip=0pt%
+    \def\+{\mathbin{\phantom{+}}}%
+    \def\={\mathrel{\phantom{=}}}%
+    \def\.{}%
+    \halign{%
+%    \end{macrocode}
+% Adding |{}| to each side of the align argument in the even columns causes
+% binary operators ($+$, $-$, $\ldots$) and relations ($=$, $<$, $\ldots$) to
+% use their natural spacing.  Assuming the even columns contain only binary
+% operators (resp.\ only relations), these columns will all be the same width.
+% The |\hfil| in the odd columns right-justifies.  There should be no spaces in
+% the templates.
+%    \begin{macrocode}
+      \tabskip=\spalignsystabspace%      
+      &$\hfil##$&${}##{}$\cr%
+      \spalignretokenize{#1}\crcr%
+      }%
+%    \end{macrocode}
+% It seems that one can't specify tabskip glue for after the last column when
+% there are repeated templates.
+%    \begin{macrocode}
+    }\hskip-\spalignsystabspace%
+  \ifspalign at star\else%
+    \spalignsysdelimskip\right\spalign at sysrightdelim%
+  \fi%
+  }
+%    \end{macrocode}
+% \end{macro}
+%    \begin{macrocode}
+\makeatother
+%    \end{macrocode}
+% \Finale
+\endinput


Property changes on: trunk/Master/texmf-dist/source/latex/spalign/spalign.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/spalign/spalign.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/spalign/spalign.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/spalign/spalign.ins	2016-10-07 22:24:58 UTC (rev 42225)
@@ -0,0 +1,55 @@
+%%
+%% Copyright (C) 2016 by Joseph Rabinoff <rabinoff at math.gatech.edu>
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version
+%% 2005/12/01 or later.
+%%
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/latex/spalign}
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2016 by Joseph Rabinoff <rabinoff at math.gatech.edu>
+
+This file may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version
+2005/12/01 or later.
+
+\endpreamble
+
+\generate{\file{spalign.sty}{\from{spalign.dtx}{package}}}
+
+\obeyspaces
+\Msg{*************************************************************}
+\Msg{*                                                           *}
+\Msg{* To finish the installation you have to move the following *}
+\Msg{* file into a directory searched by TeX:                    *}
+\Msg{*                                                           *}
+\Msg{*     spalign.sty                                           *}
+\Msg{*                                                           *}
+\Msg{* To produce the documentation run the file spalign.dtx     *}
+\Msg{* through LaTeX.                                            *}
+\Msg{*                                                           *}
+\Msg{* Happy TeXing!                                             *}
+\Msg{*                                                           *}
+\Msg{*************************************************************}
+
+\endbatchfile

Added: trunk/Master/texmf-dist/tex/latex/spalign/spalign.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/spalign/spalign.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/spalign/spalign.sty	2016-10-07 22:24:58 UTC (rev 42225)
@@ -0,0 +1,301 @@
+%%
+%% This is file `spalign.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% spalign.dtx  (with options: `package')
+%% 
+%% This is a generated file.
+%% 
+%% Copyright (C) 2016 by Joseph Rabinoff <rabinoff at math.gatech.edu>
+%% 
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version
+%% 2005/12/01 or later.
+%% 
+\NeedsTeXFormat{LaTeX2e}[2005/12/01]
+\ProvidesPackage{spalign}
+    [2016/10/05 aligns delimited by spaces]
+
+\makeatletter
+
+\RequirePackage{kvoptions}
+\SetupKeyvalOptions{family=spalign,prefix=spalign@}
+
+\DeclareStringOption[()]{delims}
+\DeclareStringOption[\{.]{sysdelims}
+\DeclareStringOption[\,]{matdelimskip}
+\DeclareStringOption[]{vecdelimskip}
+\DeclareStringOption[\,]{sysdelimskip}
+\DeclareStringOption[1pt]{systabspace}
+\DeclareStringOption[;]{endofrow}
+\DeclareStringOption[,]{separator}
+
+\ProcessLocalKeyvalOptions*
+
+\def\spaligndelims#1#2{%
+  \def\spalign at leftdelim{#1}\def\spalign at rightdelim{#2}}
+\expandafter\spaligndelims\spalign at delims
+\def\spalignsysdelims#1#2{%
+  \def\spalign at sysleftdelim{#1}\def\spalign at sysrightdelim{#2}}
+\expandafter\spalignsysdelims\spalign at sysdelims
+\let\spalignmatdelimskip=\spalign at matdelimskip
+\let\spalignvecdelimskip=\spalign at vecdelimskip
+\let\spalignsysdelimskip=\spalign at sysdelimskip
+\newdimen\spalignsystabspace
+\spalignsystabspace=\spalign at systabspace
+\let\spalignendofrow=\spalign at endofrow
+\let\spalignseparator=\spalign at separator
+\def\spalignendline{\\}
+\def\spalignaligntab{&}
+\begingroup
+\def\\{\global\let\spalign at space= } \\ %
+\endgroup
+\def\spalign at end{\spalign at end}
+\def\spalign at bgroup{\bgroup}
+\newcount\spalign at curcols
+\newif\ifspalign at ignorespaces
+\newif\ifspalign at saw@space
+\def\spalign at gobble@next{%
+  \afterassignment\spalign at gobble@spaces\let\spalign at atoken= }
+\def\spalign at check@space{%
+  \ifx\spalign at nexttok\spalign at space%
+    \spalign at saw@spacetrue%
+    \let\spalign at next=\spalign at gobble@next%
+  \else%
+    \let\spalign at next=\spalign at parsetoks%
+  \fi%
+  \spalign at next%
+  }
+\def\spalign at gobble@spaces{%
+  \futurelet\spalign at nexttok\spalign at check@space}
+\def\spalign at append#1{%
+  \begingroup%
+  \toks255={#1}%
+  \xdef\spalign at settok{%
+    \spaligntoks={\the\spaligntoks\the\toks255}}%
+  \endgroup%
+  \spalign at settok%
+  }
+\def\spalign at addcol{%
+  \expandafter\spalign at append\expandafter{\spalignaligntab}%
+  \advance\spalign at curcols by 1 %
+  }
+\def\spalign at endrow{%
+  \advance\spalign at curcols by 1 %
+  \ifnum\spalign at curcols>\spalignmaxcols%
+    \spalignmaxcols=\spalign at curcols%
+  \fi%
+  \spalign at curcols=0%
+  \spalign at ignorespacestrue%
+  }
+\def\spalign at normaltok{%
+  \ifspalign at saw@space%
+    \ifspalign at ignorespaces%
+    \else%
+      \spalign at addcol%
+    \fi%
+  \fi%
+  \spalign at ignorespacesfalse%
+  }
+\def\spalign at parsetoks#1{%
+  \let\spalign at next=\spalign at gobble@spaces%
+  \def\spalign at arg{#1}%
+  \ifx\spalign at nexttok\bgroup%
+    \spalign at normaltok%
+    \ifx\spalign at arg\spalign at bgroup%
+      \spalign at append{#1}%
+    \else%
+      \spalign at append{{#1}}%
+    \fi%
+  \else%
+    \ifx\spalign at arg\spalignendofrow%
+      \expandafter\spalign at append\expandafter{\spalignendline}%
+      \spalign at endrow%
+    \else%
+      \ifx\spalign at arg\spalignseparator%
+        \spalign at addcol%
+        \spalign at ignorespacestrue%
+      \else%
+        \ifx\spalign at arg\spalign at end%
+          \let\spalign at next=\relax%
+          \spalign at endrow%
+        \else%
+          \spalign at normaltok%
+          \spalign at append{#1}%
+        \fi%
+      \fi%
+    \fi%
+  \fi%
+  \spalign at saw@spacefalse%
+  \spalign at next%
+  }
+\def\spalign at process{%
+  \spaligntoks={}%
+  \spalignmaxcols=0%
+  \spalign at curcols=0%
+  \spalign at ignorespacestrue%
+  \spalign at saw@spacefalse%
+  \spalign at gobble@spaces%
+  }
+\newif\ifspalign at star
+\def\spalign at gobble@one#1{}
+
+\def\spalign at def@star#1{%
+  \def\spalign at cmd{#1}%
+  \edef\spalign at cmd@x{%
+    \csname\expandafter\spalign at gobble@one\string#1 at x\endcsname}%
+  \edef\spalign at cmd@star{%
+    \csname\expandafter\spalign at gobble@one\string#1 at star\endcsname}%
+  \expandafter\let\spalign at cmd@x=\relax
+  \expandafter\edef\spalign at cmd{%
+    \futurelet\noexpand\spalign at nexttok\spalign at cmd@x}%
+  \def\spalign at mkcmd##1{%
+    \expandafter\def\spalign at cmd@x{%
+      \ifx\spalign at nexttok*%
+        \spalign at startrue%
+        \let\spalign at next=\spalign at gobble@one%
+      \else%
+        \spalign at starfalse%
+        \def\spalign at next{}%
+      \fi%
+      \expandafter##1\spalign at next%
+      }%
+    }%
+  \expandafter\spalign at mkcmd\spalign at cmd@star%
+  \expandafter\def\spalign at cmd@star%
+  }
+\newtoks\spaligntoks
+\newcount\spalignmaxcols
+\def\spalignrun#1#2{%
+  \begingroup%
+  \spalign at process#2\spalign at end%
+  %\showthe\spaligntoks%  For debugging
+  #1%
+  \endgroup%
+  }
+\def\spalignenv#1#2{%
+  \spalignrun{%
+    #1%
+    \the\spaligntoks%
+    #2%
+    }%
+  }
+\def\spalignretokenize#1{%
+  \begingroup%
+  \spalign at process#1\spalign at end%
+  \expandafter\endgroup\the\spaligntoks%
+  }
+\def\spaligntabular#1#2{%
+  \begin{tabular}{#1}\spalignretokenize{#2}\end{tabular}}
+\def\spalign at maybedelim#1#2#3{%
+  \spalignenv%
+    {\ifspalign at star\else\left\spalign at leftdelim#3\fi#1}%
+    {#2\ifspalign at star\else#3\right\spalign at rightdelim\fi}%
+  }
+\spalign at def@star\spalignarray#1{%
+  \spalign at maybedelim%
+    {\begin{array}{#1}}%
+    {\end{array}}%
+    {\hskip-\arraycolsep\spalignmatdelimskip}%
+  }
+\spalign at def@star\spalignvector{}
+\renewcommand\spalignvector at star[2][c]{%
+  \begingroup%
+  \def\spalignaligntab{\\}%
+  \spalign at maybedelim%
+    {\begin{array}{#1}}%
+    {\end{array}}%
+    {\hskip-\arraycolsep\spalignvecdelimskip}%
+    {#2}%
+  \endgroup%
+  }
+\def\spalign at repeat#1#2{%
+  \begingroup%
+  \count255=0 %
+  \toks255={}%
+  \loop\ifnum\count255<#2%
+    \edef\spalign at settok{\toks255={\the\toks255 #1}}%
+    \spalign at settok%
+    \advance\count255 by 1 %
+  \repeat%
+  \xdef\spalign at repeated{\the\toks255}%
+  \endgroup
+  }
+\spalign at def@star\spalignmat{}
+\renewcommand\spalignmat at star[1][c]{%
+  \spalign at maybedelim{%
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \edef\spalign at barray{\noexpand\begin{array}{%
+        \spalign at repeated}}%
+    \spalign at barray%
+    }{\end{array}%
+    }{\hskip-\arraycolsep\spalignmatdelimskip}%
+  }
+\spalign at def@star\spalignaugmatn{}
+\renewcommand\spalignaugmatn at star[2][r]{%
+  \spalign at maybedelim{%
+    \advance\spalignmaxcols by -#2 %
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \let\spalign at repeated@one=\spalign at repeated%
+    \spalign at repeat{#1}{#2}%
+    \let\spalign at repeated@two=\spalign at repeated%
+    \edef\spalign at barray{\noexpand\begin{array}{%
+        \spalign at repeated@one|\spalign at repeated@two}}%
+    \spalign at barray%
+    }{\end{array}%
+    }{\hskip-\arraycolsep\spalignmatdelimskip}%
+  }%
+\spalign at def@star\spalignaugmat{}
+\renewcommand\spalignaugmat at star[1][r]{%
+  \spalignaugmatn at star[#1]{1}%
+  }%
+\spalign at def@star\spalignaugmathalf{}
+\renewcommand\spalignaugmathalf at star[1][r]{%
+  \spalign at maybedelim{%
+    \count255=\spalignmaxcols%
+    \divide\spalignmaxcols by 2 %
+    \advance\count255 by -\spalignmaxcols%
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \let\spalign at repeated@one=\spalign at repeated%
+    \spalignmaxcols=\count255%
+    \spalign at repeat{#1}{\spalignmaxcols}%
+    \let\spalign at repeated@two=\spalign at repeated%
+    \edef\spalign at barray{\noexpand\begin{array}{%
+      \spalign at repeated@one|\spalign at repeated@two}}%
+    \spalign at barray%
+    }{\end{array}%
+    }{\hskip-\arraycolsep\spalignmatdelimskip}%
+  }%
+\spalign at def@star\spalignsys#1{%
+  \ifspalign at star\else%
+    \left\spalign at sysleftdelim\spalignsysdelimskip%
+  \fi%
+  \vcenter{%
+    \def\spalignendline{\cr}%
+    \openup1pt%
+    \tabskip=0pt%
+    \def\+{\mathbin{\phantom{+}}}%
+    \def\={\mathrel{\phantom{=}}}%
+    \def\.{}%
+    \halign{%
+      \tabskip=\spalignsystabspace%
+      &$\hfil##$&${}##{}$\cr%
+      \spalignretokenize{#1}\crcr%
+      }%
+    }\hskip-\spalignsystabspace%
+  \ifspalign at star\else%
+    \spalignsysdelimskip\right\spalign at sysrightdelim%
+  \fi%
+  }
+\makeatother
+\endinput
+%%
+%% End of file `spalign.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/spalign/spalign.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2016-10-07 22:24:15 UTC (rev 42224)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2016-10-07 22:24:58 UTC (rev 42225)
@@ -541,7 +541,7 @@
     snapshot snotez
     songbook songs sort-by-letters soton soul sourcecodepro sourcesanspro
     sourceserifpro
-    spanish-mx sparklines spath3 spelling spie
+    spalign spanish-mx sparklines spath3 spelling spie
     sphack sphdthesis splines splitbib splitindex
     spot spotcolor spreadtab spverbatim
     sr-vorl srbook-mem srcltx srcredact sseq sslides

Modified: trunk/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc	2016-10-07 22:24:15 UTC (rev 42224)
+++ trunk/Master/tlpkg/tlpsrc/collection-mathextra.tlpsrc	2016-10-07 22:24:58 UTC (rev 42225)
@@ -56,6 +56,7 @@
 depend sesamanuel
 depend shuffle
 depend skmath
+depend spalign
 depend statex
 depend statex2
 depend stmaryrd

Added: trunk/Master/tlpkg/tlpsrc/spalign.tlpsrc
===================================================================


More information about the tex-live-commits mailing list