
다음 코드를 고려해보세요.이것대답은 접두사가 누락된 경우에만 단어에 접두사를 추가합니다.
\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
.