通常,我倾向于将 LaTeX 命令视为子程序而不是函数。我想知道 LaTeX 是否允许定义函数,例如通过替换子字符串来转换文本。
我认为这个功能是可行的,因为有些软件包允许用户使用函数(真正的函数)来转换文本。甚至MakeUppercase
确实如此。
如果我想创建一个函数,将所有“U”替换为“V”,将所有“W”替换为“VV”,那么该函数的结构应该是什么?
答案1
\documentclass{article}
\usepackage{stringstrings}
\newcommand\latinify[1]{%
\convertchar[q]{#1}{U}{V}%
\convertchar{\thestring}{W}{VV}%
}
\begin{document}
\def\myphrase{CUSTWINIUS}
\myphrase{} versus \latinify{\myphrase}
\end{document}
现在来点花招:
\documentclass{article}
\usepackage{stringstrings}
\newcommand\latinify[1]{%
\encodetoken{\kern}%
\encodetoken[2]{\footnotesize}%
\encodetoken[3]{\normalsize}%
\convertchar[e]{#1}{U}{\footnotesize V\normalsize}%
\convertchar[e]{\thestring}{W}{V\kern-5pt\footnotesize V\normalsize}%
\retokenize{\thestring}\thestring%
\decodetoken{\kern}%
\decodetoken[2]{\footnotesize}%
\decodetoken[3]{\normalsize}%
}
\begin{document}
\def\myphrase{UNCLE CUSTWINIUS WABBLEWAUSER}
\myphrase{} versus
\latinify{\myphrase}
\end{document}
答案2
可以使用来自\replacestrings
OPmac 的。它由几行 TeX 代码实现:
\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\bgroup \catcode`!=3 \catcode`?=3
\gdef\replacestrings#1#2{\long\def\replacestringsA##1#1##2!{%
\ifx!##2!\addto\tmpb{##1}\else\addto\tmpb{##1#2}\replacestringsA##2!\fi}%
\edef\tmpb{\expandafter}\expandafter\replacestringsA\tmpb?#1!%
\long\def\replacestringsA##1?{\def\tmpb{##1}}\expandafter\replacestringsA\tmpb
}
\egroup
\def\cnvUVW#1{\def\tmpb{#1}%
\replacestrings{U}{V}\replacestrings{W}{V\kern-.5emV}\tmpb}
\cnvUVW{UNCLE CUSTWINIUS WABBLEWAUSER}
编辑我很惊讶这里没有人建议使用主动角色。我修复了它:
\def\adef#1{\catcode`#1=13 \begingroup \lccode`\~=`#1\lowercase{\endgroup\def~}}
\def\setUW{\adef U{V}\adef W{V\kern-.5emV}}
{\setUW UNCLE CUSTWINIUS WABBLEWAUSER}
答案3
纯 LuaLaTeX 解决方案:一个 Lua 函数(名为u2v_w2vv
)和一个\uvwvv
调用该 Lua 函数的 LaTeX 宏(名为 )。
\documentclass{article}
%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function u2v_w2vv ( s )
s = string.gsub ( s , "U" , "V" )
s = string.gsub ( s , "W" , "VV" )
return tex.sprint ( s )
end
\end{luacode}
%% LaTeX-side code
\newcommand\uvwvv[1]{\directlua{u2v_w2vv(\luastring{#1})}}
\begin{document}
UNCLE CUSTWINIUS WABBLEWAUSER vs.
\uvwvv{UNCLE CUSTWINIUS WABBLEWAUSER}
\end{document}
答案4
这个答案解决了 LuaTeX 的 OpenType 功能文件所解决的字母替换问题:
\documentclass{article}
\usepackage{filecontents}
\usepackage{fontspec}
\begin{filecontents*}{uw2v.fea}
languagesystem DFLT dflt;
languagesystem latn dflt;
feature uw2v {
lookup U_TO_V {
sub U by V;
} U_TO_V;
lookup W_TO_VV {
sub W by V V;
} W_TO_VV;
} uw2v;
\end{filecontents*}
\DeclareRobustCommand*{\textuwtov}[1]{%
\begingroup
\addfontfeatures{
FeatureFile=uwtovs.fea,
RawFeature=+uw2v,
}%
#1%
\endgroup
}
\setmainfont[FeatureFile=uwtovs.fea]{latinmodernroman}
\setsansfont[FeatureFile=uwtovs.fea]{latinmodernsans}
\begin{document}
\noindent
UNCLE CUSTWINIUS WABBLEWAUSER\\
\textuwtov{UNCLE CUSTWINIUS WABBLEWAUSER}
\bigskip
\noindent
\textsf{UNCLE CUSTWINIUS WABBLEWAUSER\\
\textuwtov{UNCLE CUSTWINIUS WABBLEWAUSER}}
\end{document}