summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/booktabs
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/booktabs
Initial commit
Diffstat (limited to 'macros/latex/contrib/booktabs')
-rw-r--r--macros/latex/contrib/booktabs/README60
-rw-r--r--macros/latex/contrib/booktabs/booktabs.dtx1052
-rw-r--r--macros/latex/contrib/booktabs/booktabs.ins65
-rw-r--r--macros/latex/contrib/booktabs/booktabs.pdfbin0 -> 295150 bytes
4 files changed, 1177 insertions, 0 deletions
diff --git a/macros/latex/contrib/booktabs/README b/macros/latex/contrib/booktabs/README
new file mode 100644
index 0000000000..fb43faf3ac
--- /dev/null
+++ b/macros/latex/contrib/booktabs/README
@@ -0,0 +1,60 @@
+ The booktabs package
+ For publication quality tables for LaTeX
+
+
+File: README
+Author: Danie Els
+
+
+DESCRIPTION
+===========
+
+This package provide some additional commands to enhance
+the quality of tables in LaTeX. Guidelines are given as
+to what constitutes a good table in this context.
+
+Copyright: (C) 1995--2016 Simon Fear
+Licence: GPL
+
+FILES IN DISTRIBUTION
+=====================
+
+ BASE DISTRIBUTION:
+
+ README This file.
+ booktabs.ins Package installation file.
+ booktabs.dtx Package source file.
+
+ booktabs.sty Package style file. It was produced by
+ executing "latex booktabs.ins".
+
+ DOCUMENTATION:
+
+ booktabs.pdf User manual for booktabs package. It was
+ produced by executing:
+ pdflatex booktabs.dtx
+ pdflatex booktabs.dtx
+ makeindex -s gglo.ist -o booktabs.gls booktabs.glo
+ makeindex -s gind.ist -o booktabs.ind booktabs.idx
+ pdflatex booktabs.dtx
+ pdflatex booktabs.dtx
+
+BASIC INSTALLATION
+====================
+
+ The minimum requirement to use the package is to have
+ booktabs.sty in a directory where TeX can find it.
+
+ For a basic installation on a TDS compliant system, move the
+ following files to the following directories:
+
+ <texmf>/tex/latex/booktabs/
+ booktabs.sty
+
+ <texmf>/source/latex/booktabs/
+ booktabs.ins
+ booktabs.dtx
+
+ <texmf>/doc/latex/booktabs/
+ README
+ booktabs.pdf
diff --git a/macros/latex/contrib/booktabs/booktabs.dtx b/macros/latex/contrib/booktabs/booktabs.dtx
new file mode 100644
index 0000000000..e599a2d7c9
--- /dev/null
+++ b/macros/latex/contrib/booktabs/booktabs.dtx
@@ -0,0 +1,1052 @@
+% \iffalse (meta-comment)
+% -----------------------------------------------------------------
+% booktabs.dtx
+% Copyright (C) 1995--2016 Simon Fear
+% Maintained by Danie Els <dnjels@sun.ac.za>
+%
+% This file is part of the booktabs package for publication
+% quality tables for LaTeX
+% -----------------------------------------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% 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.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+% -----------------------------------------------------------------
+% \fi
+%
+% \iffalse
+%<*driver>
+\ProvidesFile{booktabs.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+%<package>\ProvidesPackage{booktabs}
+%<*package>
+ [2016/04/27 v1.618033 publication quality tables]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+ \usepackage{booktabs}[2016/04/27]
+ \EnableCrossrefs
+ \CodelineIndex
+ \RecordChanges
+ \setlength\hfuzz{15pt}
+ \hbadness=7000
+ \MakeShortVerb{\=}
+ \MakeShortVerb{\"}
+\begin{document}
+ \DocInput{booktabs.dtx}
+ \PrintChanges
+ \PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{489}
+% \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 \~}
+%
+%
+%
+% \DeleteShortVerb{\|}
+% \GetFileInfo{booktabs.dtx}
+%
+% \title{Publication quality tables in \LaTeX%
+% \thanks{This file has version number \fileversion,
+% (converging to phi, the golden ratio),
+% last revised \filedate.}}
+% \author{Simon Fear\\300A route de Meyrin\\Meyrin\\Switzerland}
+% \date{Printed \today}
+%
+% \maketitle
+%
+%
+% \begin{abstract}
+% This article describes some additional commands to enhance
+% the quality of tables in \LaTeX. Guidelines are given as
+% to what constitutes a good table in this context. The 2000
+% release (Version 1.61) of the =booktabs= package, described
+% herein, adds some enhancements to the 1995 release (Version 1.00),
+% most notably =longtable= compatibility.
+%
+% Releases (Versions 1.618, 1.6180, 1.61803 and 1.618033) are
+% only bug patches, support for the =colortbl= package and better
+% compatability with =longtable=.\footnote{By Danie Els
+% (\texttt{dnjels@sun.ac.za}) in the absence of the author.}
+% \end{abstract}
+%
+% \bigskip
+%
+% \section{Introduction}
+%
+% The routines described below are to enable the easy production
+% of tables such as should appear in published scientific books and
+% journals. What distinguishes these from plain
+% \LaTeX{} tables is the default use of additional space above and below rules,
+% and rules of varying `thickness'. What further distinguishes them from
+% the tables many people {\em do} produce using \LaTeX{} is the
+% absence of vertical rules and double rules.
+%
+% I must draw a clear
+% distinction between what I call here a {\em formal table},
+% which is a set of values in labelled columns, as distinct from
+% what I will call a {\em tableau}. The latter is the kind of thing
+% illustrated in the \LaTeX{} manual, and increasingly
+% common as the output of
+% many database management systems; it will probably have
+% icons in abundance, and no doubt use colour too.
+% The layout of such a {\em tableau} is determined
+% (hopefully) as a one-off, given a jumble of material the
+% designer is trying to combine into a meaningful configuration.
+% But the layout of a {\em table} has been established over
+% centuries of experience and should only be altered in
+% extraordinary circumstances.
+%
+% By way of illustration, consider this tableau from the \LaTeX{}
+% manual (p. 64 old edition):
+%
+% \begin{center}
+% \begin{tabular}{||l|lr||} \hline
+% gnats & gram & \$13.65 \\ \cline{2-3}
+% & each & .01 \\ \hline
+% gnu & stuffed & 92.50 \\ \cline{1-1} \cline{3-3}
+% emu & & 33.33 \\ \hline
+% armadillo & frozen & 8.99 \\ \hline
+% \end{tabular}
+% \end{center}
+%
+% This is a hotch-potch of information that is probably
+% reasonably clearly presented as is (but is the emu stuffed or
+% not?). However, as a published table, this should
+% much rather appear along the lines suggested
+% further down the page in the manual:
+%
+% \begin{center}
+% \begin{tabular}{@{}llr@{}} \toprule
+% \multicolumn{2}{c}{Item} \\ \cmidrule(r){1-2}
+% Animal & Description & Price (\$)\\ \midrule
+% Gnat & per gram & 13.65 \\
+% & each & 0.01 \\
+% Gnu & stuffed & 92.50 \\
+% Emu & stuffed & 33.33 \\
+% Armadillo & frozen & 8.99 \\ \bottomrule
+% \end{tabular}
+% \end{center}
+%
+% It takes much less work to lay
+% this out, as a formal table; we don't have to work out a new
+% layout for everything we do. Moreover, we can be almost certain
+% that the data cannot be misread, because the reader does not
+% have to learn how to read some novel presentation.
+%
+% The above table cannot be produced in pure \LaTeX,
+% unfortunately. It can be laid out as it should be, but despite
+% your best efforts, using plain =\hline= commands produces
+%
+% \begin{center}
+% \begin{tabular}{@{}llr@{}} \hline
+% \multicolumn{2}{c}{Item} \\ \cline{1-2}
+% Animal & Description & Price (\$)\\ \hline
+% Gnat & per gram & 13.65 \\
+% & each & 0.01 \\
+% Gnu & stuffed & 92.50 \\
+% Emu & stuffed & 33.33 \\
+% Armadillo & frozen & 8.99 \\ \hline
+% \end{tabular}
+% \end{center}
+%
+% Note (if it is not already obvious) that there is not enough
+% space between the top line and the capital I of `Item', and so
+% on for all the lines: contrast with the previous version. Also, in
+% the first version
+% the top and bottom rules (ie lines) are
+% heavier than the middle rule, which is turn heavier than the
+% subrule underneath `Item'. Of course you \emph{could} redefine
+% =\doublerulesep= and then use =\hline\hline= to get something
+% near the same effect, and you could use struts to improve
+% the spacing. But you should not have to
+% think of such things. The =booktabs= style defines its commands so
+% that such things are taken care of automatically.
+%
+% In general, I would say that
+% this package is of no interest to those looking for
+% an alternative to Pic\TeX{} to conjure up fancy tableaux.
+% Rather, it is a style guide for authors of scientific papers
+% and books as regards table layout. It is not going too far to
+% say that if you cannot
+% create a table using the commands in this package, you should
+% redesign it.
+%
+% \subsection{A note on terminology\label{notation}}
+%
+% In British typesetting, a `line' is always called a `rule'. Perhaps
+% confusingly (for historic reasons in fact), the `thickness' of
+% rule is often referred to as is its `width' (whereas just about
+% everyone else would call this `depth' or `height', if they were thinking
+% of a horizontal rule). A `thick black line' is called a `heavy
+% rule'. I have used this terminology in most of the new commands
+% below. If nothing else it avoids confusion with =\hline=.
+%
+% \section{The layout of formal tables}
+%
+% You will not go far wrong if you remember two simple
+% guidelines at all times:
+% \begin{enumerate}
+% \item Never, ever use vertical rules.
+% \item Never use double rules.
+% \end{enumerate}
+% These guidelines may seem extreme but I have
+% never found a good argument in favour of breaking them. For
+% example, if you feel that the information in the left half of
+% a table is so different from that on the right that it needs
+% to be separated by a vertical line, then you should use two
+% tables instead. Not everyone follows the second guideline:
+% I have worked for a publisher who insisted on a
+% double light rule above a row of totals. But this would not
+% have been my choice.
+%
+% There are three further guidelines worth mentioning here as they
+% are generally not known outside the circle of professional
+% typesetters and subeditors:
+% \begin{enumerate}\setcounter{enumi}{2}
+% \item Put the units in the column heading (not in the body of
+% the table).
+% \item Always precede a decimal point by a digit; thus 0.1
+% {\em not} just .1.
+% \item Do not use `ditto' signs or any other such convention to
+% repeat a previous value. In many circumstances a blank
+% will serve just as well. If it won't, then repeat the value.
+% \end{enumerate}
+%
+% Whether or not you wish to follow the minor niceties,
+% if you use only the following commands in your formal tables
+% your reader will be grateful. I stress that
+% the guidelines are not just to
+% keep the pedantic happy. The principal is that enforced structure of
+% presentation
+% enforces structured thought in the first instance.
+%
+% \section{Use of the new commands}
+%
+% \DescribeMacro\toprule
+% \DescribeMacro\midrule
+% \DescribeMacro\bottomrule
+% In the simplest of cases a table begins with a =\toprule=, has
+% a single row of column headings, then a dividing rule called
+% here a =\midrule=; after the columns of data we finish off with
+% a =\bottomrule=. Most book publishers set the =\toprule= and
+% =\bottomrule= heavier (ie thicker, or darker; see section \ref{notation})
+% than the intermediate =\midrule=. However, when tables appear
+% in very small typesizes it is sometimes impossible to make this
+% distinction, and moreover quite a few journals routinely use all rules of
+% the same heaviness.
+%
+% The rule commands here all take a default
+% which may be reset within the document (preferably, but not
+% necessarily, in the preamble). For the top and bottom rules this
+% default
+% is =\heavyrulewidth= and for midrules it is =\lightrulewidth=
+% (fully described below). In very rare cases where you need to do
+% something special, you may use the optional arguments to the rule
+% commands which have formal syntax as follows:
+% \begin{quote}
+% "\toprule["\meta{wd}"]" \\
+% "\midrule["\meta{wd}"]" \\
+% "\bottomrule["\meta{wd}"]"
+% \end{quote}
+% where \meta{wd} is a \TeX dimension (for example 1pt, .5em,
+% etc.).
+%
+% All the rule commands described here go after the closing
+% =\\= of the preceding row (except =\toprule=, which
+% comes right after the =\tabular{}= command); in other words,
+% exactly where plain \LaTeX{} allows =\hline= or =\cline=.
+%
+% \DescribeMacro\cmidrule
+% Frequently we need a sub-rule to extend over only some of the columns,
+% for which we need a =\cmidrule= (the analogue of \LaTeX's =\cline=
+% command). Generally, this rule should not come to the full width of
+% the columns, and this is especially the case when we need to begin
+% a =\cmidrule= straight after the end of another one (\LaTeX's
+% =\cline=s crash into each other here if you are not extra careful with
+% =\extracolsep=). Thus, you will generally want to use the optional
+% `trimming' commands.
+%
+% The trimming commands, if used at all, go in
+% parentheses (like this), with no spaces separating them. The possible
+% specifications are =r=, =r{=\meta{wd}=}=, =l= and
+% =l{=\meta{wd}=}=, or any combination of these, where \meta{wd} is a
+% dimension, and =r= and =l= indicate whether the right and/or left ends
+% of the rule should be trimmed. The form without explicit argument is
+% equivalent to =r{\cmidrulekern}=, where =\cmidrulekern= defaults to
+% $0.5$ em, but can be set by the user in the preamble.\footnote{User
+% feedback suggested the Version 1.00 default, 0.25 em, was too
+% small. Sorry for any loss of backward compatibility. Remember that
+% you
+% can easily set \texttt{\textbackslash cmidrulekern} in the preamble, or just use
+% \texttt{(r\{.25em\})} to recover the original behaviour.}
+%
+% Here's an illustrative example: =(lr{.75em})= gives you a default
+% left trim and exactly $0.75$ em right trim. Equally valid here is
+% =(r{.75em}l)=.\footnote{As a matter of fact, \texttt{(lrrlr\{.75em\})}
+% does the same thing: only the
+% last encountered left and the last encountered right specification
+% are applied.}
+%
+% The full syntax of the command is
+% \begin{quote}
+% "\cmidrule["\meta{wd}"]("\meta{trim}"){"$a$--$b$"}"
+% \end{quote}
+% where \meta{wd} is an optional rule width command, in square
+% brackets [like this] (the
+% default here is =\cmidrulewidth=), and the last argument, \emph{which
+% is not optional}, gives the column numbers to be spanned.
+%
+% An example of the commands in use is given by the code used to
+% produce the example table above:
+% \begin{verbatim}
+% \begin{tabular}{@{}llr@{}} \toprule
+% \multicolumn{2}{c}{Item} \\ \cmidrule(r){1-2}
+% Animal & Description & Price (\$)\\ \midrule
+% Gnat & per gram & 13.65 \\
+% & each & 0.01 \\
+% Gnu & stuffed & 92.50 \\
+% Emu & stuffed & 33.33 \\
+% Armadillo & frozen & 8.99 \\ \bottomrule
+% \end{tabular}
+% \end{verbatim}
+%
+% \DescribeMacro\addlinespace
+% Occasionally we want to put an extra space between certain rows
+% of a table; for example, before the last row, if this is a
+% total. This is simply a matter of inserting
+% \begin{quote}
+% "\addlinespace["\meta{wd}"]"
+% \end{quote}
+% after the =\\= alignment marker. Between ordinary rows of text, the
+% effect is identical to the ordinary \LaTeX\ usage
+% =\\[\defaultaddspace]=, which I find rather clumsy, and it is better
+% than =\\ \\=, which inserts too much space. Also,
+% =\addlinespace= can be used before, after, or between rules if you
+% want to control the exact amount of space to be inserted. The default
+% space before or after an adjacent rule is replaced by exactly
+% =\defaultaddspace= or the amount of
+% space specified in the optional argument.\footnote{This is a change
+% from version 1.00, where the space was sometimes \emph{in addition
+% to} default rule space.}
+%
+% \section{Abuse of the new commands}
+%
+% Let's face it, nobody can leave well alone, so here are some
+% guidelines and extra commands.
+%
+% The new rule commands are not guaranteed to work with =\hline=
+% or =\cline=, although these remain available and unchanged. I
+% cannot foresee any reason to want to mix them.
+%
+% More importantly the rules generated by the new commands are in
+% no way guaranteed to connect with verticals generated by ={|}=
+% characters in the preamble. This is a feature (see above). You
+% should not use vertical rules in tables, end of story.
+%
+% \DescribeMacro\morecmidrules
+% If you just cannot stop yourself from using a double rule,
+% even a construction as bizarre as =\toprule\bottomrule\midrule=
+% will work without generating an error message (just as you can
+% double =\hline=). These rules will be separated by the ordinary
+% \LaTeX\ separator =\doublerulesep=. However if your perversion
+% is to want double =\cmidrule=s you will need the extra command
+% =\morecmidrules= to do so properly, because normally two
+% =\cmidrule=s in a row is a sane construction
+% calling for two rules on the same `rule row'. Thus in
+% \begin{quote}
+% "\cmidrule{1-2}\cmidrule{1-2}"
+% \end{quote}
+% the second command writes a rule that just overwrites the first
+% one; I suppose you wanted
+% \begin{quote}
+% "\cmidrule{1-2}\morecmidrules\cmidrule{1-2}"
+% \end{quote}
+% which gives you a double rule between columns one and two,
+% separated by =\cmidrulesep= (note: since a =\cmidrule= is
+% generally very light, the ordinary =\doublerulesep= is probably
+% too much space). Finish off a whole row of rules before giving the
+% =\morecmidrules= command. Note that =\morecmidrules= has no
+% effect whatsoever if it does not immediately follow a
+% =\cmidrule= (ie it is not a general space-generating command).
+%
+% \DescribeMacro\specialrule
+% If you find some extraordinary need to specify exactly $0.5$ em, say, between two
+% rules, you could use a construction such as =\midrule =
+% =\addlinespace[.5em] \midrule=. In a rare fit of tolerance, though,
+% I have also
+% provided the command
+% \begin{quote}
+% "\specialrule{"\meta{wd}"}{"\meta{abovespace}"}{"\meta{belowspace}"}"
+% \end{quote}
+% where all three arguments are mandatory (I couldn't be bothered to
+% program in defaults). If you use this frequently, you have
+% misunderstood the purpose and content of the guidelines given above. A
+% preceeding rule does not add its default space below, and a following
+% rule adds no space above itself, so you get \emph{exactly} the space
+% specified in the arguments.\footnote{This is a change from Version 1.00,
+% which rather liked to add an extra \texttt{\textbackslash doublerulesep} space whenever it
+% could.}
+%
+%
+% \section{Booktabs and longtables}
+%
+% If you have both =booktabs= and =longtable= packages loaded, the
+% =booktabs= rule commands can now all be used exactly as described
+% above, within a longtable.
+%
+% There is an addition worth noting: within a =longtable=, you can use
+% the optional left and right trimming commands, which normally only
+% work for =\cmidrule=s, with =\toprule=, =\midrule= and =\bottomrule=
+% (and if you must, also with =\specialrule=). Users who hacked the
+% previous release for longtable compatability\footnote{Jim Service was
+% the first} seemed to like all the rules to be right trimmed 0.5 em. I
+% think you can do the same by making =@{}= be the last column
+% specifier. Still, after working out the rest of the code, it was easy
+% to add parsing for the optional arguments, so I did. (I didn't go the
+% whole way and allow the optional trimming \emph{outside} a
+% =longtable=; this would be a huge amount of work. If you must have
+% trimmed rules, make all your tables be =longtable=s!)
+%
+% A somewhat technical note: within a =longtable=, =\hline= and
+% =\hline\hline= both produce a \emph{double} rule (to allow for page
+% breaks occurring at that point). But the =booktabs= rules do
+% \emph{not}. Longtable's automatic doubling of =\hline= is
+% questionable, even according to the documentation within that
+% package. But doubled =booktabs= rules make almost no sense at all. In
+% the unfortunate event that a =booktabs= rule should occur at a page
+% break, then you will have to make the necessary adjustments by
+% hand.\footnote{Fixed in version 1.618033 (Morten H{\o}gholm)}
+% (In general, this will mean deleting the offending rule.)
+%
+%
+% \section{Booktabs and and the colortbl package}
+%
+% =Booktabs= is now compatible with the =colortbl= package.\footnote{Since v1.6180}
+% The \cmd{\arrayrulecolor} command will result in coloured
+% rules if the =colortbl= package is loaded.
+%
+%
+% \section{Technical summary of commands}
+%
+% The new rule commands are valid inside the standard =tabular= (and
+% =array=) environment, in the modified =tabular= and =array= of
+% =\usepackage{array}=, and within both standard tables and longtables
+% after =\usepackage{longtable}=.
+%
+% The commands follow the standard placement syntax of =\hline=.
+% There can be space (including carriage-return,
+% but not two carriage-returns) between successive
+% rule commands.\footnote{A welcome change from Version 1.00, where space between
+% rule commands generated a very baffling error message.}
+%
+% In what amounts to quite a big change from former releases, within
+% the macro code I now define three classes of rules. (But we don't need these
+% definitions within ordinary use, so I haven't even mentioned them above.)
+% A class 1 rule (otherwise called a `normal' rule) is any of
+% =\toprule=, =\midrule=, =\bottomrule=, or =\cmidrule=. The class 2
+% rules are =\specialrule= and =\addlinespace=. Finally, a class 0 rule
+% is none of the preceeding --- or in other words, not a rule at
+% all.\footnote{Except that \texttt{\textbackslash hline} and
+% \texttt{\textbackslash cline} are class 0. Still, there
+% is no reason to lose sleep over this, since one would not want to mix
+% the two rule-drawing systems.} Note that =\addlinespace= counts as a
+% class 2 rule, not as class 0 text.
+%
+% In the following, we first describe each command in `normal use', meaning
+% that the rule is being used between two lines of text (or more
+% technically, is preceded and followed by a class 0 rule). After that,
+% we will look at the exceptions.
+% \begin{quote}
+% "\toprule["\meta{wd}"]"
+% \end{quote}
+% A rule of width \meta{wd} (default =\heavyrulewidth=) with
+% =\abovetopsep= space above and
+% =\belowrulesep= extra vertical space inserted below it. By default,
+% =\abovetopsep= is zero, which seems sensible for a rule designed to
+% go at the top. However, if your
+% tables have captions, it can make sense to use =\abovetopsep= to
+% insert a reasonable amount of space between caption and table,
+% rather than remember to use a =\vspace{}= command in the float.
+% \begin{quote}
+% "\midrule["\meta{wd}"]"
+% \end{quote}
+% A \meta{wd} (default =\lightrulewidth=) rule with
+% =\aboverulesep= space above it and
+% with =\belowrulesep= space below it.
+% \begin{quote}
+% "\bottomrule["\meta{wd}"]"
+% \end{quote}
+% A \meta{wd} (default =\heavyrulewidth=) rule with =\aboverulesep=
+% space above it and with =\belowbottomsep= space below it. By default
+% =\belowbottomsep= is zero\footnote{This is a change from Version 1.00,
+% where there was always a \texttt{\textbackslash belowrulesep}}.
+% There is a frequent and legitimate reason
+% you might want space below a bottom rule: namely, when there's a table
+% footnote.\footnote{But don't use footnotes, Donald.}
+% If you don't override the default you could use
+% =\bottomrule \addlinespace[\belowrulesep]=
+% or you could put a suitably sized strut
+% into the footnote text.\footnote{I don't like either of these. Sort it out in
+% Version 1.618?} But the default has to be zero, so that it behaves
+% sensibly in a =longtable= footer.
+% \begin{quote}
+% "\cmidrule["\meta{wd}"]("\meta{trim}"){"$a$--$b$"}"
+% \end{quote}
+% A \meta{wd} (default =\cmidrulewidth=) rule with
+% =\aboverulesep= space above it (unless following another
+% =\cmidrule=, in which case it is on the same vertical alignment; or
+% if following =\morecmidrules=, separated from a previous =\cmidrule=
+% by =\cmidrulesep=). A =\cmidrule= has
+% =\belowrulesep= below it (unless followed by another
+% =\cmidrule=, in which case the following rule is on the same
+% vertical alignment; or if followed by =\morecmdirules=, when there
+% will be
+% =\cmidrulesep= below it).
+%
+% The =\cmidrule= spans columns $a$ to $b$ as specified in the mandatory
+% argument. The optional argument \meta{trim}, which goes in parentheses
+% if at all, can contain any sequence of the tokens =r=, =l= and
+% ={=\meta{wd}=}=, with the latter setting the kerning to be applied to
+% right or left sides as specified by the immediately preceding token.
+% (There's currently no error checking done here, so be careful to get
+% the syntax right.)
+% \begin{quote}
+% "\morecmidrules"
+% \end{quote}
+% Instructs \LaTeX\ to begin a new row of =\cmidrules=,
+% separated from the last by =\cmidrulesep=. Has no meaning
+% in any other context.
+% \begin{quote}
+% "\specialrule{"\meta{wd}"}{"\meta{abovespace}"}{"\meta{belowspace}"}"
+% \end{quote}
+% A \meta{wd} rule (note: here this is a mandatory argument) with
+% \meta{abovespace} above it and \meta{belowspace} below it.
+% \begin{quote}
+% "\addlinespace["\meta{wd}"]"
+% \end{quote}
+% Technically this has the same effect as
+% =\specialrule{0pt}{0pt}{=\meta{wd}=}=, i.e. a zero-width rule with no
+% space above and with \meta{wd} (default =\defaultaddspace=) space
+% below. This command was primarily designed to add space between rows
+% in the body of the table, but it may also be used to specify an exact
+% amount of space above or below a class 1 rule.
+%
+% \vspace{1em}
+% Now we come to the exceptions to the above. We have already seen in
+% the definitions that the type 2 rules are preceded and followed by
+% exactly the amount of space specified by the arguments. That is, a
+% type 2 rule suppresses the space that would normally be generated by a
+% previous type 1 rule (e.g. =\belowrulesep= after a =\toprule=) and
+% replaces it by the argument of the type 2 rule. Similarly, in the
+% combination \{type 2 rule\}\{type 1 rule\}, the ordinary space above
+% the type 1 rule (e.g. =\aboverulesep=) is suppressed. But in the
+% combination \{type 2 rule\}\{type 2 rule\}, no space is suppressed:
+% the rules will be separated by both the first rule's
+% ={=\meta{belowspace}=}= and the second rule's ={=\meta{abovespace}=}=
+% arguments. Last but not least, the combination \{type 1 rule\}\{type 1
+% rule\} will always give rules separated by =\doublerulesep=,
+% suppressing all normal space generated between the rules (but
+% retaining normal space above the first and below the second).
+%
+% As an exception to this last exception, `type 1 rule' excludes
+% =\cmidrule=. Such rules combine with other =\cmidrule=s and
+% =\morecmidrules= in normal use as described above. I don't know and
+% I don't care
+% care what the combination =\toprule\cmidrule{1-2}\midrule= would
+% produce. I can see no excuse for such usage.
+%
+%\vspace{1em}
+% The default dimensions are defined at the beginning of the macro
+% description section (Section \ref{code}). The user can change
+% these defaults in the preamble, or outside a
+% tabular environment, by simply
+% inserting a command in exactly the same format as in Section \ref{code}; the
+% redefinition will stay in effect for the rest of the document
+% or until redefined again. \emph{Inside a table} you would have to make the
+% assignment globally in a =noalign= group:
+% e.g. \verb|\noalign\{\global\abovetopsep=1em\toprule}|. I hope
+% you never have to do that.
+%
+% \section{Acknowledgments}
+% Hugely indebted of course to DEK and Lamport; the optional
+% argument and =\cmidrule=
+% stuff especially was stolen from =latex.sty=.
+% The documentation driver stuff is stolen from the
+% tools package description =dcolumn.dtx= by David Carlisle.
+%
+% For beta testing and encouragement ...
+%
+% \StopEventually
+%
+% \section{The code\label{code}}
+%
+% The current version is defined at the top of the file looking
+% something like this
+% \begin{macrocode}
+%<*package>
+%\NeedsTeXFormat{LaTeX2e}
+%\ProvidesPackage{booktabs}
+% [\filedate\space version\fileversion]
+% \end{macrocode}
+%
+% First we set up the new dimensions described above:
+% \begin{macrocode}
+\newdimen\heavyrulewidth
+\newdimen\lightrulewidth
+\newdimen\cmidrulewidth
+\newdimen\belowrulesep
+\newdimen\belowbottomsep
+\newdimen\aboverulesep
+\newdimen\abovetopsep
+\newdimen\cmidrulesep
+\newdimen\cmidrulekern
+\newdimen\defaultaddspace
+\heavyrulewidth=.08em
+\lightrulewidth=.05em
+\cmidrulewidth=.03em
+\belowrulesep=.65ex
+\belowbottomsep=0pt
+\aboverulesep=.4ex
+\abovetopsep=0pt
+\cmidrulesep=\doublerulesep
+\cmidrulekern=.5em
+\defaultaddspace=.5em
+% \end{macrocode}
+% And some internal counters of no interest to the end user:
+% \changes{v1.618}{2003/03/28}{Remove \cs{@cmidrulewidth} }
+% \begin{macrocode}
+\newcount\@cmidla
+\newcount\@cmidlb
+\newdimen\@aboverulesep
+\newdimen\@belowrulesep
+\newcount\@thisruleclass
+\newcount\@lastruleclass
+\@lastruleclass=0
+\newdimen\@thisrulewidth
+% \end{macrocode}
+% which will be described as needed below.
+%
+% \begin{macro}{\futurenonspacelet}
+% Next we define a very useful macro (more-or-less straight from the
+% \TeX book's Dirty Tricks chapter; documented there). Use
+% =\futurenonspacelet= instead of =\futurelet= when looking for the next
+% (non-space) token after a macro that has an argument. (After a macro
+% without an argument, space is ignored anyway, so =\futurenonspacelet=
+% wouldn't be needed.) This hack allows users to type white
+% space between successive rule commands (which did not work in Version
+% 1.00).
+% \begin{macrocode}
+\def\futurenonspacelet#1{\def\@BTcs{#1}%
+ \afterassignment\@BTfnslone\let\nexttoken= }
+\def\@BTfnslone{\expandafter\futurelet\@BTcs\@BTfnsltwo}
+\def\@BTfnsltwo{\expandafter\ifx\@BTcs\@sptoken\let\next=\@BTfnslthree
+ \else\let\next=\nexttoken\fi \next}
+\def\@BTfnslthree{\afterassignment\@BTfnslone\let\next= }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Full width rules}
+%
+% When we are not in a =longtable= environment, we can simply
+% implement the full width rules as a =\hrule= in a =\noalign{}=
+% group. But within a =longtable=, the rule has to be drawn like a
+% =\cmidrule{1-\LT@cols}= (the rationale for this is explained in the
+% =longtable= documentation).
+%
+% In order to allow for both, all the rule macros have to
+% open a =\noalign= group immediately, while they work out whether
+% they have been called within a =longtable=; if you don't do this,
+% \TeX's underlying =\halign= process gets hiccups.
+% I use \LaTeX's
+% dirty trick (\verb?\ifnum=0`}?) to fool the parser that the bracket
+% count is OK. The bracket really gets closed after all the skipping
+% at the end of the =\@BTendrule= macro.
+%
+% The class 1 rules, and =\specialrule=, really only differ in the
+% defaults for space above and
+% below, and the width, passed to a common routine, =\@BTrule=,
+% described below. The spaces, =\@aboverulesep= and =\@belowrulesep=,
+% are set within the =\noalign= group, so are inherited by
+% =\@BTrule=. Similarly, =\@BTrule= knows as much as it needs to
+% about the routine that called it by examining the inherited
+% =\@thisruleclass=. The optional width argument is parsed by
+% =\@BTrule= after being set to default if absent.
+%
+%
+% \begin{macro}{\toprule}
+% \changes{v1.61803}{2005/04/14}{Change \cmd{\@belowrulesep} to \cmd{\belowrulesep}}
+% \begin{macro}{\midrule}
+% \begin{macro}{\bottomrule}
+% \begin{macro}{\specialrule}
+% \begin{macrocode}
+\def\toprule{\noalign{\ifnum0=`}\fi
+ \@aboverulesep=\abovetopsep
+ \global\@belowrulesep=\belowrulesep %global cos for use in the next noalign
+ \global\@thisruleclass=\@ne
+ \@ifnextchar[{\@BTrule}{\@BTrule[\heavyrulewidth]}}
+\def\midrule{\noalign{\ifnum0=`}\fi
+ \@aboverulesep=\aboverulesep
+ \global\@belowrulesep=\belowrulesep
+ \global\@thisruleclass=\@ne
+ \@ifnextchar[{\@BTrule}{\@BTrule[\lightrulewidth]}}
+\def\bottomrule{\noalign{\ifnum0=`}\fi
+ \@aboverulesep=\aboverulesep
+ \global\@belowrulesep=\belowbottomsep
+ \global\@thisruleclass=\@ne
+ \@ifnextchar[{\@BTrule}{\@BTrule[\heavyrulewidth]}}
+\def\specialrule#1#2#3{\noalign{\ifnum0=`}\fi
+ \@aboverulesep=#2\global\@belowrulesep=#3\global\@thisruleclass=\tw@
+ \@BTrule[#1]}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\addlinespace}
+% An =\addlinespace= is essentially a zero-width rule with
+% zero space above and argument (or default) space below. But because
+% the rule is not actually drawn, but is just a =\vskip=, there is no
+% need to check if we're in a longtable, so we don't need to call
+% =\@BTrule= as for `real' rules. But we do share the =\@BTendrule=
+% lookahead and flagsetting code (described below), and the =\vskip= is done there.
+% \begin{macrocode}
+\def\addlinespace{\noalign{\ifnum0=`}\fi
+ \@ifnextchar[{\@addspace}{\@addspace[\defaultaddspace]}}
+\def\@addspace[#1]{\global\@belowrulesep=#1\global\@thisruleclass=\tw@
+ \futurelet\@tempa\@BTendrule}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@BTrule}
+% All the rules (except =\addlinespace=) share this code.
+% \changes{v1.618033}{2016/04/27}{Rearranged and added \cmd{\nobreak} within longtable (Morten H{\o}gholm)}
+% \begin{macrocode}
+\def\@BTrule[#1]{%
+% \end{macrocode}
+% Now we work out, by a very nasty hack, if we're within a
+% =longtable=. It's easy if =\longtable= isn't even defined: then we
+% can't be. But it is not enough just to check if =longtable= is
+% loaded --- we might be within an ordinary table rather than a
+% longtable. So we look to see if =\hline= has been re-defined
+% from its \LaTeX\ definition to be the same as
+% =\LT@hline=. (Longtable currently does this redefinition when it opens a
+% =longtable= environment, but not globally, so it is
+% cleared it when the environment closes.) Another
+% package could potentially do this! And =longtable= might change the
+% way it implements this! So, it is not entirely safe, but I have
+% found no better way so far.
+%
+% We set up =\@BTswitch= to call =\@BTnormal= or =\@BLTrule=, as
+% appropriate, then call it.
+% \begin{macrocode}
+ \ifx\longtable\undefined
+ \let\@BTswitch\@BTnormal
+ \else\ifx\hline\LT@hline
+ \nobreak
+ \let\@BTswitch\@BLTrule
+ \else
+ \let\@BTswitch\@BTnormal
+ \fi\fi
+% \end{macrocode}
+% Call =\@BTswitch= at end of macro
+% \begin{macrocode}
+ \global\@thisrulewidth=#1\relax
+% \end{macrocode}
+% Save the width argument (if the user didn't give one, then the
+% calling routine will have called =\@BTrule= with the default) in a global
+% variable for later use when drawing the rule.
+% \begin{macrocode}
+ \ifnum\@thisruleclass=\tw@\vskip\@aboverulesep\else
+% \end{macrocode}
+% Specialrules always insert specified space above. (Note: addlinespaces
+% don't come here).
+% \begin{macrocode}
+ \ifnum\@lastruleclass=\z@\vskip\@aboverulesep\else
+ \ifnum\@lastruleclass=\@ne\vskip\doublerulesep\fi\fi\fi
+% \end{macrocode}
+% After text (last rule class 0), precede the rule by =\aboverulesep=;
+% but if immediately after a
+% previous rule, insert a =\doublerulesep=.
+%
+% \begin{macrocode}
+ \@BTswitch}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\CT@arc@}
+% \changes{v1.6180}{2005/03/16}{add colortbl command for color support}
+% This is support for the colortbl package for colored
+% rules. \cmd{\CT@arc@} hold the \cmd{\arrayrulecolor} setting.
+% \begin{macrocode}
+\AtBeginDocument{%
+ \providecommand*\CT@arc@{}}%% colortbl support
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@BTnormal}
+% \changes{v1.6180}{2005/03/16}{add colortbl \cmd{\CT@arc@} command for color support}
+% This is when we're \emph{not} within a longtable. We are already in a
+% =\noalign= group, all we need do is draw an =\hrule= and gobble any
+% trailing spaces, then call the closing routine with =\@tempa= set
+% equal to the next token in the document.
+%
+% \begin{macrocode}
+\def\@BTnormal{%
+ {\CT@arc@\hrule\@height\@thisrulewidth}%
+ \futurenonspacelet\@tempa\@BTendrule}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@BLTrule}
+% This is for full width rule within a =longtable=. First we check if
+% a kerning argument has been used; if so let =\@@BLTrule= read it,
+% else call =\@@BLTrule= with an empty string:
+% \begin{macrocode}
+\def\@BLTrule{\@ifnextchar({\@@BLTrule}{\@@BLTrule()}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@BLTrule}
+% \begin{macrocode}
+\def\@@BLTrule(#1){\@setrulekerning{#1}%
+\global\@cmidlb\LT@cols
+% \end{macrocode}
+% The =\@setrulekerning= routine parses the kerning argument tokens
+% and sets global kerning widths accordingly (or to defaults, if user
+% hasn't set them explicitly). The global assignment to =\@cmidlb=
+% sets up the column count for the =\@cmidruleb= macro, which is
+% shared with =cmidrules=.
+% \begin{macrocode}
+\ifnum0=`{\fi}%
+% \end{macrocode}
+% Close the currently open =\noalign= group. Within a =longtable=,
+% rules are all to be drawn as leaders within a text box that is
+% =\LT@cols= columns wide.
+% \begin{macrocode}
+\@cmidruleb
+% \end{macrocode}
+% Draw the rule. We share the =\@cmidruleb= code with ordinary =\cmidrule=s.
+% \begin{macrocode}
+\noalign{\ifnum0=`}\fi
+% \end{macrocode}
+% We have to open a new noalign immediately else \TeX will start a new
+% text box where we don't want one. Then, after gobbling any
+% unwanted white space, we call the closing routine.
+% \begin{macrocode}
+\futurenonspacelet\@tempa\@BTendrule}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@BTendrule}
+% We look one step ahead (token is in =\@tempa=) to see if another
+% rule follows (shame on user!). If so, we set =\@lastruleclass= equal
+% to =\@thisruleclass= (thus setting it up for the following rule). If
+% there isn't a following rule, we clear =\@lastruleclass= (ie set it
+% to zero), which isn't technically true since we have just drawn a
+% rule, but sets it up correctly for the next rule encountered, which
+% must be following some intervening text.
+% \begin{macrocode}
+\def\@BTendrule{\ifx\@tempa\toprule\global\@lastruleclass=\@thisruleclass
+ \else\ifx\@tempa\midrule\global\@lastruleclass=\@thisruleclass
+ \else\ifx\@tempa\bottomrule\global\@lastruleclass=\@thisruleclass
+ \else\ifx\@tempa\cmidrule\global\@lastruleclass=\@thisruleclass
+ \else\ifx\@tempa\specialrule\global\@lastruleclass=\@thisruleclass
+ \else\ifx\@tempa\addlinespace\global\@lastruleclass=\@thisruleclass
+ \else\global\@lastruleclass=\z@\fi\fi\fi\fi\fi\fi
+ \ifnum\@lastruleclass=\@ne\relax\else\vskip\@belowrulesep\fi
+ \ifnum0=`{\fi}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Special subrules}
+%
+% \begin{macro}{\@setrulekerning}
+% The following code parses the trimming arguments (if there are any)
+% for =\cmidrule= or a =\BLTrule=. The rule
+% will be trimmed left and right by =\cmrkern@l= and =\cmrkern@l=,
+% which are zero by default, set to =\cmidrulekern= by the plain
+% =(lr)= arguments, or user set as in =(r{.5em})=. We parse token by
+% token through the arguments. The
+% tokens =r= and =l= cause =\cmrkern@r= or =\cmrkern@l= to be set to
+% =\cmidrulekern=. There is no lookahead to see if a width is the
+% next token; this strategy is efficient for the plain commands,
+% while inefficient for the qualified commands, but more importantly
+% it is much easier to program. Tokens =r= and =l= also set
+% =\cmrswitch= so that if the next token turns out to be
+% ={=\meta{wd}=}= then the kerning will be done on the side
+% currently specified. I have been too lazy to program an error
+% message should one encounter tokens other than =r=, =l= or
+% ={=\meta{wd}=}=.
+% \changes{v1.6180}{2005/03/16}{Refine option testing in \cmd{\@setrulekerning}}
+% \begin{macrocode}
+\def\@setrulekerning#1{%
+ \global\let\cmrkern@l\z@
+ \global\let\cmrkern@r\z@
+ \@tfor\@tempa :=#1\do
+ {\def\@tempb{r}%
+ \ifx\@tempa\@tempb
+ \global\let\cmrkern@r\cmidrulekern
+ \def\cmrsideswitch{\cmrkern@r}%
+ \else
+ \def\@tempb{l}%
+ \ifx\@tempa\@tempb
+ \global\let\cmrkern@l\cmidrulekern
+ \def\cmrsideswitch{\cmrkern@l}%
+ \else
+ \global\expandafter\let\cmrsideswitch\@tempa
+ \fi
+ \fi}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\cmidrule}
+% \begin{macro}{\@cmidrule}
+% \begin{macro}{\@@cmidrule}
+% \begin{macro}{\@@@cmidrule}
+% The =\cmidrule= re-uses =\@lastruleclass= in an entirely different
+% way from the full width rules. (Maybe I should have used a
+% different flag; it seemed efficient at the time \ldots). This
+% is (left) set to one if you are in the middle of a row of
+% =\cmidrules=, or starting a new one (with =\morecmidrules=).
+% Otherwise, when =\@lastruleclass= is zero, we precede the
+% rule with =\aboverulesep=.
+% \begin{macrocode}
+\def\cmidrule{\noalign{\ifnum0=`}\fi
+ \@ifnextchar[{\@cmidrule}{\@cmidrule[\cmidrulewidth]}}
+\def\@cmidrule[#1]{\@ifnextchar({\@@cmidrule[#1]}{\@@cmidrule[#1]()}}
+\def\@@cmidrule[#1](#2)#3{\@@@cmidrule[#3]{#1}{#2}}
+% \end{macrocode}
+% The above is fiddling around to set defaults for missing optional
+% arguments. We also pass to =\@@@cmidrule= in a different order,
+% namely =[a-b]=={width required}= ={kerning commands}= (this being
+% the order in which the arguments are actually processed):
+% \begin{macrocode}
+\def\@@@cmidrule[#1-#2]#3#4{\global\@cmidla#1\relax
+ \global\advance\@cmidla\m@ne
+ \ifnum\@cmidla>0\global\let\@gtempa\@cmidrulea\else
+ \global\let\@gtempa\@cmidruleb\fi
+ \global\@cmidlb#2\relax
+ \global\advance\@cmidlb-\@cmidla
+% \end{macrocode}
+% This has set up a switch (=\@gtempa=) to call the relevant routine,
+% =\@cmidrulea= or =\@cmidruleb=, depending on whether we start
+% from column one or not.
+% \begin{macrocode}
+ \global\@thisrulewidth=#3
+% \end{macrocode}
+% That is, set per default or given argument. Then parse any trimming
+% arguments to set, globally, =\cmrkern@r= and =\cmrkern@l= accordingly:
+% \begin{macrocode}
+ \@setrulekerning{#4}
+% \end{macrocode}
+% Now insert space above if needed, close the =\noalign=,
+% then switch to appropriate rule drawing routine as determined
+% above (=\let= to =\@gtempa=):
+% \begin{macrocode}
+ \ifnum\@lastruleclass=\z@\vskip \aboverulesep\fi
+ \ifnum0=`{\fi}\@gtempa
+% \end{macrocode}
+% Having now drawn the rule,
+% open another =\noalign=, and call the closing routine:
+% \begin{macrocode}
+ \noalign{\ifnum0=`}\fi\futurenonspacelet\@tempa\@xcmidrule}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@xcmidrule}
+% In this closing routine, see if another =\cmidrule= follows;
+% if so, backspace
+% vertical so it will line up with the one you just drew,
+% and setting =\@lastruleclass= to 1 will suppress
+% adding space above the next. If a =\morecimdrules= follows,
+% we add (positive) =\cmidrulesep= (and again set =\@lastruleclass=
+% to one). Otherwise this is the last rule of the current group
+% and we can just add =\belowrulesep=. Finally, we close the =\noalign=.
+% \changes{v1.618}{2003/03/28}{Change to \cmd{\@xcmidrule}:
+% replace \cmd{\@cmidrulewidth} with \cmd{\@thisrulewidth }}
+% \begin{macrocode}
+\def\@xcmidrule{%
+ \ifx\@tempa\cmidrule
+ \vskip-\@thisrulewidth
+ \global\@lastruleclass=\@ne
+ \else \ifx\@tempa\morecmidrules
+ \vskip \cmidrulesep
+ \global\@lastruleclass=\@ne\else
+ \vskip \belowrulesep
+ \global\@lastruleclass=\z@
+ \fi\fi
+ \ifnum0=`{\fi}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@cmidrulea}
+% This code (called below) actually draws the rules. They are drawn
+% as boxes in text, rather than in a =\noalign= group, which permits
+% the left and right kerning.
+% \changes{v1.6180}{2005/03/16}{add colortbl \cmd{\CT@arc@} command for color support}
+% \changes{v1.618033}{2016/04/27}{add \cmd{\kern}\cmd{\z@} after \cmd{\hfill} to protects against unskips}
+% \begin{macrocode}
+\def\@cmidrulea{%
+ \multispan\@cmidla&\multispan\@cmidlb
+ \unskip\hskip\cmrkern@l%
+ {\CT@arc@\leaders\hrule \@height\@thisrulewidth\hfill\kern\z@}%
+ \hskip\cmrkern@r\cr}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@cmidruleb}
+% \changes{v1.6180}{2005/03/16}{add colortbl \cmd{\CT@arc@} command for color support}
+% \changes{v1.618033}{2016/04/27}{add \cmd{\kern}\cmd{\z@} after \cmd{\hfill} to protects against unskips}
+% \begin{macrocode}
+\def\@cmidruleb{%
+ \multispan\@cmidlb
+ \unskip\hskip \cmrkern@l%
+ {\CT@arc@\leaders\hrule \@height\@thisrulewidth\hfill\kern\z@}%
+ \hskip\cmrkern@r\cr}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\morecmidrules}
+% This is really a dummy command; all the work is done above
+% within the =\cmidrule= routine. We look one step ahead there
+% to see if a =\morecmidrules= follows the current =\cmidrule=,
+% and if so set the flag. Otherwise, =\morecmidrules= itself
+% does nothing.
+% \begin{macrocode}
+\def\morecmidrules{\noalign{\relax}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \Finale
+%
diff --git a/macros/latex/contrib/booktabs/booktabs.ins b/macros/latex/contrib/booktabs/booktabs.ins
new file mode 100644
index 0000000000..deac64347b
--- /dev/null
+++ b/macros/latex/contrib/booktabs/booktabs.ins
@@ -0,0 +1,65 @@
+%% booktabs.ins
+%%
+%% This file will generate fast loadable files and documentation driver
+%% files from the doc files in this package when run through LaTeX or
+%% TeX.
+%% --------------------------------------------------------------------
+%%
+%% Copyright (C) 1995--2016 Simon Fear
+%% Maintained by Danie Els <dnjels@sun.ac.za>
+%%
+%% This file is part of the booktabs package for publication quality
+%% tables for LaTeX
+%% --------------------------------------------------------------------
+%%
+%% This file may be distributed and/or modified under the conditions of
+%% the LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+
+\input docstrip.tex
+\keepsilent
+
+\usedir{tex/latex/skeleton}
+
+\preamble
+
+Copyright (C) 1995--2016 Simon Fear
+Maintained by Danie Els <dnjels@sun.ac.za>
+
+This file may be distributed and/or modified under the conditions of the
+LaTeX Project Public License, either version 1.3 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.3 or later is part of all distributions of LaTeX version
+2005/12/01 or later.
+-----------------------------------------------------------------
+\endpreamble
+
+\generate{%
+ \askforoverwritefalse
+ \file{booktabs.sty}{\from{booktabs.dtx}{package}}%
+}
+
+{\obeyspaces%
+\Msg{**********************************************************}%
+\Msg{* *}%
+\Msg{* To finish the installation you have to move the *}%
+\Msg{* following file into a directory searched by TeX: *}%
+\Msg{* *}%
+\Msg{* booktabs.sty *}%
+\Msg{* *}%
+\Msg{* To produce the documentation run the file booktabs.dtx *}%
+\Msg{* through LaTeX. *}%
+\Msg{* *}%
+\Msg{* Happy TeXing! *}%
+\Msg{**********************************************************}}
+\endbatchfile
diff --git a/macros/latex/contrib/booktabs/booktabs.pdf b/macros/latex/contrib/booktabs/booktabs.pdf
new file mode 100644
index 0000000000..0628380fff
--- /dev/null
+++ b/macros/latex/contrib/booktabs/booktabs.pdf
Binary files differ