我如何确定包裹是按照什么顺序装载的?

我如何确定包裹是按照什么顺序装载的?

\listfiles命令将在文件末尾列出所有已加载的文件(因此也包括包).log,但如何从 LaTeX 内部确定包 A 是在包 B 之前加载还是反之亦然?

答案1

您可以通过逗号分隔的文件名列表访问该列表\@filelist

\begin{document}如果使用后需要进行此项检查\listfiles,那么 LaTeX 会保存该信息。

\listfiles

  \@for\@currname:=\@filelist\do{%
      .....

迭代该列表。

例如你可以定义

\makeatletter

\def\test#1#2{%
\def\hmma{#1.sty}%
\let\hmmb\@empty
\@for\@currname:=\@filelist\do{%
   \ifx\@currname\hmma
     \def\hmmb{#2.sty}%
   \fi
   \ifx\@currname\hmmb
       \typeout{#1 loaded before #2}%
   \fi}}

然后使用它作为:

\test{marginnote}{geometry}

将输入

marginnote loaded before geometry

如果事实确实如此。

正如评论中所述,您可能希望在生产代码中使用不同的命令名称,如果.sty从测试中删除这两个名称,您可以测试其他文件,例如 LaTeX 列出的 class 和 def 文件,但需要明确使用扩展名,因此\test{marginnote.sty}{geometry.sty}

答案2

\usepackage{xparse}这里有一种方法:当然,从到 的代码\ExplSyntaxOff应该在检查任何包之前。命令的定义\test只是为了显示代码可以工作,并且可以删除。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_pkgfirst_list_seq
\bool_new:N \l_pkgfirst_tmpa_bool
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\NewDocumentCommand{\ifpackagefirst}{mmmm}
  {
   \bool_set_false:N \l_pkgfirst_tmpa_bool
   \seq_set_split:Nnx \l_pkgfirst_list_seq {,} { \use:c { @filelist} }
   \seq_if_in:NnT \l_pkgfirst_list_seq {#1} { \bool_set_true:N \l_pkgfirst_tmpa_bool }
   \seq_if_in:NnT \l_pkgfirst_list_seq {#2} { \bool_set_true:N \l_pkgfirst_tmpa_bool }
   \bool_if:NTF \l_pkgfirst_tmpa_bool
     { \pkgfirst_compare:nnnn {#1}{#2}{#3}{#4} }
     { \msg_term:x {OOPS,~packages~not~both~loaded} }
  }
\cs_new:Npn \pkgfirst_compare:nnnn #1 #2 #3 #4
  {
   \bool_set_false:N \l_pkgfirst_tmpa_bool
   \seq_map_inline:Nn \l_pkgfirst_list_seq
     {
      \str_if_eq:nnT { #1 } { ##1 }
        { \prg_map_break:n { \bool_set_true:N \l_pkgfirst_tmpa_bool } }
      \str_if_eq:nnT { #2 } { ##1 }
        { \prg_map_break:n { \bool_set_false:N \l_pkgfirst_tmpa_bool } }
     }
   \bool_if:NTF \l_pkgfirst_tmpa_bool {#3} {#4}
  }


\NewDocumentCommand\test{m m}
  {\ifpackagefirst{#1}{#2}{\msg_term:x {#1~before~#2}}{\msg_term:x {#1~after~#2}}}

\ExplSyntaxOff

\usepackage{graphicx}
\usepackage{imakeidx}
\usepackage{kantlipsum}


\test{graphicx.sty}{imakeidx.sty}

\test{imakeidx.sty}{kantlipsum.sty}

\test{kantlipsum.sty}{graphicx.sty}

\test{pippo.sty}{pluto.sty}

\stop

这是输出:

*************************************************
* graphicx.sty before imakeidx.sty
*************************************************
*************************************************
* imakeidx.sty before kantlipsum.sty
*************************************************
*************************************************
* kantlipsum.sty after graphicx.sty
*************************************************
*************************************************
* OOPS, packages not both loaded
*************************************************

用法:

\ifpackagefirst{package1.sty}{package2.sty}
  {code to be executed if 1 has been loaded before 2}
  {code to be executed if 2 has been loaded before 1}

如果包裹没有两个都加载后,将不会执行任何代码。

答案3

检查文件顺序的一种方法是检查文件中加载的文件的顺序@filelist

\documentclass{book}
\usepackage{graphicx}
\usepackage{longtable}
\usepackage{verse}
\usepackage{hyperref}
\usepackage{caption}
\newcounter{ctr}
\makeatletter
\let\afilelist\@filelist
\begin{document}
% Just to see files
\@for\next:=\afilelist\do{%
 \next, \par
}
% Command factory
\stepcounter{ctr}
\@for\next:=\afilelist\do{%
      \expandafter\edef\csname @\next\endcsname{\thectr}
     \stepcounter{ctr}
}

% Define macro to check order
\def\checkpkgorder#1#2{%
   \edef\X{\csname @#1\endcsname}
    \edef\Y{\csname @#2\endcsname}
    \expandafter\ifnum\X\expandafter<\Y
      Yes loaded earlier \X, \Y
     \else
      No loaded later \X, \Y
   \fi
}

\checkpkgorder{book.cls}{ifxetex.sty}
\end{document}

相关内容