tabularray icon indicating copy to clipboard operation
tabularray copied to clipboard

Make `longtblr` compatible with `\nameref`

Open wickles opened this issue 2 years ago • 4 comments

This makes longtblr captions compatible with \nameref. Without this change, \nameref on a longtblr is simply empty.

It checks if \@currentlabelname is defined (so hyperref package is loaded, hopefully), and defines it using the entry if it exists else using the caption.

MWE provided here.

\documentclass{article}
\usepackage{tabularray}

\makeatletter
\ExplSyntaxOn
\cs_set_protected:Npn \__tblr_build_table_label_entry:
  {
    \tl_set:Nx \l_tmpa_tl { \InsertTblrText { label } }
    \tl_if_eq:NnTF \l_tmpa_tl { none }
      {
        \SetTblrTemplate { caption-tag }{ empty }
        \SetTblrTemplate { caption-sep }{ empty }
      }
      {
        \cs_if_exist:NT { \@currentlabelname }
          {
            \tl_set:Nx \l_tmpb_tl { \InsertTblrText { entry } }
            \tl_if_empty:NT \l_tmpb_tl
              { \tl_set:NV \l_tmpb_tl { \InsertTblrText { caption } } }
            \exp_args:NV \GetTitleString \l_tmpb_tl
            \tl_gset:Nx \@currentlabelname \GetTitleStringResult
          }

        \refstepcounter { table }
        \tl_if_empty:NF \l_tmpa_tl { \exp_args:NV \label \l_tmpa_tl }
      }
    \tl_set:Nx \l_tmpb_tl { \InsertTblrText { entry } }
    \tl_if_eq:NnF \l_tmpb_tl { none }
      { \UseTblrTemplate { caption-lot } { default } }
  }
\ExplSyntaxOff
\makeatother

\usepackage{hyperref}

\begin{document}

Refer to \autoref{tblr:mylongtblr}: \nameref{tblr:mylongtblr}.

\begin{longtblr}[
    caption = {My longtblr long caption},
    entry = {My longtblr entry},
    label = {tblr:mylongtblr},
]{
    colspec = { Q[10em,c] Q[10em,c] },
}
A & B \\
C & D \\
\end{longtblr}

\end{document}

wickles avatar Apr 22 '22 04:04 wickles

In tabularray, a new feature which depends on another package should be implemented as a new library (by using \NewTblrLibrary command). Also there is another feature request for supporting zref package (see #202). I think these two new libraries (nameref and zref) may be implemented at the same time.

lvjr avatar Apr 23 '22 10:04 lvjr

To make the code more flexible, it would be better to create a new template element caption-label. Then nameref library will define a new template

\DefTblrTemplate{caption-label}{nameref}{<code>}

while zref library will define another new template

\DefTblrTemplate{caption-label}{zref}{<code>}

Now we can just modify the above function as follows:

\cs_new_protected:Npn \__tblr_build_table_label_entry:
  {
    <some code>
    \UseTblrTemplate{caption-label}{default}
    <more code>
  }

lvjr avatar Apr 23 '22 10:04 lvjr

In tabularray, a new feature which depends on another package should be implemented as a new library (by using \NewTblrLibrary command). Also there is another feature request for supporting zref package (see #202). I think these two new libraries (nameref and zref) may be implemented at the same time.

nameref is bundled with hyperref and so should be supported wherever hyperref is supported, I think.

longtable for example works with nameref by default, so for compatibility longtblr should as well.

wickles avatar May 01 '22 21:05 wickles

Using private commands in other packages is always risky. Therefore I am not going to do it by default.

One reason why I wrote this package is to replace tabu package, which was broken by an update of LaTeX kernel, because it had been using some private commands in the kernel.

lvjr avatar May 02 '22 01:05 lvjr

\@currentlabelname is not a private command from nameref. It is more like \@currentlabel or the page number: A data the \label commands picks up and stores. You can set it to whatever content you think would be useful as output of \nameref. There is also no need to test if \@currentlabelname is already defined. You can simply set it, and if hyperref or nameref is loaded it is used.

The documentation officially documents the command as something other packages can (and imho even should) set

The package redefines the \label command to write additionally \@currentlabelname to the .aux file. This can then be referenced with \nameref. Package authors who want to support nameref should define this command (locally) in a suitable way. The content should be so that it can be safely written to the .aux file. nameref itself uses the package gettitlestring but this is not required.

\tl_gset:Nx \@currentlabelname \GetTitleStringResult

But this is not ok. As the documentation says \@currentlabelname should be set locally.

\documentclass{book}
\usepackage{nameref}

\begin{document}
\makeatletter
x\def\@currentlabelname{bbbb}\label{testA}

x\GetTitleString{sometext}\let\@currentlabelname\GetTitleStringResult\label{testB}

Reference: \nameref{testA}, \nameref{testB}

\end{document}

u-fischer avatar Aug 29 '22 13:08 u-fischer

@u-fischer Thanks for the information. Now I have added nameref library to tabularray package (see #256).

lvjr avatar Sep 03 '22 09:09 lvjr