这个问题是对这两个问题的后续
我想要实现的目标:
- 我想要一个环境,例如彩色盒子,其中我有
- 一种定义某种标签的方法,
\vref
可以与交叉引用一起工作或类似的方法,即顺序一定不事情 - 定义与标签相关的附加变量的方法,例如
<label-name>@definition
- 我需要能够检查某个标签变量是否可用
- 该方法必须针对文本中的位置保持稳定,尤其是在环境内部或外部工作时
我目前学到的知识:
参考值
zref
在环境之外也能很好地工作。您可以使用\zref@newprop
、\zref@setcurrent
和\zref@extractdefault
来\zref@labelbyprops
实现惊人的效果。\zifrefundefined
即使缺少某些内容,也有助于使您的编译顺利进行。zref
在环境中无法工作。我希望有类似zref
但可以在环境中工作的东西。
电子工具箱
etoolbox
(仅包含适合经验丰富的 [La]TeX 用户的文档)完全适应环境. 使用\csgdef
和\csuse
将带你走得很远。- 我缺少的补充功能
\zifrefundefined
,但这可能是我不理解文档 etoolbox
有一个警告:顺序很重要。事物必须在第一次使用之前定义。
概括
我需要结合环境的稳健性以及发生顺序的etoolbox
稳健性。这是我的测试平台:zref
\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
Markus,据我所知,您的 MWNE 中有两个错误:
- 您的拼写有误
\zref@extractdefault{#1}{Definition}{}
:我认为#1
应该替换为test-id
- 可能是代码减少事故:你忘记使用 注册变量
\zref@labelbyprops
,因此zref
看起来好像它不适合环境,但它是。所以你的假设zref
是错误的。
以下是 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}