diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/mlist/mlist.dtx |
Initial commit
Diffstat (limited to 'macros/latex/contrib/mlist/mlist.dtx')
-rw-r--r-- | macros/latex/contrib/mlist/mlist.dtx | 1439 |
1 files changed, 1439 insertions, 0 deletions
diff --git a/macros/latex/contrib/mlist/mlist.dtx b/macros/latex/contrib/mlist/mlist.dtx new file mode 100644 index 0000000000..5f201dc4db --- /dev/null +++ b/macros/latex/contrib/mlist/mlist.dtx @@ -0,0 +1,1439 @@ +% \iffalse +%<*internal> +\iffalse +%</internal> +%<*readme> +_________________ +The MLIST package +v0.6a + +This package defines the commands \newvect, \newmatr, \newfunc, +and \newmset for creating macros to typeset vectors, matrices, +functions, and sets. For example, Logical indexing can then be +used to refer to elements or arguments without hard-coding the +symbols in the document: + + \newvect\myvect{V}[elem=a,b,c] + \myvect{1,2,3} + +produces + + \left( V_a, V_b, V_c \right) + +All aspects of the typeset appearance can be adjusted, and new +`mlists' can be defined to represent other mathematical constructs. + +Consider this package an exploration of separation of form and content +for some mathematical constructions. I hope you find it useful. + +________________________ +History of major changes + +v0.6: Added the headhook option to accomodate accents to + the head symbol. Perhaps a little experimental. + +v0.5: Introduced \newmset for defining mathematical sets; + with pre-defined sets \setR, \setC, \setZ, \setN. + +______________ +Will Robertson +wspr 81 [at] gmail [dot] com + +Copyright 2007-2008 +Distributed under the LaTeX Project Public License +%</readme> +%<*internal> +\fi +\begingroup +%</internal> +%<*batchfile> +\input docstrip.tex +\keepsilent +\preamble + + __________________________________ + Copyright (C) 2007 Will Robertson + + License information appended. + + +\endpreamble +\postamble + +Copyright (C) 2007 by Will Robertson <wspr81@gmail.com> + +Distributable under the LaTeX Project Public License, +version 1.3c or higher (your choice). The latest version of +this license is at: http://www.latex-project.org/lppl.txt + +This work is "maintained" (as per LPPL maintenance status) +by Will Robertson. + +This work consists of the file mlist.dtx + and the derived files mlist.pdf, + mlist.sty, + mlist.cfg, and + mlist.ins. + +\endpostamble +\askforoverwritefalse +\generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}} +\generate{\file{\jobname.cfg}{\from{\jobname.dtx}{defaults}}} +%</batchfile> +%<batchfile>\endbatchfile +%<*internal> +\generate{\file{\jobname.ins}{\from{\jobname.dtx}{batchfile}}} +\nopreamble\nopostamble +\generate{\file{README.txt}{\from{\jobname.dtx}{readme}}} +\generate{\file{dtx-style.sty}{\from{\jobname.dtx}{dtx-style}}} +\endgroup +\immediate\write18{makeindex -s gind.ist -o \jobname.ind \jobname.idx} +\immediate\write18{makeindex -s gglo.ist -o \jobname.gls \jobname.glo} +%</internal> +% +%<*driver> +\documentclass{ltxdoc} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +%\OnlyDescription +\usepackage{dtx-style} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% +% +% \fi +% +% \GetFileInfo{\jobname.sty} +% \CheckSum{0} +% \makeatletter +% +% \title{Logical markup for mathematical lists} +% \author{Will Robertson} +% \date{\filedate \qquad \fileversion} +% +% \maketitle +% +% \tableofcontents +% \clearpage +% +% \section{Introduction} +% +% One of \LaTeX's lauded features is its separation of form and +% content. When writing a document, they say, you can just focus on +% the words. Well, that may be well and good for prose, but +% mathematicians have frequently been left out in the cold. A funny +% situation, considering \LaTeX's main audience. +% +% Recently, the \pkg{cool} package appeared, marking the first +% large-scale format-independent method of writing maths in +% \LaTeX. Need to change the brackets surrounding the arguments of +% \cmd\sin\ and \cmd\cos, or switch from $\tan^{-1}$ to $\arctan$ +% throughout an entire document? No worries. +% +% This sort of initiative will allow much easier transfer of +% mathematics from such software packages as Mathematica and Matlab, +% if it becomes popular enough. +% +% This package, \pkg{\jobname}, provides a method to write various +% sorts of mathematical lists without having to worry about +% formatting. When I say `lists', I mean things like +% $\vect{A}=\vect{A}{1,2,3}$; to me as a mechanical engineer, vectors +% and matrices; but the package is more general than that, I hope. +% +% You can use \pkg{\jobname} straight away with +% \codeline \cmd\usepackage\texttt{\char`\{\jobname\char`\}}\\ +% and +% \codeline |$\vect{A}=\vect{A}{1,2,3}$|\\ +% to get the example in the previous paragraph, but \emph{please} +% keep reading to learn its more useful features. +% +% \section{Basic Functionality}\seclabel{vect} +% +% \subsection{Prototypical example: vector notation} +% +% \DescribeMacro{\newvect} +% This example demonstrates why I wrote this package. The control +% sequence \cmd\dist\ is defined as a vector with any number of elements. The +% vector and its elements can be subsequently referred to without +% hard-coding any of the mathematical symbols or brackets used. +% \begin{example}{} +% \newvect\dist{D}[elem={r,\phi,\theta}] +% \[ \dist \qquad \dist{2} +% \qquad \dist{1,2,3} \] +% \end{example} +% +% \subsection{Matrix notation} +% +% The basic idea of this package is to separate the formatting and +% content of mathematical objects. The above example showed vector +% notation, and there are three more `data structures' that are defined +% `out of the box'. +% +% \DescribeMacro{\newmatr} The second example is for matrices, which +% one might consider quite similar to vectors; but by default the +% formatting internally uses \pkg{amsmath}'s |{bmatrix}| +% environment. Note that it's a very good idea to give your maths +% objects actual \emph{names} rather than shorthands like |\M|---who +% knows if you'll still be calling it `M' in ten years time? +% \begin{example}{} +% \newmatr\massm{M}[elem={m,0;0,m+M}] +% \[ \massm \qquad \massm{4} +% \qquad \massm{1,2;3,4} \] +% \end{example} +% +% Again, it is possible then to change the brackets used for matrices +% throughout an entire document (or collection of documents) without +% changing the fundamental markup of the mathematics itself. +% +% \subsection{Function and `set' notation} +% +% \DescribeMacro{\newfunc} Finally, here's something a little +% different. Vector and matrices are both quite similar. But it takes +% only a slight stretch to extend the syntax of this package to things +% completely different---such as functions:\label{func-example} +% \begin{example}{} +% \newfunc\traj{T}[elem={x_0;x,t},index={1;2,3}] +% \[ \traj \qquad \traj{2} \qquad \traj{2,3} \] +% \end{example} +% +% For example, Mathematica users may wish to typeset their arguments +% with square brackets in their own documents but not for published +% papers. To hammer home the point: this can be now done for an entire +% document with a simple switch. +% +% \DescribeMacro{\newmset} Here's an example to further +% demonstrate the flexibility of the package. +% \begin{example}{} +% \newmset\setT{T} +% \[ \setT \qquad \setT{2} \qquad \setT{2,3} \] +% \end{example} +% The \cmd\setR, \cmd\setC, \cmd\setN, and \cmd\setZ\ `msets' are defined +% by default for real, complex, natural, and integer numbers. +% \begin{example}{} +% \[ \bm{x}\in\setR{2,2} \] +% \end{example} +% +% \subsection{Non-specific commands} +% Sometimes you don't always want to define new macros for one-off +% maths expressions. Accompanying the \cmd\newvect, \cmd\newmatr, +% \cmd\newfunc, and \cmd\newmset\ macros are \cmd\vect, \cmd\matr, \cmd\func, +% and \cmd\mset, which can be used for single cases: +% \begin{example}{} +% \[ \vect{V}{a,b,c} \quad +% \matr{M}{a,b;c,d} \quad +% \func{f}{x_0;x,t} \quad +% \mset{D}{m,n} \] +% \end{example} +% This usage is generally not recommended except in isolated cases. +% +% \subsection{An example of some actual maths} +% +% Here's a practical example using \cmd\matr\ that I think demonstrates +% well the advantages of using this package: +% \begin{example}{} +% \newmatr\state{x} +% [elem={x_1;\dot x_1},index={1;2}] +% \newmatr\dyn{A} +% [elem={0,1;-K/M,-C/M}, +% index={1,2;3,4}] +% \[ \dot{\state{}} = \dyn{}\state{} \] +% \[ \state{} = \state \] +% \[ \dyn{} = \dyn \] +% \[ \frac\partial{\partial t} +% \state = \dyn \state \] +% \end{example} +% There's a lot more semantic meaning in that mathematical \TeX\ source than if it were hard-coded without this package. +% +% \subsection{Elements and indexing}\seclabel{indexing} +% +% For context for the following explanations, here's our first example again: +% \begin{example}{} +% \newvect\dist{D}[elem={r,\phi,\theta}] +% \[ \dist \qquad \dist{2} \qquad \dist{1,2,3} \] +% \end{example} +% \newvect\dist{D}[elem={r,\phi,\theta}] +% +% Each command created like \cmd\dist\ takes zero or one arguments, as shown +% above. Unlike regular \LaTeX\ commands with optional arguments, these still +% use curly braces, and an empty argument is equivalent (by default) to omitting the argument altogether: +% \codeline |\dist{}|~$\to~\dist{}$\quad$\equiv$\quad|\dist|~$\to~\dist$ . +% +% While numerical indexing is used to extract \opt{elem} items from +% the list, \emph{any} argument can be used instead that is passed +% through directly: +% \codeline |\dist{x^2}|~$\to~\dist{x^2}$ . +% +% As we saw for the matrix examples, the input may actually be +% `two-dimensional'; as well as being comma-separated, elements (and +% sets of elements) may also be separated by semi-colons: +% \codeline |\dist{x;y;z}|~$\to~\dist{x;y;z}$ . +% +% Input elements can also be specified with semi-colon separators to +% match up with two-dimensional element indexing. There are two ways +% to reference these elements: with a linear index from one to the +% number of elements in |elem|; or with `implicit indexing' that +% starts from one for every semi-colon list. Implicit indices are +% prefix with the |@| symbol.\footnote{The implicit indexing syntax +% will work \emph{even if} \cmd\makeatletter\ is in effect.} An +% example is useful to show how this works: +% \begin{example}{} +% \newvect\V{V}[elem={a,b,c;x,y,z}] +% \[ \V=\V{1,2,3;4,5,6} \] +% \[ \V=\V{4,5,6} \] +% \[ \V=\V{1,2,3;@1,@2,@3} \] +% \end{example} +% See \tabref{index-syntax} for a more detailed example of the indexing system. +% +% \begin{table} +% \topcaption{How two-dimension lists elements are indexed. The first row shows the input list via \opt{elem=\{\}}. The second and third rows respectively show the direct index and implicit index required to reference the elements of the list.} +% \tablabel{index-syntax} +% \centering +% \begin{tabular}{@{}l@{\quad\{~}c@{~,~}c@{~,~}c@{~;~}c@{~,~}c@{~;~}c@{~\}}} +% \toprule +% List & a & b & c & d & e & f \\ +% Direct index & 1 & 2 & 3 & 4 & 5 & 6 \\ +% Implicit index & @1 & @2 & @3 & @1 & @2 & @1 \\ +% \bottomrule +% \end{tabular} +% \end{table} +% +% You can also set the default element list when defining a vector. In this case, an empty list argument is not equivalent to omitting one: +% \begin{example}{} +% \newvect\LL{L}[elem={i,j,k},index={1,2,3}] +% $\LL$ \quad vs.\quad $\LL{}$ +% \quad vs.\quad $\LL{1,2} $ +% \end{example} +% This was shown originally in the function example on page~\pageref{func-example}. +% +% \subsection{Shorthand indices and empty elements} +% +% Shorthands are defined to allow things that +% \emph{aren't} elements into the list. +% In this example, the semi-colon separation is shown with the +% \cmd\dots\ shorthand `|:|' and the \cmd\cdot\ shorthand `|.|'. +% \begin{example}{} +% \newvect\mm{M} +% \[ \mm=\mm{1,2,:,5;a,b,.,d} \] +% \end{example} +% +% More shorthands will be defined in the future via +% an extensible mechanism that does not yet exist. +% +% Empty arguments are ignored (where `empty' $\equiv$ empty or whitespace). +% \begin{example}{} +% \newvect\nset{N} +% \[ \nset=\nset{1,,,3, ,5;;,2,;} \] +% \end{example} +% +% \subsection{\cmd\dots} +% +% Finally, some macros are defined in order to be able to typeset +% unknown ranges ($1,2,\dots,N$) without hard-coding the symbol of the +% maximum element. Similarly, it is also useful to denote a +% `mid-range' element somewhere inside the ellipses. Note the equivalence in defining the mid and last elements and indexing them. +% \begin{example}{} +% \newvect\W{W}[elem={i,j,k,:,w}] +% \newvect\Y{Y}[elem={i,j,k,:,p,:,y}] +% \[ \W=\W{1,2,:,\LAST-1,\LAST} \] +% \[ \Y=\Y{1,2,:,\MID,:,\LAST} \] +% \end{example} +% +% \noindent The \cmd\MID\ and \cmd\LAST\ control sequences are `implicit' for two dimensional lists: +% +% \begin{example}{} +% \newvect\X{X}[% +% elem={i,j,k,:,m,:,w;ii,jj,kk,:,mm,:,ww}] +% \[ \X{1,:,\MID,:,\LAST;@1,:,\MID,:,\LAST} \] +% \[ \X{1,2,3;4,5,6} \] +% \end{example} +% +% Finally, note well above that any |{:,X}| pairs for mid/last element definitions do \emph{not} add to the direct index numbering. +% +% +% \section{Generalisation} +% +% \DescribeMacro{\newmlist} +% \DescribeMacro{\renewmlist} +% The \cmd\newvect\ command that has been +% often shown previously is an example of a macro created with +% \cmd\newmlist, which can be considered something like an +% \emph{instance generator} for the types of lists we're dealing with. +% Use \cmd\renewmlist\ if the command is already in use. +% +% \cmd\newmlist\cs{<list>}\oarg{list options} creates macros +% \cs{<list>} and \cs{new<list>} (and \cs{renew<list>}) that are +% analogous to \cmd\vect\ and \cmd\newvect\ seen in +% \secref{vect}. \meta{list options} can contain any of those seen so +% far in previous \cmd\newvect\ macros, plus more to be introduced +% soon. +% +% In the examples to follow, \cmd\vect\ and \cmd\newvect\ are often +% still used to demonstrate various options, overriding the defaults. +% +% \subsection{Head and element formatting} +% +% The \opt{headcmd} and \opt{elemcmd} options are used to alter the +% formatting of the vector symbol and its elements. They are passed +% \emph{macros} that take, respectively, one and two arguments that +% define the formatting. +% +% For \cmd\vect, |headcmd=\mathbf| and |elemcmd=\mlistsub|, where +% \codeline \cmd\mlistsub |{#1}{#2}|~$\to$~|#1_{#2}|.\\ +% \cmd \mlistsup, the +% analogous command for creating superscripts, is defined by the +% package in case you need it. +% +% In this example, the vector symbol is formatted with an arrow accent, +% and the elements are exactly as specified in \opt{elem}. +% \begin{example}{} +% \newvect\A{A}[% +% headcmd=\vec, +% elemcmd=\mlistelem, +% elem={a,b,c,d}] +% +% \[\A \qquad \A{1,2,3,4} \qquad \A{3} \] +% \end{example} +% +% The \cmd\mlistelem\ command (with its friend, \cmd\mlisthead) is defined as follows: +% \codeline\cmd\mlistelem|{#1}{#2}|~$\to$~|#2| +% \codeline\cmd\mlisthead|{#1}|~$\to$~|#1| +% +% In \secref{indexing}, we saw that list indexing doesn't \emph{have} +% to be numerical. In this example, the use of \cmd\@alph\ allows +% alphabetic subscripts but non-numeric indices will produce errors: +% \begin{example}{} +% \makeatletter +% \newcommand\subalph[2]{#1_{\@alph{#2}}} +% \makeatother +% \newvect\A{A}[% +% elemcmd=\subalph] +% +% \[ \A{1,2,3,4} \qquad \A{3} \] +% \end{example} +% +% \subsection{Head prefixing} +% +% Applying (things like) accents to \pkg{mlist}s will often give the wrong result: +% \begin{example}{} +% \newfunc\A{A} +% $\A{1}$ \qquad $\bar{\A{1}}$ +% \end{example} +% +% The solution for this involves defining a prefix for the head element with the |headhook| option: +% \begin{example}{} +% \newfunc\A{A} +% \newcommand\baraccent[1]{% +% {\mlistsetup{headhook=\bar}#1}} +% $\A{1}$ \qquad $\baraccent{\A{1}}$ +% \end{example} +% +% This method can also be used to apply \emph{post}fix elements as well: +% \begin{example}{} +% \newfunc\A{A} +% \newcommand\postprime[1]{#1'} +% \newcommand\primeaccent[1]{% +% {\mlistsetup{headhook=\postprime}#1}} +% $\A{1}$ \qquad $\A{1}'$ \qquad $\primeaccent{\A{1}}$ +% \end{example} +% +% The user interface for these features is rather rough and needs more thought; it might be better if \cmd\mlistsetup\ did not need to be called in the accent definition. +% +% For these reasons the |headhook| feature should be considered a little experimental and possibly subject to change in the future. It should certainly be accompanied by a variety of `\cmd\baraccent'--like commands, unless \cmd\bar\ can be patched to recognise such situations automatically (this seems unlikely). +% +% \subsection{Delimiter formatting} +% +% The \opt{wrap} and \opt{wrapone} options are used to change the way +% elements are displayed together. Each take two +% arguments to define the opening and closing material. +% +% By default, if there is more than one element, it is surrounded by +% square brackets: |wrap=[]|. A single element is typeset naked: +% |wrapone={}{}|. If \opt{wrapone} is called with no `|=|' argument, it +% takes the same value as \opt{wrap}. +% +% In this example, the brackets around the sets are changed to +% parentheses, including single elements. The behaviour for a single +% element is then changed to use angle brackets: +% \begin{example}{firstline=2} +% \parskip1ex +% \newvect\Q{Q} +% $\Q + \Q{1} + \Q{a,b}$ +% +% \newvect\QQ{Q}[wrap=(),wrapone] +% $\QQ + \QQ{1} + \QQ{a,b}$ +% +% \newvect\QQQ{Q}[wrapone={\left<}{\right>}] +% $\QQQ + \QQQ{1} + \QQQ{a,b}$ +% \end{example} +% +% Rather than defining the open/close material around a set of +% elements, it can often be necessary to define a macro that defines +% the formatting of the set. The \opt{wrapcmd} and \opt{wraponecmd} +% options are used for this purpose, and take as argument a single +% macro that accepts two arguments: the list head and the +% list elements, respectively. +% +% \begin{example}{firstline=2} +% \parskip1ex +% \newvect\R{R} +% $\R + \R{1} + \R{a,b}$ +% +% \newcommand\mywrap[2]{\langle{\color{red}#2}\rangle_{#1}} +% \newvect\RR{R}[wrapcmd=\mywrap,wraponecmd] +% $\RR + \RR{1} + \RR{a,b}$ +% +% \newcommand\mywrapone[2]{\{{\color{green}#2}\}^{#1}} +% \newvect\RRR{R}[ +% wrapcmd=\mywrap, +% wraponecmd=\mywrapone] +% $\RRR + \RRR{1} + \RRR{a,b}$ +% \end{example} +% +% \pkg{mlist} provides some example commands for this purpose:\par\nobreak\noindent +% \begingroup\ttfamily +% \def\mean#1{\string#1 & \expandafter\parse@meaning\meaning#1\@nil} +% \def\parse@meaning #1:#2->#3\@nil{\detokenize{#3}\\} +% \begin{tabular}{l@{$~\to~$}l} +% \mean\mlistnowrap +% \mean\mlistparen +% \mean\mlistbrack +% \mean\mlistbrace +% \mean\mlistangle +% \mean\mlistheadparen +% \mean\mlistheadbrack +% \mean\mlistheadbrace +% \mean\mlistheadangle +% \end{tabular} +% \endgroup +% +% \subsection{Separator formatting} +% +% The \opt{sep} and \opt{sepsep} options take one argument that is inserted between items in comma and semi-colon lists, respectively. For example, in the \cmd\matr\ list these are defined with |[sep=&, sepsep=\\]|. +% +% Here's another example: +% \begin{example}{} +% \newvect\mysum{S}[ +% sep=+, +% wrap={}{}, +% dots=\cdots] +% $\mysum{a,b,c,d,:,p,q,r,s,:,x,y,z}$ +% \end{example} +% +% \subsection{Global options definition} +% +% \DescribeMacro{\mlistsetup} If options aren't specified in +% \cmd\newmlist\ they are inherited from the global defaults, which +% may be adjusted with \cmd\mlistsetup\marg{mlist options}. The defaults +% are shown in \secref[vref]{defaults}. +% +% \subsection{Redefining \cmd\vect, \cmd\matr, \cmd\func, \cmd\mset} +% +% This package makes little claim for being imminently usable for most +% people \emph{out of the box}. I figure there's just too much +% variety; people need to define their own `mlists' with \cmd\newmlist. +% +% If changes to the mlists provided by default with this package +% are required (as they will be if any aspect of their formatting needs +% to be adjusted), simply create a local |mlist.cfg| file with different +% defintions or even just copy them from \secref[vref]{defaults} +% in a \cmd\renewmlist. +% +% \section{TODO} +% \begin{itemize} +% \item changing features of (or adding features to, rather) `newvect' +% constructions, rather than overwriting them. +% \item generalise escaping strings like |:|$\to$|\dots|, etc. +% \item accents and appended/prepended material migrating inside the +% head (and/or each element) argument. +% \item optional arguments for \cmd\MID\ and \cmd\LAST\ (for explicit indexing). +% \item coercing one type of list into another +% (and retrieving non-wrapped lists as a special case) +% \item use ltx3! +% \end{itemize} +% +%\iffalse +%<*defaults> +%\fi +% +% \section{The default definitions} +% \seclabel{defaults} +% +% This is the code that appears in the default configuration file \pkg{mlist.cfg} to set up the +% default options and mlists. Edit a copy of \pkg{mlist.cfg} in a local location (in a local \texttt{texmf} tree or on a per-document basis) to change these definitions and to create your own mlists. +% +% \subsection{Global options} +% These are inherited by mlists that do not explicitly define their own respective +% options. Geared towards \cmd\vect, essentially. +% \begin{macrocode} +\mlistsetup{% + sep={,}, + sepsep={;}, + wrapcmd=\mlistparen, + wrapone={}{}, + dots=\dots, + dot={\,\cdot\,}, + elemcmd=\mlistelem, + headcmd=\mathbf, + index={}, + headhook={}, +} +% \end{macrocode} +% +% \subsection{Provided mlists} +% +% Redefine these with \cmd\renewmlist\ to effect your own formatting +% of these mlists. Note that these assume certain global defaults (see +% above), so some aspects of their formatting can be changed with +% \cmd\mlistsetup. +% +% \begin{macro}{\vect} +% By default |\vect{V}=\vect{V}{a,b,c}| $\to$ $\vect{V}=\vect{V}{a,b,c}$. +% \begin{macrocode} +\newmlist\vect[ + wrapcmd=\mlistparen, + wraponecmd=\mlistnowrap, + elemcmd=\mlistsub, + headcmd=\mathbf, +] +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\matr} +% By default |\matr{M}=\matr{M}{a,b;c,d}| $\to$ $\matr{M}=\matr{M}{a,b;c,d}$. +% \begin{macrocode} +\newmlist\matr[ + sep=&, + sepsep=\\, + wrap={\begin{bmatrix}} + {\end{bmatrix}}, +] +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\func} +% By default, |\func{f}=\func{f}{x,y,z}| $\to$ $\func{f}=\func{f}{x,y,z}$. +% \begin{macrocode} +\newmlist\func[ + headcmd=\mlisthead, + wrapcmd=\mlistheadparen, + wraponecmd, +] +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mset} +% By default, |\mset{N}{2,3}| $\to$ $\mset{N}{2,3}$. +% \begin{macrocode} +\newmlist\mset[ + headcmd=\mathbb, + sep=\times, + wrapcmd=\mlistsup, + wraponecmd, +] +% \end{macrocode} +% \changes{v0.5}{2007/06/06}{Added.} +% \end{macro} +% Sets for real, complex, natural, and integer numbers, respectively: +% \begin{macrocode} +\newmset\setR{R} +\newmset\setC{C} +\newmset\setN{N} +\newmset\setZ{Z} +% \end{macrocode} +% +%\iffalse +%</defaults> +%\fi +% +% \section{Prior art} +% +% With \CTAN\ getting so big these days, it's quite necessary to +% undertake extensive literature reviews before writing your own +% package. I've been burned before, spending a couple of days playing +% with ideas and then realising that someone's already done what I wanted. +% This time I looked before I jumped. +% +% \paragraph{easyvector} +% The most similar package to this one (that I could find) is +% \pkg{easyvector}. +% \note{\url|http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=easyvector|} +% Superficially, there are a number of similarities, but it didn't +% quite do what I wanted. Here's an example demonstrating the creation +% of new vector macros: +% \begin{example}{} +% \newvector[Z,\mathbf{Z}]{X} +% \[ \X = (\X[i,j;k]) \qquad +% \X[1,2,3] \neq \X![1,2,3] \] +% \end{example} +% +% Note that each macro refers only to a single vector element. This is a package +% to simplify input (and abstract formatting) of vectors with complex notation. +% \pkg{easyvector} also allows you to customise the form of the +% vectors it produces, but this is rather inflexible without a good +% deal of work. +% \begin{example}{} +% \def\myindex[#1,#2,#3]{_{#1_{#2}}^{#3}} +% \newcustomvector[\mathtt{b},\mathbf{b}]{bb}\myindex +% \[ \bb \qquad \bb[1,2,3] \qquad \bb[3,2,1] \] +% \end{example} +% +% Note also that the main symbol (`$\mathtt{b}$', here) is not +% available even in this case, so prepended sub-/superscripts are not possible. +% +% Has the interesting option to reference matrix row/column sub-vectors: (careful to ensure \cmd\makeatother\ manually) +% \makeatother +% \begin{example}{} +% \newvector(W)[wvec] +% \[ \wvec = (\wvec[@,j]) \qquad \wvec[a,b;@] \] +% \end{example} +% \makeatletter +% +% I like this idea of `shorthand' symbols. +% +% \paragraph{\pkg{vector}} +% The package \pkg{vector} +% \note{\url|http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=vector|} +% provides a few commands for setting vector and matrix symbols, shown in \tabref{vectorpkg}. +% Just a few basic macros to simplify input, but not really to separate form and content. +% +% \pkg{vector} provided the inspiration to add |\dots| ideas to this package. It also highlights that +% something specific should be done with accents in general and provide a content macro for unit vectors. +% +% \begin{table} +% \centering +% \begin{tabular}{@{}ccccccc@{}} +% \toprule +% |\bvec| & |\buvec| & |\svec| & |\suvec| & |\uvec| & |\uuvec| & |\irvec| \\ +% \bvec{a} & \buvec{a} & \svec{a} & \suvec{a} & \uvec{a} & \uuvec{a} & \irvec{a} \\ +% \bottomrule +% \end{tabular} +% \caption{Commands defined by the \pkg{vector} package. +% \cmd\uvec\ and \cmd\uuvec\ can be configured to produce an under-tilde instead. +% \cmd\irvec\ takes an optional argument for `$n$' and can be configured (globally) to begin from a different index.} +% \label{tab:vectorpkg} +% \end{table} +% +% \paragraph{hhtensor} +% The hhtensor package +% \note{\url|http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=hhtensor|} +% provides a few content-based macros with global options to specify their appearance. +% \cmd\vec, \cmd\matr\, and \cmd\tens\ are provided for vectors, matrices, and tensors, with +% mathematical symbols \cmd\dcdot\ to denote double scalar products, and \cmd\trans\ for printing +% an upright superscript `T' to denote the transpose operator. +% +% This package was the inspiration for pre-defined macros for specific meanings. +% While I approve of defining the transpose symbol, it's outside the scope of \pkg\jobname. +% +% \paragraph{Other tensor packages} +% There are three main packages for typesetting tensors. +% These start to stray from the interest of \pkg\jobname. +% The relevant packages are +% \pkg{tensind}, +% \note{\url|http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=tensind|} +% \pkg{tensor}, +% \note{\url|http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=tensor|} +% and \pkg{mattens}. +% \note{\url|http://tug.ctan.org/cgi-bin/ctanPackageInformation.py?id=mattens|} +% Each focuses on typesetting various forms of tensor notation, which differ from what +% this package is trying to do. Integration between this package and those three above are possible, +% but has not yet been investigated. +% +% +% \StopEventually{} +% +% \clearpage +% \part{\pkg{\jobname} implementation} +%\iffalse +%<*package> +%\fi +% +% \section{Setup code} +% This is the package. +% +% \begin{macrocode} +\ProvidesPackage{mlist} + [2008/08/15 v0.6a Typesetting maths lists] +% \end{macrocode} +% +% \PrintChanges +% \changes{v0.1}{27/04/2007}{Code tidy up; first decent version.} +% \changes{v0.2}{30/04/2007}{More documentation; list indexing not finalised.} +% \changes{v0.3}{2007/05/02}{List indexing decided; empty arguments ignored.} +% \changes{v0.4}{2007/05/26}{Tidied things up a little bit.} +% +% \subsection{User shorthands} +% +% For |headcmd|: +% \begin{macrocode} +\let\mlisthead\@firstofone +% \end{macrocode} +% For |elemcmd|: +% \begin{macrocode} +\let\mlistelem\@secondoftwo +\newcommand\mlistsub [2]{#1_{#2}} +\newcommand\mlistsup [2]{#1^{#2}} +% \end{macrocode} +% For |wrapcmd|: +% \begin{macrocode} +\let\mlistnowrap\@secondoftwo +\newcommand\mlistparen[2]{\left(#2\right)} +\newcommand\mlistbrack[2]{\left[#2\right]} +\newcommand\mlistbrace[2]{\left\{#2\right\}} +\newcommand\mlistangle[2]{\left<#2\right>} +\newcommand\mlistheadparen[2]{#1\left(#2\right)} +\newcommand\mlistheadbrack[2]{#1\left[#2\right]} +\newcommand\mlistheadbrace[2]{#1\left\{#2\right\}} +\newcommand\mlistheadangle[2]{#1\left<#2\right>} +% \end{macrocode} +% +% +% +% \subsection{Packages} +% \begin{macrocode} +\RequirePackage{xkeyval,ifmtarg} +% \end{macrocode} +% \subsection{Code we need} +% Conditionals and counters and things: +% \begin{macrocode} +\newif\if@mlist@notfirst@ +\newif\if@mlist@implicit@ +\newcount\mlist@elem@N +\def\@gobblenil#1\@nil{} +% \end{macrocode} +% Some specific things: +% \begin{macrocode} +\newif\if@mlist@warn +% \end{macrocode} +% Semi-colon delimited iteration (adapted from ltx2e). +% \begin{macrocode} +\long\def\@sfor#1:=#2\do#3{% + \expandafter\def\expandafter\@sfortmp\expandafter{#2}% + \ifx\@sfortmp\@empty\else + \expandafter\@sforloop#2;\@nil;\@nil\@@#1{#3}% + \fi} +\long\def\@sforloop#1;#2;#3\@@#4#5{% + \def#4{#1}% + \ifx #4\@nnil \else + #5% + \def#4{#2}% + \ifx #4\@nnil \else + #5% + \@siforloop #3\@@#4{#5}% + \fi + \fi} +\long\def\@siforloop#1;#2\@@#3#4{% + \def#3{#1}% + \ifx #3\@nnil + \expandafter\@fornoop + \else + #4\relax\expandafter\@siforloop + \fi + #2\@@#3{#4}} +% \end{macrocode} +% +% ltx3-inspired syntax. \cmd\def@c\ still needs arguments to be supplied to it. +% \begin{macrocode} +\providecommand\let@cc[2]{% + \expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname} +\providecommand\def@c[1]{% + \expandafter\def\csname#1\endcsname} +\providecommand\def@co[2]{% + \def@c{#1\expandafter}\expandafter{#2}} +% \end{macrocode} +% \begin{macro}{\mlist@optarg} +% Macro to simplify optional argument parsing. +% \begin{macrocode} +\newcommand\mlist@optarg[1]{\@ifnextchar[{#1}{#1[]}}%] +% \end{macrocode} +% \changes{v0.4}{2007/05/26}{Implemented to simplify optional arg processing.} +% \changes{v0.6a}{2008/08/15}{Renamed to avoid clashing with \pkg{breqn}'s command of the same name.} +% \end{macro} +% Shorthand to test for optional brace arguments: +% \begin{macrocode} +\newcommand\@ifnextbrace{\expandafter\@ifnextchar\bgroup} +% \end{macrocode} +% Shorthand string definitions for ifx tests: +% \begin{macrocode} +\def\mlist@colon{:} +\def\mlist@period{.} +% \end{macrocode} +% This is for checking for |@| with an `other' catcode: +% \begin{macrocode} +\makeatother +\expandafter\def\csname mlist@ampersat\endcsname{@} +\makeatletter +% \end{macrocode} +% (`Ampersat' is a name for |@| I find amusing. That symbol doesn't seem to +% have a definitive official name.) +% +% \section{keyval options} +% +% \begin{macro}{\mlistsetup} +% \darg{keyval options} +% User command to set global defaults for mlists. +% \begin{macrocode} +\newcommand\mlistsetup[1]{\setkeys[mlist]{sym}{#1}} +% \end{macrocode} +% \end{macro} +% +% \pkg{xkeyval} makes it easy for us to define a whole slew of options +% that simply save their argument to a macro. +% \begin{macrocode} +\define@cmdkeys[mlist]{sym}[mlist@]{% + symbol,index,sep,sepsep,elem, + elemcmd,headcmd,dot,dots,headhook} +% \end{macrocode} +% +% \subsection{Wrapping} +% The wrapcmd options also just save their argument, but wraponecmd +% takes wrapcmd as a default: +% \begin{macrocode} +\define@key[mlist]{sym}{wrapcmd}{\let\mlist@wrap#1} +\define@key[mlist]{sym}{wraponecmd}[\mlist@wrap]{\let\mlist@wrapone#1} +% \end{macrocode} +% The wrap and wrapone options need a bit more logic in them: +% \begin{macrocode} +\define@key[mlist]{sym}{wrap}{% + \def\mlist@wrap##1##2{\@firstoftwo#1##2\@secondoftwo#1}} +\define@key[mlist]{sym}{wrapone}[]{% + \ifx\relax#1\relax + \let\mlist@wrapone\mlist@wrap + \else + \def\mlist@wrapone##1##2{\@firstoftwo#1##2\@secondoftwo#1}% + \fi} +% \end{macrocode} +% +% \subsection{Element definition} +% +% Takes as input a two dimension list with comma-separated elements +% and semicolon-separated lists of elements: +% \codeline |#1| $\to$ |{1,2,3;4,5;6}| . +% +% Elements could be numerical or arbitrary \TeX\ code. +% \begin{macrocode} +\define@key[mlist]{sym}{elem}{% +% \end{macrocode} +% It would be easier for all involved if I used specific counters for +% the following. For now, they're generic and harder to comprehend in +% six months: +% \begin{description}[nolistsep] +% \item[\cmd\@tempcnta] Number of semicolon list. +% \item[\cmd\@tempcntb] Element number of this comma list. +% \end{description} +% \begin{macrocode} + \@tempcnta\z@ + \@tempcntb\z@ + \mlist@elem@N\z@ +% \end{macrocode} +% Iterate over every semicolon list. Set \cs{if@tempswa} true only +% after every |:| element, for each semicolon list. Maybe we should +% use a counter for this, instead? +% \begin{macrocode} + \@sfor\@jj:=#1\do{% + \advance\@tempcnta\@ne + \@tempcntb\z@ + \@tempswafalse +% \end{macrocode} +% Iterate over every comma list: +% \begin{macrocode} + \@for\@ii:=\@jj\do{% +% \end{macrocode} +% If the element is |:|, set the switch for the next comma-iteration. +% \begin{macrocode} + \ifx\@ii\mlist@colon + \@tempswatrue + \else +% \end{macrocode} +% If the previous element was |:|, save the `last' element: (TODO: add +% error check for too many |:|). If we've already defined the `last' +% element and run into |:| again, that means we actually wanted `mid' +% so make the redefinition. This should only happen once anyway so it +% can occur every time \cs{if@tempswa} is true. +% \begin{macrocode} + \if@tempswa + \let@cc{mlist@\the\@tempcnta @mid}{mlist@\the\@tempcnta @last}% + \def\@tempa{\def@c{mlist@\the\@tempcnta @last}}% + \expandafter\@tempa\expandafter{\@ii}% + \else +% \end{macrocode} +% Otherwise, bump up the counters and define the elements. There are +% two definitions we used for the element indexing. As an example, if +% we're up to index $(3,1)$ of a list like $\{a,b,c;d,e;f\}$ then we define +% \codeline |\mlist@3@1| $\to$ elem $f$ , and +% \codeline |\mlist@@6| $\to$ elem $f$ . \\ +% (Index $3,1$ is the sixth in the list.) +% \begin{macrocode} + \advance\@tempcntb\@ne + \advance\mlist@elem@N\@ne + \def@co{mlist@\the\@tempcnta @\the\@tempcntb}{\@ii}% + \def@co{mlist@@\the\mlist@elem@N}{\@ii}% + \fi + \fi}% +% \end{macrocode} +% If swa is true, we are in an element after a |:|, so turn it off. +% TODO: I guess no more regular elements can turn up anyway so this is +% probably overkill! +% \begin{macrocode} + \if@tempswa\@tempswafalse\fi}} +% \end{macrocode} +% \changes{v0.3}{2007/05/09}{Tidied up the \cmd\MID/\cmd\LAST\ element +% stuff a bit.} +% +% \subsection{Shorthand definitions} +% +% Currently defunct: +% \begin{macrocode} +\define@key[mlist]{sym}{shorthand}{% + \mlist@def@shorthand#1% + \def@c{mlist@@\@tempa\expandafter}\expandafter{\@tempb}} +% \end{macrocode} +% +% \begin{macrocode} +\def\mlist@def@shorthand#1#{% + \def\@tempa{\string#1} + \def\@tempb} +% \end{macrocode} +% +% \section{List indexing} +% +% How do I want indexing to work? Originally, the input was a one +% dimensional list with the output directly following the indexing: +% \begin{verbatim} +% A = {a1,a2,a3,a4} +% A{1,2;3,4} == {a1,a2;a3,a4} +% \end{verbatim} +% I tried a couple of other things, but went back to this idea plus the +% implicit indexing. +% +% \begin{macro}{\@mlist} +% \darg{keyval options} +% This is the \cmd\setkeys\ wrapper, which +% sets macros for us in various ways depending on how it has been +% called and then moves on to do the actual list indexing, +% extraction, and typesetting. +% \begin{macrocode} +\newcommand\@mlist[1]{% + \begingroup + \let\mlist@list@elems\@empty + \@tempcnta\@ne + \mlist@count +% \end{macrocode} +% The \cmd\setkeys\ code to extract our mlist is flanked by some scary +% code to protect ourselves inside things like |{array}| +% environments. Thanks Morten. +% \begin{macrocode} + \iffalse{\fi\ifnum0=`}\fi + \setkeys[mlist]{sym}{#1}% + \ifnum0=`{\fi\iffalse}\fi +% \end{macrocode} +% These macros only exist inside an mlist index: +% \begin{macrocode} + \def\MID{\csname mlist@\the\@tempcnta @mid\endcsname}% + \def\LAST{\csname mlist@\the\@tempcnta @last\endcsname}% +% \end{macrocode} +% If there are no optional arguments, typeset the plain vector symbol. +% \begin{macrocode} + \ifx\@empty\mlist@index\relax + \def\mlist@list{\mlist@headcmd{\mlist@headhook\mlist@symbol}}% + \else +% \end{macrocode} +% Otherwise, iterate over every semicolon-separated list. +% \begin{macrocode} + \@tempcnta\z@ + \@tempswafalse + \@sfor\@jj:=\mlist@index\do{% + \let\@jj\@jj + \advance\@tempcnta\@ne + \mlist@count + \expandafter\@ifmtarg\expandafter{\@jj}{}% ignore if empty + {\if@tempswa\mlist@add\mlist@sepsep\fi + \@tempswatrue}% +% \end{macrocode} +% And (sub-)iterate over every comma-separated list: +% \begin{macrocode} + \@tempcntb\z@ + \@mlist@notfirst@false + \@for\@ii:=\@jj\do{% + \let\@ii\@ii + \advance\@tempcntb\@ne +% \end{macrocode} +% Now grab the symbol we're up to. +% When it's empty: +% \begin{macrocode} + \expandafter\@ifmtarg\expandafter{\@ii}% + {\advance\@tempcntb\m@ne + \mlist@add{\@gobble}} +% \end{macrocode} +% When it's not empty: +% \begin{macrocode} + {\if@mlist@notfirst@\mlist@add\mlist@sep\fi + \@mlist@notfirst@true + \ifx\@ii\mlist@colon + \mlist@add{\mlist@dots\@gobble}% + \else + \ifx\@ii\mlist@period + \mlist@add{\mlist@dot\@gobble}% + \else + \mlist@add{\mlist@elemcmd{\mlist@headhook\mlist@symbol}}% + \fi + \fi}% +% \end{macrocode} +% Parse the index to see if it's an implicit reference of the form +% |@|$n$. @mlist@implicit@ is true if the index is implicit: (and we assume |@| +% will be only used in an implicit-indexing context. TODO: fix this!) +% \begin{macrocode} + \mlist@parse@implicit + \if@mlist@implicit@ + \mlist@add@ifcs{% + mlist@\the\@tempcnta @\expandafter\@gobble\@ii + }{\@ii}% + \else +% \end{macrocode} +% Because \cmd\@ii, \cmd\@jj\ can contain any possible index that +% might be passed through the macro, we use eTeX's \cmd\detokenize\ to +% prevent expansion of any weird argument that might be given. +% \begin{macrocode} + \mlist@add@ifcs{% + mlist@@\expandafter\detokenize\expandafter{\@ii}% + }{\@ii}% + \fi + }% +% \end{macrocode} +% That was the end of comma-separated iteration. +% \begin{macrocode} + }% +% \end{macrocode} +% That was the end of semicolon-separated iteration. +% \begin{macrocode} + \def\mlist@list{% + \mlist@wrap{\mlist@headcmd{\mlist@headhook\mlist@symbol}} + {\mlist@list@elems}}% +% \end{macrocode} +% If only have a single element: +% \begin{macrocode} + \ifnum\@tempcnta=\@ne + \ifnum\@tempcntb=\@ne + \let\mlist@wrap\mlist@wrapone + \fi + \fi + \fi + \mlist@list + \endgroup} +% \end{macrocode} +% TODO: move \cmd\mlist@list\ after the endgroup? +% \changes{v0.4}{2007/05/17}{Eliminated \cmd\global\ no longer +% required since I separated the list creation and typesetting.} +% \changes{v0.4}{2007/05/19}{Simplified `single index' code.} +% \changes{v0.5}{2007/06/06}{Added \cmd\mlist@headcmd\ command to the \cmd\mlist@symbol inside \cmd\mlist@wrap\ (fixed bug with \cmd\mset)} +% \changes{v0.6}{2008/04/02}{Added \cmd\mlist@headhook.} +% \end{macro} +% +% \begin{macro}{\mlist@add} +% Used in the above to build up the \cmd\mlist@list\ list. +% \begin{macrocode} +\newcommand\mlist@add[1]{% + \expandafter\gdef + \expandafter\mlist@list@elems + \expandafter{\mlist@list@elems#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mlist@count} +% This macro is used to increment the counter used in +% \cmd\MID/\cmd\LAST\ during the actual typesetting of the indexed +% elements. +% \begin{macrocode} +\def\mlist@count{% + \expandafter\mlist@add + \expandafter{% + \expandafter\@tempcnta\the\@tempcnta\relax}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mlist@add@ifcs} +% Pretty specific macro to save some repetition. Uses +% \cmd\mlist@add\ to add the first argument as a csname if it +% exists, otherwise adds the literal second argument. +% \begin{macrocode} +\newcommand\mlist@add@ifcs[2]{% + \ifcsname#1\endcsname + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi{\expandafter\mlist@add\expandafter{\expandafter{\csname#1\endcsname}}} + {\expandafter\mlist@add\expandafter{\expandafter{#2}}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mlist@parse@implicit} +% Parses the index to see if it's an implicit reference: |@|$n$. The +% idea is to expand out the index, set a conditional if the first +% char is an |@|, and then gobble up the whole thing. We do this +% twice for the two common catcodes that |@| might be. +% \begin{macrocode} +\def\mlist@parse@implicit{% + \@mlist@implicit@false + \def\@tempb{% + \expandafter\@ifnextchar\mlist@ampersat + {\@mlist@implicit@true\@gobblenil} + {\@mlist@implicit@false\@gobblenil}}% + \expandafter\@tempb\@ii\@nil + \unless\if@mlist@implicit@ + \def\@tempb{% + \@ifnextchar @ + {\@mlist@implicit@true\@gobblenil} + {\@mlist@implicit@false\@gobblenil}}% + \expandafter\@tempb\@ii\@nil + \fi} +% \end{macrocode} +% \changes{v0.3}{2007/05/09}{Added second check to \cmd\@ifnextchar +% |@| for catcode letter.} +% \end{macro} +% +% \section{List creation} +% +% This is the idea behind the user level macros of the package: +% \begin{verbatim} +% \newmlist\vect{all-vect-opts} +% \vect{v}{ind} == \@mlist{symbol={v},all-vect-opts,index={ind}} +% +% \newvect\vv{v}[this-v-options] +% \vv[ind] == \@mlist{symbol={v},all-vect-opts,this-v-options,index={ind}} +% \end{verbatim} +% +% \begin{macro}{\newmlist} +% \begin{macro}{\renewmlist} +% \darg{control sequence} +% \oarg{keyval options} +% Things get pretty hairy because I have to do all the optional +% argument processing manually. I'd be better off using the +% \pkg{suffix} package, but the code works for now. \ltx3 will make +% things much easier. +% \begin{macrocode} +\newcommand\newmlist[1]{% + \@mlist@warntrue + \mlist@optarg{\@defmlist@opt{#1}}} +\newcommand\renewmlist[1]{% + \@mlist@warnfalse + \mlist@optarg{\@defmlist@opt{#1}}} +\def\@defmlist@opt#1[#2]{\@defmlist{#1}{#2}} +% \end{macrocode} +% Processing |#1| = thislist-cmd, |#2| = all-thislist-opts +% \begin{macrocode} +\newcommand\@defmlist[2]{% + \if@mlist@warn + \ifdefined#1 + \PackageError{mlist}{Command \string#1 already defined} + {\string#1 will be overwritten}% + \fi + \fi +% \end{macrocode} +% Plain usage: (e.g., |\vect{a}{1,2,3}|) +% \begin{macrocode} + \protected\def#1##1{% + \@ifnextbrace + {\csname\string#1@opt\endcsname{##1}} + {\csname\string#1@opt\endcsname{##1}{}}}% + \def@c{\string#1@opt}##1##2{% + \csname\string#1\endcsname{##1}{##2}}% + \def@c{\string#1}##1##2{% + \@mlist{symbol=##1,#2,index={##2}}}% +% \end{macrocode} +% mlist macro definitions: (e.g., |\newvect{A}[...]|) +% Processing |##1| = this-sym-cmd, |##2| = symbol, |##3| = this-sym-options +% \begin{macrocode} + \def@c{new\expandafter\@gobble\string#1}##1##2{% + \@mlist@warntrue + \mlist@optarg{\csname @new\string#1@opt\endcsname{##1}{##2}}}% + \def@c{renew\expandafter\@gobble\string#1}##1##2{% + \@mlist@warnfalse + \mlist@optarg{\csname @new\string#1@opt\endcsname{##1}{##2}}}% + \def@c{@new\string#1@opt}##1##2[##3]{% + \csname @new\string#1\endcsname{##1}{##2}{##3}}% + \def@c{@new\string#1}##1##2##3{% + \if@mlist@warn + \ifdefined##1 + \PackageError{mlist}{Command \string##1 already defined} + {You cannot overwrite previous definition of \string##1}% + \fi + \fi + \protected\def##1{% + \@ifnextbrace + {\csname @new\string##1@opt\endcsname} + {\@mlist{symbol=##2,#2,##3}}}% + \def@c{@new\string##1@opt}####1{% + \@mlist{symbol=##2,#2,##3,index={####1}}}}% + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{example}{firstline=2} +% \raggedright\ttfamily\slshape +% \def\@mlist#1{MLIST: #1\par} +% \newmlist\testlist[opt1=one] +% \newtestlist\testone{S} +% \testone +% \testone{1,2,3} +% \newtestlist\testtwo{T}[opt2=two] +% \testtwo +% \testtwo{1,2,3} +% \end{example} +% +% \begin{macrocode} +\InputIfFileExists{mlist.cfg}{} + {\PackageWarning{mlist}{No configuration file (mlist.cfg) found nor loaded}} +% \end{macrocode} +% +%\iffalse +%</package> +%\fi +% +% +%\iffalse +%<*dtx-style> +% \begin{macrocode} +\ProvidesPackage{dtx-style} + +\errorcontextlines=999 + +\def\@dotsep{1000} +\setcounter{tocdepth}{2} +\setlength\columnseprule{0.1pt} +\renewcommand\tableofcontents{\relax + \begin{multicols}{2}[\section*{\contentsname}]\small + \@starttoc{toc}\relax + \end{multicols}} + +\setcounter{IndexColumns}{2} +\renewenvironment{theglossary} + {\small\list{}{} + \item\relax + \glossary@prologue\GlossaryParms + \let\item\@idxitem \ignorespaces + \def\pfill{\hspace*{\fill}}} + {\endlist} + +\usepackage[svgnames]{xcolor} +\usepackage{amsmath,array,bm,booktabs,calc,enumitem,fancyvrb,graphicx,ifthen,longtable,refstyle,subfig,topcapt,varioref,mlist} + +\usepackage{easyvector,vector,tensind} +\usepackage{url} + +\usepackage[sc,osf]{mathpazo} + +\linespread{1.069} % A bit more space between lines +\frenchspacing % Remove ugly extra space after punctuation + +\definecolor{niceblue}{rgb}{0.2,0.4,0.8} +\newenvironment{example}[1] + {\VerbatimEnvironment + \def\Options{#1}% + \begin{VerbatimOut}[gobble=2]{\examplefilename}} + {\end{VerbatimOut}\relax + \typesetexample} + +\fvset{formatcom=\color{niceblue}} +\DefineShortVerb{\|} + +\def\theCodelineNo{\textcolor{niceblue}{\sffamily\tiny\arabic{CodelineNo}}} + +\let\examplesize\normalsize +\let\auxwidth\relax + +\newlength\examplewidth\newlength\verbatimwidth +\newlength\exoutdent \newlength\exverbgap +\setlength\exverbgap{1em} +\setlength\exoutdent{-0.15\textwidth} +\newsavebox\verbatimbox +\edef\examplefilename{\jobname.example} + +\newcommand\typesetexample{\relax + \smallskip + \noindent + \begin{minipage}{\linewidth} + \color{niceblue} + \hrulefill\par + \edef\@tempa{[gobble=0,fontsize=\noexpand\small,\Options]}% + \begin{lrbox}{\verbatimbox}\relax + \expandafter\BVerbatimInput\@tempa{\examplefilename}% + \end{lrbox} + \begin{list}{}{\setlength\itemindent{0pt} + \setlength\leftmargin\exoutdent + \setlength\rightmargin{0pt}}\item + \ifx\auxwidth\relax + \setlength\verbatimwidth{\wd\verbatimbox}% + \else + \setlength\verbatimwidth{\auxwidth}% + \fi + \begin{minipage}[c]{\textwidth-\exoutdent-\verbatimwidth-\exverbgap} + \catcode`\%=14\centering\linespread{1.6}\input\examplefilename\relax + \end{minipage}\hfill + \begin{minipage}[c]{\verbatimwidth} + \usebox\verbatimbox + \end{minipage} + \end{list} + \par\noindent\hrulefill + \end{minipage}\par + \smallskip\noindent} + +\newcommand*\setverbwidth[1]{\def\auxwidth{#1}} + +\newcommand*\name[1]{{#1}} +\newcommand*\pkg[1]{\textsf{#1}} +\newcommand*\feat[1]{\texttt{#1}} +\newcommand*\opt[1]{\texttt{#1}} + +\newcommand*\ltx[1]{% + \ifx3#1\relax + \textsc{ltx3}% + \else + \LaTeXe + \fi} + +\newcommand*\note[1]{\unskip\footnote{#1}} + +\let\latin\textit +\def\eg{\latin{e.g.}} +\def\Eg{\latin{E.g.}} +\def\ie{\latin{i.e.}} +\def\etc{\@ifnextchar.{\latin{etc}}{\latin{etc.}\@}} + +\def\STIX{\textsc{stix}} +\def\MacOSX{Mac~OS~X} +\def\ascii{\textsc{ascii}} +\def\OMEGA{Omega} +\def\CTAN{\textsc{ctan}} + +\newcounter{argument} +\g@addto@macro\endmacro{\setcounter{argument}{0}} +\newcommand*\darg[1]{% + \stepcounter{argument}% + {\ttfamily\char`\#\theargument~:~}#1\par\noindent\ignorespaces} +\newcommand*\doarg[1]{% + \stepcounter{argument}% + {\ttfamily\makebox[0pt][r]{[}\char`\#\theargument]:~}#1\par\noindent\ignorespaces} + +\def\codeline{\par\hspace{\parindent}}% two \indents in total + +\newcommand\unichar[2]{\textsc{\MakeLowercase{u+#1: #2}}} + +\setlength\parindent{2em} + +% \end{macrocode} +%</dtx-style> +%\fi +% +% \typeout{*************************************************************} +% \typeout{*} +% \typeout{* To finish the installation you have to move the following} +% \typeout{* file into a directory searched by XeTeX:} +% \typeout{*} +% \typeout{* \space\space\space mlist.sty} +% \typeout{*} +% \typeout{*************************************************************} +% +\endinput |