% \iffalse meta-comment
%
% Copyright (C) 2005 by Scott Pakin <scott+llt@pakin.org>
% -------------------------------------------------------
%
% 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}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{listliketab}
%<*package>
    [2005/01/09 v1.0a Create list-like tabulars]
%</package>
%
%<*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}
%</driver>
% \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 <scott+llt@pakin.org>},
%   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
