我正在阅读该包的文档cleveref
,可以找到这里,这时我偶然发现了第六页的一段旁注(可以在段落中找到\Cref
),其中写道
由于 LATEX 很难³确定交叉引用是否出现在句子的开头,[...]
³ 事实上,很可能不可能!
(将原有的 Latex 生成的标志改为\LaTeX
LATEX 生成的标志)
我想知道为什么会这样?
答案1
以下是我在上面的评论中概述的基于预处理器的方法的 LuaLaTeX 实现。如果\cref
with \Cref
(和\crefrange
with \Crefrange
)的实例出现在输入行的最开始,或者前面是句末标点符号(.
、?
或!
),后面跟着一个或多个空格,它将替换它们。主要工作由 Lua 函数执行cref2Cref
,该函数被分配给process_input_buffer
回调,从而在 TeX 开始正常工作之前充当预处理器。
关于输入是句子内没有换行符。如果不满足这个假设,则该方法不能保证有效。第二个假设(希望是显而易见的)是,只有包中的宏cleveref
以字符串开头\cref
。如果出于某种原因,您的代码定义了名为\crefx
或的宏\crefzzz
,请做好迎接一些不愉快的意外的准备。该方法还忽略了非句子结尾句号后面紧跟着的可能性\cref
。因此,(非常可疑!)句子片段,例如“Mr. and Mrs. \cref{fig:a} are glad to advertise”将使算法出错。如果您的文档包含此类段落,请告诉我...
用于生成以下屏幕截图的代码加载了hyperref
包并cleveref
使用选项加载了包nameinlink
,以便于眼睛检测交叉引用。请注意,四个实例中的两个\cref
被替换为\Cref
“on the fly”。
最后,请注意,它cleveref
本身在这里没有做任何额外的工作:它只能查看和处理\cref
和的实例\Cref
。cleveref
无法知道哪些\Cref
和的实例\Crefrange
是由作者提供的,哪些是由 Lua 函数即时创建的cref2Cref
。
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{amsmath} % for 'gather' env.
\usepackage[colorlinks]{hyperref} % optional
\usepackage[nameinlink,noabbrev]{cleveref}
\usepackage{luacode}
\begin{luacode}
function cref2Cref ( s )
s = s:gsub ( "^\\cref", "\\Cref" )
s = s:gsub ( "([%.%!%?])%s*\\cref" , "%1 \\Cref" )
return s
end
\end{luacode}
%% Assign the Lua function to the 'process_input_buffer' callback:
\AtBeginDocument{\directlua{luatexbase.add_to_callback(
"process_input_buffer" , cref2Cref , "cref2Cref" )}}
\begin{document}
%% Set up a few equations and figures.
\begin{gather}
1+1=2 \label{eq:1} \\
2+2=4 \label{eq:2} \\
3+3=6 \label{eq:3}
\end{gather}
\begin{figure}[h!]
\caption{AAA} \label{fig:a} \smallskip
\caption{BBB} \label{fig:b} \smallskip
\caption{CCC} \label{fig:c}
\end{figure}
% Now generate a few cross-references.
Is this a cross-reference to \cref{eq:1}? \cref{eq:2,eq:3} show that\dots
\crefrange{fig:a}{fig:c} illustrate\dots\ As \crefrange{fig:b}{fig:c} demonstrate, \dots
\end{document}