This question is a follow-up on these two
- Why does \zifrefundefined fail on tcolorbox reference?
- \@nameuse fails on definition within tcolorbox
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 likezref
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}
#1
outside a macro instead oftest-id
and somehow\zref@labelbyprops
got also lost.