If one defines a command with a key-value argument, say \ket[<key=value>]{<stuff>}
, one gets the wrong output when nesting it (in my opinion). E.g. \ket[delim = |)]{ \ket{\psi} }
changes the delimiters of both kets, but should only do it for the outer one, if \ket
is defined as
\NewDocumentCommand{\ket}{ o m }
{
\group_begin:
\IfNoValueF{#1} { \mymodule_set_keys:n {#1} }
\mymodule_ket:n {#2}
\group_end:
}
A quick solution would be to set the keys to their default values when the o
-argument is not given as below.
\NewDocumentCommand{\ket}{ o m }
{
\group_begin:
\IfNoValueTF{#1}
{ \mymodule_set_keys:n { delim } }
{ \mymodule_set_keys:n {#1} }
\mymodule_ket:n {#2}
\group_end:
}
This solution wouldn't allow changes made by the user with \mymoduleset
(I call this 'user default' in the MWE's comments below), say \mymoduleset[delim = \langle|]
.
The idea is that when the command \ket
is defined, it should initially use the packages default values i.e. delim .default:n = {\lvert\rangle}
, but when the user want a different output for all \ket
's (globally in some sense), then he can change it with \mymoduleset
, such that \ket{<stuff>}
produces \langle <stuff> |
when \mymoduleset[delim = \langle|]
is used.
How can one achieve a solution, which
- allows 'global' changes by the user with
\mymoduleset
- and local changes i.e.
\ket[<key=value>]{<stuff>}
doesn't affect inner\ket
's when nestet i.g.\ket[delim = |)]{ \ket{\psi} }
MWE
\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}
\ExplSyntaxOn
\tl_new:N \l__mymodule_ket_delim_tl
\keys_define:nn { mymodule }
{
delim .tl_set:N = \l__mymodule_ket_delim_tl,
delim .default:n = {\lvert\rangle}
}
\cs_new_protected:Npn \mymodule_ket:n #1
{
\tl_item:Nn \l__mymodule_ket_delim_tl {1}
#1
\tl_item:Nn \l__mymodule_ket_delim_tl {2}
}
\cs_new_protected:Npn \mymodule_set_keys:n #1
{ \keys_set:nn { mymodule } {#1} }
\NewDocumentCommand{\ket}{ o m }
{
\group_begin:
\IfNoValueTF{#1}
{ \mymodule_set_keys:n { delim } } % package default, but should be user default
{ \mymodule_set_keys:n {#1} } % local change for this macro only
\mymodule_ket:n {#2}
\group_end:
}
\NewDocumentCommand{\mymoduleset}{ o }
{
\IfNoValueTF{#1}
{ \mymodule_set_keys:n { delim } } % Package default
{ \mymodule_set_keys:n {#1} } % User default
}
\ExplSyntaxOff
\mymoduleset
\begin{document}
\begin{align}
\ket{\psi} &\quad \text{desired result: } | \psi \rangle \\
\ket{ \ket{\psi} } &\quad \text{desired result: } || \psi \rangle\rangle \\
\ket[delim = |)]{ \ket{\psi} } &\quad \text{desired result: } || \psi \rangle ) \\
\ket{ \ket[delim = |)]{\psi} } &\quad \text{desired result: } || \psi ) \rangle
\end{align}
\mymoduleset[delim = {\langle\rvert}]
\begin{align}
\ket{\psi} &\quad \text{desired result: } \langle \psi | \\
\ket{ \ket{\psi} } &\quad \text{desired result: } \langle\langle \psi || \\
\ket[delim = (|]{ \ket{\psi} } &\quad \text{desired result: } ( \langle \psi || \\
\ket{ \ket[delim = (|]{\psi} } &\quad \text{desired result: } \langle ( \psi ||
\end{align}
\end{document}
Note: The MWE above is not the actual use case but illustrate the problem. The actual use case is too long to write here