Cleveref - 条件标签格式

Cleveref - 条件标签格式

我正在尝试使用以下方法定义一种新的参考样式cleveref

\crefname{prop}{property}{properties}
\creflabelformat{prop}{#2#1.\@#3}

这旨在用于枚举环境中的编号属性列表。标签应呈现为“属性 1。”,以及“属性 1. 至 4。”的范围。

它按预期工作,但我想处理某个标点符号(在普通文本中)跟在 \cref 命令后面的情况。例如,\cref{my:label},应呈现为“property 1”,而不是“property 1.,”。

我尝试在标签定义中使用@ifnextchar,但是(我猜是由于 cleveref 解析命令的方式) \cref 后面的标记不是输入到@ifnextchar 的标记。

是否可以定义一个标签格式,以 \cref 命令后面的字符为条件?

编辑:添加了 MWE(略有不同的示例)

\documentclass{article}
\usepackage{cleveref}

\makeatletter
\crefname{prop}{property}{properties}
\creflabelformat{prop}{#2#1#3\@ifnextchar.{}{.\@}}
\makeatother

\begin{document}
    \begin{enumerate}
        \item \label[prop]{my:firstlabel}
        First property of the list

        \item \label[prop]{my:secondlabel}
        Second property of the list
    \end{enumerate}

    We will discuss the implications of \cref{my:firstlabel} and we will
    follow with \cref{my:secondlabel}.
\end{document}

预期结果是“我们将讨论属性 1 的含义,然后我们将讨论属性 2。”,但最后一个句号实际上被打印了两次(\@ifnextchar未被触发)。

enumi如果我修改标准标签格式而不是指定新格式,或者使用其他环境(例如方程式),我会得到相同的行为

答案1

使用该代码,\@ifnextchar绝不看到一个句号。如果我将定义改为

\creflabelformat{prop}{#2#1#3\@ifnextchar.{}{\show\@let@token.\@}}

TeX 将在两种情况下显示

> \@let@token=\fi.
\reserved@c ->\show \@let@token 
                                .\@

当使用源自的替换文本时\creflabelformat,LaTeX 正处于漫长的处理过程中。不过你很幸运!所有操作都在一个组中执行,因此我们可以通过\aftergroup在当前组结束时推送要执行的标记来解决问题。

为了避免\@ifnextchar吞噬空间,必须使用较低级别的技术。

\documentclass{article}
\usepackage{cleveref}

\makeatletter
\crefname{prop}{property}{properties}
\creflabelformat{prop}{#2#1#3\aftergroup\possible@period}
\newcommand{\possible@period}{\futurelet\@let@token\perhaps@add@period}
\newcommand\perhaps@add@period{\ifx\@let@token.\else.\@\fi}
\makeatother

\begin{document}

\begin{enumerate}
\item \label[prop]{my:firstlabel}
   First property of the list

\item \label[prop]{my:secondlabel}
   Second property of the list
\end{enumerate}

We will discuss the implications of \cref{my:firstlabel}
and we will follow with \cref{my:secondlabel}. Some text.

\end{document}

在此处输入图片描述

使用起来更短expl3,但是技术是一样的。

\documentclass{article}
\usepackage{cleveref,expl3}

\crefname{prop}{property}{properties}

\ExplSyntaxOn
\cs_new_protected:Npn \olivo_period:w
 {
  \peek_charcode:NF { . } { .\@ }
 }
\creflabelformat{prop}{#2#1#3\group_insert_after:N \olivo_period:w}
\ExplSyntaxOff

\begin{document}

\begin{enumerate}
\item \label[prop]{my:firstlabel}
   First property of the list

\item \label[prop]{my:secondlabel}
   Second property of the list
\end{enumerate}

We will discuss the implications of \cref{my:firstlabel}
and we will follow with \cref{my:secondlabel}. Some text.

\end{document}

答案2

这是一个使用 的解决方案enumitem,它定义了ref=...键。我添加了基于 定义新列表类型的可能性,enumerate您可以完全自定义它:

\documentclass{article}
\usepackage{cleveref}
\usepackage{enumitem}

\crefname{prop}{property}{properties}
\newlist{Prop}{enumerate}{1}
\setlist[Prop]{label=\arabic*., ref=\arabic*}
\crefname{Prop}{property}{properties}

\begin{document}

    \begin{enumerate}[ref=\arabic*]
        \item \label[prop]{my:firstlabel}
        First property of the list

        \item \label[prop]{my:secondlabel}
        Second property of the list
    \end{enumerate}

    We will discuss the implications of \cref{my:firstlabel} and we will
    follow with \cref{my:secondlabel}.\bigskip

    \begin{Prop}[start=3]
        \item \label[Prop]{My:firstlabel}
        First property of this list

        \item \label[Prop]{My:secondlabel}
        Second property of this list
    \end{Prop}
    We will now discuss the implications of \cref{My:firstlabel} and we will
    follow with \cref{My:secondlabel}.

    \end{document} 

在此处输入图片描述

相关内容