(这在某种程度上是这我的问题,@egreg 提供了一个简单的解决方案。)
在以下(egreg 的略微变体)MWE 中,定义了三个命令。creates \mylabel
(将在接下来的两个命令中\label
使用)和用于记录其他信息的命令。然后是和,它们产生“条件”/“相对”引用。\Cref
\RecordProperties
\mychapref
\mysecref
\documentclass{book}
\usepackage{hyperref}
\usepackage{cleveref}
\NewProperty{chapter}{now}{\bfseries??}{\Roman{chapter}}
\NewProperty{section}{now}{\bfseries??}{\arabic{section}}
\NewDocumentCommand{\mylabel}{m}{%
\label{#1}%
\RecordProperties{#1@recProp}{chapter,section,target}%
}
\ExplSyntaxOn
\NewDocumentCommand{\myref}{m}{
% If \Cref*{#1} begins with "Chapter", then execute \mychapref{#1}.
% If \Cref*{#1} begins with "Section", then execute \mysecref{#1}.
}
\NewDocumentCommand{\mychapref}{m}{
\str_if_eq:eeTF { \RefProperty{#1@recProp}{chapter} } { \Roman{chapter} } {
% we are in the same chap
this~chapter
} {
% in a diff chap
\Cref{#1}
}
}
\NewDocumentCommand{\mysecref}{m}{
\str_if_eq:eeTF { \RefProperty{#1@recProp}{chapter} } { \Roman{chapter} } {
% we are in the same chap
\str_if_eq:eeTF{ \RefProperty{#1@recProp}{section} } { \arabic{section}} {
% in the same sec
this~section
} {
%same chap diff sec
\Cref{#1}
}
}
{
% in a diff chap
\Cref{#1},\nobreakspace Chapter\nobreakspace\RefProperty{#1@recProp}{chapter}
}
}
\ExplSyntaxOff
\begin{document}
\chapter{First chapter}\mylabel{CHAP: I}
\mychapref{CHAP: I}
\section{abc}\mylabel{SEC: I.1}
\mysecref{SEC: I.1}
\section{efg}
\mysecref{SEC: I.1}
\chapter{Second chapter}
\mychapref{CHAP: I}
\mysecref{SEC: I.1}
\end{document}
需求:我想将\mychapref
和合并\mysecref
为一个命令\myref
,如上面的评论所述。但是,我偶然发现事实上,它\Cref*
是不可扩展的,因此我无法使用\str_set:Ne
或尝试将其分配给字符串变量\exp_args:Ne
,然后继续执行逻辑。
有没有办法实现这里的目的?
编辑:
因此,我尝试\myref
通过\mycreftype
@gusbrs 定义这里,像这样:
\NewDocumentCommand{\myref}{m}{
\str_if_eq:eeTF { \mychapref{#1} } { chapter } { \mychapref{#1} } {}
\str_if_eq:eeTF { \mycreftype{#1} } { section } { \mysecref{#1} } {}
}
但是,运行 MWE(只将上述内容和@gusbrs 的定义\mycreftype
添加到序言中,并替换\mychapref{CHAP: I}
为\myref{CHAP: I}
),我收到错误消息,第一个是
Argument of \@firstoftwo has an extra }. \myref{CHAP: I}
有什么帮助吗?
答案1
您可以使用以下程序https://tex.stackexchange.com/a/692754/105447检索引用类型,然后进行比较。
\documentclass{book}
\usepackage{hyperref}
\usepackage{cleveref}
\NewProperty{chapter}{now}{\textbf{??}}{\Roman{chapter}}
\NewProperty{section}{now}{\textbf{??}}{\arabic{section}}
\AddToHookWithArguments{label}{%
\RecordProperties{#1@recProp}{chapter,section,target}%
}
\ExplSyntaxOn
\makeatletter
\tl_new:N \l_mytempvar_tl
\NewDocumentCommand{\myref}{m}{
\cref@gettype {#1} { \l_mytempvar_tl }
\str_case:VnF \l_mytempvar_tl
{
% If type is "chapter", then execute \mychapref{#1}.
{ chapter } { \mychapref{#1} }
% If type is "section", then execute \mysecref{#1}.
{ section } { \mysecref{#1} }
}
{
% Anything else, just \Cref
\Cref {#1}
}
}
\makeatother
\NewDocumentCommand{\mychapref}{m}{
\str_if_eq:eeTF { \RefProperty { #1 @recProp } { chapter } } { \Roman{chapter} }
{
% we are in the same chap
this~chapter
}
{
% in a diff chap
\Cref {#1}
}
}
\NewDocumentCommand{\mysecref}{m}{
\str_if_eq:eeTF { \RefProperty { #1@recProp } { chapter } } { \Roman{chapter} }
{
% we are in the same chap
\str_if_eq:eeTF{ \RefProperty { #1 @recProp } { section } } { \arabic{section} }
{
% in the same sec
this~section
}
{
%same chap diff sec
\Cref {#1}
}
}
{
% in a diff chap
\Cref {#1},\nobreakspace Chapter\nobreakspace
\RefProperty { #1 @recProp } { chapter }
}
}
\ExplSyntaxOff
\begin{document}
\chapter{First chapter}
\label{CHAP:I}
\mychapref{CHAP:I}\par
\myref{CHAP:I}
\section{abc}
\label{SEC:I.1}
\mysecref{SEC:I.1}\par
\myref{SEC:I.1}
\section{efg}
\mysecref{SEC:I.1}\par
\myref{SEC:I.1}
\chapter{Second chapter}
\mychapref{CHAP:I}\par
\myref{CHAP:I}\par
\mysecref{SEC:I.1}\par
\myref{SEC:I.1}
\end{document}