使用 zlabel 的宏 supra/infra

使用 zlabel 的宏 supra/infra

我正在尝试制作一个交叉引用宏。前提是我对 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等)的选项;abbrevnote
  • 布尔选项(\rref[parent])用括号将命令括起来;
  • 初始选项:ref=page;;abbrev=trueparent=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}

在此处输入图片描述

相关内容