我正在尝试制作一个交叉引用宏。前提是我对 LaTeX 的技术知识是基础的 ,-)
我改编了找到的源代码这里
% !TEX encoding = UTF-8 Unicode
% !TEX program = lualatex
\documentclass{article}
\usepackage{polyglossia}
\setmainlanguage{italian}
\usepackage{zref-clever}
\usepackage{lipsum}
\usepackage{hyperref}
\makeatletter
\newcommand*{\detect@rel}{}
\newcommand*{\rlabel}[1]{%
\@bsphack%
\label{#1}%
\listgadd{\detect@rel}{#1}%
\@esphack%
}
\newcommand*{\rref@supinf}[1]{%
\ifinlist{#1}{\detect@rel}{supra}{infra}%
}
\newcommand*{\rref@zcref}[1]{\zcref[ref=page, abbrev]{#1}}
\newcommand*{\rref}[1]{\emph{\rref@supinf{#1}}, \rref@zcref{#1}}
\makeatother
\begin{document}
\section{First Section}\zlabel{sec1}\rlabel{sec1}
\lipsum[1][1-4]
\section{Second Section}
\verb|\rref{sec1}|: \rref{sec1}
\par\medskip
\verb|\rref{sec3}|: \rref{sec3}
\section{Third Section}\zlabel{sec3}\rlabel{sec3}
\lipsum[2][1-4]
\end{document}
在此代码中我被迫使用第二个人称标签——rlabel
而我只想使用zlabel
。
此外,我想利用\NewDocumentCommand
(键/值方法;初始和默认选项)的灵活性来获得以下\rref
选项:
- 传递来自(
\zcref
、、ref
等)的选项;abbrev
note
- 布尔选项(
\rref[parent]
)用括号将命令括起来; - 初始选项:
ref=page
;;abbrev=true
parent=true
我想,expl3
所需要的就是语言。
马泰奥
答案1
不太清楚你试图在那里做什么(就我从链接的问题中了解到的情况而言),但它zref-check
提供了在文档中做出这种陈述的方法。它不会自动执行文本本身,但允许你提供文本,并检查标签相对于参考的位置。
\documentclass{article}
\usepackage{polyglossia}
\setmainlanguage{italian}
\usepackage{zref-clever}
\usepackage{zref-check}
\usepackage{lipsum}
\usepackage{hyperref}
\begin{document}
\section{First Section}
\zlabel{sec1}
\lipsum[1]
\section{Second Section}
\verb|\zcref{sec1}|: \zcref[note=supra,check=before]{sec1} % or 'above'
\par\medskip
\verb|\zcref{sec3}|: \zcref[note=infra,check=after]{sec3} % or 'below'
\par\medskip
Warning: \zcref[note=supra,check=before]{sec3}
\section{Third Section}
\zlabel{sec3}
\lipsum[2]
\end{document}
该文档将在第三次引用时产生编译时警告,因为它引用的标签实际上是在它“之后”,而我们要求检查它是否在“之前”。
Package zref-check Warning: Check failed on line 20. Failed check 'before' for
(zref-check) label 'sec3' on page 1.
优点:无需重新定义任何内容,您可以毫无顾虑地使用标准标签和引用命令;zref-check
与 集成良好zref-clever
。缺点:自动化程度比您所期望的要低一些;您必须偶尔写一个note
/ check
,还要注意编译警告(至少在您整理文档时)。
编辑:由于似乎只需要完全自动化,我可以想出一个不太好但希望令人满意的方法。它无需重新定义\zlabel
(只需一个钩子),通过计算标签,并将引用时计数器的当前状态与存储zref
标签设置时计数器值的属性进行比较(优点zref
)。现在,包的选项是内部的,我个人不会篡改它们来添加您请求的parent
选项。但您可以使用几个引用宏获得相同的效果,而不会造成太大损失。
\documentclass{article}
\usepackage{polyglossia}
\setmainlanguage{italian}
\usepackage{zref-clever}
\usepackage{lipsum}
\usepackage{hyperref}
\newcounter{labelcount}
\AddToHook{cmd/zlabel/before}{\stepcounter{labelcount}}
\makeatletter
\ExplSyntaxOn
\zref@newprop{labelcount}{\arabic{labelcount}}
\zref@addprop{main}{labelcount}
\cs_new:Npn \matteo_supinf:n #1
{
% \zcref can take multiple labels as argument, but this whole idea
% presumes only one is being given, so at least we don't typeset
% supra/infra if there are more labels.
\int_compare:nNnF { \clist_count:n {#1} } > { 1 }
{
\int_compare:nNnTF
{ \arabic{labelcount} }
<
{ \zref@extractdefault {#1} {labelcount} {0} }
{ \emph{infra},~ }
{ \emph{supra},~ }
}
}
\cs_new_protected:Npn \matteo_rzcref:nnn #1#2#3
{
\matteo_supinf:n{#3}
\bool_if:nTF {#1}
{ \zcref*[ref=page, abbrev, #2]{#3} }
{ \zcref[ref=page, abbrev, #2]{#3} }
}
\NewDocumentCommand{\rzcref}{ s O{} m }{
\matteo_rzcref:nnn {#1} {#2} {#3}
}
\NewDocumentCommand{\rzcrefp}{ s O{} m }{
(\matteo_rzcref:nnn {#1} {#2} {#3})
}
\ExplSyntaxOff
\makeatother
\begin{document}
\section{First Section}\zlabel{sec1}
\lipsum[1][1-4]
\section{Second Section}
\verb|\rzcref{sec1}|: \rzcref{sec1}, \rzcrefp{sec1}
\par\medskip
\verb|\rzcref{sec3}|: \rzcref{sec3}, \rzcrefp{sec3}
\section{Third Section}\zlabel{sec3}
\lipsum[2][1-4]
\end{document}