这属于“有用但令我紧张的事情”类别。
我在 LuaLaTeX 中使用了一个非常复杂的自定义文档类。但我的问题可以用这个通用的 MWE 轻松说明:
\documentclass{article}
\RequirePackage{xifthen}
\RequirePackage{letltxmacro}
\LetLtxMacro\myusepackage\usepackage\relax
\LetLtxMacro\myRequirePackage\RequirePackage\relax
\renewcommand\usepackage[2][]{%
\ifthenelse{\equal{#2}{hyperref}}{}{\myusepackage[#1]{#2}}%
}
\renewcommand\RequirePackage[2][]{%
\ifthenelse{\equal{#2}{hyperref}}{}{\myRequirePackage[#1]{#2}}%
}
%
\usepackage{xstring} % should work
\usepackage{hyperref} % should do nothing
%
\begin{document}
OK
\end{document}
如果用户尝试加载 hyperref,它将被默默忽略。我知道还有其他替代方案,例如\PassOptionsToPackage
,但这不是我想要的效果。
我经常修补各种 LaTeX 包中的命令,但这些是可选包中的高级命令,而不是像\usepackage
或 这样的基本命令\RequirePackage
。所以我的问题是:上述 MWE 代码是否有任何隐藏的陷阱?
我只是hyperref
为了 MWE 的目的而选择的,所以没有必要问为什么我要在真实文档中阻止它。
编辑:对于那些想知道我为什么要这样做的人:由于\immediate\write
命令,我的自定义文档类需要以精确的顺序加载某些内容。 如果用户过早加载包,目前我会通过在类代码中抛出错误来检测\@ifpackageloaded
,就在我自己的代码加载包之前\AtEndPreamble
。 但在我看来,简单地忽略过早加载会更加用户友好。
EDIT2:根据评论和回答,我认为我应该保留我目前的方法,而不是按照问题要求去做。“糟糕的用户界面”(DC 的说法)是一个重点。
无需深入研究超过 200K 字节的自定义文档类,我可以说明我一直在做什么。这已经运行了好几个月了。“myscustomclass.cls”的一般概念如下:
a) 当 mycustomclass 加载时,它还会加载和预配置许多包。它还提供自己的命令。
b) 它包含\AtEndPreamble
将加载和配置附加包。这些包直到用户前言之后才能加载,因为它需要查看用户前言并决定要做什么。
c) 至少一个稍后加载的包具有\immediate\write
,这不能早于某个时间发生。这就是为什么它被推迟到\AtEndPreamble
。
目前(良好的工作代码)我做这样的事情:
\AtEndPreamble{
% lots of code here
@ifpackageloaded{hyperref}{ % Should not have been loaded by user! Too early!
\ClassError{mycustomclass}%
{Cannot load hyperref in preamble}{See myscustomclass docs section XX.XXX}
}{
\usepackage[various options]{hyperref}
}
% lots of code here
}
答案1
不确定这里的问题是什么,但\usepackage
在某些情况下,如图所示的修补将无法按预期工作,例如
\usepackage{longtable,hyperref}
因为它不会将其hyperref
视为参数,并且它将完全破坏有效的用法,例如
\usepackage{hyperref}[2001/01/01]
因为它删除了可选参数,所以 latex 会尝试[2001/01/01]
在序言中进行排版。
答案2
此外大卫的回答, 考虑
\usepackage{bookmark}
bookmark.sty
包括
\RequirePackage{hyperref}[2010/06/18]
以及一堆其他的东西,然后是一堆依赖于的代码hyperref
。
或者
\usepackage[<options>]{hyperref}
您只是丢弃了用户的选项。
或者
\usepackage{hyperref}
\usepackage{cleveref}
或者其他必须在之后加载的包hyperref
。
或者
\usepackage{hyperref}
\hypersetup{...}