% % tblart.tex % % Article about mdwtab.sty % % (c) Mark Wooding, FWIW % % --- First, some evil hacking --- % % This lot sees if I'm in mid-document; if so it checks that necessary % packages are loaded and moans at the editor if necessary. Otherwise, % it loads an emulation of the layout, which might help me identify bad % line breaks. (I know I shouldn't be using \next like this, although % it's inside a group so I don't care.) %\begingroup %\makeatletter %\edef\next#1#2{\ifx\documentclass\@notprerr#1\else#2\fi} %\expandafter\endgroup\next %{ % \ifx\firsthline\xxundefined % \ifx\tabpause\xxundefined % \edef\ehelp{\errhelp{I can't seem to find Mr Wooding's excellent^^J% % `mdwtab' package. \space Please get it from CTAN % if^^J% % necessary, and say `\string\usepackage{mdwtab}' % in the^^J% % document preamble.}} % \ehelp % \errmessage{Package `mdwtab' not found} % \fi % \else % \edef\ehelp{\errhelp{You appear to have loaded the `array' package.^^J% % Mr Wooding's excellent `mdwtab' package doesn't^^J% % coexist well with `array' since both attempt to^^J% % redefine all the table handling. \space Since % `mdwtab'^^J% % is mostly compatible with `array', you should^^J% % load `mdwtab' instead.}} % \ehelp % \errmessage{Package `array' loaded} % \fi % \let\mdwendfile\endinput %}{ % \documentclass{baskart} % \usepackage{mdwtab} % \begin{document} % \def\mdwendfile{\end{document}} %} % --- Some other definitions --- % These three typeset common LaTeX-related things. I have no idea how these % should be formatted, although I guess this lot will be OK. \makeatletter % diagnosing what's going on... %\@ifundefined{pkg}{\typeout{No \string\pkg\space macro}}{\show\pkg} %\@ifundefined{env}{\typeout{No \string\env\space macro}}{\show\env} %\@ifundefined{cmd}{\typeout{No \string\cmd\space macro}}{\show\cmd} \providecommand{\pkg}[1]{\textsf{#1}} \providecommand{\env}[1]{\textsf{\def\*{\ensuremath{*}}#1}} \providecommand{\cmd}[1]{\expandafter\texttt\expandafter{\string#1}\cmd@i} \def\cmd@i{\futurelet\@let@token\cmd@ii} \def\cmd@ii{% \let\@tempa\relax% \ifx\@let@token\bgroup% \def\@tempa##1{\texttt{\char`\{}\textit{##1}\texttt{\char`\}}\cmd@i}% \fi% \ifx\@let@token[% \def\@tempa[##1]{\texttt{[}\textit{##1}\texttt{]}\cmd@i}% \fi% \@tempa% } \providecommand{\parg}[1]{\textit{#1}} % --- Table styling --- \renewcommand{\tabstyle}{\small} % --- Hyphenation --- \hyphenation{mdw-tab} % --- Whew. Now I can actually start --- \title{Beautiful tables, the easy way with the \pkg{mdwtab} package} \author{Mark Wooding} %\begin{multicols}{2} \begin{Article} \noindent The first thing you'll probably notice when you load the \pkg{mdwtab} package is that \TeX\ runs out of memory that much quicker. The author is well aware that the package is far too large, but can't decide which bits of its functionality can be dropped. The second thing you'll notice is that some table-related packages stop working properly, because they don't understand how \pkg{mdwtab} handles tables, and still think that \LaTeX\ is in control. The author has attempted to retain compatibility with the `Tools' collection of packages, and in particular with David Carlisle's excellent set of table handling things. The third thing you'll probably notice is that your tables still look (almost) exactly the same as they did before. In common with the \pkg{array} package, rules in tables now contribute to the table's width and height, which fixes a problem with the sides of tables looking uneven. \begin{center} % Define a rule type which does what LaTeX's standard `tabular' does. % Why does LaTeX do this, by the way? \newcolumntype{v}{!{\kern-.5\arrayrulewidth\vline\kern-.5\arrayrulewidth}} % Note that the text is lying through it's teeth. It has the full power % and beauty of mdwtab at its desposal, yet delimberately tries to make % the table look awful. \begin{tabular}{vcvcv} \hline This is an example & of a ruled \\ \hline table, using \LaTeX's & standard table \\ \hline handling. Can you see & the slight nicks \\ \hline in the vertical rules & on the sides? \\ \hline \end{tabular} \end{center} It's odd starting an article about a package with a list of its drawbacks: the author is of the firm opinion that you should have no illusions concerning the drawbacks of the package. (There are a load of others which I haven't described here; most of them aren't very interesting.) On the other hand the package \emph{does} provide all the column types and other new features of the \pkg{array} package, including the \cmd{\newcolumntype} command. \subsection{A touch of class} Tables which have horizontal rules tend to look rather better if you insert a little extra space above and below the rules. Compare \begin{tabular}[C]{|l|l|l|} \hline \bf Package & \bf Advantage & \bf Disadvantage \\ \hline Standard \LaTeX & Built-in & Ugly tables \\ \pkg{array} & New column types & It isn't perfect \\ \pkg{mdwtab} & Beautiful tables & It's very big \\ \hline \end{tabular} with \begin{tabular}[C]{|l|l|l|} \hlx{hv} \bf Package & \bf Advantage & \bf Disadvantage \\ \hlx{vhv} Standard \LaTeX & Built-in & Ugly tables \\ \pkg{array} & New column types & It isn't perfect \\ \pkg{mdwtab} & Beautiful tables & It's very big \\ \hlx{vh} \end{tabular} to see the difference. Which do you think is nicer? The first example above was created using the standard \LaTeX\ \cmd{\hline} command. The second example has some extra space inserted around the horizontal rules. This is achieved by using the \cmd{\vgap} command. If you say `\cmd \vgap{length}', \TeX\ will insert a `short' row whose height is the \parg{length} given, ensuring that the vertical rules in your table are extended appropriately. For example, I just said \verb"\vgap{2pt}" at appropriate points in the table above. However, this isn't always what you want. If you use \cmd{\multicolumn} commands for headings, you'll get odd-looking `stubs' as in the following example: \begin{tabular}[C]{|c|c|c|} \hlx{hv} Item one & \multicolumn{2}{c|}{Item two} \\ \hlx{vhv} Item three & Item four & Item five \\ \hlx{vhv} \multicolumn{2}{|c|}{Item six} & Item seven \\ \hlx{vh} \end{tabular} Please bear in mind that this \emph{could} be the effect you want (for instance, the \texttt{MIX} word-layout diagrams in \emph{The Art of Computer Programming} do this sort of thing). In the event that you don't like this effect, and I can't blame you if you don't, you can suppress the rule stubs in certain columns by saying `\cmd \vgap[columns]{length}' -- the \parg{columns} argument contains a list of column numbers whose rules are to be omitted. The rules on the very left hand side of the table are numbered~0, while the rules on the right hand side of column~$n$ are numbered~$n$. Column numbers are separated by commas, and column ranges can be given. For example, to suppress rules in columns~1,~2, 3, 5, 7, 8~and~9 you'd say `\verb"1-3, 5, 7-9"'. In the example above, if I end my table rows like this: \begin{list}{}{\leftmargin=\parindent \parskip=0pt \topsep=0pt} \footnotesize % The hacking above makes verbatim listings rather smaller, so I can fit % more into the rather narrow columns, and it looks rather less prominent: % `tt' text seems to stick out rather too obviously. \begin{Verbatim} ... \hline \vgap[2]{2pt} ... \\ \vgap[2]{2pt} \hline \vgap {2pt} ... \\ \vgap {2pt} \hline \vgap[1]{2pt} ... \\ \vgap[1]{2pt} \hline \end{Verbatim} \end{list} then it ends up looking much nicer: \begin{tabular}[C]{|c|c|c|} \hlx{hv[2]} Item one & \multicolumn{2}{c|}{Item two} \\ \hlx{v[2]hv} Item three & Item four & Item five \\ \hlx{vhv[1]} \multicolumn{2}{|c|}{Item six} & Item seven \\ \hlx{v[1]h} \end{tabular} Isn't that neat? All of this gets terribly cumbersome to type. The \cmd \hlx{hlx-commands} command provides a neat abbreviation. The \parg{hlx-commands} argument is a list of single letter commands to perform. There's a load of commands provided, for doing various little jobs: \begin{description} \renewcommand{\makelabel}[1]{\hspace{\labelsep}\cmd#1} \item [{h}] is equivalent to \cmd \hline. If you type two \cmd{h} commands in a row, a space is left between them, as usual. \item [{v[columns][length]}] means exactly the same thing as \cmd \vgap[columns]{length}, except that the \parg{length} argument is optional. If you omit it, the default value of \cmd{\doublerulesep} is used, which is usually set to 2\,pt. \item [{c{columns}}] is equivalent to \cmd \cline{columns}. You can specify the columns by giving comma separated column numbers and ranges, just as for \cmd{\vgap}: the \cmd{\cline} command has been upgraded to understand these more complex descriptions. \item [{s[length]}] leaves a vertical gap of height \parg{length}. If you omit the \parg{length}, the value of \cmd{\doublerulesep} is used. \end{description} I ought to come clean now. Since I'm a lazy typist, I didn't actually use the \cmd{\vgap} command in the tables above. What I actually said was \verb"\hlx{hv}" for the first row, \verb"\hlx{vhv}" for the middle rows, and \verb"\hlx{vh}" after the last one. \subsection{New column types} It seems to be traditional to add new column types when \LaTeX's table handling gets upgraded, and the author saw no reason not to follow the trend. The complete list of column types, and other funny characters that can be used in the argument of the \env{tabular} environment, is given below. The new ones added by this package are marked with a little `*'. \begin{description} % The following stuff attempts to compress the list vertically, while % still leaving a little space between items. \renewcommand{\makelabel}[1]{\hspace{\labelsep}\cmd#1} \parskip=0pt \itemsep=\jot plus 1pt \item [{l}] Left aligned text (in \env{tabular}) or equation (in \env{array}). \item [{c}] Centred text (in \env{tabular}) or equation (in \env{array}). \item [{r}] Right aligned text (in \env{tabular}) or equation (in \env{array}). \item [{{Ml}, \cmd{Mc} and \cmd{Mr}*}] Left, centre and right aligned equations. \item [{{Tl}, \cmd{Tc} and \cmd{Tr}*}] Left, centre and right aligned text. \item [{p{width}}] Top aligned paragraphs, with the given width. \item [{m{width}}] Vertically centred paragraphs, with the given width. \item [{b{width}}] Bottom aligned paragraphs, with the given width. \item [{#{pre}{post}*}] User defined column type: \parg{pre} is inserted before the table cell's text, and \parg{post} is inserted afterwards. \item [{|}] Inserts a vertical rule between columns. \item [{!{text}}] Inserts \parg{text} between columns, treating it just like a vertical rule. \item [{@{text}}] Inserts \parg{text} in place of the usual intercolumn space. \item [{>{text}}] Inserts \parg{text} just before the cell's text. \item [{<{text}}] Inserts \parg{text} just after the cell's text. \item [{*{count}{preamble}}] Inserts \parg{count} copies of the \parg{preamble} into the table preamble. \end{description} You can define your own new column types by saying `\cmd \newcolumntype {type}[narg][opt]{text}', which defines a new column type \parg{type}, which means exactly the same thing as the preamble characters \parg{text}. The column type can take arguments (even optional ones) -- this works in exactly the same way as \cmd{\newcommand}. \subsection{Unboxed tables} Normally \LaTeX\ will wrap tables up in a box. This makes things convenient sometimes, but horizontal positioning can be a bit of a pain. As well as the usual~\texttt{[t]}, \texttt{[c]} and~\texttt{[b]} position arguments, the package adds~\texttt{[L]}, \texttt{[C]} and~\texttt{[R]}, which position the table left-aligned, centred and right-aligned respectively. Such tables are called \emph{unboxed} tables, because they're not wrapped up in a box. As well as allowing you to control horizontal position more easily, such tables have some other advantages. \iffalse Oh, before we go any further, I ought to point out that despite not being boxed up, unboxed tables still can't be broken across pages. If you want to handle long tables, you should be using the truly wonderful \pkg{longtable} package. You can use all the new commands, like \cmd{\vgap} and \cmd{\hlx} in the \env{longtable} environment, to make your long tables just as beautiful as your short ones. \fi You can pause an unboxed table for a bit and insert some normal paragraph text. When you say \cmd\tabpause{text} in the middle of a table, \LaTeX\ inserts the \parg{text}, typeset in paragraph mode, in the middle of the table. The text can be split across pages and all the normal things like that. \subsection{Life's little luxuries} As well as perhaps not looking as glorious as they might do, \LaTeX's tables have a few other rough edges. The \pkg{mdwtab} package tries (and by and large succeeds) in smoothing these off and tucking all the nastiness under the carpet. \subsubsection{Footnotes} \LaTeX\ doesn't allow footnotes in tables. They just don't work: the footnote text mysteriously vanishes. This package will carefully handle footnotes in both boxed and unboxed tables, ensuring that they appear in the right place. (This is done by using a trimmed down version of the author's \pkg{footnote} package, which tries to provide a general solution to the problems of footnote handling.) You can therefore use footnotes in your tables with abandon, and expect everything to work beautifully. \subsubsection{Vertical alignment of ruled tables} % Time for some hacking. The `grottytab' environment attempts to emulate % LaTeX's tables in a deeply cut down way. It allows any number of centred % columns, with vertical rules working in the normal LaTeX way (i.e., looking % nasty). \newenvironment{grottytab}[1][c]{% \def\hline{\noalign{\hrule height\arrayrulewidth}}% \def\vline{% \kern-.5\arrayrulewidth% \vrule width\arrayrulewidth% \kern-.5\arrayrulewidth% } \leavevmode\hbox\bgroup$% \ifx#1t\vtop\else\ifx#1b\vbox\else\vcenter\fi\fi\bgroup% \def\upart{\hskip\tabcolsep\hfil\ignorespaces}% \def\vpart{\unskip\hfil\hskip\tabcolsep\vline}% \let\\=\cr% \halign\bgroup\strut\vline\upart##\vpart&&\upart##\vpart\cr% }{% \crcr% \egroup\egroup\mathsurround=0pt$\egroup% } It's been pointed out numerous times that having rules in tables can make top- and bottom-aligned tables look rather odd: the baseline of the text tends to be lined up with the rules in the tables, rather than with the actual first or last rows. In other words, you get strange results like \begin{grottytab}[b] \hline An & odd \\ \hline looking & table \\ \hline \end{grottytab} and \begin{grottytab}[t] \hline An & odd \\ \hline looking & table \\ \hline \end{grottytab}. Clearly this isn't terribly desirable. Various solutions have been proposed for this problem. \emph{The \LaTeX\ Companion} describes a pair of commands \cmd{\firsthline} and \cmd{\lasthline} which provide a workaround. The \pkg{mdwtab} will calculate the height of the rules and other material at the top or bottom of the table and shift it into the right position. Hence you can have {\renewcommand{\tabstyle}{} \begin{tabular}[b]{|c|c|} \hline A & nice \\ \hline looking & table \\ \hline \end{tabular} and \begin{tabular}[t]{|c|c|} \hline A & nice \\ \hline looking & table \\ \hline \end{tabular} } with no extra effort at all. \subsubsection{Extra row separation} In maths, it's conventional to insert a little extra space between the rows of an array. To save you having to end every line of an array with something like `\verb"\\[\jot]"', extra space of the amount \cmd{\arrayextrasep} is inserted automatically. (This parameter is set to 1\,jot by default.) There's an analogous \cmd{\tabextrasep} parameter, although this is initially 0\,pt, and isn't likely to be changed. If you're worried about matrices looking rather odd as a result of this extra space, don't be. In the author's opinion, they actually end up looking slightly nicer as a result. However, you can almost certainly get better results by using a dedicated \env{matrix} environment which takes extra-special care over the spacing. %\medskip\hrule\smallskip\footnotesize %\hfill Mark Wooding \\ \hspace*{\fill} \texttt{mdw@straylight.co.uk} \end{Article} \endinput \end{multicols} \mdwendfile