美学警告:我实际上使用的是悬挂数字而非衬线的小型大写字母。然而,在创建一个最小示例时,我屈服于默认设置并创建了一个排版怪物。
我正在尝试创建一个具有类似以下语法的环境:
\begin{<environment name>}{<single letter>}[<options>}
\item <stuff>
\end{<environment name>}
我希望列表被枚举,并且我希望每个项目都带有标签\textsc{<single letter>}\arabic{<number of item>}.
这很简单enumitem
。例如,我可以这样做:
\NewDocumentEnvironment{letters}{ O {} m }{%
\begin{enumerate}[label=\textsc{#2}\arabic*., ref=\textsc{#2}\arabic*, #1]
}{%
\end{enumerate}%
}
进而
\begin{letters}{a}
\item first
\item second
\end{letters}
将产生
但是,当我引用某项时,我希望引用的格式为\textsc{<letter>}\arabic{<value>}
(不带点)。同样,这很好,上面的ref
inenumitem
很好地解决了这个问题。
但是,我还希望能够在引用出现在句子开头时将字母大写。fancyref
和都cleveref
提供这种功能,但是使用小型大写字母表示小写字母会造成问题。
于是我开始调查enumitem
,并开始摆弄\AddEnumerateCounter(*)
。据我所知,这个命令并没有起到任何作用。相反,它似乎添加了一个计数器格式例如,它是将模拟量添加到\arabic
而不是 模拟量到c@page
。话虽如此,我一点也不确定我是否理解了它。
我确实设法用以下代码重现了我现有的结果
\makeatletter
\def\csimplelettered#1{\expandafter\@csimplelettered\csname c@#1\endcsname}
\def\@csimplelettered#1{\@arabic#1}
\makeatother
\AddEnumerateCounter{\csimplelettered}{\@csimplelettered}{2}
\NewDocumentEnvironment{simplelettered}{ O {} m }{%
\begin{enumerate}[label=\textsc{#2}\csimplelettered*., ref=\textsc{#2}\csimplelettered*, #1]
}{%
\end{enumerate}%
}
这让我可以写
\begin{simplelettered}{b}
\item first
\item second
\end{simplelettered}
生产
因此,我尝试在环境定义中动态创建一个新的计数器格式。以下是一次(肯定很可笑的)尝试
\makeatletter
\NewDocumentEnvironment{lettered}{ O {} m }{%
\expandafter\def\csname clettered#2\endcsname ##1{\expandafter\expandafter\expandafter\csname @clettered#2\endcsname\csname c@##1\endcsname}%
\expandafter\def\csname @clettered#2\endcsname ##1{\@arabic##1}%
\AddEnumerateCounter*{\expandafter\csname clettered#2\endcsname}{\expandafter\csname @clettered#2\endcsname}{2}%
\begin{enumerate}[label=\textsc{#2}\arabic*., ref=\textsc{#2}\arabic*, #1]
}{%
\end{enumerate}%
}
\makeatother
显然,我\expandafter
在任意位置随机抛出 s 的默认策略在这种特殊情况下并没有特别有效。
现在我对这个问题的兴趣比对原来的问题(我可以用另一种方式解决)更浓厚。我怎样才能使lettered
环境工作,以便它创建新的计数器格式并在枚举中使用它?
完成 NMWE:
\documentclass{article}
\usepackage{xparse,enumitem}
\NewDocumentEnvironment{letters}{ O {} m }{%
\begin{enumerate}[label=\textsc{#2}\arabic*., ref=\textsc{#2}\arabic*, #1]
}{%
\end{enumerate}%
}
\makeatletter
\def\csimplelettered#1{\expandafter\@csimplelettered\csname c@#1\endcsname}
\def\@csimplelettered#1{\@arabic#1}
\makeatother
\AddEnumerateCounter{\csimplelettered}{\@csimplelettered}{2}
\NewDocumentEnvironment{simplelettered}{ O {} m }{%
\begin{enumerate}[label=\textsc{#2}\csimplelettered*., ref=\textsc{#2}\csimplelettered*, #1]
}{%
\end{enumerate}%
}
\makeatletter
\NewDocumentEnvironment{lettered}{ O {} m }{%
\expandafter\def\csname clettered#2\endcsname ##1{\expandafter\expandafter\expandafter\csname @clettered#2\endcsname\csname c@##1\endcsname}%
\expandafter\def\csname @clettered#2\endcsname ##1{\@arabic##1}%
\AddEnumerateCounter*{\expandafter\csname clettered#2\endcsname}{\expandafter\csname @clettered#2\endcsname}{2}%
\begin{enumerate}[label=\textsc{#2}\arabic*., ref=\textsc{#2}\arabic*, #1]
% want to use something like:
%\begin{enumerate}[label=\textsc{\csname clettered#2\endcsname*}., ref=\csname clettered#2\endcsname*, #1]
}{%
\end{enumerate}%
}
\makeatother
\begin{document}
\begin{letters}{a}
\item first
\item second
\end{letters}
\begin{simplelettered}{b}
\item first
\item second
\end{simplelettered}
\begin{lettered}{c}
\item first
\item second
\end{lettered}
\end{document}
答案1
我不明白这个问题,所以不要指望这能回答它。但无论如何,如果你用这个代替
\expandafter\def\csname clettered#2\endcsname ##1{\expandafter\expandafter\expandafter\csname @clettered#2\endcsname\csname c@##1\endcsname}%
\expandafter\def\csname @clettered#2\endcsname ##1{\@arabic##1}%
\AddEnumerateCounter*{\expandafter\csname clettered#2\endcsname}{\expandafter\csname @clettered#2\endcsname}{2}%
和
\def\clettered##1{\expandafter\@clettered\csname c@##1\endcsname}%
\def\@clettered{\@arabic}%
\AddEnumerateCounter*{\clettered}{\@clettered}{2}%
它确实可以编译。除了你不需要定义任何变体之外,因为\csname..\endcsname
你处于环境中(如果这与问题无关,请忽略它)。
无论如何,这是您正确使用的解决方案\expandafters
\expandafter\def\csname clettered#2\endcsname##1{\csname @clettered#2\expandafter\endcsname\csname c@##1\endcsname}%
\expandafter\def\csname @clettered#2\endcsname##1{\@arabic{##1}}%
\expandafter\AddEnumerateCounter\expandafter*\csname clettered#2\expandafter\endcsname\csname @clettered#2\endcsname{2}%
为了解释这一点,你只需要一个\expandafter
在之前\endcsname
创建一个令牌,然后从下一个\csname
开始
\csname a\expandafter\endcsname\csname b\endcsname
会先创造\b
,然后\a
离开\a\b
。
答案2
我不确定我是否理解了这个问题,但我认为最好的方法是保存未格式化的标签:
\documentclass{article}
\usepackage{enumitem}
\makeatletter
\newcommand\mylabel[2]{\mylabelfont{#1}\@arabic{#2}}
\makeatother
\let\mylabelfont\textsc % Default
\newcommand\ucref[1]{%
{\let\mylabelfont\MakeUppercase\ref{#1}}}
\begin{document}
\begin{enumerate}[label=\textsc{a}\arabic*,ref=\protect\mylabel{a}{\arabic*}]
\item \label{1st} First
\item \label{2nd} Second
\end{enumerate}
First is \ref{1st} and second is \ref{2nd}. But compare with \ucref{1st} and \ucref{2nd}.
\end{document}
这里\mylabel
只保存字母和项目编号。格式在实际使用标签时决定。这是一种通用方法,可以延迟标签的格式化方式,因为它取决于上下文。