Wie kann ich Schlüssel-Wert-Optionen speichern, die Schlüssel-Wert-Optionen in expl3 enthalten?

Wie kann ich Schlüssel-Wert-Optionen speichern, die Schlüssel-Wert-Optionen in expl3 enthalten?

Ich habe einen Befehl, der eine Schlüssel-Wert-Syntax verwendet. Er fügt beispielsweise auf Wunsch ein Bild mit verschiedenen Optionen ein.

Ich verwende die Schlüssel-Wert-Verarbeitung von expl3.

Ich möchte die Schlüssel-Wert-Einstellungen in einer globalen Tokenliste speichern, damit ich sie bei der nächsten Ausführung des Befehls als Standardwerte wiederverwenden kann. Ich konnte keine offensichtliche Möglichkeit finden, dies zu tun, da ich die Makros und die Schlüssel-Wert-Optionen nicht global festlegen möchte, da dies die Dinge in vielerlei Hinsicht verkomplizieren würde. Ich möchte lediglich die relevanten Schlüsselwerte in einer globalen Tokenliste speichern, damit ich sie wiederverwenden kann. (Es ist mir egal, ob es keine Tokenliste ist – das schien einfach die offensichtliche Wahl.)

Ich kann die Booleschen Werte und Komma-getrennten Listen anscheinend problemlos speichern, habe aber Probleme mit Token-Listen, die selbst Listen mit Schlüssel-Wert-Optionen sind. Beispielsweise graphics={<key-value options>}wird verwendet, um Einstellungen an zu übergeben \includegraphics. Ich bekomme das jedoch nicht zum Laufen.

Hier ist ein (vergleichsweise) minimales Beispiel, bei dem überhaupt nicht klar ist, warum ich dies auf der Venus versuche, aber so ist das nun einmal bei Miniaturisierung.

\documentclass{article}
\usepackage{xparse,graphicx}
\begin{document}
\ExplSyntaxOn
\tl_new:N \l_pre_graphics_tl
\tl_new:N \g_pre_img_options_tl
\tl_new:N \g_pre_img_tl
\cs_new_protected_nopar:Nn \pre_key_tl_save:Nn
{
  \tl_if_empty:cF {l_pre_#2_tl}
    {
      \tl_gput_right:No #1 { #2 = }
      \tl_gput_right:NV #1 \c_left_brace_str
      \tl_gput_right:Nv #1 { l_pre_#2_tl }
      \tl_gput_right:NV #1 \c_right_brace_str
      \tl_gput_right:Nn #1 { , }
    }
}
\cs_generate_variant:Nn \tl_gput_right:Nn {Nv}
% includegraphics bit courtesy of egreg (chat 2015-01-08)
\cs_new:Npn \pre_includegraphics:nn #1 #2
 {
  \includegraphics[#1]{#2}
 }
\cs_generate_variant:Nn \pre_includegraphics:nn { VV }
\keys_define:nn { pre / img }
{
  graphics .tl_set:N = \l_pre_graphics_tl,
}
\NewDocumentCommand \incimg { o m }
{
  \group_begin:
    \tl_if_empty:NF \g_pre_img_options_tl
    {
      \keys_set:nV { pre / img } \g_pre_img_options_tl
    }
    \IfValueT{#1}{ \keys_set:nn { pre / img } { #1 } }
    \pre_key_tl_save:Nn \g_pre_img_options_tl { graphics }
    \tl_set:Nn \g_pre_img_tl { #2 }
    \pre_includegraphics:VV \l_pre_graphics_tl \g_pre_img_tl
  \group_end:
}
\ExplSyntaxOff

\incimg[
  graphics={width=\textwidth},
]{example-image-a}
\incimg[
  graphics={width=\textwidth},
]{example-image-a}
\end{document}

In der Fehlermeldung wurde vorgeschlagen, dass ich einen Menschen um Hilfe bitte, also bin ich hier …

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! LaTeX error: "kernel/misplaced-equals-sign"
! 
! Misplaced equals sign in key-value input 194
! 
! See the LaTeX3 documentation for further information.
! 
! For immediate help type H <return>.
!...............................................  

l.194 ]{example-image-a}

? h
|'''''''''''''''''''''''''''''''''''''''''''''''                                                                                              
| LaTeX is attempting to parse some key-value input but found two equals signs                                                                
| not separated by a comma.                                                                                                                   
|...............................................                                                                                              
? h                                                                                                                                           
Sorry, I already gave what help I could...                                                                                                    
Maybe you should try asking a human?                                                                                                          
An error might have occurred before I noticed any problems.                                                                                   
``If all else fails, read the instructions.''                                                                                                 

?   

Wenn ich die Tokenliste zeige, bevor ich versuche, sie zu verwenden, erhalte ich

> \g_pre_img_options_tl=graphics={width=\textwidth },.

was meinem einfachen Verstand nahelegt, dass ich irgendwie geschweifte Klammern um die Liste setzen muss. Meine Versuche, dies zu tun, waren bisher jedoch erfolglos. Entweder sucht LaTeX nach etwas, das kein Schlüssel sein soll (z. B. \g_pre_img_options), oder die Klammern lösen sich einfach auf.

Antwort1

Ich verstehe nicht ganz, was Sie erreichen möchten, und was auch immer meine Vermutung ist, ich glaube nicht, dass ich es auf die gleiche Weise machen würde, aber hier ist auf jeden Fall eine Änderung, die das Dokument kompiliert.

\cs_new_protected_nopar:Nn \pre_key_tl_save:Nn
{
  \tl_if_empty:cF {l_cfr_#2_tl}
    {
      \tl_gput_right:No #1 { #2 = }
      \tl_gput_right:NV #1 \c_left_brace_str
      \tl_gput_right:Nv #1 { l_pre_#2_tl }
      \tl_gput_right:NV #1 \c_right_brace_str
      \tl_gput_right:Nn #1 { , }
    }
}

Das scheint falsch zu sein, auch wenn ich das nicht ganz verstehe. Zum einen wird das Problem durch viele verschiedene Teile unnötig kompliziert, und zum anderen ist das eigentlich nicht möglich (Hinzufügen \c_left_brace_strbedeutet nicht, einen öffnenden Gruppen-Catcode 1 hinzuzufügen {, sondern einen Catcode „other“, ähnlich wie ). Mit einem einfachen Argument und dem richtigen \string{ist es einfacher .x\exp_not:*

\cs_new_protected_nopar:Nn \pre_key_tl_save:Nn
 {
  \tl_if_empty:cF {l_cfr_#2_tl}
   {
    \tl_gput_right:Nx #1 { #2 = { \exp_not:v { l_pre_#2_tl } } , }
   }
 }

Mit dieser Änderung wird es zumindest kompiliert, aber ich weiß nicht, ob das alle Probleme löst.


Sie möchten einen String und den Wert eines Makros zu einem anderen Makro hinzufügen. Am einfachsten geht das, indem Sie alles auf einmal mit einem xArgument tun. Es tut buchstäblich das, was Sie tun wollten, aber richtig. \tl_put_right:Nxerweitert das zweite Argument in einem \edef, das heißt, es erweitertalles, sodass Sie nur an dem Punkt anhalten müssen, an dem Sie möchten. Nach dem Ersetzen der Argumente endet es mit

\tl_gput_right:Nx \g_pre_img_options_tl { graphics = { \exp_not:v { l_pre_grahpics_tl } } , }

Wenn Sie gesehen haben, \edef\foo{graphics={foo}}wissen Sie, was der Inhalt von \foowäre: nichts wird erweitert, weder die Buchstaben noch die „anderen“ („=“), noch die Klammern {und }. Die Magie steckt also in \exp_not:v { l_pre_grahpics_tl }. Dank expl3-Argumenten ist das genau dasselbe wie \exp_not:V \l_pre_grahpics_tlwhich wiederum dasselbe wie \exp_not:n { width=\textwidth }which stoppt die Erweiterung einfach dort ( \exp_not:nist \unexpanded).

xAuf diese Weise lautet die obige Zeile nach der Erweiterung genau

\tl_gput_right:Nn \g_pre_img_options_tl { graphics = { width = \textwidth } , }

wenn es das nicht gegeben hätte, \unexpanded{width=\textwidth}hätte TeX möglicherweise versucht, sich \textwidthwie jedes andere Makro zu erweitern, was (im Moment nicht sicher) möglicherweise auch der Fall gewesen wäre, \dimen <number>und im Allgemeinen möchten wir nicht, dass diese Erweiterung stattfindet.

Es tut uns leid, aber jeder kann diese Antwort, die alles andere als perfekt ist, gerne bearbeiten.

verwandte Informationen