我正在尝试使用以下方法定义一种新的参考样式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}