Me gustaría saber si puedo usarlo l3keys
para procesar múltiples submódulos como lo puede hacer pgfoption.
Aquí hay un MWE para ilustrar mi pregunta:
- un archivo de paquete
mypkg.sty
(que contiene en el comentario el error que aparece cuando intento compilar el archivo LaTeX):
\ProvidesExplPackage{mypkg}{2024/01/01}{v0.0.0}{mypkg test}
\keys_define:nn { mypkg / title }
{
title .choice:,
title .usage:n = { general },
title .default:n = { regular },
title / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~title!}
},
title / smallcaps .code:n =
{
\PackageWarning {mypkg} {We~use~smallcaps~title!}
},
title / unknown .code:n = { \PackageWarning {mypkg} {unknown~title~option!} },
}
\keys_define:nn { mypkg / font }
{
font .choice:,
font .usage:n = { general },
font .default:n = { regular },
font / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~font!}
},
font / bold .code:n =
{
\PackageWarning {mypkg} {We~use~bold~font!}
},
font / unknown .code:n = { \PackageWarning {mypkg} {unknown~font~option!} },
}
% \ProcessKeyOptions % -> ! LaTeX Error: Unknown option 'title' for package mypkg.
\ProcessKeyOptions[mypkg/title, mypkg/font] % -> ! LaTeX Error: Unknown option 'title' for package mypkg.
% \ProcessKeyOptions[mypkg/title] % -> ! LaTeX Error: Unknown option 'font' for package mypkg.
% \ProcessKeyOptions[mypkg/font] % -> ! LaTeX Error: Unknown option 'title' for package mypkg.
- un archivo LaTeX
test.tex
,:
\documentclass{article}
\usepackage[title=smallcaps, font=regular]{mypkg}
\begin{document}
TEST
\end{document}
Respuesta1
Lo siguiente utiliza un controlador desconocido de otro submódulo más para cargar las claves de sus submódulos. Esto rompe las claves globales (por lo que las opciones dadas a \documentclass
) pero por lo demás funciona razonablemente bien.
\ProvidesExplPackage{mypkg}{2024/01/01}{v0.0.0}{mypkg test}
\seq_const_from_clist:Nn \c__mypkg_load_submodules_seq { title, font }
\keys_define:nn { mypkg / load }
{
unknown .code:n =
\__mypkg_keymodules:Vn \l_keys_key_str {#1}
}
\cs_new_protected:Npn \__mypkg_keymodules:nn #1#2
{
\seq_map_inline:Nn \c__mypkg_load_submodules_seq
{
\keys_if_exist:nnT { mypkg / ##1 } {#1}
{
% missing feature in l3keys, we have no better way to detect an
% omitted value, so we have to guess that all empty values are in
% fact omitted values.
\tl_if_empty:nTF {#2}
{ \keys_set:nn { mypkg / ##1 } { #1 } }
{ \keys_set:nn { mypkg / ##1 } { #1 = {#2} } }
\prg_break:
}
}
\msg_error:nnn { mypkg } { unknown-key } {#1}
\prg_break_point:
}
\cs_generate_variant:Nn \__mypkg_keymodules:nn { Vn }
\msg_new:nnn { mypkg } { unknown-key } { Unknown~ key~ #1~ encountered. }
\keys_define:nn { mypkg / title }
{
title .choice:,
title .usage:n = { general },
title .default:n = { regular },
title / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~title!}
},
title / smallcaps .code:n =
{
\PackageWarning {mypkg} {We~use~smallcaps~title!}
},
title / unknown .code:n = { \PackageWarning {mypkg} {unknown~title~option!} },
}
\keys_define:nn { mypkg / font }
{
font .choice:,
font .usage:n = { general },
font .default:n = { regular },
font / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~font!}
},
font / bold .code:n =
{
\PackageWarning {mypkg} {We~use~bold~font!}
},
font / unknown .code:n = { \PackageWarning {mypkg} {unknown~font~option!} },
}
\ProcessKeyOptions[mypkg/load] % -> ! LaTeX Error: Unknown option 'title' for package mypkg.
prueba de concepto
Esta es una PoC para analizar las opciones iniciales a través de los submódulos (para que las opciones globales funcionen), pero cualquier opción futura a través de nuestro load
submódulo actúa con un controlador de clave desconocida, todo eso mientras se analiza cada opción solo una vez.
Es cierto que esto es un poco complicado.
\ProvidesExplPackage{mypkg}{2024/01/01}{v0.0.0}{mypkg test}
\seq_const_from_clist:Nn \c__mypkg_load_submodules_seq { title, font }
\cs_new_protected:Npn \__mypkg_keymodules:nn #1#2
{
\seq_map_inline:Nn \c__mypkg_load_submodules_seq
{
\keys_if_exist:nnT { mypkg / ##1 } {#1}
{
% missing feature in l3keys, we have no better way to detect an
% omitted value, so we have to guess that all empty values are in
% fact omitted values.
\tl_if_empty:nTF {#2}
{ \keys_set:nn { mypkg / ##1 } { #1 } }
{ \keys_set:nn { mypkg / ##1 } { #1 = {#2} } }
\prg_break:
}
}
\msg_error:nnn { mypkg } { unknown-key } {#1}
\prg_break_point:
}
\cs_generate_variant:Nn \__mypkg_keymodules:nn { Vn }
\msg_new:nnn { mypkg } { unknown-key } { Unknown~ key~ #1~ encountered. }
\keys_define:nn { mypkg / title }
{
title .choice:,
title .usage:n = { general },
title .default:n = { regular },
title / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~title!}
},
title / smallcaps .code:n =
{
\PackageWarning {mypkg} {We~use~smallcaps~title!}
},
title / unknown .code:n = { \PackageWarning {mypkg} {unknown~title~option!} },
unknown .code:n = {}
}
\keys_define:nn { mypkg / font }
{
font .choice:,
font .usage:n = { general },
font .default:n = { regular },
font / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~font!}
},
font / bold .code:n =
{
\PackageWarning {mypkg} {We~use~bold~font!}
},
font / unknown .code:n = { \PackageWarning {mypkg} {unknown~font~option!} },
unknown .code:n = {}
}
\ProcessKeyOptions[mypkg/title]
\ProcessKeyOptions[mypkg/font]
\keys_define:nn { mypkg / load }
{
unknown .code:n = {}
}
\ProcessKeyOptions[mypkg/load] % -> ! LaTeX Error: Unknown option 'title' for package mypkg.
\keys_define:nn { mypkg / load }
{
unknown .code:n =
\__mypkg_keymodules:Vn \l_keys_key_str {#1}
}
\clist_map_inline:nn { title, font }
{
\keys_define:nn { mypkg / #1 }
{
\unknown .code:n =
\msg_error:nne { mypkg } { unknown-key } \l_keys_key_str
}
}
Respuesta2
No estoy seguro de por qué querrías definir claves de esta manera. Pero puedes simplemente agregar administración de claves desconocidas en cada módulo.
\ProvidesExplPackage{mypkg}{2024/01/01}{v0.0.0}{mypkg test}
\keys_define:nn { mypkg/title }
{
title .choice:,
title .usage:n = { general },
title .default:n = { regular },
title / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~title!}
},
title / smallcaps .code:n =
{
\PackageWarning {mypkg} {We~use~smallcaps~title!}
},
title / unknown .code:n = { \PackageWarning {mypkg} {unknown~title~option!} },
unknown .code:n = {},
}
\keys_define:nn { mypkg/font }
{
font .choice:,
font .usage:n = { general },
font .default:n = { regular },
font / regular .code:n =
{
\PackageWarning {mypkg} {We~use~regular~font!}
},
font / bold .code:n =
{
\PackageWarning {mypkg} {We~use~bold~font!}
},
font / unknown .code:n = { \PackageWarning {mypkg} {unknown~font~option!} },
unknown .code:n = {},
}
\ProcessKeyOptions[mypkg/title]
\ProcessKeyOptions[mypkg/font]