매크로를 통해 인수가 제공되는 경우 필요한 경우에만 단어 앞에 접두사를 붙이는 명령에 문제가 있습니다.

매크로를 통해 인수가 제공되는 경우 필요한 경우에만 단어 앞에 접두사를 붙이는 명령에 문제가 있습니다.

다음 코드를 고려해보세요.이것대답은 접두사가 누락된 경우에만 단어에 접두사를 추가합니다.

\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
  {
    \str_if_eq:eeTF {#2} { \str_range:nnn {#1} { 1 } { \str_count:n {#2} } }
      {#1}
      { #2#1 }
  }
\ExplSyntaxOff

\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}

\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}

\begin{document}
\forcebeginwith{fancycolor}{fancy}    \\% OK: fancycolor
\forcebeginwith{color}{fancy}         \\% OK: fancycolor
\forcebeginwith{\mystringc}{\prefixc} \\% NOT WORKING: fancyfancycolor
\end{document}

질문:확장 가능한 명령이 필요한 경우 어떻게 작동하게 합니까?

답변1

expl3 기본 함수가 주어지면 결과를 해당 함수에 전달하기 전에 하나 이상의 인수를 처리하는 변형을 생성할 수 있습니다. 예를 들어, 함수에 인수 지정자(콜론 뒤의 비트)가 있는 경우 n다음을 갖는 변형을 정의할 수 있습니다 o.영형nce) 또는 e(확장이자형전체적으로) n. 그런 다음 필요할 때마다 변형을 사용하면 됩니다.

이 경우 우리는 두 가지 기능의 변형을 원합니다.

\cs_generate_variant:Nn \str_range:nnn { enn }

이것은 \str_range:enn존재를 보장합니다. 이 변형은 처리를 위해 함수에 전달하기 전에 첫 번째 인수를 확장합니다 \str_range:nnn.

\cs_generate_variant:Nn \str_count:n { e }

이렇게 하면 \str_count:e존재를 보장하고 에 전달하기 전에 유일한 인수를 확장합니다 \str_count:n.

그런 다음 기본 기능과 마찬가지로 이러한 변형을 사용할 수 있습니다.

\NewExpandableDocumentCommand { \forcebeginwith } { m m }
  {
    \str_if_eq:eeTF {#2} { \str_range:enn {#1} { 1 } { \str_count:e {#2} } }
      {#1}
      { #2#1 }
  }

변형은 처리하기 전에 인수를 확장하므로 세 줄 모두 동일한 결과가 발생합니다.

전체 코드:

\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\cs_generate_variant:Nn \str_range:nnn { enn }
\cs_generate_variant:Nn \str_count:n { e }
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
  {
    \str_if_eq:eeTF {#2} { \str_range:enn {#1} { 1 } { \str_count:e {#2} } }
      {#1}
      { #2#1 }
  }
\ExplSyntaxOff

\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}

\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}

\begin{document}
\forcebeginwith{fancycolor}{fancy}    \par% OK: fancycolor
\forcebeginwith{color}{fancy}         \par% OK: fancycolor
\forcebeginwith{\mystringc}{\prefixc} \par% NOT WORKING: fancyfancycolor
\end{document}

답변2

예는 다음과 같습니다.

\documentclass[border=6pt,varwidth]{standalone}
\ExplSyntaxOn
\cs_generate_variant:Nn \str_range:nnn  { enn }
\NewExpandableDocumentCommand { \forcebeginwith } { m m }
  {
    \str_if_eq:eeTF {#2} { \str_range:enn {#1} { 1 } { \str_count:e {#2} } }
      {#1}
      { #2#1 }
  }
\ExplSyntaxOff

\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}

\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}

\begin{document}
\forcebeginwith{fancycolor}{fancy}    \\% OK: fancycolor
\forcebeginwith{color}{fancy}         \\% OK: fancycolor
\forcebeginwith{\mystringc}{\prefixc} \\% NOT WORKING: fancyfancycolor
\end{document}

답변3

더 나은 프로그래밍 스타일은 내부 기능 측면에서 사용자 수준 명령을 정의하는 것입니다.

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand { \forcebeginwith } { m m }
 {
  \vincent_forcebeginwith:ee { #1 } { #2 }
 }
\cs_new:Nn \vincent_forcebeginwith:nn
 {
  \str_if_eq:eeF {#2} { \str_range:nnn {#1} { 1 } { \str_count:n {#2} } } { #2 }
  #1
 }
\cs_generate_variant:Nn \vincent_forcebeginwith:nn { ee }

\ExplSyntaxOff

\newcommand{\mystringa}{fancycolor}
\newcommand{\mystringb}{\mystringa}
\newcommand{\mystringc}{\mystringb}

\newcommand{\prefixa}{fancy}
\newcommand{\prefixb}{\prefixa}
\newcommand{\prefixc}{\prefixb}

\begin{document}

\forcebeginwith{fancycolor}{fancy}    % OK: fancycolor

\forcebeginwith{color}{fancy}         % OK: fancycolor

\forcebeginwith{\mystringc}{\prefixc} % OK: fancycolor

\end{document}

보시다시피 \vincent_forcebeginwith:nn가 정의되어 있지만 사용자 수준 명령에서는 인수를 에 넘겨주기 전에 인수를 완전히 확장하는 변형을 사용합니다 \vincent_forcebeginwith:nn.

여기에 이미지 설명을 입력하세요

관련 정보