% \iffalse meta-comment
%
% Copyright (C) 1993-2026
%
% 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
%
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{hhline}
%<package>         [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}
%</driver>
% \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}
%</package>
%    \end{macrocode}
%
% \Finale
\endinput
