
Ich versuche, eine l3keys
Liste namens zu erstellen mykeys
, die verwendet wird, um das Verhalten des Befehls zu steuern mycommand:n
. Zunächst ist es nur die Identität. Durch Setzen command=\textit
sollte sie in \textit
(zusammengesetzt mit Identität) geändert werden. Im Allgemeinen command=\foo
sollte die Einstellung neu definiert werden mycommand:n
, um #1
↦ zu werden \foo{mycommand:n{#1}}
. So wie es jetzt ist, schlägt es jedoch ziemlich kläglich fehl.Ist es möglich, dass das funktioniert?
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \identity:n #1 { #1 }
\keys_define:nn { mykeys }
{
command .multichoice:,
command / none .code:n = {
\cs_set_eq:NN \mycommand:n \identity:n %this resets \mycommand:n
%to become the identity
},
command / unknown .code:n = {
\cs_set:Npx \mycommand:n ##1
{
#1 { \mycommand:n { ##1 } }
}
}
}
\keys_set:nn { mykeys } { command=none }
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\mycommand:n{test1} % should produce test1
\keys_set:nn { mykeys } { command=\textit }
\mycommand:n{test2} % should produce \textit{test2}
\keys_set:nn { mykeys } { command=\textbf }
\mycommand:n{test3} % should produce \textbf{\textit{test3}}
\ExplSyntaxOff
\end{document}
Antwort1
Ich bin nicht besonders begeistert von der Schnittstelle, aber hier würde ich die Befehle für die Anwendung in einer Reihenfolge speichern
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\seq_new:N \l__mycommand_cmds_seq
\tl_new:N \l__mycommand_tmp_tl
\keys_define:nn { mykeys }
{
command .code:n =
{
\str_if_eq:nnTF {#1} { none }
{ \seq_clear:N \l__mycommand_cmds_seq }
{ \seq_put_right:Nn \l__mycommand_cmds_seq {#1} }
}
}
\keys_set:nn { mykeys } { command = none }
\cs_new_protected:Npn \mycommand_main:n #1
{
\group_begin:
\tl_set:Nn \l__mycommand_tmp_tl {#1}
\seq_map_inline:Nn \l__mycommand_cmds_seq
{
\tl_set:Nx \l__mycommand_tmp_tl
{ \exp_not:n {##1} { \exp_not:V \l__mycommand_tmp_tl } }
}
\exp_args:NV \group_end:
\l__mycommand_tmp_tl
}
\NewDocumentCommand \mysetup { +m } { \keys_set:nn { mykeys } {#1} }
\NewDocumentCommand \mycommand { m }
{ \mycommand_main:n {#1} }
\ExplSyntaxOff
\begin{document}
\mycommand{test1} % should produce test1
\mysetup{command = \textit}
\mycommand{test2} % should produce \textit{test2}
\mysetup{command = \textbf}
\mycommand{test3} % should produce \textbf{\textit{test3}}
\end{document}
Man könnte im Rahmen der Keyval-Einstellung einen Einzeltoken-/Makrotest durchführen, aber das ist wahrscheinlich übertrieben.
Man könnte die „funktionale“ Token-Liste während der Keyval-Einstellung erstellen, aber ich vermute, dass es beim Debuggen nützlich sein könnte, die Sequenz zur Überprüfung verfügbar zu haben.
Antwort2
Solange die beteiligten Befehle ihre Implementierung nach einer einzigen Erweiterung offenlegen, können Sie etwa Folgendes tun:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \identity:n #1 { #1 }
\cs_new:Npn\wrap_def:NN#1#2{
\exp_after:wN\cs_set:Npn
\exp_after:wN#2\exp_after:wN##\exp_after:wN1\exp_after:wN{
\exp_after:wN#1\exp_after:wN{#2{##1}}}
}
\keys_define:nn { mykeys }
{
command .multichoice:,
command / none .code:n = {
\cs_set_eq:NN \mycommand:n \identity:n %this resets \mycommand:n
%to become the identity
},
command / unknown .code:n = {
\wrap_def:NN #1 \mycommand:n
}
}
\keys_set:nn { mykeys } { command=none }
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\mycommand:n{test1} % should produce test1
\keys_set:nn { mykeys } { command=\textit }
\mycommand:n{test2} % should produce \textit{test2}
\keys_set:nn { mykeys } { command=\textbf }
\mycommand:n{test3} % should produce \textbf{\textit{test3}}
\ExplSyntaxOff
\end{document}
Antwort3
Umsetzung von Davids Vorschlag:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\tl_new:N \l_gaussler_command_start_tl
\tl_new:N \l_gaussler_command_end_tl
\keys_define:nn { mykeys }
{
command .multichoice:,
command / none .code:n =
{
\tl_clear:N \l_gaussler_command_start_tl
\tl_clear:N \l_gaussler_command_end_tl
\cs_set_protected:Nn \gaussler_thecommand:n { ##1 }
},
command / unknown .code:n =
{
\tl_put_left:Nn \l_gaussler_command_start_tl { \exp_not:N #1 \gaussler_command_open: }
\tl_put_right:Nn \l_gaussler_command_end_tl { \gaussler_command_close: }
\cs_set_protected:Nx \gaussler_thecommand:n
{
\tl_use:N \l_gaussler_command_start_tl
##1
\tl_use:N \l_gaussler_command_end_tl
}
}
}
\cs_new:Nn \gaussler_command_open: { \if_true: { \else: } \fi: }
\cs_new:Nn \gaussler_command_close: { \if_false: { \else: } \fi: }
\keys_set:nn { mykeys } { command=none }
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\gaussler_thecommand:n{test1} % should produce test1
\keys_set:nn { mykeys } { command=\textit }
\gaussler_thecommand:n{test2} % should produce \textit{test2}
\keys_set:nn { mykeys } { command=\textbf }
\gaussler_thecommand:n{test3} % should produce \textbf{\textit{test3}}
\keys_set:nn { mykeys } { command=none }
\gaussler_thecommand:n{test4}
\ExplSyntaxOff
\end{document}