这是这个帖子。最初的问题是将某些函数的选项存储在某个容器中。此类函数的示例:\includepdf
、 或\newwatermark
。如果选项很多且\function[options]
需要重复使用,这种方法会很有用。如果选项直接存储在 中l3seq
(第一种方法),则可以正常工作。但我想将选项存储在 中,l3prop
因为它可以处理重复项(例如,如果我在扩展点更新选项)。因此,在扩展点需要一个额外的步骤:将选项从 转移到l3prop
,l3seq
然后使用 进行扩展\seq_use:Nn
。这定义了第二种方法。它适用于\includepdf
,但不适用于\newwatermark
。但是,有人指出该l3prop
方法不保留 catcode,特别是将键的 catcode 更改为l3str
。建议的解决方案(下面的代码)带有以下标题:“该代码的第一部分对应于您的编程,结果为 FALSE。在第二种情况下,键在构造上仍然是字符串,结果为 TRUE。”它识别了代码失败的位置,但并未解决问题。因此,主题行中的挑战是:能够将 key-val 对存储在 中l3prop
,并且能够恢复提供给它们的 catcode。特别是,它们的扩展适用于\newwatermark[options]
。
附言:有人建议xwatermark
完全放弃。我指出我遇到了问题background
。
\documentclass{article}
\begin{document}
\ExplSyntaxOn
{
\seq_set_from_clist:Nn \l_tmpa_seq { key = smth }
\prop_set_from_keyval:Nn \l_tmpa_prop { key = smth }
\prop_map_inline:Nn \l_tmpa_prop { \seq_put_right:Nn \l_tmpb_seq { #1 = #2 } }
\tl_set:Nf \l_tmpa_tl { \seq_use:Nn \l_tmpa_seq { } }
\tl_set:Nf \l_tmpb_tl { \seq_use:Nn \l_tmpb_seq { } }
\tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { TRUE } { FALSE } % return FALSE
}
--
{
\str_set:Nn \l_tmpa_str { key }
\exp_args:NNx \seq_set_from_clist:Nn \l_tmpa_seq { \l_tmpa_str = smth }
\exp_args:NNx \prop_set_from_keyval:Nn \l_tmpa_prop { \l_tmpa_str = smth }
\prop_map_inline:Nn \l_tmpa_prop { \seq_put_right:Nn \l_tmpb_seq { #1 = #2 } }
\tl_set:Nf \l_tmpa_tl { \seq_use:Nn \l_tmpa_seq { } }
\tl_set:Nf \l_tmpb_tl { \seq_use:Nn \l_tmpb_seq { } }
\tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { TRUE } { FALSE } % return TRUE
}
\ExplSyntaxOff
\end{document}
答案1
下面为替代prop
结构(基于l3prop
的类型)定义了一组函数,该函数将密钥存储两次,一次作为正常prop
密钥,一次以未标记化的形式存储在prop
的值中。这些函数都名为\erwannprop_...
,变量..._eprop
。这些函数只是l3prop
和l3seq
函数的薄包装。
\documentclass[]{article}
\ExplSyntaxOn
\cs_new_protected:Npn \erwannprop_new:N #1
{ \prop_new:N #1 }
\msg_new:nnn { erwannprop } { no-value }
{ Missing~ '='~ in~ '#1'~ (in~ ..._keyval:Nn) }
\cs_new_protected:Npn \erwannprop_set_from_keyval:Nn #1#2
{
\prop_clear:N #1
\keyval_parse:nnn
{ \msg_error:nnn { erwannprop } { no-value } }
{ \erwannprop_put:Nnn #1 }
{#2}
}
\cs_new_protected:Npn \erwannprop_put:Nnn #1#2#3
{ \prop_put:Nnn #1 {#2} { {#2} {#3} } }
\cs_new_protected:Npn \erwannprop_to_seq:NN #1#2
{
\seq_clear:N #2
\prop_map_tokens:Nn #1 { \__erwannprop_to_seq:Nnn #2 }
}
\cs_new_protected:Npn \__erwannprop_to_seq:Nnn #1#2#3
{ \__erwannprop_to_seq_aux:Nnn #1 #3 }
\cs_new_protected:Npn \__erwannprop_to_seq_aux:Nnn #1#2#3
{ \seq_put_right:Nn #1 { #2 = #3 } }
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\erwannprop_new:N \l_tmpa_eprop
\seq_set_from_clist:Nn \l_tmpa_seq { key = smth }
\erwannprop_set_from_keyval:Nn \l_tmpa_eprop { key = smth }
\erwannprop_to_seq:NN \l_tmpa_eprop \l_tmpb_seq
\tl_set:Nf \l_tmpa_tl { \seq_use:Nn \l_tmpa_seq { } }
\tl_set:Nf \l_tmpb_tl { \seq_use:Nn \l_tmpb_seq { } }
\tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { TRUE } { FALSE }
\ExplSyntaxOff
\end{document}
答案2
可以使用 来重新\tl_set_rescan:Nnn
标记expl3
。
但是,我们根本不推荐这样做。正如文档中所说(interface3.pdf
):
虽然支持此功能,但通常最好找到实现结果的替代方法,而不是重新扫描令牌。
我写这个答案只是为了提供一般信息。
\documentclass{article}
\begin{document}
\ExplSyntaxOn
{
\seq_set_from_clist:Nn \l_tmpa_seq { key = smth }
\prop_set_from_keyval:Nn \l_tmpa_prop { key = smth }
\prop_map_inline:Nn \l_tmpa_prop { \seq_put_right:Nn \l_tmpb_seq { #1 = #2 } }
\tl_set:Nf \l_tmpa_tl { \seq_use:Nn \l_tmpa_seq { } }
\tl_set:Nf \l_tmpb_tl { \seq_use:Nn \l_tmpb_seq { } }
\tl_set_rescan:Nno \l_tmpb_tl { } \l_tmpb_tl
\tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { TRUE } { FALSE } % return TRUE because of the previous line
}
--
{
\str_set:Nn \l_tmpa_str { key }
\exp_args:NNx \seq_set_from_clist:Nn \l_tmpa_seq { \l_tmpa_str = smth }
\exp_args:NNx \prop_set_from_keyval:Nn \l_tmpa_prop { \l_tmpa_str = smth }
\prop_map_inline:Nn \l_tmpa_prop { \seq_put_right:Nn \l_tmpb_seq { #1 = #2 } }
\tl_set:Nf \l_tmpa_tl { \seq_use:Nn \l_tmpa_seq { } }
\tl_set:Nf \l_tmpb_tl { \seq_use:Nn \l_tmpb_seq { } }
\tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl { TRUE } { FALSE } % return TRUE
}
\ExplSyntaxOff
\end{document}