% \iffalse %<*internal> \iffalse % %<*readme> _________________ The MLIST package v0.6 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. ____________________ Brief change history 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 % %<*internal> \fi \begingroup % %<*batchfile> \input docstrip.tex \keepsilent \preamble __________________________________ Copyright (C) 2007 Will Robertson License information appended. \endpreamble \postamble Copyright (C) 2007 by Will Robertson 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}}} % %\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} % % %<*driver> \documentclass{ltxdoc} \EnableCrossrefs \CodelineIndex \RecordChanges %\OnlyDescription \usepackage{dtx-style} \begin{document} \DocInput{\jobname.dtx} \end{document} % % % % \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} % % So 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 two 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{}\oarg{list options} creates macros % \cs{} and \cs{new} (and \cs{renew}) 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 % %\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. % So 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/05/22 v0.6 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}{\@optarg} % Macro to simplify optional argument parsing. % \begin{macrocode} \newcommand\@optarg[1]{\@ifnextchar[{#1}{#1[]}}%] % \end{macrocode} % \changes{v0.4}{2007/05/26}{Implemented to simplify optional arg processing.} % \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 \@optarg{\@defmlist@opt{#1}}} \newcommand\renewmlist[1]{% \@mlist@warnfalse \@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 \@optarg{\csname @new\string#1@opt\endcsname{##1}{##2}}}% \def@c{renew\expandafter\@gobble\string#1}##1##2{% \@mlist@warnfalse \@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 % %\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} % %\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