Closed xkwxdyy closed 1 month ago
我试了一下,如果这个 hook 和 \RequirePackage{hyperref}
在同一个文件中是可以的:
\documentclass{ctexart}
\usepackage{etoolbox}
\AddToHook{package/hyperref/after}{\hypersetup{hidelinks}}
\AtEndPreamble
{
\RequirePackage{hyperref}
}
\begin{document}
\tableofcontents
\section{test}
test
\end{document}
但是我在项目中处理的时候发现失效了。主要是我的 hook 是在一个库里面设置的,然后通过 cus
加载库,而 \RequirePackage{hyperref}
在 cls
文件中
\AtEndPreamble
{
\AddToHook { package / hyperref / after }
{ \hypersetup { allcolors = black } }
\RequirePackage { hyperref }
\hypersetup
{
pdfencoding = auto,
citecolor = magenta,
linkcolor = blue,
hidelinks
}
}
行不通,而
\AtEndPreamble
{
\RequirePackage { hyperref }
\hypersetup
{
pdfencoding = auto,
citecolor = magenta,
linkcolor = blue,
hidelinks
}
\AddToHook { package / hyperref / after }
{ \hypersetup { allcolors = black } }
}
可以。应该是因为前者相当于
\AtEndPreamble
{
\RequirePackage { hyperref }
\hypersetup { allcolors = black }
\hypersetup
{
pdfencoding = auto,
citecolor = magenta,
linkcolor = blue,
hidelinks
}
}
导致前面的 black 被覆盖了。这么看的话,即使能把 \hypersetup { allcolors = black }
延迟到 hyperref
后面加载,好像我本身的问题也没解决。
为了防止出现 X-Y 问题,我说一下我最初的需求:
\AtEndPreamble
{
\RequirePackage { hyperref }
\hypersetup
{
pdfencoding = auto,
citecolor = magenta,
linkcolor = blue,
hidelinks
}
}
是默认的配置,然后在文档是 for-print
和 for-library
的时候,需要把颜色设置为 black
。然后这个设置是放在了另一个库里。
这么看的话好像只能把 \RequirePackage { hyperref }
和设置放在库里处理了。
目前我想到的唯一办法,就是把 hyperref
的加载放在库里面进行
% -------- %
% 超链接设置 %
% -------- %
\AtEndPreamble
{
\RequirePackage { hyperref }
\hypersetup
{
pdfencoding = auto,
citecolor = magenta,
linkcolor = blue,
hidelinks
}
}
% ----------------- %
% 不同文档类型下的设置 %
% ----------------- %
\cs_set:Nn \__whu_type_for_print_additional_setting:
{
\AtEndPreamble { \hypersetup { allcolors = black } }
}
\cs_set:Nn \__whu_type_for_library_additional_setting:
{
\AtEndPreamble { \hypersetup { allcolors = black } }
}
然后由于 cls
里
\seq_put_right:Nx \l_file_search_path_seq { ./module }
\seq_put_right:Nx \l_file_search_path_seq { ./library }
\seq_put_right:Nx \l_file_search_path_seq { ./library-cus }
\RequirePackage { whu }
\PassOptionsToClass{ \g__whu_to_book_clist }{ book }
\LoadClass { book }
\str_case:Vn \g__whu_type_str
{
{ electronic } { \__whu_type_electronic_setting: }
{ for-print } { \__whu_type_for_print_setting: }
{ for-library } { \__whu_type_for_library_setting: }
}
的
\str_case:Vn \g__whu_type_str
{
{ electronic } { \__whu_type_electronic_setting: }
{ for-print } { \__whu_type_for_print_setting: }
{ for-library } { \__whu_type_for_library_setting: }
}
是在宏包加载之后的,也就会在库调用之后,所以
\cs_set:Nn \__whu_type_for_print_additional_setting:
{
\AtEndPreamble { \hypersetup { allcolors = black } }
}
\cs_set:Nn \__whu_type_for_library_additional_setting:
{
\AtEndPreamble { \hypersetup { allcolors = black } }
}
部分的 \AtEndPreamble
会在
\AtEndPreamble
{
\RequirePackage { hyperref }
\hypersetup
{
pdfencoding = auto,
citecolor = magenta,
linkcolor = blue,
hidelinks
}
}
的后面,从而生效。
\begin{document}
除了会执行通用的环境钩子:env/document/before
env/document/begin
还会执行 begindocument/before
begindocument
begindocument/end
这三个钩子。执行顺序就是这里列出的顺序。
\AtEndPreamble
使用的是 begindocument/before
,\AtBeginDocument
用的是 begindocument
。
可以用的钩子有很多,感觉 cus
可做的不多了。
比如,这个问题就可以用 \AtBeginDocument
解决。
好的,感谢!用 \AtBeginDocument
解决了
场景
希望能开发一个类似于
\CUSLibraryDelayedUntil
用于日常使用的延迟加载命令,比如hyperref
宏包一般是比较晚加载的,比如可能在\AtEndPreamble
时才加载。但是我在前期根据文档选项的不同会进行一些设置,比如如果要打印,就会把hyperref
的 link 去掉,但这部分命令需要在hyperref
宏包使用,而这些设置一般和\AtEndPreamble{\RequirePackage{hyperref}}
不在同一处,甚至不在同一个文件中。想法
我第一反应是
\CUSLibraryDelayedUntil
,但是发现这个只能是把库移动到后面,有点“大”了,我的需求偏向于小的,精准的定位。 然后我看了一下\CUSLibraryDelayedUntil
的源码: https://github.com/Sophanatprime/cus/blob/dd143f406d628a41863a13d71f9264d8767133fc/cus.sty#L236-L262发现本质上也是用钩子
\hook_gput_code:nnn { package/#2/after }
,钩在 package 的后面,但是这个操作还是有点底层了,不仅用于开发,日常在 2e 层可能也会有这个需求。所以希望能开发一个这样的命令。