l3keys
pgfoption と同じように、複数のサブモジュールを処理するために使用できるかどうかを知りたいです。
私の質問を説明するための MWE を以下に示します。
- パッケージ ファイル
mypkg.sty
(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.
- LaTeXファイル
test.tex
:
\documentclass{article}
\usepackage[title=smallcaps, font=regular]{mypkg}
\begin{document}
TEST
\end{document}
答え1
以下は、別のサブモジュールの不明なハンドラーを使用して、サブモジュールのキーをロードします。これにより、グローバル キー (つまり、 に指定されたオプション\documentclass
) が壊れますが、それ以外は適切に機能します。
\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.
概念実証
これは、サブモジュールを介して初期オプションを解析する(グローバル オプションが機能するように)という PoC ですが、将来のオプションは、load
不明なキー ハンドラーで動作する -submodule を介して解析され、すべてのオプションが 1 回だけ解析されます。
確かにこれは少し複雑です。
\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
}
}
答え2
なぜこのようにキーを定義する必要があるのかわかりません。ただし、各モジュールに不明なキーの管理を追加するだけで済みます。
\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]