-
Notifications
You must be signed in to change notification settings - Fork 204
Add support for key value expansion #1769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some minor comments
l3kernel/l3keys.dtx
Outdated
@@ -774,6 +774,23 @@ | |||
% is not processed in any way by \cs{keys_set:nn}. | |||
% \end{variable} | |||
% | |||
% \subsection{Expanding the values of keys} | |||
% | |||
% To allow the user to apply value expansion at point-of-use, key names can be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already at the time the key is set (and not later when it is used), % or something
I find point-of-use difficult to understand as the "usage" seems to happen later not then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to contrast with a key where the expansion is 'built-in', so e.g. \tl_set_e:N
or similar - suggestions on wording welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
normally key values aren't expanded at time of setting and all this expansion stuff is there precisely when no expansion happens. I thought I gave a suggestion. Not good?
l3kernel/l3keys.dtx
Outdated
% \keys_set:nn { mymodule } { key : v = { l_mymodule_value_tl } } | ||
% \keys_set:nn { mymodule } { key : e = \exp_not:V \l_mymodule_value_tl } | ||
% \end{verbatim} | ||
% all pass \texttt{value} to the key handler. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that would then need some adjustment of course
l3kernel/l3keys.dtx
Outdated
Key~values~can~only~be~expanded~using~one~of~the~pre-defined~methods:~ | ||
n,~o,~V,~v~or~e. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c might be useful here too? (given that we support v)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't really make sense - we are expanding n
-type tokens - as I've said, we are in the end storing a token list in the first instance, so the expansion behaviours available do not include c
. Also, really would be odd to do key:c = value
rather than just key = \value
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that depends on what "\value" is, it may contain chars that you can't just write behind a backslash but you need c expansio nto construct it. For example a use who want to have @secntformat as a value. Not insisting but it is similar to supporting v in addition to V (same reason)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point re. v
, but my take is to omit that :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@josephwright I'm not sure why you say c
wouldn't make sense? It would make sense in the same way that c generally makes sense wouldn't it? supporting all the L3 letters seems simpler than subsetting here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Key values are strings, so are (more-or-less) n
-type - you can therefore o
-, V
-, v
-, e
-, f
- or x
-type expand them, but not c
-type. v
-type feels rather odd to do, and we don't really want to encourage new f
- or x
-type usage, hence I've omitted those from the message by design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Key values are strings, [...]
Not l3str string, but n
-type parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I do mean here the general programming idea of a string - so for us a tl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First: Key values are not strings, they are token lists in their most abstract form! (as already established)
Second: Subsetting is more work than simply allowing all variants (make sure it's a single token, stringify and do \cs_if_exist_use:cTF { exp_args:N #1 }
.
Third: There might be valid keys that only take a single token in user land, which might be enforced by additional checks in the user code. For instance a key allowing to define the control sequence in which to store the results of some operation. Here :c
would be helpful.
l3kernel/l3keys.dtx
Outdated
% \tl_set:Nn \l_mymodule_value_tl { value } | ||
% \dime_set:N \l__mymodule_value_dim { 123pt } | ||
% \keys_set:nn { mymodule } { key = value } | ||
% \keys_set:nn { mymodule } { key : o = \l_mymodule_value_tl } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here it would be better to show no space around the :
spaces work here but just because of L3 syntax, you could equally spell the key name as k e y
with spaces. Unlike defining the keys, setting them is often, perhaps usually, lifted up to a document level command and there you need key:e
with no space (unless we want to take the cost of removing spaces by hand.)
\documentclass{article}
\begin{document}
\ExplSyntaxOn
\keys_define:nn {me} {
k .tl_set:N = \l_me_foo_tl
}
\def\myset{\keys_set:nn {me}}
\def\myshow{\show\l_me_foo_tl}
\ExplSyntaxOff
\def\qq{88}
%\myset{k :e=\qq} %expansion ' e' unknown
%\myset{k :e=\qq} %key 'me/k' unknown
%\myset{k : e=\qq} %expansion ' e' unknown
\myset{k:e=\qq} % works
\myshow
\end{document}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could do that, or I could zap the spaces ... thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the analogy with csname suffixes is stronger if you use :e
with no space so I'd be happy to document that form, but in all the other kv parsing I suppose an extra pass to lose space here is another possibility if people want to write key : e
(or could you lose the spaces in the same pass, so ignoring spaces was "free"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed the docs; we do have 'trim spaces only one side' functions, so if we wish to revisit later, the cost of space trimming isn't a disaster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer not show spaces between around the : . In my opinion the syntax should be key:char regardless of the fact that within ExplSyntaxOn you can in fact always write m yk ey : e
or worse to mean mykey:e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still think that c an v are useful, but that can wait until you get user requests :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typos and a bit more.
\cs_new_protected:Npe \@@_find_key_module_auxiv:Nw | ||
#1 #2 \s_@@_nil #3 \s_@@_mark | ||
\s_@@_nil \@@_find_key_module_auxiv:Nw #4 | ||
{ | ||
\cs_set_nopar:Npn #4 { #2 } | ||
\exp_not:N \@@_find_key_module_auxv:Nw #4 | ||
#2 \token_to_str:N : n \token_to_str:N : \s_@@_mark | ||
} | ||
\use:e | ||
{ | ||
\cs_new_protected:Npn \exp_not:N \@@_find_key_module_auxv:Nw | ||
#1 #2 \token_to_str:N : #3 \token_to_str:N : #4 \s_@@_mark | ||
} | ||
{ | ||
\cs_set_nopar:Npn #1 {#2} | ||
\cs_set_nopar:Npn \l_@@_exp_str {#3} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
\token_to_str:N :
can be replaced with \c_colon_str
.
Or, these two function definitions can be wrapped in \@@_tmp:w
, then actually defined by \exp_args:No \@@_tmp:w { \c_colon_str }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but I don't know this is any clearer
Co-authored-by: Yukai Chou <muzimuzhi@gmail.com>
% To allow the user to apply expansion of values when the key is set, rather | ||
% than when they are used, key names can be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still find the distinction with "use" strange. What does "use" mean? The key isn't used when the (internal) variable, which was set to the value given, is used, the variable is used then. So what is key usage?
This is part one of addressing latex3/latex2e#1801 - I also need to do the template code in the 2e repo.
I've chosen to go for the 'higher level'
l3keys
rather than\keyval_parse:nnn
, as the latter is meant to be entirely generic, so to me feels like expansion control is down the programmer there.I expect to write something for
ltnews
but will do that as part of the PR for template code; I may also look at adding something tousrguide
at that point (but that's more tricky as this doesn't affect all keyvals provided by the base distro. most obviously the classicalkeyval
pkg).I've gone for performance over allowing
:
in key names - I hope this minor restriction is not too much of an issue as a breaking change.