有时我想参考一长串的表格或图片。我已经对它们进行了分类标记,但要输入类似以下内容需要很多输入(我是个懒惰的程序员):
\ref{tab:foo1}, \ref{tab:foo2}, \ref{tab:foo3}, \ref{tab:foo4}
理想的结果如下:
1、2、3、4
如果我能在这里使用正则表达式,那不是很好吗?那就是:
\ref{tab:foo.*}
或者,甚至更好:
\ref{tab:foo[0-9]*}
我不太希望这个存在。我主要是好奇:有人知道有哪个软件包可以实现这个吗?
答案1
l3regex
LaTeX3 模块可能会有所帮助。
您使用\lazylabel
它来标记对象并\lazyref
使用正则表达式作为其参数。
实际上,对标签的“类别”有支持,这留作练习。
请参阅文档l3regex
以检查正则表达式的精确语法。
\documentclass{article}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\seq_clear_new:N \g_lazylabel_alllabels_seq
\seq_new:N \l_lazylabel_temp_seq
\NewDocumentCommand{\lazylabel}{O{alllabels}m}
{
\label{#2}
\seq_if_in:cnF { g_lazylabel_#1_seq } { #2 }
{ \seq_gput_right:cn { g_lazylabel_#1_seq } { #2 } }
\iow_shipout:cn { @auxout } { \newlazylabel { #1 } { #2 } }
}
\cs_generate_variant:Nn \iow_shipout:Nn { c }
\NewDocumentCommand{\newlazylabel}{m m}
{
\seq_if_exist:cF { g_lazylabel_#1_seq }
{ \seq_new:c { g_lazylabel_#1_seq } }
\seq_if_in:cnF { g_lazylabel_#1_seq } { #2 }
{ \seq_gput_right:cn { g_lazylabel_#1_seq } { #2 } }
}
\NewDocumentCommand{\definelabelclass}{m}
{
\seq_clear_new:c { g_lazylabel_#1_seq }
}
\NewDocumentCommand{\lazyref}{O{alllabels} m}
{
\lazylabel_extract:nn { #1 } { #2 }
}
\cs_new_protected:Npn \lazylabel_extract:nn #1 #2
{
\seq_clear:N \l_lazylabel_temp_seq
\seq_map_inline:cn { g_lazylabel_#1_seq }
{
\regex_match:nnT { #2 } { ##1 }
{
\seq_put_right:Nn \l_lazylabel_temp_seq { \ref{##1} }
}
}
\seq_use:Nnnn \l_lazylabel_temp_seq { ~and~ } { ,~ } { ~and~ }
}
\ExplSyntaxOff
\begin{document}
In sections \lazyref{sec:*} \dots
\section{a}\lazylabel{sec:a}
\section{b}\lazylabel{sec:b}
\begin{table}
\caption{a}\lazylabel{tab:foo}
\caption{a}\lazylabel{tab:foo1}
\caption{a}\lazylabel{tab:foo2}
\caption{a}\lazylabel{tab:bar1}
\end{table}
See tables \lazyref{tab:foo[1-9]+}
\end{document}
答案2
TeX 和 LaTeX 的设置并不适合“执行”正则表达式,至少在没有大量额外编程的情况下是这样。不过,您可能还是很幸运的:该cleveref
软件包可能会执行您想要执行的操作。
例如,命令
\crefrange{tab:foo1}{tab:foo4}
将排版Tables 1 to 4
;当然,这假设标有 的表格{tab:foo1}
已编号1
,并且标有 的表格{tab:foo4}
已编号4
。如果它们的编号为 22 和 25,则命令\crefrange{tab:foo1}{tab:foo4}
将生成Tables 22 to 25
。
\crefrange
如果第一个和最后一个标签指向连续编号的项目(这里是表格,对吧?),则该命令适用。如果不是这种情况,您可以使用该命令
\cref{tab:foo1,tab:foo2,tab:foo3,tab:foo4}
并让cleveref
包对引用进行排序和(如有必要)压缩。例如,如果四个表的编号分别为3
、、4
和,则5
上述命令将生成。如果您不想压缩连续的数字,请确保使用选项加载包;这将导致以下排版输出:。8
\cref
Tables 3 to 5 and 8
[sort]
Tables 3, 4, 5 and 8
如果出于某种原因,你不是想要Table
在交叉引用中包含交叉引用项的“名称”(此处:)——大概是因为您想自己提供它——您可以使用命令\labelcref
而不是\cref
。
最后,如果你hyperref
也使用该包,请务必加载cleveref
后 hyperref
。