让宏检查其输入中的引用

让宏检查其输入中的引用

我想编写一个宏来检查输入中是否存在未定义的引用,如果是,则省略生成任何内容。我想像这样工作:

\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}}

相关内容