summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/cellprops
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-02-03 03:00:54 +0000
committerNorbert Preining <norbert@preining.info>2021-02-03 03:00:54 +0000
commit9de8091bfb3391699d0b900932b91525a86d490e (patch)
treebeb932e2b0e5eb8dea7a1e68c6615ffd154b8d7c /macros/latex/contrib/cellprops
parente2e61931409be2a7142b4d0f4b59a275b7f59e2a (diff)
CTAN sync 202102030300
Diffstat (limited to 'macros/latex/contrib/cellprops')
-rw-r--r--macros/latex/contrib/cellprops/LICENSE4
-rw-r--r--macros/latex/contrib/cellprops/README.md2
-rw-r--r--macros/latex/contrib/cellprops/cellprops.dtx451
-rw-r--r--macros/latex/contrib/cellprops/cellprops.ins2
-rw-r--r--macros/latex/contrib/cellprops/cellprops.pdfbin564606 -> 573920 bytes
5 files changed, 368 insertions, 91 deletions
diff --git a/macros/latex/contrib/cellprops/LICENSE b/macros/latex/contrib/cellprops/LICENSE
index 19e0cc42ed..cb305a7a0b 100644
--- a/macros/latex/contrib/cellprops/LICENSE
+++ b/macros/latex/contrib/cellprops/LICENSE
@@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
cellprops
- Copyright (C) 2016-2020 Julien "_FrnchFrgg_" RIVAUD
+ Copyright (C) 2016-2021 Julien "_FrnchFrgg_" RIVAUD
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
- cellprops Copyright (C) 2016-2020 Julien "_FrnchFrgg_" RIVAUD
+ cellprops Copyright (C) 2016-2021 Julien "_FrnchFrgg_" RIVAUD
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
diff --git a/macros/latex/contrib/cellprops/README.md b/macros/latex/contrib/cellprops/README.md
index 5378701f8e..89ae3b3d1f 100644
--- a/macros/latex/contrib/cellprops/README.md
+++ b/macros/latex/contrib/cellprops/README.md
@@ -13,7 +13,7 @@ Look at the PDF documentation to see examples and detailed usage.
-Copyright (C) 2016-2020 Julien "_FrnchFrgg_" RIVAUD
+Copyright (C) 2016-2021 Julien "_FrnchFrgg_" RIVAUD
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/macros/latex/contrib/cellprops/cellprops.dtx b/macros/latex/contrib/cellprops/cellprops.dtx
index 86c1d8ef2c..264361e91e 100644
--- a/macros/latex/contrib/cellprops/cellprops.dtx
+++ b/macros/latex/contrib/cellprops/cellprops.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
% vim: tw=80 spl=en
%
-%% File: cellprops.dtx (C) Copyright 2016-2020 RIVAUD Julien
+%% File: cellprops.dtx (C) Copyright 2016-2021 RIVAUD Julien
%%
%% It may be distributed and/or modified under the conditions of the
%% General Public License (GPL), either version 3 of this
@@ -14,8 +14,8 @@
\RequirePackage{expl3}[2018/06/19]
\def\ExplFileName{cellprops}
\def\ExplFileDescription{CSS-like cell and table properties}
-\def\ExplFileDate{2020/06/07}
-\def\ExplFileVersion{1.7a}
+\def\ExplFileDate{2021/01/30}
+\def\ExplFileVersion{2.0}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
@@ -66,13 +66,13 @@
%
% I recommend to add globally:
%\begin{verbatim}
-%\cellprops{ td { padding: 1ex; min-height: 0pt; min-depth: 0pt; } }
+% \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:
+% To produce the (arguably ugly):
% \[
% \cellprops{
% td {
@@ -102,6 +102,15 @@
% math-mode: text;
% text-align: left;
% }
+% tr:nth-child(6) td:nth-child(1) {
+% vertical-align: top; % see remark in usage guide
+% }
+% tr:nth-child(6) td:nth-child(2) {
+% vertical-align: middle;
+% }
+% tr:nth-child(6) td:nth-child(3) {
+% vertical-align: bottom; % see remark in usage guide
+% }
% }
% \begin{array}{nnnp{5em}}
% This is text & A_2 & A_3 & A_4 \\
@@ -109,6 +118,16 @@
% C1 & C_2 & X & Y \\
% D1 & D_2 & DX & v \\
% & F & \int_a^b f(t) dt & v \\
+% \fbox{Top} & \fbox{Middle} & \fbox{Bottom} & \fbox{Baseline}%
+% \textcolor{red}{%
+% \kern -9cm\relax
+% \vrule height 0.1pt depth 0.1pt width 10cm
+% \kern -1cm\relax
+% }\textcolor{blue}{%
+% \kern -9cm\relax
+% \vrule height 0.52ex depth -0.48ex width 10cm
+% \kern -1cm\relax
+% } \\
% \end{array}
% \]
% you can use:
@@ -142,13 +161,32 @@
% math-mode: text;
% text-align: left;
% }
+% tr:nth-child(6) td:nth-child(1) {
+% vertical-align: top; % see remark in usage guide
+% }
+% tr:nth-child(6) td:nth-child(2) {
+% vertical-align: middle;
+% }
+% tr:nth-child(6) td:nth-child(3) {
+% vertical-align: bottom; % see remark in usage guide
+% }
% }
-% \begin{array}{nnnn}
+% \begin{array}{nnnp{5em}}
% 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 \\
+% & F & \int_a^b f(t) dt & v \\
+% \fbox{Top} & \fbox{Middle} & \fbox{Bottom} & \fbox{Baseline}%
+% \textcolor{red}{%
+% \kern -9cm\relax
+% \vrule height 0.1pt depth 0.1pt width 10cm
+% \kern -1cm\relax
+% }\textcolor{blue}{%
+% \kern -9cm\relax
+% \vrule height 0.52ex depth -0.48ex width 10cm
+% \kern -1cm\relax
+% } \\
% \end{array}
% \]
%\end{verbatim}
@@ -200,7 +238,7 @@
%
% This table has been produced by:
%\begin{verbatim}
-%\cellprops{
+% \cellprops{
% td { border: thin solid black; }
% tr:nth-child(-n+3) { background-color: black!10; }
% tr:nth-child(n+8) { background-color: blue!10; }
@@ -210,12 +248,12 @@
% tr:nth-child(4n+3) td:nth-child(4) {
% border: thick solid red;
% }
-%}
-%\begin{longtable}{nnnn}
+% }
+% \begin{longtable}{nnnn}
% aaaaa & baaaa & caaaaa & dbbbb \\
% ...
% aaaaa & baaaa & caaaaa & dbbbb \\
-%\end{longtable}
+% \end{longtable}
%\end{verbatim}
%
% \subsection{Usage guide}
@@ -229,15 +267,16 @@
% ]
% \item[usage] "'\cellprops{'" [ \<selectors> "'{'" \<properties> "'}'" ]* "'}'"
% \item[selectors] \<selector> ["," \<selectors> ]
-% \item[selector] [\<environment> "' '"] \<element1>
-% \item[element1]
-% "'table'" \OR
-% "'tr'"[\<pseudo-class>] ["' '" \<element2>] \OR
-% \<element2>
-% \item[element2] "'td'"[\<pseudo-class>] ["' '" \<parbox>] \OR \<parbox>
-% \item[parbox] "'p'"
-% \item[pseudo-class] "':nth-child('"\<nth>"')"
-% \item[nth] \<number> \OR "'odd'" \OR "'even'" \OR \<number>"'n+'"\<number>
+% \item[selector] [\<table> "' '"] [\<tr> "' '"] [\<td> "' '"] [\<parbox>]
+% \item[table] "'table'" ["'.'" \<class>]* ["':where(.'"\<class>"')'"]*
+% \OR "':where('"\<table>"')'"
+% \item[tr] "'tr'" [\<pseudoclass>]* \OR "':where('"\<tr>"')'"
+% \item[td] "'td'" [\<pseudoclass>]* \OR "':where('"\<td>"')'"
+% \item[parbox] "'p'" \OR "':where('"\<p>"')'"
+% \item[pseudoclass] "':where('"[\<pseudoclass>]*"')'" \OR "':nth-child('"\<nth>"')"
+% \item[nth]
+% "'odd'" \OR "'even'" \OR \<number> \OR
+% \<number>"'n+'"\<number> \OR \<number>"'n-'"\<number>
% \item[properties] [ \<property> "';'" ]*
% \item[property]
% "'padding: '" ( \<dimension> ) \{1,4\} \OR \\
@@ -249,6 +288,7 @@
% "'min-depth: '" \<dimension> \OR \\
% "'min-width: '" \<dimension> \OR \\
% "'text-align: '" ( "'left'" \OR "'right'" \OR "'center'" ) \OR \\
+% "'vertical-align: '" ( "'top'" \OR "'middle'" \OR "'baseline'" \OR "'bottom'" ) \OR \\
% "'math-mode: '" ( "'text'" \OR "'math'" \OR "'auto'" ) \OR \\
% "'color: '" \<color> \OR \\
% "'background-color: '" ( \<color> \OR "'transparent'" ) \OR \\
@@ -323,6 +363,29 @@
% ":nth-child("$B$")" is supported, with arbitrary $A$~and~$B$, including
% nothing for~$A$ (standing for~$A = 1$) or just a minus sign (standing
% for~$A = -1$).
+% \item "vertical-align" values "baseline" and "middle" are following the CSS
+% specification. On the other hand, "top" (resp.~"bottom") align the top
+% (resp.~bottom) of the cell with the row baseline which gives a
+% different result than CSS if there is mixed alignment in the row.
+% The common case where all cells have "vertical-align: top" or
+% "vertical-align: bottom" behaves as expected from the CSS
+% specification.
+%
+% As fas as I can tell, obeying CSS in all cases would require
+% typesetting each row in two passes.
+% \item Class names are matched against the classes defined with
+% \cs{cellpropsclass}, which takes a space-separated list of classes. By
+% default, \cs{cellpropsclass} also add as a class the name of the
+% environment that created the tabular-like structure (that is, "tabular"
+% or "array" or "matrix" or similar). If you do not want that behavior,
+% you can use \cs{cellpropsclass*}. The class list is
+% redefined locally, and \pkg{cellprops} initially calls
+% "\cellpropsclass{}".
+% \item The ":where()" pseudo-class is the same as in CSS selectors level 4,
+% except that it does not accept spaces nor commas. Its only effect is to
+% neutering the specificity of the selectors within while still keeping
+% their matching conditions. This is mainly useful to write default yet
+% specific rules whose specificity would otherwise dwarf simple rules.
% \end{itemize}
%
% \subsection{Compatibility}
@@ -465,20 +528,16 @@
\seq_map_inline:Nn \l_tmpa_seq {
\tl_if_empty:nF {##1} {
\exp_args:NNV \seq_set_split:Nnn \l_tmpb_seq \c_colon_str {##1}
- \int_compare:nNnTF {\seq_count:N \l_tmpb_seq} = { 2 } {
+ \int_compare:nNnT {\seq_count:N \l_tmpb_seq} = { 2 } {
\seq_get_left:NN \l_tmpb_seq \l_tmpa_tl
\exp_args:NNV \str_set:Nn \l_tmpa_str \l_tmpa_tl
\seq_get_right:NN \l_tmpb_seq \l_tmpa_tl
- \cs_if_exist:cTF { _@@_property_type_\l_tmpa_str :nn } {
+ \cs_if_exist:cT { _@@_property_type_\l_tmpa_str :nn } {
\tl_put_right:Nx #1 {
\exp_args:NVV \@@_delegate_setter:nn
\l_tmpa_str \l_tmpa_tl
}
- }{
- % TODO: ERROR-no property with that name
}
- }{
- % TODO: ERROR-too many : or none at all
}
}
}
@@ -615,7 +674,7 @@
}
}{
\quark_if_no_value:nTF {#3} {
- %% TODO: Error, one no-style value, ambiguous
+ %% One no-style value, ambiguous. Ignore the property
}{
\@@_border_setter_isstyle:nTF {#3} {
\@@_delegate_setter:nn {#1-width} {#2}
@@ -676,6 +735,7 @@
\@@_generic_setter:nnn \tl_to_str:n
}{
text-align,
+ vertical-align,
math-mode,
}
% \end{macrocode}
@@ -748,6 +808,17 @@
\cs_new_protected:Nn \@@_parse_css:n {
\@@_parse_css:w #1 \q_mark {\q_nil} \q_stop
+% \end{macrocode}
+%
+% Ensure the already seen specificities is in order without duplicates.
+%
+% \begin{macrocode}
+ \seq_remove_duplicates:N \l_@@_specificities_seq
+ \seq_sort:Nn \l_@@_specificities_seq {
+ \int_compare:nNnTF { ##1 } > { ##2 }
+ { \sort_return_swapped: }
+ { \sort_return_same: }
+ }
}
% \end{macrocode}
%
@@ -761,7 +832,7 @@
\quark_if_nil:nF {#2} {
\@@_parse_properties:Nn \l_@@_parse_properties_tl {#2}
\clist_map_inline:nn {#1} {
- \@@_parse_css_addprops:n {##1}
+ \tl_if_empty:nF {##1} { \@@_parse_css_addprops:n {##1} }
}
\@@_parse_css:w #3 \q_stop
}
@@ -777,16 +848,19 @@
\tl_new:N \l_@@_current_selector_check_tl
\cs_new_protected:Nn \@@_parse_css_addprops:n {
\@@_parse_selector:n {#1}
- \tl_set:Nx \l_tmpa_tl { l_@@_property_group_\l_@@_current_selector_tl _tl }
- \tl_if_exist:cF { \l_tmpa_tl } { \tl_clear:c { \l_tmpa_tl } }
- \tl_if_empty:NTF \l_@@_current_selector_check_tl {
- \tl_put_right:cV { \l_tmpa_tl } \l_@@_parse_properties_tl
- }{
- \tl_put_right:cx { \l_tmpa_tl } {
- \exp_not:N \bool_if:nT {
- \exp_not:V \l_@@_current_selector_check_tl
- }{
- \exp_not:V \l_@@_parse_properties_tl
+ \tl_if_empty:NF \l_@@_current_selector_tl {
+ \tl_set:Nx \l_tmpa_tl
+ { l_@@_property_group_\l_@@_current_selector_tl _tl }
+ \tl_if_exist:cF { \l_tmpa_tl } { \tl_clear:c { \l_tmpa_tl } }
+ \tl_if_empty:NTF \l_@@_current_selector_check_tl {
+ \tl_put_right:cV { \l_tmpa_tl } \l_@@_parse_properties_tl
+ }{
+ \tl_put_right:cx { \l_tmpa_tl } {
+ \exp_not:N \bool_if:nT {
+ \exp_not:V \l_@@_current_selector_check_tl
+ }{
+ \exp_not:V \l_@@_parse_properties_tl
+ }
}
}
}
@@ -822,12 +896,17 @@
% \end{macrocode}
%
% Now that we can sanitize pseudo-classes, parsing the selector is safe. The
-% only construct to protect is currently ":nth-child()".
+% constructs to protect are ":nth-child()" and ":where()" since other supported
+% pseudo-classes have no argument.
%
% \begin{macrocode}
\seq_new:N \l_@@_current_selector_seq
\seq_new:N \l_@@_pseudoclasses_seq
\tl_new:N \l_@@_current_element_tl
+\tl_new:N \l_@@_current_tableclass_tl
+\int_new:N \l_@@_current_level_int
+\int_new:N \l_@@_current_specificity_int
+\seq_new:N \l_@@_specificities_seq
\cs_new_protected:Nn \@@_parse_selector:n {
\tl_set:Nx \l_@@_current_selector_tl { \tl_to_str:n {#1} }
% \end{macrocode}
@@ -839,23 +918,141 @@
\exp_args:NNV \tl_replace_all:Nnn
\l_@@_current_selector_tl \c_colon_str {:}
\@@_parse_selector_sanitize:n {nth-child}
+ \@@_parse_selector_sanitize:n {where}
\seq_set_split:NnV \l_@@_current_selector_seq {~} \l_@@_current_selector_tl
\tl_clear:N \l_@@_current_selector_tl
\tl_clear:N \l_@@_current_selector_check_tl
+ \tl_clear:N \l_@@_current_tableclass_tl
+ \int_set:Nn \l_@@_current_level_int {-1}
+ \int_zero:N \l_@@_current_specificity_int
\seq_map_inline:Nn \l_@@_current_selector_seq {
+ \tl_clear:N \l_@@_current_element_tl
+ \@@_parse_simple_selector:n {##1}
+ }
+% \end{macrocode}
+%
+% Remember the current selector as "<last element>~<specificity>".
+%
+% \begin{macrocode}
+ \tl_if_empty:NF \l_@@_current_element_tl {
+ \tl_if_empty:NF \l_@@_current_tableclass_tl {
+ \tl_set:Nx \l_@@_current_tableclass_tl {
+ l_@@_active_classes_\l_@@_current_tableclass_tl _bool
+ }
+ \bool_if_exist:cF { \l_@@_current_tableclass_tl } {
+ \bool_new:c { \l_@@_current_tableclass_tl }
+ }
+ \@@_add_check:x {
+ \exp_not:n { \bool_if_p:N }
+ {
+ \exp_not:c { \l_@@_current_tableclass_tl }
+ }
+ }
+ }
+ \tl_set:Nx \l_@@_current_selector_tl {
+ \exp_not:V \l_@@_current_element_tl
+ \exp_not:n {~}
+ \int_use:N \l_@@_current_specificity_int
+ }
+ \seq_put_right:Nx \l_@@_specificities_seq {
+ \int_use:N \l_@@_current_specificity_int
+ }
+ }
+}
+
+\tl_new:N \l_@@_maybe_element_tl
+
+\cs_new_protected:Nn \@@_parse_simple_selector:n {
+% \end{macrocode}
+%
+% First we replace "." with ":." so that class selectors can be handled with
+% the same code as pseudo-classes. Then we split the current selector item on
+% ":" to get the base element and the pseudo-classes.
+%
+% \begin{macrocode}
+ \tl_set:Nn \l_tmpa_tl { #1 }
+ \tl_replace_all:Nnn \l_tmpa_tl {.} {:.}
+ \seq_set_split:NnV \l_@@_pseudoclasses_seq {:} \l_tmpa_tl
+ \seq_pop_left:NN \l_@@_pseudoclasses_seq \l_@@_maybe_element_tl
+% \end{macrocode}
+%
+% Known type selectors increase the specificity by one.
+%
+% \begin{macrocode}
+ \str_case:VnTF \l_@@_maybe_element_tl {
+ { table } { \int_set:Nn \l_tmpa_int { 1 } }
+ { tr } { \int_set:Nn \l_tmpa_int { 2 } }
+ { td } { \int_set:Nn \l_tmpa_int { 3 } }
+ { p } { \int_set:Nn \l_tmpa_int { 4 } }
+ }{
+ \int_add:Nn \l_@@_current_specificity_int { 1 }
+ }{
+% \end{macrocode}
+%
+% An empty type selector is accepted to account for ":where()" pseudo-classes.
+% They will be handled in the loop below, but of course there should be a type
+% selector eventually. Map that case to a big positive next level so that we can
+% detect that and keep the current level as-is.
+%
+% Unknown type selectors are mapped to big negative levels
+% so that the descendant check will refuse them, unless we are at the very
+% first type selector in which case we map the deprecated environment
+% selector to a class selector.
+%
+% \begin{macrocode}
+ \tl_if_empty:NTF \l_@@_maybe_element_tl {
+ \int_set:Nn \l_tmpa_int { 10 }
+ }{
+ \int_compare:nNnTF \l_@@_current_level_int = { -1 } {
+ \tl_set_eq:NN
+ \l_@@_current_tableclass_tl
+ \l_@@_maybe_element_tl
+ \tl_set:Nn \l_@@_maybe_element_tl { table }
+ \int_set:Nn \l_tmpa_int { 1 }
+ \int_add:Nn \l_@@_current_specificity_int { 11 }
+ }{
+ \int_set:Nn \l_tmpa_int { -10 }
+ }
+ }
+ }
+% \end{macrocode}
+%
+% If no type selector has been found yet, record the one we may have found
+% now. Else, refuse to have two in the same selector.
+%
+% \begin{macrocode}
+ \tl_if_empty:NTF \l_@@_current_element_tl {
+ \tl_set_eq:NN \l_@@_current_element_tl \l_@@_maybe_element_tl
+ }{
+ \tl_if_empty:NF \l_@@_maybe_element_tl {
+ \int_set:Nn \l_tmpa_int { -10 }
+ }
+ }
% \end{macrocode}
%
-% Split the current selector item on ":" to get the base element and the
-% pseudo-classes.
+% If the detected element is a descendent of the previous one, the selector
+% can match; count the element selector specificity and parse its
+% pseudo-classes. If not, the whole selector cannot match and we discard it
+% early.
%
% \begin{macrocode}
- \seq_set_split:Nnn \l_@@_pseudoclasses_seq {:} {##1}
- \seq_pop_left:NN \l_@@_pseudoclasses_seq \l_@@_current_element_tl
- \tl_put_right:Nn \l_@@_current_selector_tl {~}
- \tl_put_right:NV \l_@@_current_selector_tl \l_@@_current_element_tl
+ \int_compare:nNnTF \l_tmpa_int > \l_@@_current_level_int {
+ \int_compare:nNnT \l_tmpa_int < 10 {
+ \int_set_eq:NN \l_@@_current_level_int \l_tmpa_int
+ }
\seq_map_inline:Nn \l_@@_pseudoclasses_seq {
- \@@_parse_pseudoclass:w ####1{}\q_stop
+ \@@_parse_pseudoclass:w ##1{}\q_stop
}
+ }{
+ \tl_clear:N \l_@@_current_element_tl
+ }
+% \end{macrocode}
+%
+% At the end of the selector parsing, the current element should not be empty.
+%
+% \begin{macrocode}
+ \tl_if_empty:NT \l_@@_current_element_tl {
+ \seq_map_break:
}
}
% \end{macrocode}
@@ -864,11 +1061,25 @@
% brace (if any), and the second argument is the braced content (if any).
% The third argument gobbles any trailing garbage.
%
+% If the pseudo-class starts with a "." this is a class selector. Else, this
+% is an unknown pseudo-class and we reject the complete selector.
+%
% \begin{macrocode}
\NewDocumentCommand \@@_parse_pseudoclass:w { lmu{\q_stop} } {
- \exp_args:Nx \str_case:nn { #1 } {
+ \str_case:nnF { #1 } {
{first-child} { \@@_parse_selector_nth:n {1} }
- {nth-child} { \@@_parse_selector_nth:n {#2} }
+ {nth-child} { \@@_parse_selector_nth:n {#2} }
+ {where} { \@@_parse_where:n {#2} }
+ }{
+ \str_if_eq:eeTF { \str_head:n { #1 } } {.} {
+ \tl_set:Nx \l_@@_current_tableclass_tl {
+ \str_tail:n { #1 }
+ }
+ \int_add:Nn \l_@@_current_specificity_int { 10 }
+ }{
+ \tl_clear:N \l_@@_current_element_tl
+ \seq_map_break:n { \seq_map_break: }
+ }
}
}
@@ -878,11 +1089,10 @@
\cs_new_protected:Nn \@@_parse_selector_nth:n {
% \end{macrocode}
%
-% Put something in the selector token list, for specificity ordering
-% of declarations.
+% Count the pseudo-class in the specificity.
%
% \begin{macrocode}
- \tl_put_right:Nn \l_@@_current_selector_tl { :nth-child }
+ \int_add:Nn \l_@@_current_specificity_int { 10 }
% \end{macrocode}
%
% Now parse the nth-child argument:
@@ -920,7 +1130,7 @@
% At last, generate the condition code.
%
% \begin{macrocode}
- \exp_args:NV \str_case:nn \l_@@_current_element_tl {
+ \str_case:Vn \l_@@_current_element_tl {
{tr} { \@@_generate_check_nth:n {\g_@@_row_int} }
{td} { \@@_generate_check_nth:n {\g_@@_col_int} }
}
@@ -928,9 +1138,11 @@
\cs_new_protected_nopar:Nn \@@_generate_check_nth:n {
\int_compare:nNnTF \l_@@_nth_coeff_int = { 0 } {
- \tl_set:Nx \l_tmpa_tl {
+ \@@_add_check:x {
\exp_not:n { \int_compare_p:nNn #1 = }
- \exp_not:V \l_@@_nth_offset_int
+ {
+ \exp_not:V \l_@@_nth_offset_int
+ }
}
}{
\tl_set:Nx \l_tmpb_tl {
@@ -941,7 +1153,7 @@
\exp_not:V \l_@@_nth_coeff_int
}
}
- \tl_set:Nx \l_tmpa_tl {
+ \@@_add_check:x {
\exp_not:N \bool_lazy_and_p:nn {
\exp_not:n { \int_compare_p:nNn 0 = }
{
@@ -958,26 +1170,48 @@
}
}
}
+}
+
+\cs_new_protected:Nn \@@_parse_where:n {
+ \use:x {
+ \exp_not:n {
+ \@@_parse_simple_selector:n { #1 }
+ \int_set:Nn \l_@@_current_specificity_int
+ }
+ {
+ \int_use:N \l_@@_current_specificity_int
+ }
+ }
+}
+
+\cs_new_protected:Nn \@@_add_check:n {
\tl_if_empty:NTF \l_@@_current_selector_check_tl {
- \tl_set_eq:NN \l_@@_current_selector_check_tl \l_tmpa_tl
+ \tl_set:Nn \l_@@_current_selector_check_tl { #1 }
}{
\tl_set:Nx \l_@@_current_selector_check_tl {
\exp_not:N \bool_lazy_and_p:nn {
\exp_not:V \l_@@_current_selector_check_tl
}{
- \exp_not:V \l_tmpa_tl
+ \exp_not:n { #1 }
}
}
}
}
+\cs_generate_variant:Nn \@@_add_check:n {x}
-\cs_set_protected:Nn \@@_recall_properties:n {
- \tl_if_exist:cT { l_@@_property_group_~#1_tl } {
- \tl_use:c { l_@@_property_group_~#1_tl }
+\seq_new:N \l_@@_classes_seq
+\NewDocumentCommand \cellpropsclass { sm } {
+ \seq_set_split:Nnn \l_@@_classes_seq {~} { #2 }
+ \IfBooleanF {#1} {
+ \seq_put_right:Nn \l_@@_classes_seq { \@currenvir }
}
- \clist_map_inline:nn { \@currenvir } {
- \tl_if_exist:cT { l_@@_property_group_~##1~#1_tl } {
- \tl_use:c { l_@@_property_group_~##1~#1_tl }
+}
+\cellpropsclass{}
+
+\cs_set_protected:Nn \@@_recall_properties:n {
+ \seq_map_inline:Nn \l_@@_specificities_seq {
+ \tl_if_exist:cT { l_@@_property_group_#1~##1_tl } {
+ \tl_use:c { l_@@_property_group_#1~##1_tl }
}
}
}
@@ -988,22 +1222,23 @@
\ExplSyntaxOff
\cellprops{
- td {
+ :where(td) {
padding: 0pt \csname l_@@_colsep_dim\endcsname;
min-height: \csname l_@@_strut_ht_dim\endcsname;
min-depth: \csname l_@@_strut_dp_dim\endcsname;
min-width: 0pt;
text-align: left;
+ vertical-align: baseline;
math-mode: auto;
color: inherit;
background-color: transparent;
border: thin none inherit;
}
- tr {
+ :where(tr) {
color: inherit;
background-color: transparent;
}
- table {
+ :where(table) {
padding: 0pt; % No change at load time
color: inherit;
background-color: transparent;
@@ -1030,7 +1265,8 @@
\tl_new:N \l_@@_color_tl
\tl_new:N \l_@@_bgcolor_tl
-% To count rows and columns
+\seq_new:N \l_@@_classes_at_start_seq
+
\cs_new_protected:Nn \@@_array_init: {
\tl_set:Nx \l_@@_restore_tl {
\bool_if:NTF \g_@@_inrow_bool {
@@ -1049,6 +1285,23 @@
\exp_not:n { \tl_gset:Nn \g_@@_borders_tl }
{ \exp_not:V \g_@@_borders_tl }
}
+% \end{macrocode}
+%
+% Unset all previous active classes, and set current ones as active.
+%
+% \begin{macrocode}
+ \seq_map_inline:Nn \l_@@_classes_at_start_seq {
+ \bool_set_false:c { l_@@_active_classes_##1_bool }
+ }
+ \seq_set_eq:NN \l_@@_classes_at_start_seq \l_@@_classes_seq
+ \seq_map_inline:Nn \l_@@_classes_at_start_seq {
+ \bool_set_true:c { l_@@_active_classes_##1_bool }
+ }
+% \end{macrocode}
+%
+% To count rows and columns.
+%
+% \begin{macrocode}
\int_gzero:N \g_@@_row_int
\bool_gset_false:N \g_@@_inrow_bool
\tl_gclear:N \g_@@_borders_tl
@@ -1080,7 +1333,6 @@
\dim_set_eq:NN \l_@@_tablepadding_bottom_dim \g_tmpb_dim
\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
@@ -1360,13 +1612,7 @@
\global\@minipagefalse
\everypar{}
}
- \@@_recall_properties:n {td~p}
- \@@_recall_properties:n {tr~td~p}
- \@@_recall_properties:n {tr:nth-child~p}
- \@@_recall_properties:n {td:nth-child~p}
- \@@_recall_properties:n {tr:nth-child~td~p}
- \@@_recall_properties:n {tr~td:nth-child~p}
- \@@_recall_properties:n {tr:nth-child~td:nth-child~p}
+ \@@_recall_properties:n {p}
}
}
\cs_new_protected_nopar:Nn \@@_end_par_cell:n {
@@ -1381,14 +1627,9 @@
\cs_new_protected_nopar:Nn \@@_begin_raw_cell:n {
\group_begin:
- \@@_recall_properties:n {tr:nth-child}
+ \@@_recall_properties:n {tr}
\@@_update_colors:
\@@_recall_properties:n {td}
- \@@_recall_properties:n {tr~td}
- \@@_recall_properties:n {td:nth-child}
- \@@_recall_properties:n {tr:nth-child~td}
- \@@_recall_properties:n {tr~td:nth-child}
- \@@_recall_properties:n {tr:nth-child~td:nth-child}
\@@_update_colors:
% Additional init code
#1
@@ -1476,12 +1717,50 @@
\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}
+ % Handle min-height, min-depth and vertical-align
+ % wrong values are treated as |baseline|.
\box_set_ht:Nn \l_@@_cell_box {
\dim_max:nn
{\box_ht:N \l_@@_cell_box}
{\@@_get_property:n {min-height}}
+ }
+ \box_set_dp:Nn \l_@@_cell_box {
+ \dim_max:nn
+ {\box_dp:N \l_@@_cell_box}
+ {\@@_get_property:n {min-depth}}
+ }
+ \str_case_e:nn {\@@_get_property:n {vertical-align}} {
+ { top } {
+ \hbox_set:Nn \l_@@_cell_box {
+ \vbox_top:n {
+ \kern 0pt\relax
+ \box_use_drop:N \l_@@_cell_box
+ }
+ }
+ }
+ { bottom } {
+ \hbox_set:Nn \l_@@_cell_box {
+ \vbox:n {
+ \box_use_drop:N \l_@@_cell_box
+ \kern 0pt\relax
+ }
+ }
+ }
+ { middle } {
+ \hbox_set:Nn \l_@@_cell_box {
+ \dim_set:Nn \l_tmpa_dim {
+ (\box_dp:N \l_@@_cell_box
+ - \box_ht:N \l_@@_cell_box
+ + 1ex) / 2
+ }
+ \raisebox{\l_tmpa_dim}{\box_use_drop:N \l_@@_cell_box}
+ }
+ }
+ }
+ % Handle padding-top and border-top
+ \@@_get_border_info:n {top}
+ \box_set_ht:Nn \l_@@_cell_box {
+ \box_ht:N \l_@@_cell_box
+ (\@@_get_property:n {padding-top})
+ \l_@@_border_width_dim
}
@@ -1497,12 +1776,10 @@
{ \exp_not:V \l_@@_border_color_tl }
}
}
- % Handle padding-bottom, min-depth and border-bottom
+ % Handle padding-bottom 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}}
+ \box_dp:N \l_@@_cell_box
+ (\@@_get_property:n {padding-bottom})
+ \l_@@_border_width_dim
}
diff --git a/macros/latex/contrib/cellprops/cellprops.ins b/macros/latex/contrib/cellprops/cellprops.ins
index 3619d87296..1b50038e33 100644
--- a/macros/latex/contrib/cellprops/cellprops.ins
+++ b/macros/latex/contrib/cellprops/cellprops.ins
@@ -1,6 +1,6 @@
\iffalse meta-comment
-File cellprops.ins (C) Copyright 2016-2020 RIVAUD Julien
+File cellprops.ins (C) Copyright 2016-2021 RIVAUD Julien
It may be distributed and/or modified under the conditions of the
General Public License (GPL), either version 3 of this
diff --git a/macros/latex/contrib/cellprops/cellprops.pdf b/macros/latex/contrib/cellprops/cellprops.pdf
index f315384a17..ae4071a20e 100644
--- a/macros/latex/contrib/cellprops/cellprops.pdf
+++ b/macros/latex/contrib/cellprops/cellprops.pdf
Binary files differ