tabularray icon indicating copy to clipboard operation
tabularray copied to clipboard

Add `\hlinenext` and `\vlinenext` command

Open JoJoDeveloping opened this issue 1 year ago • 8 comments

Here's a table that has a line below the last row:

\begin{tblr}{colspec={lcr}}
\hline
\vline Top Left & \vline Top Middle & \vline Top Right\\
\hline
Center Left & Center Middle & Center Right\\
\hline
Bottom Left & Bottom Middle & Bottom Right\\
\hline
\end{tblr}

Text Below Table

It looks like this: image

Note that there is no actual fourth column, even though we ended the third column with a \\ and put an extra \hline in, even though a \hline is "above the row it is written in," i.e. the first \hline is above the text in the first row, and the last \hline is above the (non-existing) text in the fourth row. But as said, there is no fourth row, and the \hline terminates the table at the bottom. This is nice and intuitive.

The issue is that no such thing is possible with the rightmost vertical line. We can try this:

\begin{tblr}{colspec={lcr}}
\hline
\vline Top Left & \vline Top Middle & \vline Top Right \vline\\
\hline
Center Left & Center Middle & Center Right\\
\hline
Bottom Left & Bottom Middle & Bottom Right
\end{tblr}

but this just looks wrong: image

And unsurprisingly so--a \vline must come as the first thing in a column, but here it does not. So let's add an extra column that is empty:

\begin{tblr}{colspec={lcr}}
\hline
\vline Top Left & \vline Top Middle & \vline Top Right &\vline\\
\hline
Center Left & Center Middle & Center Right&\\
\hline
Bottom Left & Bottom Middle & Bottom Right&%
\end{tblr}

this also does not work: image

This is surprising. When we added a fake support row for the last \hline, this did not add any extra whitespace, but instead put the \hline at the true bottom of the table. But here, adding an extra "fake" column without content does not put a \vline at the true right of the table.

In the end, the bug report/feature request is that there should be a means of putting a \vline at the very right of the table. It does not necessarily need to be by means of a "fake last column."

JoJoDeveloping avatar Oct 06 '24 21:10 JoJoDeveloping

\hlines and \vlines used in tblr environment are emulations to their same-named correspondences in traditional tabular-like environments. In tble-derived envs, they are table commands which "must be put at the beginning of the cell text" (see package manual, version 2024A, sec. 2.1). This explains why in & \vline Top Right \vline \\ the second \vline failed to produce a vertical table line.

The behavior of trailing \hline is inherited from tabular env, so no trailing empty row is created. See related source lines.

But the behavior of \vline used in the beginning of cell text is tblr's own syntax. Considering \hline and \vline are both part of the old interfaces, I'm afraid efforts won't be put on extending the supported insertion positions of \vline.

If possible, new interface is recommended, for this case there is colspec={lcr}, vline{Z} which will add a vline at the right side of the last column. Of course there's also colspec={lcr|} and colspec={lcr}, vlines (add all vlines).

muzimuzhi avatar Oct 06 '24 22:10 muzimuzhi

Indeed, they all work. But these all require that the vlines be specified at the start, and that if you e.g. insert a line at the top you need to shift all the numbers (Imagine that I specifically want to have lines in the 1337th row of the cell, and then if I add a new row it's now the 1338th line that should have the lines). It is much easier to put something like \SetVline[=]{\c@rownum}{} somewhere (which is what I am actually doing), since that does not need shifting when the row moves around the table.

So the solution for me would be to add a \SetVlineAtEnd[=]{\c@rownum}{} that would to the same but for the rightmost column. A potential implementation (that seems to work) is

\NewTableCommand \SetVlineAtEnd [3] [+]
  {
    \tblr_set_vline:nnnn { \int_eval:n { \c@colcount + 1 } } {#1} {#2} {#3}
  } 

but it only works when I put it into the tabularray.sty file (and not into my own headers) :disappointed:

So I would just PR this, if wanted.

JoJoDeveloping avatar Oct 06 '24 23:10 JoJoDeveloping

To make it working in user headers, you only need to switch some catcode settings:

\ExplSyntaxOn\makeatletter
\NewTableCommand \SetVlineAtEnd [3] [+]
  {
    \tblr_set_vline:nnnn { \int_eval:n { \c@colcount + 1 } } {#1} {#2} {#3}
  }
\makeatother\ExplSyntaxOff

Update: Implementation and example for experimental \vlineSolely are removed since it would wrongly ignore real empty cells.

muzimuzhi avatar Oct 06 '24 23:10 muzimuzhi

Ah, I forgot the expl syntax. Thanks, that works! Also thanks for the project in general ❤️

JoJoDeveloping avatar Oct 07 '24 11:10 JoJoDeveloping

Since you can get what you want with public interfaces, I will close this issue.

lvjr avatar Nov 15 '24 02:11 lvjr

Is \tblr_set_vline:nnnn really part of the public interfaces?

The more general question is, do all public tblr latex3 functions and variables, documented or not, have stable behavior or meaning, and if changed are (at least) mentioned in future release notes?

muzimuzhi avatar Nov 15 '24 18:11 muzimuzhi

Is \tblr_set_vline:nnnn really part of the public interfaces?

The more general question is, do all public tblr latex3 functions and variables, documented or not, have stable behavior or meaning, and if changed are (at least) mentioned in future release notes?

I have created issue #527 for this. It is an experimental public function. I can record the change if I know some users or packages are already using it.

lvjr avatar Nov 16 '24 07:11 lvjr

Based on issue #548, I think it is good to add \hlinenext and \vlinenext commands, so that users can use four line commands (\hline, \hlinenext, \vline, \vlinenext) to set four borders of cells.

lvjr avatar Dec 07 '24 05:12 lvjr