0

I would like to modify the following personal cross-reference macro (the initial idea comes from the question: macro supra/infra using zlabel).

% !TEX encoding = UTF-8 Unicode
% !TEX program = lualatex

\documentclass{article}
\usepackage{polyglossia}
  \setmainlanguage{italian}
\usepackage{zref-vario}
\usepackage{varioref}
\usepackage{lipsum}
\usepackage{hyperref}

\newcounter{labelcount}
\AddToHook{cmd/zlabel/before}{\stepcounter{labelcount}}

\makeatletter
\ExplSyntaxOn

\zref@newprop{labelcount}{\arabic{labelcount}}
\zref@addprop{main}{labelcount}

\cs_new:Npn \suprainfra_text:n #1
  {
    \int_compare:nNnF { \clist_count:n {#1} } > { 1 }
      {
        \int_compare:nNnTF
          { \arabic{labelcount} }
            <
          { \zref@extractdefault {#1} {labelcount} {0} }
          { infra }
          { supra }
      }
  }

\cs_new_protected:Npn \tl_zcref_ref:n #1 { \zcref{#1} }
\cs_new_protected:Npn \tl_zcref_page:n #1 { \zvpageref{#1} }
\keys_define:nn {option}
  {
    type .choice: ,
    type / ref .code:n = \tl_set:Nn \l__option_type_tl {\tl_zcref_ref:n} ,
    type / page .code:n = \tl_set:Nn \l__option_type_tl {\tl_zcref_page:n} ,
    type .initial:n = page ,
    ref .meta:n     = { type = ref } ,
    ref .value_forbidden:n = true ,
  }

\bool_new:N \l__option_parent_bool
\keys_define:nn {option}
  {
    parent .bool_set:N = \l__option_parent_bool ,
    parent .initial:n = true ,
    noparent .meta:n    = { parent = false } ,
    noparent .value_forbidden:n = true ,
  }

\cs_new_protected:Npn \ts_suprainfra_text_type_noparent:nn #1#2
  { \emph { \suprainfra_text:n {#2} }, ~ \l__option_type_tl {#2} }

\cs_new_protected:Npn \ts_suprainfra_text_type_parent:nn #1#2
  { ( \ts_suprainfra_text_type_noparent:nn {#1}{#2} ) }

\cs_new_protected:Npn \ts_suprainfra:nn #1#2
  {
    \group_begin:
      \keys_set:nn {option} {#1}
      \bool_if:NTF \l__option_parent_bool
        { \ts_suprainfra_text_type_parent:nn {#1}{#2} }
        { \ts_suprainfra_text_type_noparent:nn {#1}{#2} }
    \group_end:
  }
  
\NewDocumentCommand {\supinf} {O{} m}
  { \ts_suprainfra:nn {#1} {#2} }

\ExplSyntaxOff
\makeatother

\begin{document}
\section{First Section}\zlabel{sec1}
\lipsum[1][1-4]

\section{Second Section}
\verb|\supinf[type=ref]{sec1}|\quad \supinf[type=ref]{sec1}
\par\medskip
\verb|\supinf[type=page]{sec1}|\quad \supinf[type=page]{sec1}
\par\medskip
\verb|\supinf{sec3}|\quad \supinf{sec3}
\par\medskip
\verb|\supinf[ref]{sec3}|\quad \supinf[ref]{sec3}
\par\medskip
\verb|\supinf[noparent]{sec3}|\quad \supinf[noparent]{sec3}
\par\medskip
\verb|\supinf[noparent,ref]{sec3}|\quad \supinf[noparent,ref]{sec3}

\section{Third Section}\zlabel{sec3}
\lipsum[2][1-4]
\end{document}

enter image description here The macro \supinf takes two optional parameters: type=ref|page and parent=true|false.

type parameter call \zcref function (by zref-clever package) and \zvpageref function (by zref-vario package).

Now I would like to implement two things that I cannot do independently:

  1. a \supinf* (starred) version, depending on \zcref* and \zvpageref*;
  2. modify some default terms about italian localization (the changes should only apply within the personal macro), as followed:
    • zref-clever italian term:
      • type = chapter
        • name-sg|name-pl = cap.
      • type = section
        • name-sg|name-pl = §
      • type = page
        • name-sg|name-pl = p.
      • type = footnote|endnote|note
        • name-sg|name-pl = n.
    • zref-vario italian expressions:
      • reftextfaceafter = {\zvhyperlink{p. a fianco}}
      • reftextfacebefore = {\zvhyperlink{p. a fianco}}
      • reftextafter = {\zvhyperlink{p. successiva}}
      • reftextbefore = {\zvhyperlink{p. successiva}}
      • reftextcurrent = {\zvhyperlink{p. corrente}}
      • reftextfaraway = {\zcpageref{#1}}
      • reftextpagerange = {\zcpageref[range]{#1,#2}}
      • reftextlabelrange = {\zcref[range]{#1,#2}}

Finally, I am fully aware that my code does not respect expl3 conventions, but I could not do better :-) I would be grateful if anyone would give me suggestions.

6
  • 1
    You still seem to want a macro with custom options. So I'll ask, are you sure? You'd get better results without them, as I suggested in the other question. The reason is because it is hard to mix your custom options with those of \zcref, so you loose the ability to control \zcref. For the sake of having an option that controls a parenthesis wrapping, and such?
    – gusbrs
    Commented Jan 31, 2023 at 10:00
  • Regarding the question, you still haven't told us what you want "setup within a group". How are we supposed to know? Which terms of the Italian localization you'd like to change?
    – gusbrs
    Commented Jan 31, 2023 at 10:02
  • Also, the question would probably benefit from a more informative title.
    – gusbrs
    Commented Jan 31, 2023 at 11:12
  • @gusbrs The macro will have to create a precisely formalized string, so there is no need to have full control over \zcref options.
    – matteofg
    Commented Jan 31, 2023 at 14:18
  • @gusbrs Regarding the changes about Italian localization, I have modified my question so as to explain better.
    – matteofg
    Commented Jan 31, 2023 at 14:19

1 Answer 1

0

As mentioned in the comments, I think you had a better base in the other answer, by trying to control your customizations with a few variants of the command, instead making them options. Because, there you had full access to the \zcref options, as you passed them along to the wrapped call. Here, you'd have to mix them, what you cannot do without hacking the package's internals. Or, lose the ability to pass options to \zcref.

Regarding the reference customization to be applied just for this command, you cannot do this "for Italian". In both zref-clever and zref-vario, language settings are conceived as global, and hence \zcLanguageSetup and \zvLanguageSetup are preamble only. For zref-clever there's \zcRefTypeSetup which you can employ within the group of your command for local settings to do this kind of thing. There's however no equivalent for zref-vario, which is already a wrapper around varioref and zref-clever, so there are some limitations to the flexibility it can offer. The only real alternative here would be to declare a new "language" for zref-clever, say supinf-italian, populate it for both zref-clever and zref-vario, and then set \zcsetup{lang=supinf-italian} within the group of your command. You'd get full flexibility, but it'd be quite some setup for this.

But you seem to want this pretty badly, so there you have one possible version of things:

% !TEX encoding = UTF-8 Unicode
% !TEX program = lualatex

\documentclass{article}
\usepackage{polyglossia}
  \setmainlanguage{italian}
\usepackage{zref-clever}
\usepackage{zref-vario}
\usepackage{varioref}
\usepackage{lipsum}
\usepackage{hyperref}

\newcounter{labelcount}
\AddToHook{cmd/zlabel/before}{\stepcounter{labelcount}}

\makeatletter
\ExplSyntaxOn

\zref@newprop{labelcount}{\arabic{labelcount}}
\zref@addprop{main}{labelcount}

% From https://tex.stackexchange.com/a/670745/105447
\cs_new:Npn \my_suprainfra_text:n #1
  {
    \int_compare:nNnF { \clist_count:n {#1} } > { 1 }
      {
        \int_compare:nNnTF
          { \arabic{labelcount} }
            <
          { \zref@extractdefault {#1} {labelcount} {0} }
          { \emph{infra},~ }
          { \emph{supra},~ }
      }
  }

\cs_new_protected:Npn \my_supinf:nnn #1#2#3
  {
    \group_begin:
    \my_supinf_setup:
    \keys_set:nn { my/supinf } {#2}
    \bool_if:NT \l__my_supinf_parens_bool { ( }
    \my_suprainfra_text:n {#3}
    \bool_if:nTF {#1}
      {
        \bool_if:NTF \l__my_supinf_vario_page_bool
          { \zvpageref*{#3} }
          { \zcref*{#3} }
      }
      {
        \bool_if:NTF \l__my_supinf_vario_page_bool
          { \zvpageref{#3} }
          { \zcref{#3} }
      }
    \bool_if:NT \l__my_supinf_parens_bool { ) }
    \group_end:
  }

\cs_new_protected:Npn \my_supinf_setup:
  {
    \zcRefTypeSetup{chapter}
      {
        Name-sg=Cap.,
        Name-pl=Cap.,
        name-sg=cap.,
        name-pl=cap.,
      }
    \zcRefTypeSetup{section}
      {
        Name-sg=§,
        Name-pl=§,
        name-sg=§,
        name-pl=§,
      }
    \zcRefTypeSetup{page}
      {
        Name-sg=P.,
        Name-pl=P.,
        name-sg=p.,
        name-pl=p.,
      }
    \zcRefTypeSetup{footnote}
      {
        Name-sg=N.,
        Name-pl=N.,
        name-sg=n.,
        name-pl=n.,
      }
    \zcRefTypeSetup{endnote}
      {
        Name-sg=N.,
        Name-pl=N.,
        name-sg=n.,
        name-pl=n.,
      }
    \zcRefTypeSetup{note}
      {
        Name-sg=N.,
        Name-pl=N.,
        name-sg=n.,
        name-pl=n.,
      }
  }

\bool_new:N \l__my_supinf_parens_bool
\bool_new:N \l__my_supinf_vario_page_bool
\keys_define:nn { my/supinf }
  {
    type .choice: ,
    type / ref .code:n = { \bool_set_false:N \l__my_supinf_vario_page_bool } ,
    type / page .code:n = { \bool_set_true:N \l__my_supinf_vario_page_bool } ,
    type .initial:n = page ,
    ref .meta:n = { type = ref } ,
    ref .value_forbidden:n = true ,
    parens .bool_set:N = \l__my_supinf_parens_bool ,
    parens .initial:n = true ,
    noparens .meta:n    = { parens = false } ,
    noparens .value_forbidden:n = true ,
  }

\NewDocumentCommand{\supinf}{ s O{} m }{
  \my_supinf:nnn {#1} {#2} {#3}
}

\ExplSyntaxOff
\makeatother

\begin{document}
\section{First Section}\zlabel{sec1}
\lipsum[1][1-4]

\section{Second Section}
\verb|\supinf[type=ref]{sec1}|\quad \supinf[type=ref]{sec1}
\par\medskip
\verb|\supinf[type=page]{sec1}|\quad \supinf[type=page]{sec1}
\par\medskip
\verb|\supinf{sec3}|\quad \supinf{sec3}
\par\medskip
\verb|\supinf[ref]{sec3}|\quad \supinf[ref]{sec3}
\par\medskip
\verb|\supinf[noparens]{sec3}|\quad \supinf[noparens]{sec3}
\par\medskip
\verb|\supinf[noparens,ref]{sec3}|\quad \supinf[noparens,ref]{sec3}
\par\medskip
\verb|\supinf*{sec3}|\quad \supinf*{sec3}

\section{Third Section}\zlabel{sec3}
\lipsum[2][1-4]
\end{document}

enter image description here

7
  • I have declared the pseudo "italianSupinf" language, so everything works perfectly! Thank you very much for your help!
    – matteofg
    Commented Feb 1, 2023 at 13:53
  • It would be great if it were possible to set the pseudo-language automatically via babel/polyglossia, so that if the document language is 'x' then the pseudo-language would be set as \zcsetup{lang=xSupinf}
    – matteofg
    Commented Feb 1, 2023 at 13:55
  • @matteo339 Mhm, I don't think that would be possible. How would babel or polyglossia know that "italianSupinf" even exists? You are clearly stretching the intended use case of the functionality, as I think you are well aware. Do note that this "independent" behavior of the lang option is what at this point I think was an ill advised decision of my past self which, if I find a good way to get rid of in the future, I may seize it.
    – gusbrs
    Commented Feb 1, 2023 at 14:27
  • Sorry, I misspoke. I was thinking something like 1) language set in babel/polyglossia (e.g. italian) 2) macro that generates the pseudo-language name (e.g. italianSupinf) 3) pseudo-language set via macro \zcsetup{lang=\macro}. All this automation would be convenient to be able to use different pseudo-languages, without intervening within the tex code
    – matteofg
    Commented Feb 1, 2023 at 15:14
  • @matteo339 "macro that generates the pseudo-language name". No way, sorry. ;-) As mentioned, you are stretching the intended use case of a "language" in so doing.
    – gusbrs
    Commented Feb 1, 2023 at 15:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .