% \iffalse meta-comment % % Copyright (C) 1993-2023 % % The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the Standard LaTeX `Tools Bundle'. % ------------------------------------------------------- % % It may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % https://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % The list of all files belonging to the LaTeX `Tools Bundle' is % given in the file `manifest.txt'. % % \fi % \iffalse %% File: hhline.dtx Copyright (C) 1991-1994 David Carlisle % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{hhline} % [2020/01/04 v2.04 Table rule package (DPC)] % %<*driver> \documentclass{ltxdoc} \usepackage{hhline} \GetFileInfo{hhline.sty} \begin{document} \title{The \textsf{hhline} package\thanks{This file has version number \fileversion, last revised \filedate.}} \author{David Carlisle} \date{\filedate} \MaintainedByLaTeXTeam{tools} \maketitle \DeleteShortVerb{\|} \DocInput{hhline.dtx} \end{document} % % \fi % % % \changes{v1.00}{1991/06/04}{Initial Version} % \changes{v2.00}{1991/11/06} % {Add tilde which allows \cmd\cline-like constructions.} % \changes{v2.01}{1992/06/26} % {Re-issue for the new doc and docstrip.} % \changes{v2.02}{1994/03/14} % {Update for LaTeX2e.} % \changes{v2.03}{1994/05/23} % {New style warning.} % \changes{v2.04}{2020/01/04} % {Ignore spaces.} % % % % \MakeShortVerb{\"} % % \begin{abstract} % "\hhline" produces a line like "\hline", or a double line like % "\hline\hline", except for its interaction with vertical lines. % \end{abstract} % % \arrayrulewidth=1pt % \doublerulesep=3pt % % \section{Introduction} % The argument to "\hhline" is similar to the preamble of an {\tt % array} or {\tt tabular}. It consists of a list of tokens with the % following meanings: % \[ % \begin{tabular}{cl} % "=" & A double hline the width of a column.\\ % "-" & A single hline the width of a column.\\[10pt] % "~" & A column with no hline.\\[10pt] % % "|" & A vline which `cuts' through a double (or single) hline.\\ % ":" & A vline which is broken by a double hline.\\[10pt] % % "#" & A double hline segment between two vlines.\\ % "t" & The top half of a double hline segment.\\ % "b" & The bottom half of a double hline segment.\\ % % "*" & "*{3}{==#}" expands to "==#==#==#", % as in the {\tt*}-form for the preamble. % \end{tabular} % \] % If a double vline is specified ("||" or "::") then the hlines % produced by "\hhline" are broken. To obtain the effect of an hline % `cutting through' the double vline, use a "#" or omit the vline % specifiers, depending on whether or not you wish the double vline to % break. % % The tokens {\tt t} and {\tt b} must be used between two vertical % rules. "|tb|" produces the same lines as "#", but is much less % efficient. The main use for these are to make constructions like % "|t:" (top left corner) and ":b|" (bottom right corner). % % If "\hhline" is used to make a single hline, then the argument % should only contain the tokens "-", "~" and "|" (and % {\tt*}-expressions). % % An example using most of these features is: % \[ % \vcenter{\hsize=2in\begin{verbatim} % \begin{tabular}{||cc||c|c||} % \hhline{|t:==:t:==:t|} % a&b&c&d\\ % \hhline{|:==:|~|~||} % 1&2&3&4\\ % \hhline{#==#~|=#} % i&j&k&l\\ % \hhline{||--||--||} % w&x&y&z\\ % \hhline{|b:==:b:==:b|} % \end{tabular} % \end{verbatim} % } % \qquad % \begin{tabular}{||cc||c|c||} % \hhline{|t:==:t:==:t|} % a&b&c&d\\ % \hhline{|:==:|~|~||} % 1&2&3&4\\ % \hhline{#==#~|=#} % i&j&k&l\\ % \hhline{||--||--||} % w&x&y&z\\ % \hhline{|b:==:b:==:b|} % \end{tabular} % \] % % The lines produced by \LaTeX's "\hline" consist of a single (\TeX\ % primitive) "\hrule". The lines produced by "\hhline" are made % up of lots of small line segments. \TeX\ will place these very % accurately in the {\tt .dvi} file, but the program that you use to % print the {\tt .dvi} file may not line up these segments exactly. (A % similar problem can occur with diagonal lines in the {\tt picture} % environment.) % % If this effect causes a problem, you could try a different driver % program, or if this is not possible, increasing "\arrayrulewidth" % may help to reduce the effect. % % \MaybeStop{} % % \section{The Macros} % % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macro}{\HH@box} % Makes a box containing a double hline segment. The most common case, % both rules of length "\doublerulesep" will be stored in "\box1", this % is not initialised until "\hhline" is called as the user may change % the parameters "\doublerulesep" and "\arrayrulewidth". The two % arguments to "\HH@box" are the widths (ie lengths) of the top and % bottom rules. % \begin{macrocode} \def\HH@box#1#2{\vbox{% \hrule \@height \arrayrulewidth \@width #1 \vskip \doublerulesep \hrule \@height \arrayrulewidth \@width #2}} % \end{macrocode} % \end{macro} % % \begin{macro}{\HH@add} % Build up the preamble in the register "\toks@". % \begin{macrocode} \def\HH@add#1{\toks@\expandafter{\the\toks@#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\HH@xexpast} % \begin{macro}{\HH@xexnoop} % We `borrow' the version of "\@xexpast" from Mittelbach's array.sty, % as this allows "#" to appear in the argument list. % \begin{macrocode} \def\HH@xexpast#1*#2#3#4\@@{% \@tempcnta #2 \toks@={#1}\@temptokena={#3}% \let\the@toksz\relax \let\the@toks\relax \def\@tempa{\the@toksz}% \ifnum\@tempcnta >0 \@whilenum\@tempcnta >0\do {\edef\@tempa{\@tempa\the@toks}\advance \@tempcnta \m@ne}% \let \@tempb \HH@xexpast \else \let \@tempb \HH@xexnoop \fi \def\the@toksz{\the\toks@}\def\the@toks{\the\@temptokena}% \edef\@tempa{\@tempa}% \expandafter \@tempb \@tempa #4\@@} \def\HH@xexnoop#1\@@{} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\hhline} % Use a simplified version of "\@mkpream" to break apart the argument % to "\hhline". Actually it is oversimplified, It assumes that the % vertical rules are at the end of the column. If you were to specify % "c|@{xx}|" in the array argument, then "\hhline" would not be % able to access the first vertical rule. (It ought to have an "@" % option, and add "\leaders" up to the width of a box containing the % "@"-expression. We use a loop made with "\futurelet" rather % than "\@tfor" so that we can use "#" to denote the crossing of % a double hline with a double vline.\\ % "\if@firstamp" is true in the first column and false otherwise.\\ % "\if@tempswa" is true if the previous entry was a vline % (":", "|" or "#"). % \begin{macrocode} \def\hhline#1{\omit\@firstamptrue\@tempswafalse % \end{macrocode} % Put two rules of width "\doublerulesep" in "\box1" % \begin{macrocode} \global\setbox\@ne\HH@box\doublerulesep\doublerulesep % \end{macrocode} % If Mittelbach's {\tt array.sty} is loaded, we do not need the negative % "\hskip"'s around vertical rules. % \begin{macrocode} \xdef\@tempc{\ifx\extrarowheight\HH@undef\hskip-.5\arrayrulewidth\fi}% % \end{macrocode} % Now expand the {\tt*}-forms and add dummy tokens ( "\relax" and % "`" ) to either end of the token list. Call "\HH@let" to start % processing the token list. % \begin{macrocode} \HH@xexpast\relax#1*0x\@@\toks@{}\expandafter\HH@let\@tempa`} % \end{macrocode} % \end{macro} % \begin{macro}{\HH@let} % Discard the last token, look at the next one. % \begin{macrocode} \def\HH@let#1{\futurelet\@tempb\HH@loop} % \end{macrocode} % \end{macro} % \begin{macro}{\HH@loop} % The main loop. Note we use "\ifx" rather than "\if" in % version~2 as the new token "~" is active. % \begin{macrocode} \def\HH@loop{% % \end{macrocode} % If next token is "`", stop the loop and put the lines into this row % of the alignment. % \begin{macrocode} \ifx\@tempb`\def\next##1{\the\toks@\cr}\else\let\next\HH@let % \end{macrocode} % "|", add a vertical rule (across either a double or % single hline). % \begin{macrocode} \ifx\@tempb|\if@tempswa\HH@add{\hskip\doublerulesep}\fi\@tempswatrue \HH@add{\@tempc\vline\@tempc}\else % \end{macrocode} % ":", add a broken vertical rule (across a double hline). % \begin{macrocode} \ifx\@tempb:\if@tempswa\HH@add{\hskip\doublerulesep}\fi\@tempswatrue \HH@add{\@tempc\HH@box\arrayrulewidth\arrayrulewidth\@tempc}\else % \end{macrocode} % "#", add a double hline segment between two vlines. % \begin{macrocode} \ifx\@tempb##\if@tempswa\HH@add{\hskip\doublerulesep}\fi\@tempswatrue \HH@add{\@tempc\vline\@tempc\copy\@ne\@tempc\vline\@tempc}\else % \end{macrocode} % "~", A column with no hline (this gives an effect similar to % \verb+\cline+). % \begin{macrocode} \ifx\@tempb~\@tempswafalse \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi \HH@add{\hfil}\else % \end{macrocode} % "-", add a single hline across the column. % \begin{macrocode} \ifx\@tempb-\@tempswafalse \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi \HH@add{\leaders\hrule\@height\arrayrulewidth\hfil}\else % \end{macrocode} % "=", add a double hline across the column. % \begin{macrocode} \ifx\@tempb=\@tempswafalse \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi % \end{macrocode} % Put in as many copies of "\box1" as possible with % "\leaders", this may leave gaps at the ends, so put an extra box % at each end, overlapping the "\leaders". % \begin{macrocode} \HH@add {\rlap{\copy\@ne}\leaders\copy\@ne\hfil\llap{\copy\@ne}}\else % \end{macrocode} % "t", add the top half of a double hline segment, in a "\rlap" % so that it may be used with {\tt b}. % \begin{macrocode} \ifx\@tempb t\HH@add{\rlap{\HH@box\doublerulesep\z@}}\else % \end{macrocode} % "b", add the bottom half of a double hline segment in a "\rlap" % so that it may be used with {\tt t}. % \begin{macrocode} \ifx\@tempb b\HH@add{\rlap{\HH@box\z@\doublerulesep}}\else % \end{macrocode} % "space", Gobble the space and loop again. % \begin{macrocode} \ifx\@tempb\@sptoken\let\next\HH@spacelet\else % \end{macrocode} % Otherwise ignore the token, with a warning. % \begin{macrocode} \PackageWarning{hhline}% {\meaning\@tempb\space ignored in \noexpand\hhline argument% \MessageBreak}% \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi % \end{macrocode} % Go around the loop again. % \begin{macrocode} \next} % \end{macrocode} % \end{macro} % % \begin{macro}{\HH@spacelet} % Helper macro to gobble a space token and continue the loop. % \begin{macrocode} \lowercase{\def\HH@spacelet} {\futurelet\@tempb \HH@loop} % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % \Finale \endinput