% \iffalse meta-comment % % Copyright (C) 2005 by Scott Pakin % ------------------------------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.2 % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.2 or later is part of all distributions of LaTeX % version 1999/12/01 or later. % % \fi % % \iffalse %<*driver> \ProvidesFile{listliketab.dtx} % %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{listliketab} %<*package> [2005/01/09 v1.0a Create list-like tabulars] % % %<*driver> \documentclass{ltxdoc} \usepackage{listliketab} \usepackage{tabularx} \usepackage{amstext} \usepackage{hyperref} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{listliketab.dtx} \phantomsection \addcontentsline{toc}{section}{Change History} \PrintChanges \phantomsection \addcontentsline{toc}{section}{Index} \PrintIndex \end{document} % % \fi % % \CheckSum{100} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % % \changes{v1.0}{2000/09/08}{Initial version} % \changes{v1.0a}{2005/01/09}{Cleaned up the \string\texttt{.dtx} file} % % \GetFileInfo{listliketab.dtx} % % \DoNotIndex{\begin,\catcode,\DeclareRobustCommand,\def,\dp,\end} % \DoNotIndex{\expandafter,\gdef,\global,\hfill,\hspace,\ht} % \DoNotIndex{\ignorespaces,\ignorespacesafterend,\item} % \DoNotIndex{\newenvironment,\newlength,\newsavebox,\noindent} % \DoNotIndex{\ratio,\renewcommand,\setlength,\strip@pt,\strutbox} % \DoNotIndex{\vspace,\xdef} % % % \title{The \textsf{listliketab} package\thanks{This document % corresponds to \textsf{listliketab}~\fileversion, dated \filedate.}} % \author{Scott Pakin \\ \texttt{scott+llt@pakin.org}} % % \hypersetup{^^A % pdftitle={The listliketab package}, % pdfauthor={Scott Pakin }, % pdfsubject={LaTeX package to make tabulars look like lists}, % pdfkeywords={tabulars, tables, lists, itemize, enumerate, columns} % } % % \maketitle % \sloppy % % ^^A Define an environment for command/environment delcarations. % \newsavebox{\declbox} % \newenvironment{decl}{% % \begin{lrbox}{\declbox}\begin{tabular}{l}}{% % \end{tabular}\end{lrbox}% % \vspace{3ex}\noindent\hspace*{-3em}\fbox{\usebox{\declbox}}\vspace*{2ex}} % % \begin{abstract} % The \texttt{listliketab} package helps the user make list-like % \texttt{tabular}s, i.e., a \texttt{tabular} that is indistinguishable % from an \texttt{itemize} or \texttt{enumerate} environment. % The advantage of using a \texttt{tabular} is that the user can add % additional columns to each entry in the list. % \end{abstract} % % \section{Introduction} % % Here's an itemized list: % % \begin{itemize} % \item Fee % \item Fi % \item Fo % \item Fum % \end{itemize} % % \noindent % Here's another itemized list: % % \storestyleof{itemize} % \begin{listliketab} % \begin{tabular}{LlR} % \textbullet & Fee \\ % \textbullet & Fi \\ % \textbullet & Fo \\ % \textbullet & Fum % \end{tabular} % \end{listliketab} % % What's the difference? The two look identical, but the first was typeset % in the ordinary way, with an \texttt{itemize} environment. The second % was typeset within a \texttt{tabular} environment, using the % \texttt{listliketab} package. Because the second is a \texttt{tabular}, % it can contain additional columns on each line: % % \begin{listliketab} % \begin{tabular}{Ll@{\hspace*{2cm}}|lR} % \textbullet & Fee & % We can have additional text (and rules) with each item. \\ % \textbullet & Fi & % Try doing \emph{that} in an \texttt{itemize} environment! \\ % \textbullet & Fo \\ % \textbullet & Fum & % Not so easy, is it? % \end{tabular} % \end{listliketab} % % \texttt{listliketab} works with enumerated lists, too: % % \storestyleof{enumerate} % \begin{listliketab} % \newcounter{lltenum}\setcounter{lltenum}{0} % \newcommand{\nextnum}{\addtocounter{lltenum}{1}\thelltenum.} % \begin{tabularx}{\linewidth}{LX@{\qquad}lR} % & & \multicolumn{1}{c}{Due date} \\ \cline{3-3} % \nextnum & Clean desk. & 2005/01/10 \\ % \nextnum & Sort ``in'' pile. & 2005/01/11 \\ % \nextnum & Discard random applications from ``in'' pile. & 2005/01/11 \\ % \nextnum & Move applications from ``in'' pile to ``out'' pile, stamping % each one with a different official-looking stamp. % & 2005/01/15 \\ % \nextnum & Write and mail meaningless memos. & 2005/01/16 \\ % \nextnum & Update r\'esum\'e. & 2005/01/20 \\ % \end{tabularx} % \end{listliketab} % % \section{Usage} % % There are two steps involved in making list-like \texttt{tabulars}: % First, you store a list environment's parameters. And second, you % create a \texttt{tabular} using the stored parameters. The following % are the commands and environments needed to perform these operations. % % \begin{decl} % |\storestyleof| \marg{environment} % \end{decl} % % |\storestyleof| is the easier to use of the two commands that store a list's % formatting style. Merely pass this command the name of an existing list % environment---generally either \texttt{itemize} or \texttt{enumerate}---as % its \meta{environment} parameter. |\storestyleof| will then remember the % formatting of that list environment for later use in a \texttt{tabular}. % % \begin{decl} % |\storeliststyle| % \end{decl} % % Sometimes, you have a list environment that takes parameters. % |\storestyleof| has no mechanism for passing parameters to such an % environment. In this situation, you can manually create a list of the % appropriate type and call |\storeliststyle| from within that list. % For example: % % \begin{verbatim} % \begin{mylistenvironment}{something}{something else} % \item[] \storeliststyle{} % \end{mylistenvironment} % \end{verbatim} % \vspace*{-\baselineskip} % % Note that the above will probably leave some blank space in your document. % |\storestyleof|---which uses |\storeliststyle|, incidentally---gets around % that problem by building the list within a \texttt{minipage} within an % \texttt{lrbox}. As you can tell, |\storestyleof| is a lot more convenient % to use, when applicable. % % \begin{decl} % |\begin{listliketab}| \\ % \meta{tabular} \\ % |\end{listliketab}| % \end{decl} % % Once you've stored a list environment's style with |\storestyleof| or % |\storeliststyle|, you're ready to typeset list-like \texttt{tablular}s. % The \texttt{listliketab} environment adjusts the internal and external % spacing of a \texttt{tablular} to match that of the previously given list. % It also defines two new field types: |L| and |R|\@. |L| inserts spacing % corresponding to the list's left margin, a right-justified parbox of the % same size as the list's label field, and spacing to separate the label % from the remaining fields. |R| inserts spacing corresponding to the list's % right margin, and is more useful in \texttt{tabularx} environments than % in ordinary \texttt{tabular}s. % % Speaking of which, the \meta{tabular} you put inside \texttt{listliketab} % can be any environment that's compatible with the \texttt{array} package. % This includes \texttt{tabular}, \texttt{tabularx}, \texttt{longtable}, and % probably others, as well. Basically, \texttt{listliketab} needs to call % |\newcolumntype| to define the |L| and |R| fields. % % The styles stored by |\storestyleof| and |\storeliststyle| are valid % until the next call to one of those commands. Hence, any number of % \texttt{listliketab} environments can follow a single |\storestyleof| % or |\storeliststyle|. % % \section{Examples} % % Here's a simple bullet list: % % \begin{verbatim} % \storestyleof{itemize} % \begin{listliketab} % \begin{tabular}{Ll} % \textbullet & One \\ % \textbullet & Two \\ % \textbullet & Three \\ % \end{tabular} % \end{listliketab} % \end{verbatim} % \vspace*{-\baselineskip} % % \noindent % and its output: % % \storestyleof{itemize} % \begin{listliketab} % \begin{tabular}{Ll} % \textbullet & One \\ % \textbullet & Two \\ % \textbullet & Three \\ % \end{tabular} % \end{listliketab} % % \bigskip\noindent % Here's an enumerated list that contains multiple columns after the label: % % \begin{verbatim} % \storestyleof{enumerate} % \begin{listliketab} % \newcounter{tabenum}\setcounter{tabenum}{0} % \newcommand{\nextnum}{\addtocounter{tabenum}{1}\thetabenum.} % \begin{tabular}{L>{\bf}l@{~or~}>{\bf}l@{~or~}>{\bf}l} % \nextnum & Red & green & blue \\ % \nextnum & Short & stout & tall \\ % \nextnum & Happy & sad & confused \\ % \end{tabular} % \end{listliketab} % \end{verbatim} % \vspace*{-\baselineskip} % % \noindent % and what it produces: % % \storestyleof{enumerate} % \begin{listliketab} % \newcounter{tabenum}\setcounter{tabenum}{0} % \newcommand{\nextnum}{\addtocounter{tabenum}{1}\thetabenum.} % \begin{tabular}{L>{\bf}l@{~or~}>{\bf}l@{~or~}>{\bf}l} % \nextnum & Red & green & blue \\ % \nextnum & Short & stout & tall \\ % \nextnum & Happy & sad & confused \\ % \end{tabular} % \end{listliketab} % % \bigskip\noindent % And finally, here's an example using \texttt{tabularx}: % % \begin{verbatim} % \storestyleof{itemize} % \begin{listliketab} % \begin{tabularx}{0.5\linewidth}{% % LX@{\raisebox{-2pt}{\framebox(12,12){}}}R} % \textbullet & Milk \\ % \textbullet & Flour \\ % \textbullet & Sugar \\ % \textbullet & Butter \\ % \textbullet & Eggs \\ % \end{tabularx} % \end{listliketab} % \end{verbatim} % \vspace*{-\baselineskip} % % \noindent % and the generated list: % % \storestyleof{itemize} % \begin{listliketab} % \begin{tabularx}{0.5\linewidth}{% % LX@{\raisebox{-2pt}{\framebox(12,12){}}}R} % \textbullet & Milk \\ % \textbullet & Flour \\ % \textbullet & Sugar \\ % \textbullet & Butter \\ % \textbullet & Eggs \\ % \end{tabularx} % \end{listliketab} % % \StopEventually{^^A % \section{Future work} % % The \texttt{listliketab} environment is too inflexible in terms of % defining the |L| and |R| column types for the user's \texttt{tabular} % environments. First, the user should be able to choose what letters % to use, in case he has already assigned a meaning to |L| or |R|\@. % Second, |L| always formats the label as a right-justified parbox, % while there may be a case in which the user wants the label to be % formatted differently. % % The next limitation that should be addressed in a later version of % \texttt{listliketab} is that the user must manually insert % |\textbullet|s (when mimicking \texttt{itemize}) or numbers (when % mimicking \texttt{enumerate}) into the ``label'' field of his % \texttt{tabular}. It would be nice if the \texttt{listliketab} % environment could do this automatically. % % Finally, there is no support for nested lists. Those would probably % be tricky to mimic properly in a \texttt{tabular}, but could % occasionally be useful to have. % } % % % \section{Implementation} % % This section contains the complete source code for \texttt{listliketab}. % Most users will not get much out of it, but it should be of use to % those who need more precise documentation and those who want to extend % the \texttt{listliketab} package. % % \subsection{Required packages} % \label{sec:packages} % % \texttt{listliketab} requires that the following packages be loaded: % % \begin{macrocode} \RequirePackage{calc} \RequirePackage{array} % \end{macrocode} % % \subsection{List parameter storage} % % Once we're inside a list environment, we'll need some (global) locations % in which to store the local values of various list parameters. % % \begin{macro}{\llt@labelwidth} % \begin{macro}{\llt@labelsep} % \begin{macro}{\llt@topsep} % \begin{macro}{\llt@rightmargin} % These are the global equivalents of |\labelwidth|, |\labelsep|, |\topsep|, % and |\rightmargin|, respectively. They're stored by the |\storeliststyle| % command from within a list environment. % \begin{macrocode} \newlength{\llt@labelwidth} \newlength{\llt@labelsep} \newlength{\llt@topsep} \newlength{\llt@rightmargin} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\llt@tab@indent} % |\llt@tab@indent| is the indentation of the entire list. It % corresponds to the space to the left of the label or, more precisely, % |\leftmargin|-|\labelsep|-|\labelwidth|. % \begin{macrocode} \newlength{\llt@tab@indent} % \end{macrocode} % \end{macro} % % \begin{macro}{\llt@bot@sep} % |\llt@bot@sep| is the amount of space to add at the end of a list. % It is set to |\itemsep|+|\parsep| by |\storeliststyle|. % (I'm not actually positive this is the right amount of space to add, % but it looks okay to me.) % \begin{macrocode} \newlength{\llt@bot@sep} % \end{macrocode} % \end{macro} % % \subsection{Other variables} % % \begin{macro}{\llt@arraystretch} % \begin{macro}{\llt@arraystretch@clean} % |\llt@arraystretch| is the value we need to assign to |\arraystretch| to % make \texttt{tabular} spacing mimic the spacing used in the given list. % |\llt@arraystretch@clean| is the same as |\llt@arraystretch|, except it % is ordinary text instead of a length and does not end in ``|pt|''. % \begin{macrocode} \newlength{\llt@arraystretch} \def\llt@arraystretch@clean{} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\llt@list@box} % This box is used by |\storestyleof| to hold a throwaway list. % \begin{macrocode} \newsavebox{\llt@list@box} % \end{macrocode} % \end{macro} % % \subsection{Author commands and environments} % % \begin{macro}{\storeliststyle} % When |\storeliststyle| is invoked within a list environment, it does % two things. First, it copies the current settings of various list % parameters into global variables, so they can be used outside the list. % And second, it calculates a value for |\arraystretch| to match the list's % inter-item spacing. % \begin{macrocode} \DeclareRobustCommand{\storeliststyle}{ % \end{macrocode} % Storing list parameters is fairly straightforward. % \begin{macrocode} \setlength{\llt@tab@indent}{\leftmargin-\labelsep-\labelwidth} \global\llt@tab@indent=\llt@tab@indent \setlength{\llt@bot@sep}{\itemsep+\parsep} \global\llt@bot@sep=\llt@bot@sep \global\llt@labelwidth=\labelwidth \global\llt@labelsep=\labelsep \global\llt@rightmargin=\rightmargin \global\llt@topsep=\topsep % \end{macrocode} % Determining an appropriate value for |\arraystretch| takes a bit of % explanation. Rows of a \texttt{tabular} environment normally have the % same height and depth as a strut. Entries in a list are also one strut % high/deep, but are separated by |\itemsep|+|\parsep|'s worth of glue. % Hence, to get the new value of |\arraystretch|, we have to take: % \newcommand{\strutfunc}[1]{\text{#1}(\text{strut})} % \begin{eqnarray*} % |\arraystretch| & = & \frac{\text{total space between baselines in a % list}}% % {\text{total space between baselines in a % \texttt{tabular}}} \\[2ex] % & = & \frac{\text{item height + item depth + % inter-item spacing}}% % {\text{row height + row depth}} \\[2ex] % & = & \frac{\strutfunc{height} + \strutfunc{depth} + % \texttt{\bslash itemsep} + % \texttt{\bslash parsep}}% % {\strutfunc{height} + \strutfunc{depth}} % \end{eqnarray*} % \begin{macrocode} \setlength{\llt@arraystretch}{% 1.0pt*\ratio{\ht\strutbox+\dp\strutbox+\itemsep+\parsep} {\ht\strutbox+\dp\strutbox}} % \end{macrocode} % |\arraystretch| takes a unitless fixed-point number as an argument. % Unfortunately, \TeX\ doesn't support such a thing. So we use % \LaTeXe's |\strip@pt| macro to convert from a length to the equivalent % text, dropping the units in the process. % ^^A % \makeatletter % \changes{v1.0a}{2005/01/09}{Modified to use \string\LaTeXe's % \string\texttt\string{\string\string\string\strip@pt\string} macro % instead of defining the equivalent ourselves.} % \makeatother % \begin{macrocode} \xdef\llt@arraystretch@clean{\strip@pt\llt@arraystretch}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\storestyleof} % The problem with |\storeliststyle| is that it can be called only from % within a list. What if you don't have a list to use as a template? Well, % you have to make one. Unfortunately, that list then winds up in your % document. |\storestyleof| to the rescue! This convenience function creates % a list of type |#1| (probably either \texttt{itemize} or \texttt{enumerate}) % containing a call to |\storeliststyle|, but then discards the list % environment, so you never see it. (More accurately, |\storelist| % constructs the list within an \texttt{lrbox} that it never typesets.) % \begin{macrocode} \DeclareRobustCommand{\storestyleof}[1]{% \begin{lrbox}{\llt@list@box} \noindent \begin{minipage}{\linewidth} \begin{#1} \item[] \storeliststyle{} \end{#1} \end{minipage} \end{lrbox}\ignorespacesafterend } % \end{macrocode} % \end{macro} % % \begin{environment}{listliketab} % The \texttt{listliketab} environment defines a new \texttt{tabular} % column type, |L|, which corresponds to the list's indentation, the label % (a right justified parbox), and the separation between the label and the % list body. |L| should be the first field in the user's \texttt{tabular} % environment. Similarly, \text{listliketab} defines |R|, which is the % spacing on the right side of the list. |R| is useful when the user is % using \texttt{tabularx} instead of \texttt{tabular}. In that case, a good % \texttt{tabularx} format string is ``|LXR|'', possibly with other fields % between the |X| and the |R|. % % \texttt{listliketab} also stretches the array appropriately and suppresses % paragraph indentation. (The |L| field will ensure the \texttt{tabular} is % properly indented.) % \begin{macrocode} \newenvironment{listliketab}{% \newcolumntype{L}{% @{\hspace*{\llt@tab@indent}}% >{\hfill}p{\llt@labelwidth}% @{\hspace*{\llt@labelsep}}}% \newcolumntype{R}{% @{\hspace*{\llt@rightmargin}}}% \renewcommand{\arraystretch}{\llt@arraystretch@clean}% \vspace{\llt@topsep}% \noindent\ignorespaces }{% \vspace{\llt@bot@sep}% } % \end{macrocode} % \end{environment} % % % \Finale \endinput