% (C) 2006-2022 Josselin Noirel
% 
% Package cellspace: Ensuring a minimal spacing of table cells.
%
% This material is subject to the LaTeX Project Public License. See
% https://www.latex-project.org/lppl/ .
%
\def \filedate    {2022/01/04}%
\def \fileversion {v1.9.0}%

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{cellspace}%
  [\filedate \space \fileversion \space Spacing table cells (JN)]

\RequirePackage{ifthen}  % \newboolean, \ifthenelse
\RequirePackage{array}   % \newcolumntype, \@{start,end}pbox
\RequirePackage{calc}    % \setlength{<dimen>}{<expression>}
\RequirePackage{xkeyval} % key=val options

% 2. Check the definitions of \@startpbox and \@endpbox
%    from array.sty

\@ifpackagelater{array}{2021/04/20}{%
      % New version of \@endpbox
      % Includes a \par
      \CheckCommand*{\@startpbox}[1]{%
        \bgroup
          \color@begingroup
            \setlength\hsize{#1}%
            \@arrayparboxrestore
            \everypar{%
                  \vrule \@height \ht\@arstrutbox \@width \z@
                  \everypar{}}%
      }%
      %
      \CheckCommand*{\@endpbox}%
        {\@finalstrut \@arstrutbox \par \color@endgroup \egroup\hfil}%
}{%
\@ifpackagelater{array}{2018/12/30}{%
      % New versions of \@startpbox / \@endpbox
      % Includes a \color@...group
      \CheckCommand*{\@startpbox}[1]{%
        \bgroup
          \color@begingroup
            \setlength\hsize{#1}%
            \@arrayparboxrestore
            \everypar{%
                  \vrule \@height \ht\@arstrutbox \@width \z@
                  \everypar{}}%
      }%
      %
      \CheckCommand*{\@endpbox}{\@finalstrut \@arstrutbox \color@endgroup \egroup \hfil}%
}{%
      % Older versions of \@startpbox / \@endpbox
      \CheckCommand*{\@startpbox}[1]{%
         \bgroup
            \setlength\hsize{#1}%
            \@arrayparboxrestore
            \everypar{%
                  \vrule \@height \ht\@arstrutbox \@width \z@
                  \everypar{}%
            }%
      }%
      %
      \CheckCommand*{\@endpbox}{\@finalstrut \@arstrutbox \egroup \hfil}%
}}

  % New version of array.sty

% 3. Declare registers and other variables

\newboolean{cellspace@lr} % Is it a LR column type ?
\newboolean{cellspace@}   % Is it a paragraph column that needs to be
                          % spaced out?
\newboolean{cellspace@m}  % [math] option: matrices

\@ifdefinable \cellspacetoplimit    {\newdimen \cellspacetoplimit}
\@ifdefinable \cellspacebottomlimit {\newdimen \cellspacebottomlimit}
\@ifdefinable \cellspace@firstht {\newdimen \cellspace@firstht} % Global
\@ifdefinable \cellspace@lastdp {\newdimen \cellspace@lastdp}   % Global

\setlength{\cellspacetoplimit}{1pt}
\setlength{\cellspacebottomlimit}{1pt}

% Options

\DeclareOptionX{math}{\setboolean{cellspace@m}{true}}
\DeclareOptionX{nomath}{\setboolean{cellspace@m}{false}}
\define@key{cellspace.sty}{column}{\def\cellspace@column{#1}}

\ExecuteOptionsX{nomath, column=S}
\ProcessOptionsX

% 4. Redefinitions

\renewcommand*{\@startpbox}[1]{%
  \bgroup
    \setbox \@tempboxa = \vtop \bgroup
      \color@begingroup
      \setlength{\hsize}{#1}%
      \@arrayparboxrestore
      % We need to test \ifcellspace@ within the \everypar
      % because it is still not set correctly
      \everypar{%
        \unless \ifcellspace@
          \vrule \@height \ht\@arstrutbox \@width \z@
        \fi
        \everypar{}%
      }%
}

\renewcommand*{\@endpbox}{%
      \unless \ifcellspace@
        \@finalstrut \@arstrutbox
      \fi
      \par
      % Save the depth of the last line
      \global \cellspace@lastdp = \prevdepth
      \expandafter % v1.7 This expandafter is now important
      \color@endgroup
      % \ifcellspace@ is only locally true, so we need to expand it before
      % \egroup stops it action
      \expandafter
    \egroup
    \ifcellspace@
    \unless \ifdim \cellspace@lastdp = -1000pt %
      % Save the height of the first line
      \global \cellspace@firstht = \ht\@tempboxa
      \setbox \@tempboxa = \vbox {%
        \setlength{\@tempdima}{\ht\@arstrutbox - \cellspace@firstht}%
        \ifthenelse{\lengthtest{\@tempdima<\cellspacetoplimit}}{%
          \setlength{\@tempdima}{\cellspace@firstht + \cellspacetoplimit}%
        }{%
          \setlength{\@tempdima}{\ht\@arstrutbox}%
        }%
        \hbox{\vrule height \@tempdima width 0pt depth 0pt }%
        \nointerlineskip
        \vskip-\cellspace@firstht
        \unvbox \@tempboxa
        \setlength{\@tempdima}{\dp\@arstrutbox - \cellspace@lastdp}%
        \ifthenelse{\lengthtest{\@tempdima<\cellspacebottomlimit}}{%
          \setlength{\@tempdima}{\cellspace@lastdp + \cellspacebottomlimit}%
        }{%
          \setlength{\@tempdima}{\dp\@arstrutbox}%
        }%
        \vskip-\cellspace@lastdp
        \nointerlineskip
        \hbox{\vrule height 0pt depth \@tempdima width 0pt }%
      }%
    \fi \fi
    \unvbox \@tempboxa
  \egroup
  \hfil
}

\let \@@startpbox = \@startpbox
\let \@@endpbox = \@endpbox

% Make it work with matrices
% 31 Jul 2009: suggested by Bastien Roucaries (for a long time)

\ifcellspace@m
  \RequirePackage{amsmath}%
  \def \env@matrix {%
    \hskip -\arraycolsep
    \let \@ifnextchar \new@ifnextchar
    \array{%
          *{\c@MaxMatrixCols}%
           {>{\bcolumn c\@nil$}c<{$\ecolumn}}@{}}}%
\fi

% 5. Defining a prefix

\expandafter
\newcolumntype
\expandafter{\cellspace@column}[1]%
    {>{\bcolumn #1\@nil}#1<{\ecolumn}}

\newcommand*{\bcolumn}{}
\def \bcolumn #1#2\@nil {%
  \cellspace@lrtrue
  \@expandtwoargs \in@{#1}{\cellspace@parcoltypes}%
  \ifin@
    \cellspace@lrfalse
  \fi
  \ifcellspace@lr
    \begingroup \lrbox {\@tempboxa}%
  \else
    \cellspace@true
  \fi
}

\newcommand*{\ecolumn}{%
  \ifcellspace@lr
    \endlrbox \endgroup
    \setlength{\@tempdima}{\ht\@arstrutbox - \ht\@tempboxa}%
    \ifthenelse{\lengthtest{\@tempdima<\cellspacetoplimit}}{%
      \setlength{\@tempdima}{\ht\@tempboxa + \cellspacetoplimit}%
      \ht\@tempboxa = \@tempdima
    }{}%
    \setlength{\@tempdima}{\dp\@arstrutbox - \dp\@tempboxa}%
    \ifthenelse{\lengthtest{\@tempdima<\cellspacebottomlimit}}{%
      \setlength{\@tempdima}{\dp\@tempboxa + \cellspacebottomlimit}%
      \dp\@tempboxa = \@tempdima
    }{}%
    \usebox{\@tempboxa}%
  \fi
}

\newcommand*{\cellspace@parcoltypes}{pmb}

\newcommand*{\addparagraphcolumntypes}[1]{%
  \edef \cellspace@parcoltypes {\cellspace@parcoltypes #1}%
}

\@onlypreamble \addparagraphcolumntypes

\endinput
