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