You can use \text_expand:n
to have a sort of expansion that should work for commands (there might be edge cases which aren't handled correctly though, \text_expand:n
isn't the most simple macro).
But honestly, I think it's easier to set the name macro in an different way than via a variable in a frozen/precompiled kv-list.
Anyways, first the code that shows your current way, but with \text_expand:n
:
\documentclass{article}
\usepackage{amsthm}
\ExplSyntaxOn
\keys_define:nn { thmkeys/thm }
{
name .tl_set:N = \l_thmkeys_thm_name_tl,
}
\tl_new:N \l_thmkeys_thm_defaultkeys_tl
\keys_precompile:nnN { thmkeys/thm }
{
name = \text_titlecase:n { \l_thmkeys_thm_envname_tl },
}
\l_thmkeys_thm_defaultkeys_tl
\NewDocumentCommand { \NewThm } { m O{} }
{
% Store envname
\tl_set:Nn \l_thmkeys_thm_envname_tl { #1 }
% Set default keys
\tl_use:N \l_thmkeys_thm_defaultkeys_tl
% Set env-specific keys
\keys_set:nn { thmkeys/thm } { #2 }
% Call \newtheorem
\thmkeys_thm_new:ne { #1 } { \text_expand:n { \l_thmkeys_thm_name_tl } }
}
\cs_new_eq:NN \thmkeys_thm_new:nn \newtheorem
\cs_generate_variant:Nn \thmkeys_thm_new:nn { ne }
\ExplSyntaxOff
\NewThm{theorem}
\NewThm{prop}[name=\textit{Proposition}]
\NewThm{lemma}
\begin{document}
\begin{theorem}
text
\end{theorem}
\begin{prop}
text
\end{prop}
\begin{lemma}
text
\end{lemma}
\end{document}
A variant that doesn't use a precompiled kv-list but instead sets the default (at least for name
) inside of \keys_set:nn
:
\documentclass{article}
\usepackage{amsthm}
\ExplSyntaxOn
\keys_define:nn { thmkeys/thm }
{
name .tl_set:N = \l_thmkeys_thm_name_tl,
}
\NewDocumentCommand { \NewThm } { m O{} }
{
% Store envname
\tl_set:Nn \l_thmkeys_thm_envname_tl { #1 }
% Set env-specific keys
\exp_args:Nne \keys_set:nn { thmkeys/thm }
{ name = { \text_titlecase:n {#1} }, \exp_not:n {#2} }
% Call \newtheorem
\thmkeys_thm_new:nV { #1 } { \l_thmkeys_thm_name_tl }
}
\cs_new_eq:NN \thmkeys_thm_new:nn \newtheorem
\cs_generate_variant:Nn \thmkeys_thm_new:nn { nV }
\ExplSyntaxOff
\NewThm{theorem}
\NewThm{prop}[name=\textit{Proposition}]
\NewThm{lemma}
\begin{document}
\begin{theorem}
text
\end{theorem}
\begin{prop}
text
\end{prop}
\begin{lemma}
text
\end{lemma}
\end{document}
Another version using expkv
1 instead of l3keys
. expkv
also features precompiling key lists, but inside of expkv
the precompilation works slightly different. Here the key list isn't fixed (well, the key list is, but not the values), but instead \ekvcompile
works like \cs_set:Npn
with key-value processing intervined. This way, you can precompile your keys, but still give different values to the individual keys via macro arguments.
In expkv-def
(a kv-list based frontend to define keys in expkv
) the equivalent of .tl_set:N
is named store
. Note that expkv
uses space-delimited prefixes instead of .
-separated postfixes to denote the key types.
The drawback is that you mix in non-L3-syntax into your code, as exkpv
isn't programmed in L3, and has no frontend for it.
1Disclaimer: I'm the author of expkv
\documentclass{article}
\usepackage{amsthm}
\usepackage{expkv-def}
\ExplSyntaxOn
\ekvdefinekeys { thmkeys/thm }
{
store~ name = \l_thmkeys_thm_name_tl
}
\ekvcompile \__thmkeys_defaults:n #1 { thmkeys/thm } { name = {#1} }
\cs_generate_variant:Nn \__thmkeys_defaults:n { e }
\NewDocumentCommand { \NewThm } { m O{} }
{
% Store envname
\tl_set:Nn \l_thmkeys_thm_envname_tl { #1 }
% Set defaults
\__thmkeys_defaults:e { \text_titlecase:n { \l_thmkeys_thm_envname_tl } }
% Set env-specific keys
\ekvset { thmkeys/thm } { #2 }
% Call \newtheorem
\thmkeys_thm_new:nV { #1 } { \l_thmkeys_thm_name_tl }
}
\cs_new_eq:NN \thmkeys_thm_new:nn \newtheorem
\cs_generate_variant:Nn \thmkeys_thm_new:nn { nV }
\ExplSyntaxOff
\NewThm{theorem}
\NewThm{prop}[name=\textit{Proposition}]
\NewThm{lemma}
\begin{document}
\begin{theorem}
text
\end{theorem}
\begin{prop}
text
\end{prop}
\begin{lemma}
text
\end{lemma}
\end{document}
Yet another pure L3 answer could be to, instead of setting your name
key directly to your envname
, set it to \q_no_value
, and later check whether it's \q_no_value
, and if so, use your envname
.
This variant has the additional advantage that \text_titlecase:n
is only used if really necessary (and \text_titlecase:n
is comparatively slow).
\documentclass{article}
\usepackage{amsthm}
\ExplSyntaxOn
\keys_define:nn { thmkeys/thm }
{
name .tl_set:N = \l_thmkeys_thm_name_tl,
}
\tl_new:N \l_thmkeys_thm_defaultkeys_tl
\keys_precompile:nnN { thmkeys/thm }
{
name = \q_no_value,
}
\l_thmkeys_thm_defaultkeys_tl
\NewDocumentCommand { \NewThm } { m O{} }
{
% Store envname
\tl_set:Nn \l_thmkeys_thm_envname_tl { #1 }
% Set default keys
\tl_use:N \l_thmkeys_thm_defaultkeys_tl
% Set env-specific keys
\keys_set:nn { thmkeys/thm } { #2 }
% Call \newtheorem
\quark_if_no_value:NTF \l_thmkeys_thm_name_tl
{
\thmkeys_thm_new:ne {#1}
{ \text_titlecase:n { \l_thmkeys_thm_envname_tl } }
}
{ \thmkeys_thm_new:nV {#1} \l_thmkeys_thm_name_tl }
}
\cs_new_eq:NN \thmkeys_thm_new:nn \newtheorem
\cs_generate_variant:Nn \thmkeys_thm_new:nn { nV, ne }
\ExplSyntaxOff
\NewThm{theorem}
\NewThm{prop}[name=\textit{Proposition}]
\NewThm{lemma}
\begin{document}
\begin{theorem}
text
\end{theorem}
\begin{prop}
text
\end{prop}
\begin{lemma}
text
\end{lemma}
\end{document}
envname
variable instead of directly setting yourname
variable? This seems like an unnecessary indirection.\keys_precompile
where I can't sayname = \text_titlecase:n { #1 }
. There are supposedly speed benefits to precompiling but perhaps that's negated by the misdirection...\tl_set:Nn \l_thmkeys_thm_name_tl { \text_titlecase:n { #1 } }
. That is clearly better. Please feel free to post as an answer\tl_set:Nn
(well, actually a\tl_set:Ne
/\tl_set:Nx
-- better to pay the\text_titlecase:n
overhead once even if unnecessary than on each usage later out in the document), but I think I added a slightly different answer, that might be more interesting, as it shows different ways to achieve this.