3

I am fixing my command \fullref, which internally uses \nameref and does not support multiple labels to be used simultaneously. However, on the question How to nameref multiple labels simultaneously?, it is presented a fixed version of \nameref which support multiple labels simultaneously.

The answer on that question, offers 2 variants of \nameref, but for my \fullref command, I need a new variant which allows me to omit the reference label name as Figure in Figure My Caption.

Editing the answer on the question How to nameref multiple labels simultaneously?, I managed to create this new variant, beyond the 2 variants already on the answer. Resulting in the following 3 variants of \nameref command:

% “Start in lower case” variant. With star: disable hyperlinks.
% Does put the label name, i.e., Figure My Figure. #2: comma list of refs
\NewDocumentCommand \namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_false_bool {#1} {#2}
  }

% “Start in upper case” variant. With star: disable hyperlinks.
% Does put the label name, i.e., Figure My Figure. #2: comma list of refs
\NewDocumentCommand \Namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_true_bool {#1} {#2}
  }

% “Start in lower case” variant. With star: disable hyperlinks.
% Does NOT put the label name, i.e., My Figure. #2: comma list of refs
\NewDocumentCommand \nameRefs { s m }
  {
    \__user_name_refs:NNnn \c_false_bool \c_false_bool {#1} {#2}
  }

The changes I did were just adding a new boolean parameter as the first parameter on the \__user_name_refs:NNnn function, and pass this parameter forward to the function \user_name_refs:nnxn, and use it inside the function \user_name_refs:nnxn to not print the \nameref label name as Figure.

If the first parameter of the function \user_name_refs:nnxn is true, then, the reference label as Figure will be printed/output. If it is false, then, it prints nothing, i.e., no Figure label.

    \bool_if:nTF {#1}
    {
      % (section, Section, sections or Sections) or (theorem, Theorem, ...) or...
      \user_name_cref:xV
        { \bool_if:nTF {#2} { C } { c }
          ref
         \int_compare:nNnTF { \l__user_name_refs_nbrefs_int } > { 1 } { s } { } }
       \l__user_name_refs_firstref_tl
      \nobreakspace
    }{}

So far, I have edited all the code which should be enough to make these 3 \nameref variants above to work. But I cannot make it compile as latex throws this error:

(D:\User\Documents\latex\texmfs\install\tex\latex\base\omscmr.fd)
! Undefined control sequence.
\__user_name_refs:NNnn ...4->\user_name_refs:nnxn
                                                  {#1}{#2}{\IfBooleanTF {#3}...
l.114 ...reference and hyperlink: \nameRefs{first}
                                                   (we'll disable

I do not know very well new extended syntax and I am probably missing something quite simple. Can you find what did I forget to add with my changes?

% The code below automatically adapts to the selected language.
\documentclass[english]{memoir}
\usepackage{babel}
\usepackage{xparse}

\usepackage[colorlinks=true]{hyperref}
\usepackage{cleveref}
\OnehalfSpacing

\ExplSyntaxOn

% #1: variant (cref, Cref, crefs or Crefs)
% #2: reference name (label)
\cs_new_protected:Npn \user_name_cref:nn #1#2
  { \use:c { name #1 } {#2} }

\cs_generate_variant:Nn \user_name_cref:nn { xV }

% #1: boolean expression (true: disable hyperlink)
% #2: reference name (label)
\cs_new_protected:Npn \user_name_ref:nn #1#2
  { \bool_if:nTF {#1} { \nameref* } { \nameref } {#2} }

\cs_generate_variant:Nn \user_name_ref:nn { nV }

\seq_new:N \l__user_name_refs_tmpa_seq
\seq_new:N \l__user_name_refs_tmpb_seq
\int_new:N \l__user_name_refs_nbrefs_int
\tl_new:N \l__user_name_refs_firstref_tl

% #1: boolean expression (true: Does put the label name, i.e., Figure My Figure)
% #2: boolean expression (true: start with capitalized letter, as in \Cref)
% #3: boolean expression (true: disable hyperlinks)
% #4: comma list of refs
\cs_new_protected:Npn \user_name_refs:nnnn #1#2#3#4
  {
    \seq_set_from_clist:Nn \l__user_name_refs_tmpa_seq {#4}
    \int_set:Nn \l__user_name_refs_nbrefs_int
                { \seq_count:N \l__user_name_refs_tmpa_seq }
    \seq_get_left:NN \l__user_name_refs_tmpa_seq \l__user_name_refs_firstref_tl

    \bool_if:nTF {#1}
    {
      % (section, Section, sections or Sections) or (theorem, Theorem, ...) or...
      \user_name_cref:xV
        { \bool_if:nTF {#2} { C } { c }
          ref
         \int_compare:nNnTF { \l__user_name_refs_nbrefs_int } > { 1 } { s } { } }
       \l__user_name_refs_firstref_tl
      \nobreakspace
    }{}

    % Now print the references.
    \seq_clear:N \l__user_name_refs_tmpb_seq
    \seq_map_inline:Nn \l__user_name_refs_tmpa_seq
      {
        \seq_put_right:Nn \l__user_name_refs_tmpb_seq
                          { \user_name_ref:nn {#3} {##2} }
      }
    \seq_use:Nnnn \l__user_name_refs_tmpb_seq { \crefpairconjunction }
                  { \crefmiddleconjunction } { \creflastconjunction }
  }

\cs_generate_variant:Nn \user_name_refs:nnnn { nx }

\cs_new_protected:Npn \__user_name_refs:NNnn #1#2#3#4
  {
    \user_name_refs:nnxn {#1}
      {#2}
      { \IfBooleanTF {#3} { \c_true_bool } { \c_false_bool } }
      {#4}
  }

% “Start in lower case” variant.
% Does put the label name, i.e., Figure My Figure.
% With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_false_bool {#1} {#2}
  }

% “Start in upper case” variant.
% Does put the label name, i.e., Figure My Figure.
% With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \Namerefs { s m }
  {
    \__user_name_refs:NNnn \c_true_bool \c_true_bool {#1} {#2}
  }

% “Start in lower case” variant.
% Does NOT put the label name, i.e., My Figure.
% With star: disable hyperlinks.
% #2: comma list of refs
\NewDocumentCommand \nameRefs { s m }
  {
    \__user_name_refs:NNnn \c_false_bool \c_false_bool {#1} {#2}
  }

\ExplSyntaxOff

\newcommand*{\fullref}[1]{\Cref{#1}: \nameRefs{#1}}

\begin{document}

\fullref{first,second,third,fourth}.

\namerefs{first,second,third,fourth}.

\Namerefs{first,second,third,fourth}.

\nameRefs{first,second,third,fourth}.

\section{First section}
\label{first}

\section{Second section}
\label{second}

\section{Third section}
\label{third}

\section{Fourth section}
\label{fourth}

\end{document}

References:

  1. What `\cs_new_protected` and `\cs_generate_variant` do?
  2. What do ExplSyntaxOn and ExplSyntaxOff do?
  3. https://github.com/textmate/latex.tmbundle/issues/79 expl3 syntax highlighting
  4. http://mirror.las.iastate.edu/tex-archive/macros/latex/contrib/l3kernel/expl3.pdf
  • You do not seem to generate \user_name_refs:nnxn, try adding \cs_generate_variant:Nn \user_name_refs:nnnn { nnxn } – siracusa Nov 10 at 20:57
  • @siracusa, after adding it, latex now throws the error Illegal parameter number in definition of \__seq_item:n – user Nov 10 at 21:02
  • In the definition of \user_name_refs:nnnn, there's no argument ##2 for \seq_map_inline:Nn, that should be a ##1 – siracusa Nov 10 at 21:29
  • @siracusa, It worked! Thanks! Would you like to post it as an answer? – user Nov 10 at 22:19
2

The problem can be solved by generating the proper function variant to be able to use \user_name_refs:nnxn:

\cs_generate_variant:Nn \user_name_refs:nnnn { nnxn }

and by using the correct inline function parameter (##1 instead of ##2) in the defintion of \user_name_refs:nnnn:

\seq_map_inline:Nn \l__user_name_refs_tmpa_seq
  {
    \seq_put_right:Nn \l__user_name_refs_tmpb_seq
                      { \user_name_ref:nn {#3} {##1} }
  }

Resulting PDF:

Resulting PDF of the full compiled document

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.