\ExplSyntaxOn \cs_new_protected:Npn \__expkvdoc_patchfootnote:% >>= { \cs_set:Npx \footnote { \exp_not:n { \ClassError {expkvdoc} {Footnote~ in~ function} {} } \exp_not:o { \footnote } } }% =<< \AddToHook{env/function/begin}{\__expkvdoc_patchfootnote:} \group_begin: \cs_set_protected:Npn \__expkvdoc_tmp:nN #1#2 { \__kernel_tl_set:Nx #2 { \tl_to_str:n {#1} } \tl_replace_all:Nxn #2 { \c_underscore_str } { / } \tl_remove_all:Nx #2 { \c_backslash_str } \tl_put_left:Nn #2 { doc/function// } } \cs_if_eq:NNTF \__expkvdoc_tmp:nN \__codedoc_get_hyper_target:nN { \cs_gset:Npn \__codedoc_get_hyper_target:nN #1#2 { \__kernel_tl_set:Nx #2 { \tl_to_str:n {#1} } \tl_replace_all:Nxn #2 { \c_underscore_str } { / } \tl_remove_all:Nx #2 { \c_backslash_str } \tl_put_left:Nx #2 { doc/function/ \g__expkvdoc_module_str / } } } { \ClassWarning{expkvdoc} { Didn't~ patch~ l3doc's~ hyper~ targets.~ You~ might~ get~ duplicate~ labels. } } \group_end: \ExplSyntaxOff