如何挂接 \input{foo/bar} 而不是 \input{bar}?

如何挂接 \input{foo/bar} 而不是 \input{bar}?

考虑以下导入两个不同名称的文件bar并使用file/before/...钩子的根文档。

\documentclass{minimal}
\begin{document}
\ExplSyntaxOn
\AddToHook { file/before/bar } {
  \iow_term:n { ****~HOOKED }
}
\input{bar}
\input{foo/bar}
\end{document}

排版完成后,终端显示**** HOOKED 两次,各一个\input

我怎样才能挂接\input{foo/bar}但不进入\input{bar},同时仍导入两个文档?

我正在猜测某种解决方案\CurrentFilePath但它似乎过于复杂。

答案1

检查 \CurrentFilePath 有什么过于复杂的?

\documentclass{minimal}
\begin{document}
\ExplSyntaxOn
\AddToHook { file/before/bar.tex } {
  \str_if_in:NnT\CurrentFilePath{bib}
   {
    \iow_term:n { ****~HOOKED }
   } 
}
\ExplSyntaxOff
\input{bar}
\input{bib/bar}
\end{document}

答案2

这是考虑完整路径的概念证明,而不仅仅是最后一个组件。我们都从钩子中添加或删除代码。我们假设bar.texfoo/bar.texfoo.tex可用。

\documentclass{minimal}
\ExplSyntaxOn
\cs_set:Npn \myLog #1 {
  \iow_term:x { ****~#1 }
}
\NewDocumentCommand\myAddToFileBefore { m } {
  \group_begin:
  \regex_set:Nn \l_tmpa_regex { \A \s* (?:(.*)\/)? \s* (.*?) \s* \Z }
  \regex_extract_once:NnNTF \l_tmpa_regex { #1 } \l_tmpa_seq {
    \cs_set:Nn \my_tmpa:nn {
      \AddToHook { file/before/##2 } [ my/file/before/#1 ] {
        \str_if_eq:VnT \CurrentFilePath { ##1 } {
          \myLog{HOOKED~#1 }
        }
      }
    }
    \cs_generate_variant:Nn \my_tmpa:nn { xx }
    \my_tmpa:xx { \seq_item:Nn \l_tmpa_seq 2 } { \seq_item:Nn \l_tmpa_seq 3 }
  } {
    \myLog{Bad argument:~#1 }
  }
  \group_end:
}
\NewDocumentCommand\myRemoveFromFileBefore { m } {
  \regex_set:Nn \l_tmpa_regex { \A \s* (?:(.*)\/)? \s* (.*?) \s* \Z }
  \regex_extract_once:NnNTF \l_tmpa_regex { #1 } \l_tmpa_seq {
    \RemoveFromHook { file/before/\seq_item:Nn \l_tmpa_seq 3 } [ my/file/before/#1 ]
  } {
    \myLog{Bad argument:~#1 }
  }
}
\ExplSyntaxOff
\begin{document}
NO INPUT
\myLog{EXPECTED NO HOOK}
\input{bar.tex}        % (./bar.tex)
\input{foo/bar.tex}    % (./foo/bar.tex)
\input{foo.tex}        % (./foo.tex)
\myLog{EXPECTED HOOKED bar.tex}
\myAddToFileBefore{bar.tex}
\input{bar.tex}        % **** HOOKED bar.tex (./bar.tex)
\input{foo/bar.tex}    % (./foo/bar.tex)
\input{foo.tex}        % (./foo.tex)
\myLog{EXPECTED HOOKED bar.tex and foo/bar.tex}
\myAddToFileBefore{foo/bar.tex}
\input{bar.tex}        % **** HOOKED bar.tex (./bar.tex)
\input{foo/bar.tex}    % **** HOOKED foo/bar.tex (./foo/bar.tex)
\input{foo.tex}        % (./foo.tex)
\myLog{EXPECTED HOOKED foo/bar.tex}
\myRemoveFromFileBefore{bar.tex}
\input{bar.tex}        % **** (./bar.tex)
\input{foo/bar.tex}    % **** HOOKED foo/bar.tex (./foo/bar.tex)
\input{foo.tex}        % (./foo.tex)
\myLog{EXPECTED NO HOOK}
\myRemoveFromFileBefore{foo/bar.tex}
\input{bar.tex}        % (./bar.tex)
\input{foo/bar.tex}    % (./foo/bar.tex)
\input{foo.tex}        % (./foo.tex)
\end{document}

解释和评论:

  1. \myAddToFileBefore向终端添加一些代码日志,仅当当前路径是预期路径时才在文件输入之前执行
  2. \myRemoveFromFileBefore删除同一段代码。
  3. \AddToHook“技巧”是在和中使用标签\RemoveFromHook
  4. 然后,我们\inputbar.tex其中一个添加代码或删除代码
  5. 每行的注释读取相应的终端输出
  6. 正则表达式提取后可能会发生一些路径规范化。
  7. foo.tex从未上钩。

相关内容