0

This question is a follow-up on these two

What I want to achieve:

  • I want to have an environment, e.g. tcolorbox, in which I have
  • a way to define some kind of label that works with \vref or similar apporaches for having cross-references working back and forth, i.e. order must not matter
  • a way to define additional variables connected to the label, something like <label-name>@definition
  • I need to be able to check whether a certain label variable is available
  • The approach must be stable against position in text, especially work inside or outside of environments

What I have learned so far:

zref

  • zref works outside of environments like a charm. You can use \zref@newprop, \zref@setcurrent, \zref@extractdefault and \zref@labelbyprops to achieve astonishing results. \zifrefundefined helps top make your compilation run through even when something is missing.
  • zref does not work within environments. I would appreciate something like zref but working within environments.

etoolbox

  • etoolbox (which has only a documentation that works for very experienced [La]TeX users) is totally robust with environments. Using \csgdef and \csuse brings you very far.
  • I am missing the complement feature of \zifrefundefined, but that is probably me not understanding the docs
  • etoolbox has a caveat: order matters. Things have to be defined before first use.

Summary

I need the robustness for environments of etoolbox combined with the robustness of zref with regard to order of occurrence. Here's my testbed:

\documentclass[
  a4paper,
  11pt,
  parskip=half
]{scrbook}

\usepackage[nospace]{varioref}
\usepackage[pdfencoding=unicode, psdextra]{hyperref}
\usepackage{cleveref}
\usepackage[user]{zref}
\usepackage{tcolorbox}
\usepackage{etoolbox}

\tcbuselibrary{breakable}

\DeclareNewTOC[
  category=float,
  float,% declares floating environment eq
  floatpos=ht,
  nonfloat,% declares non-floating environment eq-
  listname={Some Items},
  name=TM,
  tocentrystyle=tocline,
  tocentrylevel:=table,
  tocentryindent:=table,
  tocentrynumwidth:=table,
  type=MySpecialEnvFloat,
]{ltm}

\newtcolorbox[
    auto counter,
    crefname={TM}{TMs}]{MyBox}[2][]{
    title={TM\,\thetcbcounter: #2},
    #1}
  
\newcounter{MySpecialEnvCounter}

    
\begin{document}

\makeatletter
\zref@newprop{Definition}{}

\newcommand{\MySpecialEnv}[4]{%
    \refstepcounter{MySpecialEnvCounter}%

    % etoolbox
    \csgdef{#1@Definition}{#2}

    % 
    \zlabel{#1}
    \zref@setcurrent{Definition}{#2}

    \begin{MyBox}[label={#1}]{#2}
        \addcontentsline{ltm}{section}{TM\,\theMySpecialEnvCounter: #2}

        Some text
        \tcblower
        #4
    \end{MyBox}
}%  
\makeatother

\listofMySpecialEnvFloats

\MySpecialEnv{test-id}{Something that looks like a summary}{-}{
    sdjoajhsja sijaoihs siahskah

    Nameuse: \@nameuse{test-id-2@Definition}

    Csname: \emph{\csname test-id-2@Definition\endcsname}

    % Order matters for etoolbox, so this one will fail
    Etoolbox: \csuse{test-id-2@Definition}
}

\MySpecialEnv{test-id-2}{Yet another summary}{-}{
    asjajsaj sakjskaj sjkajs
}

\subsection{varioref test}

\textbf{Varioref test}: Reference to \vref{test-id} and \vref{test-id-2},
\textbf{Pageref test}: \vpageref{test-id-2}

\subsection{Cref Test}

\cref{test-id}  \cpageref{test-id}

\subsection{etoolbox}

\makeatletter

A \csuse{test-id-2@Definition}

% How do I test for test-id-2 to bne defined?
B \ifdef{test-id-2}{\csuse{test-id-2@Definition}}{test-id-2 DOES NOT EXIST}

C \csuse{test-id-4@Definition}

D \ifdef{test-id-4}{\csuse{test-id-4@Definition}}{test-id-4 DOES NOT EXIST}

\makeatother

\subsection{zifrefundefined}

% Not robust against environments
\makeatletter
\zifrefundefined{test-id}{\nfss@text{\reset@font\bfseries??}}{
    \zref@extractdefault{#1}{Definition}{}
}
\makeatother

\end{document}
9
  • 3
    I think that you neither really understand zref nor etoolbox and that it would better if you state your real problem instead of showing your half working tries to implement something. Feb 13, 2022 at 17:49
  • I find this rather harsh. If I would understand any of those packages I probably would not be forced to ask here (which is the main reason for SO's existence). I tried to formulate my problem in text form and find it pretty clear what I want to achieve. And I show code that fails. If zref can work within environments (this is where the problem started for me) then I am happy to learn about it. AFAICS there are at least 5 different ways in LateX to get cross-refs and user-defined vars up and running and none really is straight forward nor are the docs for the faint-hearted to say the least.
    – Markus W.
    Feb 13, 2022 at 21:32
  • 5
    well just in case you don't know: I'm one of the current maintainer of zref and I know quite well how it works and can even extend it in case it misses something. But as long I have no idea what you are actually trying to achieve I can't help you (the answer of Heiko about align is not really relevant as your code doesn't load amsmath). Feb 13, 2022 at 21:49
  • 3
    you are not explaining why you use zref. It is not clear if you are using the right tool. Feb 13, 2022 at 22:36
  • 1
    I am so sorry. I have a typo (copy paste error) in my MNWE above: #1 outside a macro instead of test-id and somehow \zref@labelbyprops got also lost.
    – Markus W.
    Feb 13, 2022 at 22:56

1 Answer 1

0

Markus, as far as I can see, you have two errors in your MWNE:

  1. You have a typo in \zref@extractdefault{#1}{Definition}{}: I think #1 should be replaced by test-id
  2. Probably a code reduction accident: You forgot to register your variables with \zref@labelbyprops, therefore zref appears as if it is not suitable for environments, but it is. So your assumption about zref is wrong.

Here is a MWE:

\documentclass[
  a4paper,
  11pt,
  parskip=half
]{scrbook}

\usepackage[nospace]{varioref}
\usepackage[pdfencoding=unicode, psdextra]{hyperref}
\hypersetup{linkcolor=blue}
\usepackage{cleveref}
\usepackage[user]{zref}
\usepackage{tcolorbox}

\tcbuselibrary{breakable}

\DeclareNewTOC[
  category=float,
  float,% declares floating environment eq
  floatpos=ht,
  nonfloat,% declares non-floating environment eq-
  listname={Some Items},
  name=TM,
  tocentrystyle=tocline,
  tocentrylevel:=table,
  tocentryindent:=table,
  tocentrynumwidth:=table,
  type=MySpecialEnvFloat,
]{ltm}

\newtcolorbox[
    auto counter,
    crefname={TM}{TMs}]{MyBox}[2][]{
    title={TM\,\thetcbcounter: #2},
    #1}
  

\makeatletter
\newcommand{\referToMySpecialEnv}[1]{
    \zifrefundefined{#1}{\nfss@text{\reset@font\bfseries??}}{
        \hyperref[#1]{\zref@extractdefault{#1}{ID}{}: 
        \emph{\zref@extractdefault{#1}{Definition}{}}} \vpageref{#1}
    }
}    
\makeatother
    
    
\begin{document}

\makeatletter
\zref@newprop{Definition}{}
\zref@newprop{ID}{}

\newcommand{\MySpecialEnv}[4]{%

    \begin{MyBox}[label={#1}]{#2}
        \zref@setcurrent{Definition}{#2}%
        \zref@setcurrent{ID}{TM\,\thetcbcounter}
        \zref@labelbyprops{#1}{Definition, ID}
        \addcontentsline{ltm}{section}{TM\,\thetcbcounter: #2}
        Some text
        \tcblower
        #4
    \end{MyBox}
}%  
\makeatother

\listofMySpecialEnvFloats

\MySpecialEnv{test-id}{Something that looks like a summary}{-}{
    Here is a cross-reference to
    % Works like a charm within the box!
    \referToMySpecialEnv{test-id-2}
}

\MySpecialEnv{test-id-2}{Yet another summary}{-}{
    Here is a cross-reference to
    % Works like a charm within the box!
    \referToMySpecialEnv{test-id}
}

\subsection{varioref test}

\textbf{Varioref test}: Reference to \vref{test-id} and \vref{test-id-2},
\textbf{Pageref test}: \vpageref{test-id-2}

\subsection{Cref Test}

\cref{test-id}  \cpageref{test-id}

\subsection{zifrefundefined}

% Works outside in the wild
Let us check \referToMySpecialEnv{test-id} and \referToMySpecialEnv{test-id-2}

\end{document}
1
  • Alright. Looks like you solved your own problem. As for the question, I suggest that you explain, as text outside the code block (as comment inside the code block is hard to spot), what output do you expect from the test and why. There's a comment such as "Not robust against environments" in the code, but from a quick read of the code I can't tell what does it mean or what output do you expect. (by the way no need to talk "as if you were someone else" in a self-answer...)
    – user202729
    Jul 14, 2022 at 2:17

You must log in to answer this question.

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