
내 문자열이 항상 S1로 시작하도록 S2가 S1로 시작하지 않는 경우 다른 문자열 S2의 시작 부분에 문자열 S1을 추가하는 확장 가능한 명령을 작성하고 싶습니다.
현재 xstring 패키지에 의존하는 이 코드가 있습니다.
\NewDocumentCommand\forcebeginwith{m m}{%
\edef\expandedstring{#1}%
\edef\expandedbeginning{#2}%
\IfBeginWith{
\expandedstring % String
}{
\expandedbeginning % Beginning
}{
\expandedstring % String
}{
\expandedbeginning\expandedstring % Beginning + String
}
}
예를 들어 :
\forcebeginwith{fancycolor}{fancy} % fancycolor
\forcebeginwith{color}{fancy} % fancycolor
질문:이 명령을 확장 가능한 명령으로 변환하고 싶지만 NewExpandableDocumentCommand
어떻게 해야 할지 모르겠습니다(결과 코드가 5년 전의 라텍스 버전에서 작동하도록 하고 싶기 때문에 최근의 슈퍼 듀퍼를 피하고 싶습니다). 명령/패키지).
답변1
명령은 \forcebeginwith
로 정의됩니다 \NewExpandableDocumentCommand
. 테스트는 으로 수행됩니다 \str_if_eq:eeTF
. 아래 예와 같이 내부에서 명령을 \forcebeginwith
사용할 수 있습니다 .\edef
\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
\begin{document}
\forcebeginwith{fancycolor}{fancy}\\% fancycolor
\forcebeginwith{color}{fancy}\\% fancycolor
\edef\testA{\forcebeginwith{LaTeX}{La}}\testA\\
\edef\testB{\forcebeginwith{TeX}{La}}\testB
\end{document}
답변2
을 사용하면 pdflatex
다음과 같이 할 수 있습니다.
\documentclass{article}
\newcommand{\forcebeginwith}[2]{%
\ifnum\pdfmatch{^#2}{#1}=0 #2\fi#1%
}
\begin{document}
\forcebeginwith{fancycolor}{fancy}% fancycolor
\forcebeginwith{color}{fancy}% fancycolor
\edef\testA{\forcebeginwith{LaTeX}{La}}\testA
\edef\testB{\forcebeginwith{TeX}{La}}\testB
\end{document}
TeX Live 2012까지 테스트했습니다.
답변3
TeX 기본 요소만 사용하는 경우 코드는 다음과 같아야 합니다.
\def\forcebeginwith#1#2{\fbwA .#1\end .#2\end{#1}{#2}}
\def\fbwA #1#2\end #3#4\end #5#6{%
\ifx #1#3%
\ifx \end#4\end #5% S2 is included at the start of S1, print S1 only
\else
\ifx \end#2\end {#5} shorter than {#6}, something wrong%
\else \fbwB {#2\end #4\end {#5}{#6}}%
\fi
\fi
\else #6#5% S2 isn't inluded at the start of S1, print S2S1.
\fi
}
\def\fbwB #1\fi\fi#2\fi{\fi\fi\fi \fbwA #1}
% test:
\message{\forcebeginwith{fancycolor}{fancy}}
\message{\forcebeginwith{color}{fancy}}
\bye
TeX은 "문자열"에서는 작동하지 않으며 토큰 목록만 있습니다.
답변4
다음은 LuaLaTeX 기반 솔루션에서 \forcebeginwith
. \directlua
원시 버전의 속성은 처음 등장한 이후 실제로 변경되지 않았기 때문에 10년이 훨씬 넘은 LaTeX 커널 버전에서 작동해야 합니다. 확장 가능하기 때문에 \directlua
확장 가능합니다 \forcebeginwith
. 인수는 \forcebeginwith
ASCII로 인코딩될 필요가 없습니다. 대신 UTF8로 인코딩할 수 있습니다.
% !TEX program = lualatex
\documentclass{article} % or some other suitable document class
\directlua{% Define the Lua function 'forcebeginwith':
function forcebeginwith ( s1 , s2 )
if unicode.utf8.sub ( s1 , 1 , unicode.utf8.len ( s2 ) ) == s2 then
return ( s1 )
else
return ( s2..s1 )
end
end
}
\newcommand\forcebeginwith[2]{%
\directlua{ tex.sprint ( forcebeginwith ( "#1" , "#2" ) ) }}
\newcommand\Za{color}
\newcommand\Zb{fancy}
\begin{document}
\obeylines % just for this document
\forcebeginwith{fancycolor}{fancy}
\forcebeginwith{color}{fancy}
\smallskip
% Demonstrate that '\forcebeginwith' is expandable
\forcebeginwith{\Zb\Za}{\Zb}
\forcebeginwith{\Za}{\Zb}
\end{document}