texlive[48023] Master/texmf-dist: cellprops (15jun18)

commits+karl at tug.org commits+karl at tug.org
Fri Jun 15 23:10:45 CEST 2018


Revision: 48023
          http://tug.org/svn/texlive?view=revision&revision=48023
Author:   karl
Date:     2018-06-15 23:10:45 +0200 (Fri, 15 Jun 2018)
Log Message:
-----------
cellprops (15jun18)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/cellprops/cellprops.pdf
    trunk/Master/texmf-dist/source/latex/cellprops/cellprops.dtx
    trunk/Master/texmf-dist/tex/latex/cellprops/cellprops.sty

Modified: trunk/Master/texmf-dist/doc/latex/cellprops/cellprops.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/cellprops/cellprops.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/cellprops/cellprops.dtx	2018-06-15 21:10:33 UTC (rev 48022)
+++ trunk/Master/texmf-dist/source/latex/cellprops/cellprops.dtx	2018-06-15 21:10:45 UTC (rev 48023)
@@ -14,11 +14,13 @@
 \RequirePackage{expl3}[2016/01/19]
 \def\ExplFileName{cellprops}
 \def\ExplFileDescription{CSS-like cell and table properties}
-\def\ExplFileDate{2018/06/12}
-\def\ExplFileVersion{1.2}
+\def\ExplFileDate{2018/06/14}
+\def\ExplFileVersion{1.3}
 %</driver|package>
 %<*driver>
 \documentclass[full]{l3doc}
+\usepackage[english]{babel}
+\usepackage{longtable}
 \usepackage{cellprops}
 \begin{document}
   \DocInput{\jobname.dtx}
@@ -53,67 +55,160 @@
 %
 % This package reworks the internals of \env{tabular}, \env{array}, and similar
 % constructs, and adds a \cs{cellprops} command accepting CSS-like selectors and
-% properties.
+% properties. It implements the "border-collapse: separate" CSS model.
 %
 % It depends on \pkg{mdwtab}, \pkg{xcolor} and of course \pkg{expl3} and
 % \pkg{xparse}.
 %
-% \subsection{Example}
+% \pkg{cellprops} default settings mimick the LaTeX layout, that is left and
+% right padding equal to "\tabcolsep" or "\arraycolsep", zero top and bottom
+% padding, but minimum height and depth corresponding to the table strut box.
 %
-% The code:
+% I recommend to add globally:
+%\begin{verbatim}
+%\cellprops{ td { padding: 1ex; min-height: 0pt; min-depth: 0pt; } }
+%\end{verbatim}
+% so that you get better-looking tables by default.
 %
+% \subsection{Examples}
+%
+% To produce:
+% \[
+%   \cellprops{
+%       td {
+%           padding: 1ex;
+%           min-height: 0pt;
+%           min-depth: 0pt;
+%           border-style: none solid solid none;
+%           background-color: black!5!white;
+%           text-align: center;
+%       }
+%       tr:nth-child(even) td {
+%           background-color: black!15!white;
+%       }
+%       td:nth-child(even) {
+%           background-color: yellow!20!white
+%       }
+%       tr:nth-child(even) td:nth-child(even) {
+%           background-color: yellow!50!white;
+%       }
+%       tr:first-child td {
+%           border-top-style: solid;
+%       }
+%       td:first-child {
+%           border-left-style: solid;
+%           math-mode: text;
+%           text-align: left;
+%       }
+%   }
+%   \begin{array}{nnnn}
+%       This is text & A_2 & A_3 & A_4 \\
+%       B1 & This is maths & B_3 & \\
+%       C1 &  C_2  &  X  & Y \\
+%       D1 &  D_2  &  DX & v \\
+%       E &  F  &  \int_a^b f(t) dt & v \\
+%   \end{array}
+% \]
+% you can use:
 %\begin{verbatim}
 % \[
-%    \cellprops{
-%        td { padding: 1ex; }
-%        td:nth-child(4) { color: red; }
-%        tr:nth-child(2) { color: red; }
-%        tr:nth-child(1) td:nth-child(4) { color: inherit; }
-%        td:nth-child(even) { background-color: black!5!white; }
-%        tr:nth-child(2n+1) { background-color: yellow!30!white; }
-%        tr:nth-child(odd) td:nth-child(even) {
-%            background-color: black!20!yellow!20!white;
-%        }
-%    }
-%    \begin{array}{Tlccc}
-%    \hline
-%    This is text & A_2 & A_3 & A_4 \\
-%    \hline
-%    B1 & This is maths & B_3 & \\
-%    C1 &  C_2  &  X  & Y \\
-%    D1 &  D_2  &  DX & v \\
-%    E &  F  &  \int_a^b f(t) dt & v \\
-%    \hline
-% \end{array}\]
+%   \cellprops{
+%       td {
+%           padding: 1ex;
+%           min-height: 0pt;
+%           min-depth: 0pt;
+%           border-style: none solid solid none;
+%           background-color: black!5!white;
+%           text-align: center;
+%       }
+%       tr:nth-child(even) td {
+%           background-color: black!15!white;
+%       }
+%       td:nth-child(even) {
+%           background-color: yellow!20!white
+%       }
+%       tr:nth-child(even) td:nth-child(even) {
+%           background-color: yellow!50!white;
+%       }
+%       tr:first-child td {
+%           border-top-style: solid;
+%       }
+%       td:first-child {
+%           border-left-style: solid;
+%           math-mode: text;
+%           text-align: left;
+%       }
+%   }
+%   \begin{array}{nnnn}
+%       This is text & A_2 & A_3 & A_4 \\
+%       B1 & This is maths & B_3 & \\
+%       C1 &  C_2  &  X  & Y \\
+%       D1 &  D_2  &  DX & v \\
+%       E &  F  &  \int_a^b f(t) dt & v \\
+%   \end{array}
+% \]
 %\end{verbatim}
 %
-% produces:
+% You can also use the \env{longtable} environment:
 %
-% \[
-%    \cellprops{
-%        td { padding: 1ex; }
-%        td:nth-child(4) { color: red; }
-%        tr:nth-child(2) { color: red; }
-%        tr:nth-child(1) td:nth-child(4) { color: inherit; }
-%        td:nth-child(even) { background-color: black!5!white; }
-%        tr:nth-child(2n+1) { background-color: yellow!30!white; }
-%        tr:nth-child(odd) td:nth-child(even) {
-%            background-color: black!20!yellow!20!white;
-%        }
-%    }
-%    \begin{array}{Tlccc}
-%    \hline
-%    This is text & A_2 & A_3 & A_4 \\
-%    \hline
-%    B1 & This is maths & B_3 & \\
-%    C1 &  C_2  &  X  & Y \\
-%    D1 &  D_2  &  DX & v \\
-%    E &  F  &  \int_a^b f(t) dt & v \\
-%    \hline
-% \end{array}\]
+%\begingroup
 %
+%\cellprops{
+%   td { border: thin solid black; }
+%   tr:nth-child(4n) td:first-child,
+%   tr:nth-child(4n+1) td:nth-child(2),
+%   tr:nth-child(4n+2) td:nth-child(3),
+%   tr:nth-child(4n+3) td:nth-child(4) {
+%       border: thick solid red;
+%   }
+%}
+%\begin{longtable}{nnnn}
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%\end{longtable}
 %
+%\endgroup
 %
+% This table has been produced by:
+%\begin{verbatim}
+%\cellprops{
+%   td { border: thin solid black; }
+%   tr:nth-child(4n) td:first-child,
+%   tr:nth-child(4n+1) td:nth-child(2),
+%   tr:nth-child(4n+2) td:nth-child(3),
+%   tr:nth-child(4n+3) td:nth-child(4) {
+%       border: thick solid red;
+%   }
+%}
+%\begin{longtable}{nnnn}
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%   ...
+%   aaaaa & baaaa & caaaaa & dbbbb \\
+%\end{longtable}
+%\end{verbatim}
 %
 % \subsection{Usage guide}
 %
@@ -136,21 +231,46 @@
 %    \item[nth] \<number> \OR "'odd'" \OR "'even'" \OR \<number>"'n+'"\<number>
 %    \item[properties] [ \<property> "';'" ]*
 %    \item[property]
-%       "'padding: '" \<dimension> [ "' '" \<dimension> ]* \OR \\
+%       "'padding: '" ( \<dimension> ) \{1,4\} \OR \\
 %       "'padding-top: '" \<dimension> \OR \\
+%       "'padding-right: '" \<dimension> \OR \\
+%       "'padding-bottom: '" \<dimension> \OR \\
 %       "'padding-left: '" \<dimension> \OR \\
-%       "'padding-bottom: '" \<dimension> \OR \\
-%       "'padding-right: '" \<dimension> \OR \\
 %       "'min-height: '" \<dimension> \OR \\
 %       "'min-depth: '" \<dimension> \OR \\
 %       "'min-width: '" \<dimension> \OR \\
 %       "'text-align: '" ( "'left'" \OR "'right'" \OR "'center'" ) \OR \\
 %       "'math-mode: '" ( "'text'" \OR "'math'" \OR "'auto'" ) \OR \\
-%       "'color: '" ( \<xcolor-expression> \OR "'inherit'" ) \OR \\
-%       "'background-color: '" ( \<xcolor-expression> \OR "'transparent'" ) \\
+%       "'color: '" \<color> \OR \\
+%       "'background-color: '" ( \<color> \OR "'transparent'" ) \OR \\
+%       "'border: '" [ \<bd-width> ] [ \<bd-style> ] [ \<color> ] \OR \\
+%       "'border-top: '" [ \<bd-width> ] [ \<bd-style> ] [ \<color> ] \OR \\
+%       "'border-right: '" [ \<bd-width> ] [ \<bd-style> ] [ \<color> ] \OR \\
+%       "'border-bottom: '" [ \<bd-width> ] [ \<bd-style> ] [ \<color> ] \OR \\
+%       "'border-left: '" [ \<bd-width> ] [ \<bd-style> ] [ \<color> ] \OR \\
+%       "'border-width: '" ( \<bd-width> ) \{1,4\} \OR \\
+%       "'border-top-width: '" \<bd-width> ) \OR \\
+%       "'border-right-width: '" \<bd-width> ) \OR \\
+%       "'border-bottom-width: '" \<bd-width> ) \OR \\
+%       "'border-left-width: '" \<bd-width> ) \OR \\
+%       "'border-style: '" ( \<bd-style> ) \{1,4\} \OR \\
+%       "'border-top-style: '" \<bd-style> ) \OR \\
+%       "'border-right-style: '" \<bd-style> ) \OR \\
+%       "'border-bottom-style: '" \<bd-style> ) \OR \\
+%       "'border-left-style: '" \<bd-style> ) \OR \\
+%       "'border-color: '" ( \<color> ) \{1,4\} \OR \\
+%       "'border-top-color: '" \<color> ) \OR \\
+%       "'border-right-color: '" \<color> ) \OR \\
+%       "'border-bottom-color: '" \<color> ) \OR \\
+%       "'border-left-color: '" \<color> )
+%    \item[color] "'inherit'" \OR \<xcolor-expression> \OR \\
+%       "'rgb('"\<red-0-255>"','"\<green-0-255>"','"\<blue-0-255>"')'" \OR \\
+%       "'hsl('"\<hue-0-360>"','"\<sat-0-1>"','"\<lum-0-1>"')'"
 % \end{description}
 %
-% Most of these properties are straight-forward. Some explanations:
+% Most of these properties are straight-forward. You should check a
+% CSS documentation to get more information. A very good source is the Mozilla
+% Developer Network.
 %
 % Here are the supported column types:
 % \begin{itemize}
@@ -203,12 +323,15 @@
 %
 % This package has been tested compatible with \pkg{diagbox}, \pkg{spreadtab},
 % \pkg{collcell}. Compatibility with \pkg{longtable} has been specifically taken
-% care of, provided \pkg{cellprops} is loaded afterwards.
+% care of, provided \pkg{cellprops} is loaded afterwards. Table packages that
+% only introduce new column types should be loaded after \pkg{mdwtab}, so either
+% you load \pkg{mdwtab} manually and load your package in between \pkg{mdwtab}
+% and \pkg{cellprops}, or you load your package after \pkg{cellprops} (provided
+% it doesn't overwrite the machinery).
 %
 % \subsection{TODO}
 %
-% Add "border" properties. Test with different table-oriented packages, and add
-% a test suite with compatibility tests. Improve
+% Add a test suite with compatibility tests. Improve
 % the documentation, and test more \LaTeX\ table constructs and preamble column
 % types. Enforce $n\ge0$ in ":nth-child" selectors to match the CSS
 % specification.
@@ -266,7 +389,7 @@
 %   value in a token list.
 %
 %    \begin{macrocode}
-\cs_set:Nn \@@_generic_setter:nnn {
+\cs_new:Nn \@@_generic_setter:nnn {
     \exp_not:N \tl_set:Nn
     \exp_not:c { l_@@_property_value_#2_tl }
     {#1 {#3}}
@@ -276,7 +399,7 @@
     \tl_use:c { l_@@_property_value_#1_tl }
 }
 
-\cs_set_protected_nopar:Nn \@@_get_property:nN {
+\cs_new_protected_nopar:Nn \@@_get_property:nN {
     \tl_if_exist:cTF { l_@@_property_value_#1_tl } {
         \tl_set_eq:Nc #2 { l_@@_property_value_#1_tl }
     }{
@@ -294,7 +417,7 @@
 %   The control sequence \cs{_@@_property_type_<name>:nn} holds the setter for
 %   the property \meta{name}. It can be set by the following helper:
 %    \begin{macrocode}
-\cs_set_protected:Nn \@@_define_properties:nn {
+\cs_new_protected:Nn \@@_define_properties:nn {
     \clist_map_inline:nn {#2} {
         \cs_set:cpn { _@@_property_type_##1:nn } {#1}
     }
@@ -307,9 +430,12 @@
 %   Sometimes we need to use a setter right away rather than save its action
 %   somewhere. The following helper does that with an x-expansion.
 %    \begin{macrocode}
-\cs_set_protected:Nn \@@_use_setter:nn {
+\cs_new:Nn \@@_delegate_setter:nn {
+    \use:c {_@@_property_type_#1:nn} {#1} {#2}
+}
+\cs_new_protected:Nn \@@_use_setter:nn {
     \use:x {
-        \use:c {_@@_property_type_#1:nn} {#1} {#2}
+        \@@_delegate_setter:nn {#1} {#2}
     }
 }
 %    \end{macrocode}
@@ -316,7 +442,7 @@
 %   \end{macro}
 %
 %    \begin{macrocode}
-\cs_set_protected:Nn \@@_parse_properties:Nn {
+\cs_new_protected:Nn \@@_parse_properties:Nn {
     \tl_clear:N #1
     \seq_set_split:Nnn \l_tmpa_seq {;} {#2}
     \seq_map_inline:Nn \l_tmpa_seq {
@@ -328,9 +454,8 @@
                 \seq_get_right:NN \l_tmpb_seq \l_tmpa_tl
                 \cs_if_exist:cTF { _@@_property_type_\l_tmpa_str :nn } {
                     \tl_put_right:Nx #1 {
-                        \exp_args:Nc \exp_args:NVV
-                        { _@@_property_type_\l_tmpa_str :nn }
-                        \l_tmpa_str \l_tmpa_tl
+                        \exp_args:NVV \@@_delegate_setter:nn
+                            \l_tmpa_str \l_tmpa_tl
                     }
                 }{
                 % TODO: ERROR-no property with that name
@@ -342,30 +467,39 @@
     }
 }
 
-\cs_set:Nn \@@_fourdim_setter:nn {
-    \@@_fourdim_setter_aux:w
-        {#1}#2~{\q_no_value}~{\q_no_value}~{\q_no_value}~\q_stop
+\cs_new:Nn \@@_fourval_setter:nnnnnn {
+    \@@_fourval_setter_aux:w
+        {#1}{#2}{#3}{#4}#6~{\q_no_value}~{\q_no_value}~{\q_no_value}~\q_stop
 }
-\cs_set:Npn \@@_fourdim_setter_aux:w #1#2~#3~#4~#5~#6\q_stop {
-    \@@_generic_setter:nnn \exp_not:n {#1-top} {#2}
-    \quark_if_no_value:nTF {#3} {
-        \@@_generic_setter:nnn \exp_not:n {#1-right} {#2}
-        \@@_generic_setter:nnn \exp_not:n {#1-left}  {#2}
+\cs_new:Npn \@@_fourval_setter_aux:w #1#2#3#4#5~#6~#7~#8~#9\q_stop {
+    \@@_delegate_setter:nn {#1} {#5}
+    \quark_if_no_value:nTF {#6} {
+        \@@_delegate_setter:nn {#2} {#5}
+        \@@_delegate_setter:nn {#4} {#5}
     }{
-        \@@_generic_setter:nnn \exp_not:n {#1-right} {#3}
-        \quark_if_no_value:nTF {#5} {
-            \@@_generic_setter:nnn \exp_not:n {#1-left} {#3}
+        \@@_delegate_setter:nn {#2} {#6}
+        \quark_if_no_value:nTF {#8} {
+            \@@_delegate_setter:nn {#4} {#6}
         }{
-            \@@_generic_setter:nnn \exp_not:n {#1-left} {#5}
+            \@@_delegate_setter:nn {#4} {#8}
         }
     }
-    \quark_if_no_value:nTF {#4} {
-        \@@_generic_setter:nnn \exp_not:n {#1-bottom} {#2}
+    \quark_if_no_value:nTF {#7} {
+        \@@_delegate_setter:nn {#3} {#5}
     }{
-        \@@_generic_setter:nnn \exp_not:n {#1-bottom} {#4}
+        \@@_delegate_setter:nn {#3} {#7}
     }
 }
 
+\cs_new_protected:Nn \@@_define_fourval_properties:nnnnnn {
+    \@@_define_properties:nn {#1} { #3, #4, #5, #6 }
+    \@@_define_properties:nn {
+        \@@_fourval_setter:nnnnnn {#3}{#4}{#5}{#6}
+    }{
+        #2
+    }
+}
+
 \tl_const:Nn \c_@@_inherit_color_tl { \q_nil }
 
 \cs_new_nopar:Nn \@@_color_setter:nn {
@@ -396,24 +530,70 @@
     }
 }
 
+\cs_new_nopar:Nn \@@_linewidth_setter:nn {
+    \str_case:nnF {#2} {
+        {thin}   { \@@_generic_setter:nnn \exp_not:n {#1} { \fboxrule} }
+        {medium} { \@@_generic_setter:nnn \exp_not:n {#1} { 2\fboxrule} }
+        {thick}  { \@@_generic_setter:nnn \exp_not:n {#1} { 3\fboxrule} }
+    }{
+        \@@_generic_setter:nnn \exp_not:n {#1} {#2}
+    }
+}
 
+\cs_new_nopar:Nn \@@_border_setter:nn {
+    \@@_border_setter_aux:nw
+        {#1}#2~{\q_no_value}~{\q_no_value}~\q_stop
+}
+\cs_new:Npn \@@_border_setter_aux:nw #1#2~#3~#4~#5\q_stop {
+    \quark_if_no_value:nTF {#4} {
+        \@@_border_setter_isstyle:nTF {#2} {
+            \@@_delegate_setter:nn {#1-width} {thin}
+            \@@_delegate_setter:nn {#1-style} {#2}
+            \quark_if_no_value:nTF {#3} {
+                \@@_delegate_setter:nn {#1-color} {inherit}
+            }{
+                \@@_delegate_setter:nn {#1-color} {#3}
+            }
+        }{
+            \quark_if_no_value:nTF {#3} {
+                %% TODO: Error, one no-style value, ambiguous
+            }{
+                \@@_border_setter_isstyle:nTF {#3} {
+                    \@@_delegate_setter:nn {#1-width} {#2}
+                    \@@_delegate_setter:nn {#1-style} {#3}
+                    \@@_delegate_setter:nn {#1-color} {inherit}
+                }{
+                    \@@_delegate_setter:nn {#1-width} {#2}
+                    \@@_delegate_setter:nn {#1-style} {none}
+                    \@@_delegate_setter:nn {#1-color} {#3}
+                }
+            }
+        }
+    }{
+        \@@_delegate_setter:nn {#1-width} {#2}
+        \@@_delegate_setter:nn {#1-style} {#3}
+        \@@_delegate_setter:nn {#1-color} {#4}
+    }
+}
+\cs_new:Npn \@@_border_setter_isstyle:nTF #1 {
+    \str_case:nnTF {#1} {
+        {none}{} {hidden}{} {dotted}{} {dashed}{} {solid}{}
+        {double}{} {groove}{} {ridge}{} {inset}{} {outset}{}
+    }
+}
+
 \@@_define_properties:nn {
     \@@_generic_setter:nnn \exp_not:n
 }{
-    padding-top,
-    padding-right,
-    padding-bottom,
-    padding-left,
     min-height,
     min-depth,
     min-width,
 }
 
-\@@_define_properties:nn {
-    \@@_fourdim_setter:nn
-}{
-    padding
-}
+\@@_define_fourval_properties:nnnnnn
+    { \@@_generic_setter:nnn \exp_not:n }
+    {padding}
+    {padding-top}{padding-right}{padding-bottom}{padding-left}
 
 \@@_define_properties:nn {
     \@@_generic_setter:nnn \tl_to_str:n
@@ -434,6 +614,30 @@
     background-color,
 }
 
+\@@_define_fourval_properties:nnnnnn
+    { \@@_linewidth_setter:nn }
+    {border-width}
+    {border-top-width}{border-right-width}
+    {border-bottom-width}{border-left-width}
+
+\@@_define_fourval_properties:nnnnnn
+    { \@@_generic_setter:nnn \tl_to_str:n }
+    {border-style}
+    {border-top-style}{border-right-style}
+    {border-bottom-style}{border-left-style}
+
+\@@_define_fourval_properties:nnnnnn
+    { \@@_color_setter:nn }
+    {border-color}
+    {border-top-color}{border-right-color}
+    {border-bottom-color}{border-left-color}
+
+\@@_define_properties:nn {
+    \@@_border_setter:nn
+}{
+    border, border-top, border-right, border-bottom, border-left
+}
+
 \NewDocumentCommand \cellprops { m } {
     \@@_parse_css:n {#1}
 }
@@ -565,17 +769,21 @@
 }
 
 \dim_new:N \l_@@_colsep_dim
+\dim_new:N \l_@@_strut_ht_dim
+\dim_new:N \l_@@_strut_dp_dim
+
 \ExplSyntaxOff
 \cellprops{
     td {
         padding: 0pt \csname l_@@_colsep_dim\endcsname;
-        min-height: 0pt;
-        min-depth: 0pt;
+        min-height: \csname l_@@_strut_ht_dim\endcsname;
+        min-depth: \csname l_@@_strut_dp_dim\endcsname;
         min-width: 0pt;
         text-align: left;
         math-mode: auto;
         color: inherit;
         background-color: transparent;
+        border: thin none inherit;
     }
     tr {
         color: inherit;
@@ -599,6 +807,7 @@
 \skip_new:N \l_@@_right_skip
 \dim_new:N \g_@@_ht_dim
 \dim_new:N \g_@@_dp_dim
+\tl_new:N \g_@@_borders_tl
 
 \tl_new:N \l_@@_restore_tl
 
@@ -623,9 +832,12 @@
             { \dim_use:N \g_@@_ht_dim }
         \exp_not:n { \dim_gset:Nn \g_@@_dp_dim }
             { \dim_use:N \g_@@_dp_dim }
+        \exp_not:n { \tl_gset:Nn \g_@@_borders_tl }
+            { \exp_not:V \g_@@_borders_tl }
     }
     \int_gzero:N \g_@@_row_int
     \bool_gset_false:N \g_@@_inrow_bool
+    \tl_gclear:N \g_@@_borders_tl
     \cs_set_eq:NN \@@_orig_tab at readpreamble:n \tab at readpreamble
     \cs_set_eq:NN \tab at readpreamble \@@_readpreamble:n
 %    \end{macrocode}
@@ -651,6 +863,9 @@
     \tl_set_eq:NN \l_@@_color_tl \g_tmpa_tl
     \tl_set_eq:NN \l_@@_bgcolor_tl \g_tmpb_tl
     \@@_recall_properties:n {tr}
+    \dim_set:Nn \l_@@_strut_ht_dim { \box_ht:N \@arstrutbox }
+    \dim_set:Nn \l_@@_strut_dp_dim { \box_dp:N \@arstrutbox }
+    \box_clear:N \@arstrutbox
 }
 
 \cs_set_nopar:Nn \@@_array_startcontent: {
@@ -702,12 +917,13 @@
     }
 }
 
-\cs_set_protected_nopar:Nn \@@_update_colors: {
+\cs_new_protected_nopar:Nn \@@_update_colors: {
     \@@_update_color:Nn \l_@@_color_tl {color}
     \@@_update_color:Nn \l_@@_bgcolor_tl {background-color}
 }
 
-\cs_set_nopar:Nn \@@_end_array:n {
+\cs_new_nopar:Nn \@@_end_array:n {
+    \tl_if_empty:NF \g_@@_borders_tl { \\ }
     \crcr
     \hlx{s[\l_@@_tablepadding_bottom_dim]}
     #1
@@ -718,6 +934,8 @@
 \cs_set_nopar:Npn \endarray {
     \@@_end_array:n { \@@_orig_endarray: }
 }
+\cs_set_eq:NN \endtabular \endarray
+\cs_set_eq:cN {endtabular*} \endarray
 
 \cs_set_eq:NN \@@_orig_endLT: \endlongtable
 \cs_set_nopar:Npn \endlongtable {
@@ -724,7 +942,7 @@
     \@@_end_array:n { \@@_orig_endLT: }
 }
 
-\cs_set_protected_nopar:Nn \@@_startrow: {
+\cs_new_protected_nopar:Nn \@@_startrow: {
     \bool_if:NF \g_@@_inrow_bool {
         \bool_gset_true:N \g_@@_inrow_bool
         \int_gincr:N \g_@@_row_int
@@ -734,16 +952,34 @@
     }
 }
 
-\cs_set_protected_nopar:Npn \@@_endrow: {
+\cs_new_protected_nopar:Nn \@@_endrow: {
     \bool_if:NT \g_@@_inrow_bool {
         \bool_gset_false:N \g_@@_inrow_bool
-        \@@_fix_valign_end:
     }
 }
 
-\cs_set_eq:NN \@@_orig_tab at arraycr:n \tab at arraycr
-\cs_set_nopar:Npn \tab at arraycr { \@@_endrow:\@@_orig_tab at arraycr:n }
+\cs_new_protected_nopar:Nn \@@_cr:n {
+    \@@_endrow:
+    \tl_if_empty:NF \g_@@_borders_tl {
+        \cr
+        \noalign{\nobreak}
+        \tl_use:N \g_@@_borders_tl
+        \tl_gclear:N \g_@@_borders_tl
+    }
+    \cr
+    \@@_fix_valign_end:n {#1}
+    \use_none:n
+}
 
+\cs_set_protected_nopar:Npn \tab at tabcr #1#2 { \@@_cr:n {#2} }
+\cs_set_protected_nopar:Npn \@xargarraycr #1 { \@@_cr:n {#1} }
+\cs_set_protected_nopar:Npn \@yargarraycr #1 { \@@_cr:n {#1} }
+\tl_if_exist:NT \LT at echunk {
+    \tl_put_left:Nn \LT at echunk {
+        \tl_if_empty:NF \g_@@_borders_tl { \\ }
+    }
+}
+
 \cs_set_eq:NN \@@_orig_multicolumn:w \multicolumn
 \cs_set:Npn \multicolumn#1#2#3 {
     \@@_orig_multicolumn:w {#1}{#2}{
@@ -752,15 +988,15 @@
     }
 }
 
-\cs_new_protected_nopar:Nn \@@_fix_valign_end: {
-    \exp_args:NV \tl_if_eq:nnTF \tab at hlstate {b} {
-        \dim_gadd:Nn \tab at endheight {
-            \g_@@_dp_dim - \box_dp:N \@arstrutbox
-        }
-    }{
-        \int_compare:nNnT \g_@@_row_int = \c_one {
-            \dim_gadd:Nn \tab at endheight {
-                \g_@@_ht_dim - \box_ht:N \@arstrutbox
+\cs_new_nopar:Nn \@@_fix_valign_end:n {
+    \noalign{
+        \dim_set:Nn \l_tmpa_dim {#1}
+        \skip_vertical:n {\l_tmpa_dim}
+        \exp_args:NV \tl_if_eq:nnTF \tab at hlstate {b} {
+            \dim_gadd:Nn \tab at endheight { \g_@@_dp_dim + \l_tmpa_dim }
+        }{
+            \int_compare:nNnT \g_@@_row_int = \c_one {
+                \dim_gadd:Nn \tab at endheight { \g_@@_ht_dim }
             }
         }
     }
@@ -923,22 +1159,124 @@
     \tl_use:N \l_@@_color_tl
 }
 
+\cs_new_protected_nopar:Nn \@@_make_solid_hborder:nnn {
+    \group_begin:
+        \hbox_set_to_wd:Nnn \l_tmpa_box {1pt} {
+            \hss
+            \hbox:n {
+                #3 % install color
+                \vrule height~\dim_eval:n{#1+#2}
+                    ~depth~-\dim_eval:n{#2}
+                    ~width~3pt
+            }
+            \hss
+        }
+        \box_set_ht:Nn \l_tmpa_box { \c_zero_dim }
+        \box_set_dp:Nn \l_tmpa_box { \c_zero_dim }
+        \kern 1pt
+        \box_use:N \l_tmpa_box
+        \xleaders
+            \box_use:N \l_tmpa_box
+            \skip_horizontal:n {-4pt~plus~1fil}
+        \box_use:N \l_tmpa_box
+        \kern 1pt
+        \skip_horizontal:n {0pt~plus~-1fil}
+    \group_end:
+}
+\cs_new_protected_nopar:Nn \@@_make_solid_vborder:nnn {
+    \group_begin:
+        \hbox_set_to_wd:Nnn \l_tmpa_box {0pt} {
+            \hbox:n {
+                #3 % install color
+                \vrule height~\dim_eval:n{#2}~width~\dim_eval:n{#1}
+            }
+            \hss
+        }
+        \box_set_ht:Nn \l_tmpa_box { \c_zero_dim }
+        \box_set_dp:Nn \l_tmpa_box { \c_zero_dim }
+        \box_use:N \l_tmpa_box
+    \group_end:
+}
+\clist_map_inline:nn {
+    dotted, dashed, solid, double,
+    groove, ridge, inset, outset
+}{
+    \cs_set_eq:cN {@@_make_#1_hborder:nnn} \@@_make_solid_hborder:nnn
+    \cs_set_eq:cN {@@_make_#1_vborder:nnn} \@@_make_solid_vborder:nnn
+}
+
+\dim_new:N \l_@@_border_width_dim
+\str_new:N \l_@@_border_style_str
+\tl_new:N \l_@@_border_color_tl
+\cs_new_protected_nopar:Nn \@@_get_border_info:n {
+    \dim_set:Nn \l_@@_border_width_dim {\@@_get_property:n {border-#1-width}}
+    \@@_get_property:nN {border-#1-style} \l_tmpa_tl
+    \exp_args:NNV \str_set:Nn \l_@@_border_style_str \l_tmpa_tl
+    \tl_clear:N \l_@@_border_color_tl
+    \cs_if_exist:cTF {@@_make_\l_@@_border_style_str _hborder:nnn} {
+        \@@_update_color:Nn \l_@@_border_color_tl {border-#1-color}
+    }{
+        \dim_zero:N \l_@@_border_width_dim
+    }
+}
+
+\cs_new_protected_nopar:Npn \@@_make_hborder:nnnn #1 {
+    \use:c { @@_make_#1_hborder:nnn }
+}
+\cs_new_protected_nopar:Npn \@@_make_vborder:nnnn #1 {
+    \use:c { @@_make_#1_vborder:nnn }
+}
+
 \cs_new_protected_nopar:Nn \@@_end_raw_cell: {
     % Here \l_@@_cell_box must contain the contents of the cell
     %
-    % Handle vpadding and min-height/depth
+    % Prepare the borders token list
+    \int_compare:nNnT \g_@@_col_int = 1 {
+        \tl_gclear:N \g_@@_borders_tl
+    }
+    \tl_gput_right:Nx \g_@@_borders_tl {
+        \tl_if_empty:NF \g_@@_borders_tl { \exp_not:n {&} }
+        \exp_not:n { \omit \kern \c_zero_dim }
+    }
+    % Handle padding-top, min-height and border-top
+    \@@_get_border_info:n {top}
     \box_set_ht:Nn \l_@@_cell_box {
         \dim_max:nn
             {\box_ht:N \l_@@_cell_box}
             {\@@_get_property:n {min-height}}
         + (\@@_get_property:n {padding-top})
+        + \l_@@_border_width_dim
     }
+    \dim_compare:nNnT \l_@@_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g_@@_borders_tl {
+            \exp_not:N \@@_make_hborder:nnnn
+                { \exp_not:V \l_@@_border_style_str }
+                { \dim_use:N \l_@@_border_width_dim }
+                {
+                    \exp_not:n { \g_@@_dp_dim + \g_@@_ht_dim - }
+                    \dim_use:N \l_@@_border_width_dim
+                }
+                { \exp_not:V \l_@@_border_color_tl }
+        }
+    }
+    % Handle padding-bottom, min-depth and border-bottom
+    \@@_get_border_info:n {bottom}
     \box_set_dp:Nn \l_@@_cell_box {
         \dim_max:nn
             {\box_dp:N \l_@@_cell_box}
             {\@@_get_property:n {min-depth}}
         + (\@@_get_property:n {padding-bottom})
+        + \l_@@_border_width_dim
     }
+    \dim_compare:nNnT \l_@@_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g_@@_borders_tl {
+            \exp_not:N \@@_make_hborder:nnnn
+                { \exp_not:V \l_@@_border_style_str }
+                { \dim_use:N \l_@@_border_width_dim }
+                { \exp_not:n { 0pt } }
+                { \exp_not:V \l_@@_border_color_tl }
+        }
+    }
     % To fix vertical alignment later
     \dim_gset:Nn \g_@@_ht_dim {
         \dim_max:nn
@@ -960,10 +1298,42 @@
     \skip_add:Nn \l_tmpa_skip {
         0pt plus 1fil
     }
+    % padding-left and border-left
+    \@@_get_border_info:n {left}
     \skip_set:Nn \l_@@_left_skip
-        {\@@_get_property:n {padding-left}}
+        {\@@_get_property:n {padding-left} + \l_@@_border_width_dim}
+    \dim_compare:nNnT \l_@@_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g_@@_borders_tl {
+            \exp_not:N \@@_make_vborder:nnnn
+                { \exp_not:V \l_@@_border_style_str }
+                { \dim_use:N \l_@@_border_width_dim }
+                { \exp_not:n { \g_@@_dp_dim + \g_@@_ht_dim } }
+                { \exp_not:V \l_@@_border_color_tl }
+        }
+    }
+    \tl_gput_right:Nx \g_@@_borders_tl {
+        \exp_not:n {
+            \skip_horizontal:n {0pt~plus~1fil}
+            \kern \c_zero_dim
+        }
+    }
+    \@@_get_border_info:n {right}
     \skip_set:Nn \l_@@_right_skip
-        {\@@_get_property:n {padding-right}}
+        {\@@_get_property:n {padding-right} + \l_@@_border_width_dim}
+    \dim_compare:nNnT \l_@@_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g_@@_borders_tl {
+            \exp_not:N \skip_horizontal:n
+                { - \dim_use:N \l_@@_border_width_dim }
+            \exp_not:N \@@_make_vborder:nnnn
+                { \exp_not:V \l_@@_border_style_str }
+                { \dim_use:N \l_@@_border_width_dim }
+                { \exp_not:n { \g_@@_dp_dim + \g_@@_ht_dim } }
+                { \exp_not:V \l_@@_border_color_tl }
+            \exp_not:N \skip_horizontal:n
+                { \dim_use:N \l_@@_border_width_dim }
+            \exp_not:n { \kern \c_zero_dim }
+        }
+    }
     \str_case_x:nnF {\@@_get_property:n {text-align}} {
         { right } {
             \skip_add:Nn \l_@@_left_skip { \l_tmpa_skip }

Modified: trunk/Master/texmf-dist/tex/latex/cellprops/cellprops.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/cellprops/cellprops.sty	2018-06-15 21:10:33 UTC (rev 48022)
+++ trunk/Master/texmf-dist/tex/latex/cellprops/cellprops.sty	2018-06-15 21:10:45 UTC (rev 48023)
@@ -15,8 +15,8 @@
 \RequirePackage{expl3}[2016/01/19]
 \def\ExplFileName{cellprops}
 \def\ExplFileDescription{CSS-like cell and table properties}
-\def\ExplFileDate{2018/06/12}
-\def\ExplFileVersion{1.2}
+\def\ExplFileDate{2018/06/14}
+\def\ExplFileVersion{1.3}
 \ProvidesExplPackage
   {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
 
@@ -25,7 +25,7 @@
 \RequirePackage{mdwtab}
 \cs_set_nopar:Npn \tab at pop #1 { \tl_set:Nx #1 { \tl_tail:N #1 } }
 
-\cs_set:Nn \__cellprops_generic_setter:nnn {
+\cs_new:Nn \__cellprops_generic_setter:nnn {
     \exp_not:N \tl_set:Nn
     \exp_not:c { l__cellprops_property_value_#2_tl }
     {#1 {#3}}
@@ -35,7 +35,7 @@
     \tl_use:c { l__cellprops_property_value_#1_tl }
 }
 
-\cs_set_protected_nopar:Nn \__cellprops_get_property:nN {
+\cs_new_protected_nopar:Nn \__cellprops_get_property:nN {
     \tl_if_exist:cTF { l__cellprops_property_value_#1_tl } {
         \tl_set_eq:Nc #2 { l__cellprops_property_value_#1_tl }
     }{
@@ -42,17 +42,20 @@
         \tl_clear:N #2
     }
 }
-\cs_set_protected:Nn \__cellprops_define_properties:nn {
+\cs_new_protected:Nn \__cellprops_define_properties:nn {
     \clist_map_inline:nn {#2} {
         \cs_set:cpn { __cellprops_property_type_##1:nn } {#1}
     }
 }
-\cs_set_protected:Nn \__cellprops_use_setter:nn {
+\cs_new:Nn \__cellprops_delegate_setter:nn {
+    \use:c {__cellprops_property_type_#1:nn} {#1} {#2}
+}
+\cs_new_protected:Nn \__cellprops_use_setter:nn {
     \use:x {
-        \use:c {__cellprops_property_type_#1:nn} {#1} {#2}
+        \__cellprops_delegate_setter:nn {#1} {#2}
     }
 }
-\cs_set_protected:Nn \__cellprops_parse_properties:Nn {
+\cs_new_protected:Nn \__cellprops_parse_properties:Nn {
     \tl_clear:N #1
     \seq_set_split:Nnn \l_tmpa_seq {;} {#2}
     \seq_map_inline:Nn \l_tmpa_seq {
@@ -64,9 +67,8 @@
                 \seq_get_right:NN \l_tmpb_seq \l_tmpa_tl
                 \cs_if_exist:cTF { __cellprops_property_type_\l_tmpa_str :nn } {
                     \tl_put_right:Nx #1 {
-                        \exp_args:Nc \exp_args:NVV
-                        { __cellprops_property_type_\l_tmpa_str :nn }
-                        \l_tmpa_str \l_tmpa_tl
+                        \exp_args:NVV \__cellprops_delegate_setter:nn
+                            \l_tmpa_str \l_tmpa_tl
                     }
                 }{
                 % TODO: ERROR-no property with that name
@@ -78,30 +80,39 @@
     }
 }
 
-\cs_set:Nn \__cellprops_fourdim_setter:nn {
-    \__cellprops_fourdim_setter_aux:w
-        {#1}#2~{\q_no_value}~{\q_no_value}~{\q_no_value}~\q_stop
+\cs_new:Nn \__cellprops_fourval_setter:nnnnnn {
+    \__cellprops_fourval_setter_aux:w
+        {#1}{#2}{#3}{#4}#6~{\q_no_value}~{\q_no_value}~{\q_no_value}~\q_stop
 }
-\cs_set:Npn \__cellprops_fourdim_setter_aux:w #1#2~#3~#4~#5~#6\q_stop {
-    \__cellprops_generic_setter:nnn \exp_not:n {#1-top} {#2}
-    \quark_if_no_value:nTF {#3} {
-        \__cellprops_generic_setter:nnn \exp_not:n {#1-right} {#2}
-        \__cellprops_generic_setter:nnn \exp_not:n {#1-left}  {#2}
+\cs_new:Npn \__cellprops_fourval_setter_aux:w #1#2#3#4#5~#6~#7~#8~#9\q_stop {
+    \__cellprops_delegate_setter:nn {#1} {#5}
+    \quark_if_no_value:nTF {#6} {
+        \__cellprops_delegate_setter:nn {#2} {#5}
+        \__cellprops_delegate_setter:nn {#4} {#5}
     }{
-        \__cellprops_generic_setter:nnn \exp_not:n {#1-right} {#3}
-        \quark_if_no_value:nTF {#5} {
-            \__cellprops_generic_setter:nnn \exp_not:n {#1-left} {#3}
+        \__cellprops_delegate_setter:nn {#2} {#6}
+        \quark_if_no_value:nTF {#8} {
+            \__cellprops_delegate_setter:nn {#4} {#6}
         }{
-            \__cellprops_generic_setter:nnn \exp_not:n {#1-left} {#5}
+            \__cellprops_delegate_setter:nn {#4} {#8}
         }
     }
-    \quark_if_no_value:nTF {#4} {
-        \__cellprops_generic_setter:nnn \exp_not:n {#1-bottom} {#2}
+    \quark_if_no_value:nTF {#7} {
+        \__cellprops_delegate_setter:nn {#3} {#5}
     }{
-        \__cellprops_generic_setter:nnn \exp_not:n {#1-bottom} {#4}
+        \__cellprops_delegate_setter:nn {#3} {#7}
     }
 }
 
+\cs_new_protected:Nn \__cellprops_define_fourval_properties:nnnnnn {
+    \__cellprops_define_properties:nn {#1} { #3, #4, #5, #6 }
+    \__cellprops_define_properties:nn {
+        \__cellprops_fourval_setter:nnnnnn {#3}{#4}{#5}{#6}
+    }{
+        #2
+    }
+}
+
 \tl_const:Nn \c__cellprops_inherit_color_tl { \q_nil }
 
 \cs_new_nopar:Nn \__cellprops_color_setter:nn {
@@ -132,23 +143,70 @@
     }
 }
 
+\cs_new_nopar:Nn \__cellprops_linewidth_setter:nn {
+    \str_case:nnF {#2} {
+        {thin}   { \__cellprops_generic_setter:nnn \exp_not:n {#1} { \fboxrule} }
+        {medium} { \__cellprops_generic_setter:nnn \exp_not:n {#1} { 2\fboxrule} }
+        {thick}  { \__cellprops_generic_setter:nnn \exp_not:n {#1} { 3\fboxrule} }
+    }{
+        \__cellprops_generic_setter:nnn \exp_not:n {#1} {#2}
+    }
+}
+
+\cs_new_nopar:Nn \__cellprops_border_setter:nn {
+    \__cellprops_border_setter_aux:nw
+        {#1}#2~{\q_no_value}~{\q_no_value}~\q_stop
+}
+\cs_new:Npn \__cellprops_border_setter_aux:nw #1#2~#3~#4~#5\q_stop {
+    \quark_if_no_value:nTF {#4} {
+        \__cellprops_border_setter_isstyle:nTF {#2} {
+            \__cellprops_delegate_setter:nn {#1-width} {thin}
+            \__cellprops_delegate_setter:nn {#1-style} {#2}
+            \quark_if_no_value:nTF {#3} {
+                \__cellprops_delegate_setter:nn {#1-color} {inherit}
+            }{
+                \__cellprops_delegate_setter:nn {#1-color} {#3}
+            }
+        }{
+            \quark_if_no_value:nTF {#3} {
+                %% TODO: Error, one no-style value, ambiguous
+            }{
+                \__cellprops_border_setter_isstyle:nTF {#3} {
+                    \__cellprops_delegate_setter:nn {#1-width} {#2}
+                    \__cellprops_delegate_setter:nn {#1-style} {#3}
+                    \__cellprops_delegate_setter:nn {#1-color} {inherit}
+                }{
+                    \__cellprops_delegate_setter:nn {#1-width} {#2}
+                    \__cellprops_delegate_setter:nn {#1-style} {none}
+                    \__cellprops_delegate_setter:nn {#1-color} {#3}
+                }
+            }
+        }
+    }{
+        \__cellprops_delegate_setter:nn {#1-width} {#2}
+        \__cellprops_delegate_setter:nn {#1-style} {#3}
+        \__cellprops_delegate_setter:nn {#1-color} {#4}
+    }
+}
+\cs_new:Npn \__cellprops_border_setter_isstyle:nTF #1 {
+    \str_case:nnTF {#1} {
+        {none}{} {hidden}{} {dotted}{} {dashed}{} {solid}{}
+        {double}{} {groove}{} {ridge}{} {inset}{} {outset}{}
+    }
+}
+
 \__cellprops_define_properties:nn {
     \__cellprops_generic_setter:nnn \exp_not:n
 }{
-    padding-top,
-    padding-right,
-    padding-bottom,
-    padding-left,
     min-height,
     min-depth,
     min-width,
 }
 
-\__cellprops_define_properties:nn {
-    \__cellprops_fourdim_setter:nn
-}{
-    padding
-}
+\__cellprops_define_fourval_properties:nnnnnn
+    { \__cellprops_generic_setter:nnn \exp_not:n }
+    {padding}
+    {padding-top}{padding-right}{padding-bottom}{padding-left}
 
 \__cellprops_define_properties:nn {
     \__cellprops_generic_setter:nnn \tl_to_str:n
@@ -169,6 +227,30 @@
     background-color,
 }
 
+\__cellprops_define_fourval_properties:nnnnnn
+    { \__cellprops_linewidth_setter:nn }
+    {border-width}
+    {border-top-width}{border-right-width}
+    {border-bottom-width}{border-left-width}
+
+\__cellprops_define_fourval_properties:nnnnnn
+    { \__cellprops_generic_setter:nnn \tl_to_str:n }
+    {border-style}
+    {border-top-style}{border-right-style}
+    {border-bottom-style}{border-left-style}
+
+\__cellprops_define_fourval_properties:nnnnnn
+    { \__cellprops_color_setter:nn }
+    {border-color}
+    {border-top-color}{border-right-color}
+    {border-bottom-color}{border-left-color}
+
+\__cellprops_define_properties:nn {
+    \__cellprops_border_setter:nn
+}{
+    border, border-top, border-right, border-bottom, border-left
+}
+
 \NewDocumentCommand \cellprops { m } {
     \__cellprops_parse_css:n {#1}
 }
@@ -279,17 +361,21 @@
 }
 
 \dim_new:N \l__cellprops_colsep_dim
+\dim_new:N \l__cellprops_strut_ht_dim
+\dim_new:N \l__cellprops_strut_dp_dim
+
 \ExplSyntaxOff
 \cellprops{
     td {
         padding: 0pt \csname l__cellprops_colsep_dim\endcsname;
-        min-height: 0pt;
-        min-depth: 0pt;
+        min-height: \csname l__cellprops_strut_ht_dim\endcsname;
+        min-depth: \csname l__cellprops_strut_dp_dim\endcsname;
         min-width: 0pt;
         text-align: left;
         math-mode: auto;
         color: inherit;
         background-color: transparent;
+        border: thin none inherit;
     }
     tr {
         color: inherit;
@@ -313,6 +399,7 @@
 \skip_new:N \l__cellprops_right_skip
 \dim_new:N \g__cellprops_ht_dim
 \dim_new:N \g__cellprops_dp_dim
+\tl_new:N \g__cellprops_borders_tl
 
 \tl_new:N \l__cellprops_restore_tl
 
@@ -336,9 +423,12 @@
             { \dim_use:N \g__cellprops_ht_dim }
         \exp_not:n { \dim_gset:Nn \g__cellprops_dp_dim }
             { \dim_use:N \g__cellprops_dp_dim }
+        \exp_not:n { \tl_gset:Nn \g__cellprops_borders_tl }
+            { \exp_not:V \g__cellprops_borders_tl }
     }
     \int_gzero:N \g__cellprops_row_int
     \bool_gset_false:N \g__cellprops_inrow_bool
+    \tl_gclear:N \g__cellprops_borders_tl
     \cs_set_eq:NN \__cellprops_orig_tab at readpreamble:n \tab at readpreamble
     \cs_set_eq:NN \tab at readpreamble \__cellprops_readpreamble:n
     \dim_set_eq:NN \l__cellprops_colsep_dim \col at sep
@@ -357,6 +447,9 @@
     \tl_set_eq:NN \l__cellprops_color_tl \g_tmpa_tl
     \tl_set_eq:NN \l__cellprops_bgcolor_tl \g_tmpb_tl
     \__cellprops_recall_properties:n {tr}
+    \dim_set:Nn \l__cellprops_strut_ht_dim { \box_ht:N \@arstrutbox }
+    \dim_set:Nn \l__cellprops_strut_dp_dim { \box_dp:N \@arstrutbox }
+    \box_clear:N \@arstrutbox
 }
 
 \cs_set_nopar:Nn \__cellprops_array_startcontent: {
@@ -400,12 +493,13 @@
     }
 }
 
-\cs_set_protected_nopar:Nn \__cellprops_update_colors: {
+\cs_new_protected_nopar:Nn \__cellprops_update_colors: {
     \__cellprops_update_color:Nn \l__cellprops_color_tl {color}
     \__cellprops_update_color:Nn \l__cellprops_bgcolor_tl {background-color}
 }
 
-\cs_set_nopar:Nn \__cellprops_end_array:n {
+\cs_new_nopar:Nn \__cellprops_end_array:n {
+    \tl_if_empty:NF \g__cellprops_borders_tl { \\ }
     \crcr
     \hlx{s[\l__cellprops_tablepadding_bottom_dim]}
     #1
@@ -416,6 +510,8 @@
 \cs_set_nopar:Npn \endarray {
     \__cellprops_end_array:n { \__cellprops_orig_endarray: }
 }
+\cs_set_eq:NN \endtabular \endarray
+\cs_set_eq:cN {endtabular*} \endarray
 
 \cs_set_eq:NN \__cellprops_orig_endLT: \endlongtable
 \cs_set_nopar:Npn \endlongtable {
@@ -422,7 +518,7 @@
     \__cellprops_end_array:n { \__cellprops_orig_endLT: }
 }
 
-\cs_set_protected_nopar:Nn \__cellprops_startrow: {
+\cs_new_protected_nopar:Nn \__cellprops_startrow: {
     \bool_if:NF \g__cellprops_inrow_bool {
         \bool_gset_true:N \g__cellprops_inrow_bool
         \int_gincr:N \g__cellprops_row_int
@@ -432,16 +528,34 @@
     }
 }
 
-\cs_set_protected_nopar:Npn \__cellprops_endrow: {
+\cs_new_protected_nopar:Nn \__cellprops_endrow: {
     \bool_if:NT \g__cellprops_inrow_bool {
         \bool_gset_false:N \g__cellprops_inrow_bool
-        \__cellprops_fix_valign_end:
     }
 }
 
-\cs_set_eq:NN \__cellprops_orig_tab at arraycr:n \tab at arraycr
-\cs_set_nopar:Npn \tab at arraycr { \__cellprops_endrow:\__cellprops_orig_tab at arraycr:n }
+\cs_new_protected_nopar:Nn \__cellprops_cr:n {
+    \__cellprops_endrow:
+    \tl_if_empty:NF \g__cellprops_borders_tl {
+        \cr
+        \noalign{\nobreak}
+        \tl_use:N \g__cellprops_borders_tl
+        \tl_gclear:N \g__cellprops_borders_tl
+    }
+    \cr
+    \__cellprops_fix_valign_end:n {#1}
+    \use_none:n
+}
 
+\cs_set_protected_nopar:Npn \tab at tabcr #1#2 { \__cellprops_cr:n {#2} }
+\cs_set_protected_nopar:Npn \@xargarraycr #1 { \__cellprops_cr:n {#1} }
+\cs_set_protected_nopar:Npn \@yargarraycr #1 { \__cellprops_cr:n {#1} }
+\tl_if_exist:NT \LT at echunk {
+    \tl_put_left:Nn \LT at echunk {
+        \tl_if_empty:NF \g__cellprops_borders_tl { \\ }
+    }
+}
+
 \cs_set_eq:NN \__cellprops_orig_multicolumn:w \multicolumn
 \cs_set:Npn \multicolumn#1#2#3 {
     \__cellprops_orig_multicolumn:w {#1}{#2}{
@@ -450,15 +564,15 @@
     }
 }
 
-\cs_new_protected_nopar:Nn \__cellprops_fix_valign_end: {
-    \exp_args:NV \tl_if_eq:nnTF \tab at hlstate {b} {
-        \dim_gadd:Nn \tab at endheight {
-            \g__cellprops_dp_dim - \box_dp:N \@arstrutbox
-        }
-    }{
-        \int_compare:nNnT \g__cellprops_row_int = \c_one {
-            \dim_gadd:Nn \tab at endheight {
-                \g__cellprops_ht_dim - \box_ht:N \@arstrutbox
+\cs_new_nopar:Nn \__cellprops_fix_valign_end:n {
+    \noalign{
+        \dim_set:Nn \l_tmpa_dim {#1}
+        \skip_vertical:n {\l_tmpa_dim}
+        \exp_args:NV \tl_if_eq:nnTF \tab at hlstate {b} {
+            \dim_gadd:Nn \tab at endheight { \g__cellprops_dp_dim + \l_tmpa_dim }
+        }{
+            \int_compare:nNnT \g__cellprops_row_int = \c_one {
+                \dim_gadd:Nn \tab at endheight { \g__cellprops_ht_dim }
             }
         }
     }
@@ -616,22 +730,124 @@
     \tl_use:N \l__cellprops_color_tl
 }
 
+\cs_new_protected_nopar:Nn \__cellprops_make_solid_hborder:nnn {
+    \group_begin:
+        \hbox_set_to_wd:Nnn \l_tmpa_box {1pt} {
+            \hss
+            \hbox:n {
+                #3 % install color
+                \vrule height~\dim_eval:n{#1+#2}
+                    ~depth~-\dim_eval:n{#2}
+                    ~width~3pt
+            }
+            \hss
+        }
+        \box_set_ht:Nn \l_tmpa_box { \c_zero_dim }
+        \box_set_dp:Nn \l_tmpa_box { \c_zero_dim }
+        \kern 1pt
+        \box_use:N \l_tmpa_box
+        \xleaders
+            \box_use:N \l_tmpa_box
+            \skip_horizontal:n {-4pt~plus~1fil}
+        \box_use:N \l_tmpa_box
+        \kern 1pt
+        \skip_horizontal:n {0pt~plus~-1fil}
+    \group_end:
+}
+\cs_new_protected_nopar:Nn \__cellprops_make_solid_vborder:nnn {
+    \group_begin:
+        \hbox_set_to_wd:Nnn \l_tmpa_box {0pt} {
+            \hbox:n {
+                #3 % install color
+                \vrule height~\dim_eval:n{#2}~width~\dim_eval:n{#1}
+            }
+            \hss
+        }
+        \box_set_ht:Nn \l_tmpa_box { \c_zero_dim }
+        \box_set_dp:Nn \l_tmpa_box { \c_zero_dim }
+        \box_use:N \l_tmpa_box
+    \group_end:
+}
+\clist_map_inline:nn {
+    dotted, dashed, solid, double,
+    groove, ridge, inset, outset
+}{
+    \cs_set_eq:cN {__cellprops_make_#1_hborder:nnn} \__cellprops_make_solid_hborder:nnn
+    \cs_set_eq:cN {__cellprops_make_#1_vborder:nnn} \__cellprops_make_solid_vborder:nnn
+}
+
+\dim_new:N \l__cellprops_border_width_dim
+\str_new:N \l__cellprops_border_style_str
+\tl_new:N \l__cellprops_border_color_tl
+\cs_new_protected_nopar:Nn \__cellprops_get_border_info:n {
+    \dim_set:Nn \l__cellprops_border_width_dim {\__cellprops_get_property:n {border-#1-width}}
+    \__cellprops_get_property:nN {border-#1-style} \l_tmpa_tl
+    \exp_args:NNV \str_set:Nn \l__cellprops_border_style_str \l_tmpa_tl
+    \tl_clear:N \l__cellprops_border_color_tl
+    \cs_if_exist:cTF {__cellprops_make_\l__cellprops_border_style_str _hborder:nnn} {
+        \__cellprops_update_color:Nn \l__cellprops_border_color_tl {border-#1-color}
+    }{
+        \dim_zero:N \l__cellprops_border_width_dim
+    }
+}
+
+\cs_new_protected_nopar:Npn \__cellprops_make_hborder:nnnn #1 {
+    \use:c { __cellprops_make_#1_hborder:nnn }
+}
+\cs_new_protected_nopar:Npn \__cellprops_make_vborder:nnnn #1 {
+    \use:c { __cellprops_make_#1_vborder:nnn }
+}
+
 \cs_new_protected_nopar:Nn \__cellprops_end_raw_cell: {
     % Here \l__cellprops_cell_box must contain the contents of the cell
     %
-    % Handle vpadding and min-height/depth
+    % Prepare the borders token list
+    \int_compare:nNnT \g__cellprops_col_int = 1 {
+        \tl_gclear:N \g__cellprops_borders_tl
+    }
+    \tl_gput_right:Nx \g__cellprops_borders_tl {
+        \tl_if_empty:NF \g__cellprops_borders_tl { \exp_not:n {&} }
+        \exp_not:n { \omit \kern \c_zero_dim }
+    }
+    % Handle padding-top, min-height and border-top
+    \__cellprops_get_border_info:n {top}
     \box_set_ht:Nn \l__cellprops_cell_box {
         \dim_max:nn
             {\box_ht:N \l__cellprops_cell_box}
             {\__cellprops_get_property:n {min-height}}
         + (\__cellprops_get_property:n {padding-top})
+        + \l__cellprops_border_width_dim
     }
+    \dim_compare:nNnT \l__cellprops_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g__cellprops_borders_tl {
+            \exp_not:N \__cellprops_make_hborder:nnnn
+                { \exp_not:V \l__cellprops_border_style_str }
+                { \dim_use:N \l__cellprops_border_width_dim }
+                {
+                    \exp_not:n { \g__cellprops_dp_dim + \g__cellprops_ht_dim - }
+                    \dim_use:N \l__cellprops_border_width_dim
+                }
+                { \exp_not:V \l__cellprops_border_color_tl }
+        }
+    }
+    % Handle padding-bottom, min-depth and border-bottom
+    \__cellprops_get_border_info:n {bottom}
     \box_set_dp:Nn \l__cellprops_cell_box {
         \dim_max:nn
             {\box_dp:N \l__cellprops_cell_box}
             {\__cellprops_get_property:n {min-depth}}
         + (\__cellprops_get_property:n {padding-bottom})
+        + \l__cellprops_border_width_dim
     }
+    \dim_compare:nNnT \l__cellprops_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g__cellprops_borders_tl {
+            \exp_not:N \__cellprops_make_hborder:nnnn
+                { \exp_not:V \l__cellprops_border_style_str }
+                { \dim_use:N \l__cellprops_border_width_dim }
+                { \exp_not:n { 0pt } }
+                { \exp_not:V \l__cellprops_border_color_tl }
+        }
+    }
     % To fix vertical alignment later
     \dim_gset:Nn \g__cellprops_ht_dim {
         \dim_max:nn
@@ -653,10 +869,42 @@
     \skip_add:Nn \l_tmpa_skip {
         0pt plus 1fil
     }
+    % padding-left and border-left
+    \__cellprops_get_border_info:n {left}
     \skip_set:Nn \l__cellprops_left_skip
-        {\__cellprops_get_property:n {padding-left}}
+        {\__cellprops_get_property:n {padding-left} + \l__cellprops_border_width_dim}
+    \dim_compare:nNnT \l__cellprops_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g__cellprops_borders_tl {
+            \exp_not:N \__cellprops_make_vborder:nnnn
+                { \exp_not:V \l__cellprops_border_style_str }
+                { \dim_use:N \l__cellprops_border_width_dim }
+                { \exp_not:n { \g__cellprops_dp_dim + \g__cellprops_ht_dim } }
+                { \exp_not:V \l__cellprops_border_color_tl }
+        }
+    }
+    \tl_gput_right:Nx \g__cellprops_borders_tl {
+        \exp_not:n {
+            \skip_horizontal:n {0pt~plus~1fil}
+            \kern \c_zero_dim
+        }
+    }
+    \__cellprops_get_border_info:n {right}
     \skip_set:Nn \l__cellprops_right_skip
-        {\__cellprops_get_property:n {padding-right}}
+        {\__cellprops_get_property:n {padding-right} + \l__cellprops_border_width_dim}
+    \dim_compare:nNnT \l__cellprops_border_width_dim > \c_zero_dim {
+        \tl_gput_right:Nx \g__cellprops_borders_tl {
+            \exp_not:N \skip_horizontal:n
+                { - \dim_use:N \l__cellprops_border_width_dim }
+            \exp_not:N \__cellprops_make_vborder:nnnn
+                { \exp_not:V \l__cellprops_border_style_str }
+                { \dim_use:N \l__cellprops_border_width_dim }
+                { \exp_not:n { \g__cellprops_dp_dim + \g__cellprops_ht_dim } }
+                { \exp_not:V \l__cellprops_border_color_tl }
+            \exp_not:N \skip_horizontal:n
+                { \dim_use:N \l__cellprops_border_width_dim }
+            \exp_not:n { \kern \c_zero_dim }
+        }
+    }
     \str_case_x:nnF {\__cellprops_get_property:n {text-align}} {
         { right } {
             \skip_add:Nn \l__cellprops_left_skip { \l_tmpa_skip }



More information about the tex-live-commits mailing list