我想编写一个宏来检查输入中是否存在未定义的引用,如果是,则省略生成任何内容。我想像这样工作:
\begin{document}
some text...
\defref{We will see an example of this in \ref{exp:1}}
some more text
\end{document}
在此,宏defref
应该检查标签是否exp:1
已定义,然后打印句子,或者(如果标签未定义)不执行任何操作。
到目前为止,我有这个:
\newcommand{\defref}[2]{
\makeatletter
\@ifundefined{r@#1}{
%do nothing
}{
#2
}
\makeatother
}
它的使用方式是将引用本身作为第一个参数,将所需的输出作为第二个参数:
\begin{document}
some text...
\defref{exp:1}{We will see an example of this in \ref{exp:1}}
some more text
\end{document}
有没有办法让宏在检查其是否定义之前搜索引用?
答案1
下面的代码从参数中提取\defref
所有\ref{...}
部分。
接下来,它处理每个部分;如果它以 开头\ref
,它会使用参数来查看是否r@#1
定义,如果没有定义,则将布尔值设置为 true。
在处理结束时,\defref
仅当布尔值仍然为假时,才会对参数进行排版。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\defref}{m}
{
\stitch_defref:n { #1 }
}
\seq_new:N \l__stitch_defref_seq
\bool_new:N \l__stitch_defref_undefined_bool
\cs_new_protected:Nn \stitch_defref:n
{
\regex_extract_all:nnN { \c{ref}\{.*?\} } { #1 } \l__stitch_defref_seq
\group_begin:
\bool_set_false:N \l__stitch_defref_undefined_bool
\cs_set_eq:NN \ref \__stitch_defref_check:n
\seq_use:Nn \l__stitch_defref_seq { }
\bool_if:NTF \l__stitch_defref_undefined_bool
{ \group_end: }
{ \group_end: #1 }
}
\cs_new_protected:Nn \__stitch_defref_check:n
{
\cs_if_exist:cF { r@#1 } { \bool_set_true:N \l__stitch_defref_undefined_bool }
}
\ExplSyntaxOff
\begin{document}
\section{Test}\label{exp:2}
Some text
X\defref{We will see an example of this in \ref{exp:1}}X
X\defref{We will see an example of this in \ref{exp:2}}X
X\defref{We will see an example of this in \ref{exp:1} or in \ref{exp:2}; who knows?}X
\end{document}
在三个调用中,参数被拆分成的序列如下
The sequence \l__stitch_defref_seq contains the items (without outer braces):
> {\ref {exp:1}}
The sequence \l__stitch_defref_seq contains the items (without outer braces):
> {\ref {exp:2}}
The sequence \l__stitch_defref_seq contains the items (without outer braces):
> {\ref {exp:1}}
> {\ref {exp:2}}