Cleveref 在 etoolbox 测试中的 namecref 使用情况

Cleveref 在 etoolbox 测试中的 namecref 使用情况

我目前正在尝试创建新的命令,以便在需要时在交叉引用前面添加正确的法语冠词(例如“图XX”或“第二十章”)。

我最初的想法是创建类似的\acref命令\Acref

\newcommand{\acref}[1]{%
\def\rtype{\namecref{#1}}% namecref will produce something like "figure"
\def\article{{\bf error:[\rtype](#1)} }% default value to help debugging
\ifstrequal{\rtype}{figure}{\def\article{la }}{}%
\article\cref{#1}\xspace
}

我也尝试过像这样\expandafter添加:\ifstrequal

\expandafter\ifstrequal\expandafter{\rtype}{figure}{\def\article{la }}{}%

我还尝试了一些我不掌握的命令组合,但结果很糟糕。

我所有的尝试都产生了无效的输出,要么总是使用图形的文章(因为它目前是我尝试测试的唯一一个),因为条件语句的两个分支都被执行(太多\expandafter)或者它永远不会进入真正的分支。

最小编译但不工作的示例:

\documentclass{paper}

\usepackage{cleveref}
\usepackage{etoolbox}
\usepackage{xspace}

\crefname{figure}{figure}{figures} % instead of fig.

\newcommand{\acref}[1]{%
\def\rtype{\namecref{#1}}% namecref will produce something like "figure"
\def\article{{\bf error:[\rtype](#1)} }% default value to help debugging
\ifstrequal{\rtype}{figure}{\def\article{la }}{}%
\article\cref{#1}\xspace
}

\begin{document}
  \section{Title}
  \label{sec:title}

  \begin{figure}
    \caption{Caption}
    \label{fig:caption}
  \end{figure}

  Test with figure: \acref{fig:caption}. % should print "la figure" but prints error:...

  Test with section: \acref{sec:title}. % should print error:...
\end{document}

我读到etoolbox在大多数测试中,包括,都不会扩展其参数\ifstrequal。我的想法是创建一个包含的结果的列表,\namecref因为有\listeadd扩展其项目参数,然后测试该列表是否包含文本“figure”。但是,当我尝试(\listeadd{\mylist}{\namecref{#1}})时,pdflatex停止编译并返回(过滤):

! Argument of \@firstoftwo has an extra }
! Paragraph ended before \@firstoftwo was complete.
! TeX capacity exceeded, sorry [parameter stack size=10000].

那么,是\namecref不可扩展的吗?


在我的情况下,我未能回答的非常接近的问题:

答案1

欢迎使用 TeX.SE。您可以使用获取所选宏中\cref@gettype的引用类型(在下面的代码中),然后根据结果执行特殊代码。期望宏已经定义,这是在第一次编译运行相关内容后执行文件中的命令时完成的。因此,我的代码检查宏是否已定义,如果没有,则在文档中打印,并在终端和日志文件中打印常规消息:cleveref\mycref@type\cref@gettype\r@〈reference〉@cref\newlabel.aux〈reference〉\r@〈reference〉@cref??

LaTeX 警告:标签可能已更改。请重新运行以获取正确的交叉引用。

xspace我删除了代码中的使用,因为nowdays的原作者xspace建议不要使用它(此外,正如 egreg 指出的那样,xspace在这里没有用,因为您的宏接受一个参数)。我将标签更改fig:captionfig-caption,否则使用cleveref:作为活动字符1您会遇到问题。还请注意,我amsthm在示例中使用了定理。如果您使用从\newtheoremLaTeX 内核定义的定理环境,您会发现cleveref使用共享计数器的定理类型不一定是您期望的(您会得到共享计数器的名称而不是“特定”名称;这不会发生在amsthm定理环境中)。

最后,不要忘记cleveref最后加载!:-)

\documentclass{article}
\usepackage{expl3}
\usepackage{amsthm}             % only for the demo
%\usepackage{hyperref}          % usually last, but before cleveref
\usepackage{cleveref}           % load this package last

\newtheorem{theorem}{Théorème}

\crefname{figure}{figure}{figures}    % instead of fig.
\crefname{theorem}{théorème}{théorèmes}

\makeatletter
\ExplSyntaxOn
% Let's borrow \str_case:onF from expl3 (\cs_new_eq:NN is like \let but checks
% that the “destination” command name doesn't already exist).
\cs_new_eq:NN \mycref@str@oswitch \str_case:onF
\ExplSyntaxOff

\newcommand*{\acref}[1]{%
  \ifcsname r@#1@cref\endcsname
    \cref@gettype{#1}{\mycref@type}%
    \mycref@str@oswitch{\mycref@type}
      {{figure}{la }%
       {theorem}{le }%
%      {...}{...}% you can add as many cases as you want!
      }
      {\errmessage{%
         My package: unknown reference type for label '#1':
         '\unexpanded\expandafter{\mycref@type}'}%
      }%
  \else
    \G@refundefinedtrue
    \nfss@text{\reset@font\bfseries ??}%
    \@latex@warning{Reference `#1' on page \thepage\space undefined}%
  \fi
  \cref{#1}%
}
\makeatother

\begin{document}

  \section{Title}\label{sec-title}

  \begin{theorem}\label{th-some-theorem}
    This is a theorem.
  \end{theorem}

  \begin{figure}
    \centering X
    \caption{Caption}
    \label{fig-caption}
  \end{figure}

  Test with figure: \acref{fig-caption}.

  Test with theorem: \acref{th-some-theorem}.

% Test with section: \acref{sec-title}. % prints an error, as expected

\end{document}

在此处输入图片描述

如果你取消注释该\usepackage{hyperref}行并重新编译直到 LaTeX 满意(因为\newlabel这意味着语法的变化),你会得到:

在此处输入图片描述


脚注

  1. \usepackage[french]{babel}如果您使用pdfTeX 引擎,通常就会出现这种情况。

相关内容