规范化,删除标签名称前后的空格并删除空条目。

规范化,删除标签名称前后的空格并删除空条目。

我认为这个 MWE 说明了一切。\cite可以忽略其参数中的空格,而\cref不能。我想知道是否\cref可以通过这种方式进行改进。

\documentclass{article}
\usepackage{cleveref}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
    @misc{1, author="One Author", year=2000}
    @misc{2, author="Another Writer", year=2010}
\end{filecontents}
\begin{document}
    We can use \cite{1,2} AND \cite{1, 2}!

    Yet, we can use \cref{1,2}, but not \cref{1, 2}!

    \section{Section 1}
    \label{1}

    \section{Section 2}
    \label{2}

    \bibliographystyle{apalike}
    \bibliography{\jobname}

\end{document}

为什么这很重要?因为有些文本编辑器(TeXstudio 就是其中之一)在实现逗号处换行时遇到困难,因为后面没有空格。

答案1

规范化,删除标签名称前后的空格并删除空条目。

以下示例使用 package 的逗号解析器kvsetkeys来解析 package 的引用命令的标签名称列表。为此,第二个参数中包含列表的cleveref内部函数被重新定义:\@cref

\documentclass{article}
\usepackage{cleveref}
\usepackage{kvsetkeys}

\makeatletter
\let\org@@cref\@cref
\renewcommand*{\@cref}[2]{%
  \begingroup
    \toks@={}%
    \comma@parse{#2}\add@cref@item
  \edef\process@me{\endgroup
    \noexpand\org@@cref{#1}{\the\toks@}%
  }\process@me
}
\newcommand*{\add@cref@item}[1]{%
  \expandafter\ifx\expandafter\\\the\toks@\\%
    \toks@{#1}%
  \else
    \toks@\expandafter{\the\toks@,#1}%
  \fi
}
\makeatother

\begin{document}
    \noindent
    We can use \cref{1,2}, and now  \cref{1, 2},\\
    and even with a leading or trailing comma: \Cref{ , 1 , 2 ,}.

    \section{Section 1}
    \label{1}

    \section{Section 2}
    \label{2}
\end{document}

结果

删除空格并保留逗号

消除所有空白的解决方案。如果标签包含空格,则必须将标签放在花括号中。:

\documentclass{article}
\usepackage{cleveref}
\usepackage{kvsetkeys}

\makeatletter
\let\org@@cref\@cref
\renewcommand*{\@cref}[2]{%
  \edef\process@me{%
    \noexpand\org@@cref{#1}{\zap@space#2 \@empty}%
  }\process@me
}
\makeatother

\begin{document}
    \noindent
    We can use \cref{1,2}, and now  \cref{1, 2}.

    \section{Section 1}
    \label{1}

    \section{Section 2}
    \label{2}
\end{document}

结果

\zap@space在 LaTeX 内核中定义,例如用于规范化类和包的选项列表。

答案2

几乎不言自明的代码:

\begin{filecontents}{\jobname.bib}
    @misc{1, author="One Author", year=2000}
    @misc{2, author="Another Writer", year=2010}
\end{filecontents}

\documentclass{article}
\usepackage{xparse}
\usepackage{cleveref}

\ExplSyntaxOn
\cs_set_eq:Nc \bers_cref:nn { @cref }
\cs_generate_variant:Nn \bers_cref:nn { nx }
\cs_set_protected:cpn { @cref } #1 #2
 {
  \seq_set_split:Nnn \l_bers_cref_seq { , } { #2 }
  \bers_cref:nx { #1 } { \seq_use:Nn \l_bers_cref_seq { , } }
 }
\seq_new:N \l_bers_cref_seq
\ExplSyntaxOff

\begin{document}

We can use \cite{1,2} AND \cite{1, 2}!

Yet, we can use \cref{1 space,2}, but also \cref{1 space, 2}!

Also \cref{1 space,2 , 3,, 4}

Also \Cref{1 space, 2, 3 , , 4}

\section{Section 1}
\label{1 space}

\section{Section 2}
\label{2}

\section{Section 3}
\label{3}

\section{Section 4}
\label{4}

\bibliographystyle{apalike}
\bibliography{\jobname}

\end{document}

我重新定义了内部命令\@cref,首先将其第二个参数拆分为逗号,这样可以删除前导空格和尾随空格,但保留内部空格。原始命令\@cref保存在 中\bers_cref:nn,然后\@cref重新定义为使用\bers_cref:nx,这是一种完全扩展其第二个参数的变体,我们\seq_use:Nn在条目之间使用逗号。

请注意,也会\Cref自动修改。空条目也有效。

在此处输入图片描述

答案3

\cref这是一个基于 LuaLaTeX 的解决方案。它允许在、\Cref和的参数中使用空格(空格、制表符、换行符)\labelcref。请注意,此解决方案中采用的方法不会cleveref以任何方式修改宏。

在此处输入图片描述

\documentclass{article}
\usepackage{cleveref}

\usepackage{luacode}
\begin{luacode}
function nospace ( t ) -- remove all whitespace characters from string "t"
  return ( t:gsub ( "%s", "" ) )
end
function crefnospace ( s ) 
  return ( s:gsub ( "\\.-[cC]ref%s-%b{}" , nospace ) )
end 
\end{luacode}
\AtBeginDocument{\directlua{luatexbase.add_to_callback ( 
   "process_input_buffer", crefnospace, "crefnospace" )}}

\begin{document}
We may use \cref{a,b}, \Cref{a, b}, \cref{a ,b}, and \Cref{{ a }, b }.
``\labelcref{ b , {a }}'' works too.

\section{Section 1}\label{a}
\section{Section 2}\label{b}
\end{document}

相关内容