
我想編寫一個可擴展的命令,如果 S2 不以 S1 開頭,則在另一個字串 S2 的開頭添加一個字串 S1,以確保我的字串始終以 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
。它應該可以與已有十多年歷史的 LaTeX 核心版本一起使用,因為 \directlua
基元的屬性自第一次出現以來並沒有真正改變。因為\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}