1 % \iffalse meta-comment
5 % The LaTeX3 Project and any individual authors listed elsewhere
8 % This file is part of the Standard LaTeX `Tools Bundle'.
9 % -------------------------------------------------------
11 % It may be distributed and/or modified under the
12 % conditions of the LaTeX Project Public License, either version 1.3c
13 % of this license or (at your option) any later version.
14 % The latest version of this license is in
15 % http://www.latex-project.org/lppl.txt
16 % and version 1.3c or later is part of all distributions of LaTeX
17 % version 2005/12/01 or later.
19 % The list of all files belonging to the LaTeX `Tools Bundle' is
20 % given in the file `manifest.txt'.
24 %% File: hhline.dtx Copyright (C) 1991-1994 David Carlisle
26 %<package>\NeedsTeXFormat{LaTeX2e}
27 %<package>\ProvidesPackage{hhline}
28 %<package> [2014/10/28 v2.03 Table rule package (DPC)]
31 \documentclass{ltxdoc}
33 \GetFileInfo{hhline.sty}
35 \title{The \textsf{hhline} package\thanks{This file
36 has version number \fileversion, last
38 \author{David Carlisle}
40 \MaintainedByLaTeXTeam{tools}
49 % \changes{v1.00}{1991/06/04}{Initial Version}
50 % \changes{v2.00}{1991/11/06}
51 % {Add tilde which allows \cmd\cline-like constructions.}
52 % \changes{v2.01}{1992/06/26}
53 % {Re-issue for the new doc and docstrip.}
54 % \changes{v2.02}{1994/03/14}
55 % {Update for LaTeX2e.}
56 % \changes{v2.03}{1994/05/23}
57 % {New style warning.}
65 % "\hhline" produces a line like "\hline", or a double line like
66 % "\hline\hline", except for its interaction with vertical lines.
72 % \section{Introduction}
73 % The argument to "\hhline" is similar to the preamble of an {\tt
74 % array} or {\tt tabular}. It consists of a list of tokens with the
78 % "=" & A double hline the width of a column.\\
79 % "-" & A single hline the width of a column.\\[10pt]
80 % "~" & A column with no hline.\\[10pt]
82 % "|" & A vline which `cuts' through a double (or single) hline.\\
83 % ":" & A vline which is broken by a double hline.\\[10pt]
85 % "#" & A double hline segment between two vlines.\\
86 % "t" & The top half of a double hline segment.\\
87 % "b" & The bottom half of a double hline segment.\\
89 % "*" & "*{3}{==#}" expands to "==#==#==#",
90 % as in the {\tt*}-form for the preamble.
93 % If a double vline is specified ("||" or "::") then the hlines
94 % produced by "\hhline" are broken. To obtain the effect of an hline
95 % `cutting through' the double vline, use a "#" or omit the vline
96 % specifiers, depending on whether or not you wish the double vline to
99 % The tokens {\tt t} and {\tt b} must be used between two vertical
100 % rules. "|tb|" produces the same lines as "#", but is much less
101 % efficient. The main use for these are to make constructions like
102 % "|t:" (top left corner) and ":b|" (bottom right corner).
104 % If "\hhline" is used to make a single hline, then the argument
105 % should only contain the tokens "-", "~" and "|" (and
106 % {\tt*}-expressions).
108 % An example using most of these features is:
110 % \vcenter{\hsize=2in\begin{verbatim}
111 % \begin{tabular}{||cc||c|c||}
112 % \hhline{|t:==:t:==:t|}
114 % \hhline{|:==:|~|~||}
118 % \hhline{||--||--||}
120 % \hhline{|b:==:b:==:b|}
125 % \begin{tabular}{||cc||c|c||}
126 % \hhline{|t:==:t:==:t|}
128 % \hhline{|:==:|~|~||}
132 % \hhline{||--||--||}
134 % \hhline{|b:==:b:==:b|}
138 % The lines produced by \LaTeX's "\hline" consist of a single (\TeX\
139 % primitive) "\hrule". The lines produced by "\hhline" are made
140 % up of lots of small line segments. \TeX\ will place these very
141 % accurately in the {\tt .dvi} file, but the program that you use to
142 % print the {\tt .dvi} file may not line up these segments exactly. (A
143 % similar problem can occur with diagonal lines in the {\tt picture}
146 % If this effect causes a problem, you could try a different driver
147 % program, or if this is not possible, increasing "\arrayrulewidth"
148 % may help to reduce the effect.
152 % \section{The Macros}
158 % \begin{macro}{\HH@box}
159 % Makes a box containing a double hline segment. The most common case,
160 % both rules of length "\doublerulesep" will be stored in "\box1", this
161 % is not initialised until "\hhline" is called as the user may change
162 % the parameters "\doublerulesep" and "\arrayrulewidth". The two
163 % arguments to "\HH@box" are the widths (ie lengths) of the top and
166 \def\HH@box#1#2{\vbox{%
167 \hrule \@height \arrayrulewidth \@width #1
168 \vskip \doublerulesep
169 \hrule \@height \arrayrulewidth \@width #2}}
173 % \begin{macro}{\HH@add}
174 % Build up the preamble in the register "\toks@".
176 \def\HH@add#1{\toks@\expandafter{\the\toks@#1}}
180 % \begin{macro}{\HH@xexpast}
181 % \begin{macro}{\HH@xexnoop}
182 % We `borrow' the version of "\@xexpast" from Mittelbach's array.sty,
183 % as this allows "#" to appear in the argument list.
185 \def\HH@xexpast#1*#2#3#4\@@{%
187 \toks@={#1}\@temptokena={#3}%
188 \let\the@toksz\relax \let\the@toks\relax
189 \def\@tempa{\the@toksz}%
190 \ifnum\@tempcnta >0 \@whilenum\@tempcnta >0\do
191 {\edef\@tempa{\@tempa\the@toks}\advance \@tempcnta \m@ne}%
192 \let \@tempb \HH@xexpast \else
193 \let \@tempb \HH@xexnoop \fi
194 \def\the@toksz{\the\toks@}\def\the@toks{\the\@temptokena}%
195 \edef\@tempa{\@tempa}%
196 \expandafter \@tempb \@tempa #4\@@}
198 \def\HH@xexnoop#1\@@{}
203 % \begin{macro}{\hhline}
204 % Use a simplified version of "\@mkpream" to break apart the argument
205 % to "\hhline". Actually it is oversimplified, It assumes that the
206 % vertical rules are at the end of the column. If you were to specify
207 % "c|@{xx}|" in the array argument, then "\hhline" would not be
208 % able to access the first vertical rule. (It ought to have an "@"
209 % option, and add "\leaders" up to the width of a box containing the
210 % "@"-expression. We use a loop made with "\futurelet" rather
211 % than "\@tfor" so that we can use "#" to denote the crossing of
212 % a double hline with a double vline.\\
213 % "\if@firstamp" is true in the first column and false otherwise.\\
214 % "\if@tempswa" is true if the previous entry was a vline
217 \def\hhline#1{\omit\@firstamptrue\@tempswafalse
219 % Put two rules of width "\doublerulesep" in "\box1"
221 \global\setbox\@ne\HH@box\doublerulesep\doublerulesep
223 % If Mittelbach's {\tt array.sty} is loaded, we do not need the negative
224 % "\hskip"'s around vertical rules.
226 \xdef\@tempc{\ifx\extrarowheight\HH@undef\hskip-.5\arrayrulewidth\fi}%
228 % Now expand the {\tt*}-forms and add dummy tokens ( "\relax" and
229 % "`" ) to either end of the token list. Call "\HH@let" to start
230 % processing the token list.
232 \HH@xexpast\relax#1*0x\@@\toks@{}\expandafter\HH@let\@tempa`}
236 % \begin{macro}{\HH@let}
237 % Discard the last token, look at the next one.
239 \def\HH@let#1{\futurelet\@tempb\HH@loop}
243 % \begin{macro}{\HH@loop}
244 % The main loop. Note we use "\ifx" rather than "\if" in
245 % version~2 as the new token "~" is active.
249 % If next token is "`", stop the loop and put the lines into this row
252 \ifx\@tempb`\def\next##1{\the\toks@\cr}\else\let\next\HH@let
254 % "|", add a vertical rule (across either a double or
257 \ifx\@tempb|\if@tempswa\HH@add{\hskip\doublerulesep}\fi\@tempswatrue
258 \HH@add{\@tempc\vline\@tempc}\else
260 % ":", add a broken vertical rule (across a double hline).
262 \ifx\@tempb:\if@tempswa\HH@add{\hskip\doublerulesep}\fi\@tempswatrue
263 \HH@add{\@tempc\HH@box\arrayrulewidth\arrayrulewidth\@tempc}\else
265 % "#", add a double hline segment between two vlines.
267 \ifx\@tempb##\if@tempswa\HH@add{\hskip\doublerulesep}\fi\@tempswatrue
268 \HH@add{\@tempc\vline\@tempc\copy\@ne\@tempc\vline\@tempc}\else
270 % "~", A column with no hline (this gives an effect similar to
273 \ifx\@tempb~\@tempswafalse
274 \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi
277 % "-", add a single hline across the column.
279 \ifx\@tempb-\@tempswafalse
280 \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi
281 \HH@add{\leaders\hrule\@height\arrayrulewidth\hfil}\else
283 % "=", add a double hline across the column.
285 \ifx\@tempb=\@tempswafalse
286 \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi
288 % Put in as many copies of "\box1" as possible with
289 % "\leaders", this may leave gaps at the ends, so put an extra box
290 % at each end, overlapping the "\leaders".
293 {\rlap{\copy\@ne}\leaders\copy\@ne\hfil\llap{\copy\@ne}}\else
295 % "t", add the top half of a double hline segment, in a "\rlap"
296 % so that it may be used with {\tt b}.
298 \ifx\@tempb t\HH@add{\rlap{\HH@box\doublerulesep\z@}}\else
300 % "b", add the bottom half of a double hline segment in a "\rlap"
301 % so that it may be used with {\tt t}.
303 \ifx\@tempb b\HH@add{\rlap{\HH@box\z@\doublerulesep}}\else
305 % Otherwise ignore the token, with a warning.
307 \PackageWarning{hhline}%
308 {\meaning\@tempb\space ignored in \noexpand\hhline argument%
310 \fi\fi\fi\fi\fi\fi\fi\fi\fi
312 % Go around the loop again.