0

Using zref I want to define a clever cross-ref command for ranges \clevestrip{ref1}{ref2} which returns a "stripping" string (1ab) if theExNo is equal for ref1 and ref2, and only prints ref1ref2 otherwise.

But there must be some issue with expandability because it does not work. If anyone can tell me why...

Edited @Ulrike told me to use \zref@extract because \zref is not expandable, and it works like a charm.

MAWE (almost working...)


\documentclass{report}
\usepackage{zref-user}
\usepackage{philex}

\setlength{\parskip}{1em}

\makeatletter
\zref@newprop{exno}{\arabic{ExNo}}
\zref@newprop{theexno}{\theExNo}
\zref@newprop{subexno}{\alph{SubExNo}}
\zref@newprop{thesubexno}{\theSubExNo}
\zref@newprop{subsubexno}{\roman{SubSubExNo}}
\zref@newprop{refskip}{\ifnum\theExDepth=3\roman{SubSubExNo}\else\alph{SubExNo}\fi}

\zref@addprops{main}{exno,subexno,subsubexno,theexno,thesubexno,refskip}

\makeatother

\newcommand{\refstrip}[2]{(\zref{#1}--\zref[refskip]{#2})}


\begin{document}

\phildashes{}{.} 
\subformat{a}{}{.}     


\lb{main1}{Example One.\zlabel{main1}
    \lba{sub11}{Subexample One-One.\zlabel{sub11}
        \lba{subsub111}{Subsubexample One-One-One.\zlabel{subsub111}}
        \lbb{subsub112}{Subsubexample One-One-Two.}
        \lbz{subsub113}{Subsubexample One-One-Three.\zlabel{subsub113}}} 
    \lbz{sub12}{Subexample One-Two.\zlabel{sub12}
        \lba{subsub121}{Subsubexample One-Two-One.}
        \lbz{subsub122}{Subsubexample One-Two-Two.}}}

\lb{main2}{Example Two. \zlabel{main2}
        \lba{sub21}{Subexample Two-One.}
        \lbz{sub22}{Subexample Two-Two.}} \zlabel{sub22}
        
        
\refstrip{sub11}{sub12}

\refstrip{subsub111}{subsub113}

\makeatletter
\newcommand{\clevestrip}[2]{%
    \ifnum\zref@extract{#1}{theexno}=\zref@extract{#2}{theexno}\refstrip{#1}{#2}\else\zref{#1}\zref{#2}\fi} % Using the expandable version (thanks to Ulrike Fischer)

\makeatother

\clevestrip{sub11}{sub12}   %   ERROR
    
\end{document}

enter image description here

8
  • 1
    commands with optional arguments are not expandable. If you want to retrieve the values in an expandable way you have to use the commands marked as "exp2" in the documentation, e.g. \zref@extractdefault. Commented May 13, 2022 at 9:18
  • Yes I was looking for this "exp" variant in the doc but couldn't find it. Thanks! Commented May 13, 2022 at 9:27
  • I edited the MWE replacing \zref by its expandable avatar \zrefextract, but with no success. Problem lies elsewhere. Commented May 13, 2022 at 9:34
  • you need the command which sets a default number. Commented May 13, 2022 at 9:36
  • 2
    You are missing the \makeatletter. And I would recommend not to use \ifnum (or other low level tex tests), it is easy to forget to correctly delimit a number or a test. Use etoolbox or expl3. Commented May 13, 2022 at 9:49

1 Answer 1

1

One thing I've learned with time is to always follow @UlrikeFischer's advice. Since she suggested you take a look at zref-clever in another question (which made my day :-), I think you should. Indeed, zref-clever's endrange option seems particularly suited to solve the problem you are trying to solve.

The endrange option can receive a number of predefined values, such as stripprefix, or pagecomp, in which case it calls a processing function to build the end part of the range. But it can also receive a zref property (perks of zref), in which case you can pretty much build the end part of the range the way you want it. And, if using a zref property there is no need to process the reference in any way, so you don't need to guess the form it will take, or add a "marker" to be able to split it at the right point.

(I haven't the faintest of philex and linguex, I hope I'm not butchering them...)

\documentclass{report}

\usepackage{philex}

\usepackage{zref-clever}
\zcsetup{
  countertype={
    ExNo=example, % I'm assuming this is what "ExNo" means
    SubExNo=example,
    SubSubExNo=example,
  },
  counterresetby={
    SubExNo=ExNo,
    SubSubExNo=SubExNo,
  },
}

\ExplSyntaxOn
\makeatletter
\zref@newprop{refskip}
  {
    \int_compare:nNnTF { \value{ExDepth} } = { 3 }
      { \roman{SubSubExNo} }
      { \alph{SubExNo} }
  }
\zref@addprop{main}{refskip}
\makeatother
\ExplSyntaxOff

\zcRefTypeSetup{example}{
  endrange=refskip,
  rangesep={--},
  rangetopair=false,
}

\usepackage{hyperref}

\setlength{\parskip}{1em}

\begin{document}

\phildashes{}{.}
\subformat{a}{}{.}

\lb{main1}{Example One.\zlabel{main1}
    \lba{sub11}{Subexample One-One.\zlabel{sub11}
        \lba{subsub111}{Subsubexample One-One-One.\zlabel{subsub111}}
        \lbb{subsub112}{Subsubexample One-One-Two.\zlabel{subsub112}}
        \lbz{subsub113}{Subsubexample One-One-Three.\zlabel{subsub113}}}
    \lbz{sub12}{Subexample One-Two.\zlabel{sub12}
        \lba{subsub121}{Subsubexample One-Two-One.}
        \lbz{subsub122}{Subsubexample One-Two-Two.}}}

\lb{main2}{Example Two. \zlabel{main2}
        \lba{sub21}{Subexample Two-One.}
        \lbz{sub22}{Subexample Two-Two.\zlabel{sub22}}}

\zcref[range]{sub11,sub12}

\zcref[range]{subsub111,subsub113}

\zcref{subsub111,subsub112,subsub113}

\zcref[range]{sub11,sub22}

\end{document}

enter image description here

13
  • 1
    \int_compare:nNnTF is just an expl3 version of your test (also following Ulrike's advice ;-).
    – gusbrs
    Commented May 13, 2022 at 12:11
  • 1
    @VincentKrebs Well, technically, you can just use your previous definition of refskip, or take a look at etoolbox. I just "translated" the test.
    – gusbrs
    Commented May 13, 2022 at 12:14
  • 1
    Ah, \ExplSyntaxOn/\ExplSyntaxOff is the equivalent of \makeatletter/\makeatother for expl3 code.
    – gusbrs
    Commented May 13, 2022 at 12:16
  • 1
    expl3 is the new programming layer inside latex. Much new code is written with it. Look e.g. into siunitx or other new packages. Or into latex.ltx there you find some parts written in expl3 too. Commented May 13, 2022 at 12:21
  • 1
    @VincentKrebs It is LaTeX3, or the "LaTeX3 programming layer". It is part of the kernel nowadays, and expl3 was the name of the package which provided it when it was still "experimental" (but I think the name just stuck around). Anyway, you don't have to use it at all (though it is better if you do), as I said, you can use your previous definition of the refskip property.
    – gusbrs
    Commented May 13, 2022 at 12:23

You must log in to answer this question.

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