有没有办法\RequirePackage
为文档中使用的软件包创建相互依赖的依赖关系树,最好使用各自所需的选项和版本号?是否有用于此目的的工具或软件包?这对于调试包选项冲突非常重要(参见“包选项和 \RequirePackage:命令顺序和选项冲突吗?“; 也可以看看 ”软件包作者处理软件包冲突的最佳实践是什么?“)。
例如,我不需要graphicx
明确加载,因为dtklogos
(我正在使用的)已经需要/加载它。事实上,graphicx
也需要/加载graphics
和keyval
,而这也恰好是需要/加载的microtype
。等等。我想给出一个涉及包选项冲突的例子,但由于相关的依赖关系很难弄清楚和调试,所以我现在想不出任何例子(我遇到过几个,但由于它们没有编译,我放弃了它们并忘记了它们);这个问题实际上可以帮助解决这一问题。
答案1
我同意约瑟夫的观点,你应该总是明确地需要你需要的任何包,不管其他包是否已经加载了它,但要回答你关于记录依赖关系树的问题,可以\@onefilewithoptions
像这样挂钩(这比仅仅挂钩更好,\RequirePackage
因为它还挂钩类等):
\errorcontextlines=\maxdimen
% begin code to log calls to \@onefilewithoptions (http://tex.stackexchange.com/questions/99723/creating-a-dependency-tree-requirepackage-for-packages-used-in-my-document)
\makeatletter
\def\@log@onefilewithoptions@{}% this will store the file tree
\def\@log@onefilewithoptions@delim{^^J}%
\def\@log@onefilewithoptions#1[#2][#3]#4{% our hook
\ifx\@currnamestack\@empty
\def\@log@onefilewithoptions@tmp{.}%
\else
\edef\@log@onefilewithoptions@tmp{\expandafter\@parse@curnamestack\@currnamestack\@nil}%
\fi
\expandafter\g@addto@macro\expandafter\@log@onefilewithoptions@\expandafter{\@log@onefilewithoptions@tmp}%
\edef\@log@onefilewithoptions@tmp{#4[#2]{#1}[#3]\@log@onefilewithoptions@delim}%
\expandafter\g@addto@macro\expandafter\@log@onefilewithoptions@\expandafter{\@log@onefilewithoptions@tmp}%
}
\def\@parse@curnamestack#1#2#3#4\@nil{%
|%
\@log@onefilewithoptions@ifblank{#4}{%
+%
}{%
\@parse@curnamestack#4\@nil
}%
}
\newcommand{\typeoutonefilewithoptionstree}{\typeout{@onefilewithoptions tree follows:\@log@onefilewithoptions@delim\@log@onefilewithoptions@ end @onefilewithoptions tree.}}
% display the tree at end document (for demonstration purposes)
\AtEndDocument{\typeoutonefilewithoptionstree}%
% patch the original to invoke our hook first, and to show the tree if there's an option clash
\def\@onefilewithoptions#1[#2][#3]#4{%
%added by cyberSingularity
\@log@onefilewithoptions{#1}[#2][#3]{#4}%
%end addition
\@pushfilename
\xdef\@currname{#1}%
\global\let\@currext#4%
\expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty
\let\CurrentOption\@empty
\@reset@ptions
\makeatletter
\def\reserved@a{%
\@ifl@aded\@currext{#1}%
{\@if@ptions\@currext{#1}{#2}{}%
{%added by cyberSingularity
\typeout{Option clash for \@cls@pkg\space #1. To help,}%
\typeoutonefilewithoptionstree
%end addition
\@latex@error
{Option clash for \@cls@pkg\space #1}%
{The package #1 has already been loaded
with options:\MessageBreak
\space\space[\@ptionlist{#1.\@currext}]\MessageBreak
There has now been an attempt to load it
with options\MessageBreak
\space\space[#2]\MessageBreak
Adding the global options:\MessageBreak
\space\space
\@ptionlist{#1.\@currext},#2\MessageBreak
to your \noexpand\documentclass declaration may fix this.%
\MessageBreak
Try typing \space <return> \space to proceed.}}}%
{\@pass@ptions\@currext{#2}{#1}%
\global\expandafter
\let\csname ver@\@currname.\@currext\endcsname\@empty
\InputIfFileExists
{\@currname.\@currext}%
{}%
{\@missingfileerror\@currname\@currext}%
\let\@unprocessedoptions\@@unprocessedoptions
\csname\@currname.\@currext-h@@k\endcsname
\expandafter\let\csname\@currname.\@currext-h@@k\endcsname
\@undefined
\@unprocessedoptions}
\@ifl@ter\@currext{#1}{#3}{}%
{\@latex@warning@no@line
{You have requested,\on@line,
version\MessageBreak
`#3' of \@cls@pkg\space #1,\MessageBreak
but only version\MessageBreak
`\csname ver@#1.\@currext\endcsname'\MessageBreak
is available}}%
\ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi
\@popfilename
\@reset@ptions}%
\reserved@a}
% borrowed from etoolbox (don't really want to load it just for this)
\newcommand{\@log@onefilewithoptions@ifblank}[1]{%
\etb@ifblank@i#1&&\@secondoftwo\@firstoftwo:}
\long\def\etb@ifblank@i#1#2#4#5:{#4}
\makeatother
% end code to log calls to \@onefilewithoptions
% real document begins
\documentclass[a4paper]{article}
\usepackage{graphicx}
\usepackage{keyval}
%\usepackage{tikz}% uncomment this to get an option clash on the next line
\usepackage[svgnames]{xcolor}
\begin{document}
See console output or log file.
\end{document}
现在,当您遇到选项冲突时,您应该在错误发生之前获得依赖关系树的转储。
此外,依赖关系树始终会显示\AtEndDocument
。
请注意,在这两种情况下,都需要检查控制台或日志输出,其中将包含如下内容:
@onefilewithoptions tree follows:
.cls[a4paper]{article}[]
.sty[]{graphicx}[]
|+sty[]{keyval}[]
|+sty[]{graphics}[]
||+sty[]{trig}[]
||+sty[]{infwarerr}[2007/09/09]
||+sty[]{ltxcmds}[2010/12/07]
.sty[]{keyval}[]
.sty[svgnames]{xcolor}[]
end @onefilewithoptions tree.
希望这篇文章足够容易阅读。
答案2
虽然如评论中所述,我建议直接要求那些你使用的包,但包依赖关系“树”的概念已在 LaTeX2e 中得到解决pkgloader
包装:见自动管理包装选项和加载顺序) 了解更多信息。如软件包文档中所述,其理念是,您可以按任意顺序给出要使用的软件包列表,然后它会“整理”出依赖关系树。