对于我和我的合作伙伴正在进行的一个项目,我们的文本包含大量混合小写和小型大写的单词:
我们目前正在使用一个相当笨重的宏来实现这一点:
\newcommand{\famword}[5]{%
#1\textsc{#2}#3\textsc{#4}#5}
这样,我们就可以在一个单词内拥有两个小型大写字母“集群”,如下所示:
\famword{a}{k}{i}{l}{ulat}
它可以很好地发挥作用,而不会浪费我们太多的时间。但是,由于我们要输入很多这样的单词,我们真正需要的是喜欢要做的就是有一个宏,我们可以在其中输入如下命令:
\famword{aKiLulat}
并让它自动将命令中的大写字母转换为文档中的小写字母。我们在这个堆栈交换中搜索了答案,并找到了一些相关问题的解决方案,但没有一个能解决这个特定问题。
补充一下,其中一些单词包含“拉丁大写字母喉塞音”字符 Ɂ。我们现有的宏可以很好地处理这个字符(据我所知,它只是让它保持不变),但万一存在任何会破坏这个非 ASCII 字符的解决方案,它就不会这样做。
有人知道这是否可行吗?
答案1
当将现代字体与 LuaLaTeX 或 XeLaTeX 结合使用时,人们(有时)能够将此委托给字体,因为 OpenType Layout 定义了一种c2sc
将大写字母转换为小写字母的字体功能。不幸的是,Latin Modern 不包含此功能。当可用时,人们可以通过fontspec
功能激活此功能Letters=UppercaseSmallCaps
。示例:
\documentclass{article}
\usepackage{fontspec}
\setmainfont{Stix Two Text} % Font with c2sc feature and italic SC
\newcommand\famword[1]{{\addfontfeatures{Letters=UppercaseSmallCaps}#1}}
\begin{document}
\famword{aKiLulat}
\itshape \famword{aKiLulat}
\end{document}
答案2
该tokcycle
包 (https://www.ctan.org/pkg/tokcycle) 可用于此目的。
\documentclass{article}
\usepackage{tokcycle}
\newcommand\famword[1]{%
\resettokcycle%
\Characterdirective{\ifcat A##1\ifnum`##1<`Z\addcytoks{%
\textsc{\char\numexpr32+`##1\relax}}\else
\addcytoks{##1}\fi\else\addcytoks{##1}\fi}%
\tokcyclexpress{#1}%
\the\cytoks%
}
\begin{document}
\famword{aKiLulat or even aK\textit{iLulat}!}
\end{document}
正如我所评论的,要获得斜体小写字母,您需要一种支持它的字体,例如\usepackage{newtxtext}
:
如果人们更喜欢基于环境而不是基于宏的调用,那么可以这样做:
\documentclass{article}
\usepackage{tokcycle}
\tokcycleenvironment\famword%
{\ifcat A##1\ifnum`##1<`Z\addcytoks{%
\textsc{\char\numexpr32+`##1\relax}}\else
\addcytoks{##1}\fi\else\addcytoks{##1}\fi}% <-CHARACTERS
{\processtoks{##1}}% <-GROUPS
{\addcytoks{##1}}% <-MACROS
{\addcytoks{##1}}% <-SPACES
\begin{document}
\famword aKiLulat or even aK\textit{iLulat}!\endfamword
\end{document}
答案3
这是一个基于 LuaLaTeX 的解决方案。它由 (a) 一个主 Lua 函数uc2sc
(我猜是“大写转小写”的缩写)和一个辅助 Lua 函数组成makesc
,它们一起完成大部分工作,以及 (b) 一个 LaTeX 宏,\famword
用作该函数的包装器uc2sc
。Lua 函数使用 Lua 的多功能内置string.gsub
函数string.lower
。
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for "luacode" environment
\begin{luacode}
function makesc ( x )
return ( "\\textsc{" .. x:lower() .. "}" )
end
function uc2sc ( s )
return ( s:gsub ( "%u", makesc ) )
end
\end{luacode}
%% LaTeX wrapper macro:
\newcommand\famword[1]{\directlua{tex.sprint(uc2sc("#1"))}}
\usepackage{fontspec}
\setmainfont{Stix Two Text} % a font with italic-smallcap letters
\begin{document}
\famword{aKiLulat}
\itshape \famword{aKiLulat}
\end{document}
答案4
输入中使用大写字母来表示输出中使用小写字母:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\famword}{m}
{
\tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_all:nnN { ([A-Z]+) } { \c{spark_lc:n}\cB\{\1\cE\} } \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\cs_new_protected:Nn \spark_lc:n { \textsc { \text_lowercase:n { #1 } } }
\ExplSyntaxOff
\begin{document}
\famword{aKiLulat}
\end{document}
这仅涉及大写字母。