expl3에 키-값 옵션이 포함된 키-값 옵션을 어떻게 저장하나요?

expl3에 키-값 옵션이 포함된 키-값 옵션을 어떻게 저장하나요?

키-값 구문을 사용하는 명령이 있습니다. 예를 들어 원하는 경우 다양한 옵션이 포함된 이미지가 포함됩니다.

expl3 키-값 처리를 사용하고 있습니다.

다음에 명령이 실행될 때 기본값으로 재사용할 수 있도록 키-값 설정을 전역 토큰 목록에 저장하고 싶습니다. 매크로를 키-값 옵션으로 전역으로 설정하고 싶지 않기 때문에 이를 수행할 수 있는 확실한 방법을 찾을 수 없었습니다. 매크로를 전역으로 만들면 여러 가지 방식으로 상황이 복잡해지기 때문입니다. 내가 원하는 것은 관련 키-값을 재사용할 수 있도록 전역 토큰 목록에 저장하는 것입니다. (토큰 목록이 아니더라도 상관없습니다. 당연한 선택인 것 같았습니다.)

부울과 쉼표로 구분된 목록은 잘 저장할 수 있는 것 같지만 키-값 옵션 목록인 토큰 목록에 문제가 있습니다. 예를 들어 graphics={<key-value options>}는 설정을 에 전달하는 데 사용됩니다 \includegraphics. 그러나 나는 이것을 작동시킬 수 없습니다.

여기에 (비교적으로) 최소한의 예가 있는데, 금성에서 내가 왜 이것을 하려고 하는지 완전히 불분명해지게 만드는데, 여러분에게는 그것이 소형화입니다.

\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}

오류 메시지에는 사람에게 도움을 요청하라는 메시지가 표시되어 있습니다.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! 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.''                                                                                                 

?   

사용하기 전에 토큰 목록을 표시하면

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

이는 목록 주위에 중괄호를 포함해야 한다는 것을 내 단순한 생각에 제안합니다. 그러나 이를 수행하려는 나의 시도는 지금까지 성공하지 못했습니다. LaTeX는 키가 아닌 것을 찾거나(예 \g_pre_img_options: ) 대괄호가 증발합니다.

답변1

나는 당신이 달성하려는 것이 무엇인지 완전히 이해하지 못하고, 내가 추측하는 것이 무엇이든, 나는 같은 방식으로 할 것이라고 생각하지 않습니다. 그러나 어쨌든 여기에 해당 문서를 컴파일하게 만드는 변경 사항이 있습니다.

\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 { , }
    }
}

내가 명확하게 이해하지 못하더라도 이는 잘못된 것 같습니다. 즉, 여러 부분으로 인해 문제가 너무 복잡해지고 실제로 그렇게 할 수 없다는 사실입니다(추가는 \c_left_brace_str시작 그룹 catcode 1을 추가하는 것이 {아니라 와 유사한 catcode “other” \string{. 올바른 .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 } } , }
   }
 }

이 변경으로 최소한 컴파일은 되지만 이것이 모두 해결되는지는 모르겠습니다.


문자열과 매크로 값을 다른 매크로에 추가하려고 합니다. 이를 수행하는 가장 쉬운 방법은 x인수를 사용하여 한 번에 모든 작업을 수행하는 것입니다. 말 그대로 당신이 하고 싶었던 일을 하고 있지만, 맞습니다. \tl_put_right:Nx의 두 번째 인수를 확장합니다 \edef. 즉, 확장합니다.모든 것, 따라서 원하는 정확한 순간에만 중지하면 됩니다. 인수를 대체한 후 다음으로 끝납니다.

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

\edef\foo{graphics={foo}}내용이 무엇인지 이해 했다면 \foo확장도 없고 문자도 없고 "기타"("=")도 없고 중괄호도 {없고 }. 그래서 마법은 내부에 있습니다 \exp_not:v { l_pre_grahpics_tl }. expl3 인수 덕분에 이는 확장을 중지하는 것과 \exp_not:V \l_pre_grahpics_tl정확히 동일합니다 ( is ).\exp_not:n { width=\textwidth }\exp_not:n\unexpanded

그렇게 하면 확장 후 위의 선은 x정확히 다음과 같이 됩니다.

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

TeX 가 아니었다면 다른 매크로와 마찬가지로 \unexpanded{width=\textwidth}확장을 시도했을 수도 있습니다 \textwidth. (지금은 확실하지 않지만) 확장되었을 수 \dimen <number>있으며 일반적으로 우리는 그러한 확장이 발생하는 것을 원하지 않습니다.

죄송합니다. 누구나 이 답변을 자유롭게 편집할 수 있습니다. 이는 완벽하지는 않습니다.

관련 정보