我正在写一篇文章,需要字母 'a', 'e', 'i', 'o', 'u' 始终以粗体显示。给定以下 TeX 文件:
\documentclass{article}
% What should be put here?
\begin{article}
You can say Hi as Hello.
\end{article}
默认结果是:你可以将 Hi 说成 Hello。
我真正想要的是:是欧CA纳秒AyH我 A氢埃二o。
答案1
当您使用 XeTeX 时,您的任务完全可以通过 XeTeX 基元\XeTeXcharclass
和来解决\XeTeXinterchartoks
。阅读 XeTeX 手册。对于字母 'a'、'e'、'i'、'o'、'u',设置如下:
\newXeTeXintercharclass \mycharclassbf
\XeTeXcharclass `\a =\mycharclassbf
\XeTeXcharclass `\e =\mycharclassbf
\XeTeXcharclass `\i =\mycharclassbf
\XeTeXcharclass `\o =\mycharclassbf
\XeTeXcharclass `\u =\mycharclassbf
\XeTeXinterchartoks 0 \mycharclassbf = {\bgroup\bf}
\XeTeXinterchartoks \mycharclassbf 0 = {\egroup}
\XeTeXinterchartoks 255 \mycharclassbf = {\bgroup\bf}
\XeTeXinterchartoks \mycharclassbf 255 = {\egroup}
\XeTeXinterchartokenstate = 1
You can say Hi as hello.
\bye
答案2
让我展示一下 LuaTeX 中的一小段代码。我们将一个参数和选定的字母传递给 Lua 核心,代码段在字符级别对其进行分解,并仅通过命令包装预选的字母\malbf
。
需要标记的单词已加标签,我没想到会用到 TeX 命令,我以为是纯文本。我附上了一个包含英语(原帖要求的字母)和捷克语文本(所有字素)的小例子。
我们还可以在终端中检查输出,它写道:
H\malbf{e}ll\malbf{o} W\malbf{o}rld! Y\malbf{ou} c\malbf{a}n s\malbf{a}y H\malbf{i} \malbf{a}s H\malbf{e}ll\malbf{o}.
Č\malbf{au} d\malbf{ě}ck\malbf{a}, j\malbf{a}k s\malbf{e} d\malbf{a}ř\malbf{í}?
如果我们想了解如何保留格式化字母的连字和字距调整对(我删除了}\malbf{
此示例中的所有序列),请参阅此版本 2回答。我在那里提到了另一种可能的策略(我使用了一个变量来切换字体)。在这个例子中,我们得到了Č\malbf{au}
而不是Č\malbf{a}\malbf{u}
,以及Y\malbf{ou}
而不是Y\malbf{o}\malbf{u}
。
我附上了代码片段的源代码和 PDF 文件的预览。我们运行lualatex mal-letters.tex
。
% lualatex mal-letters.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\usepackage{xcolor}
\usepackage{luatextra} % luacode
\begin{luacode*}
function boldme () -- the core function
letters=tex.toks[1] -- some more/other letters?
text=tex.toks[0] -- text taken from TeX
towrite="" -- an empty string
markerbegin="\\malbf{" -- a command to be used as a marker
markerend="}"
for i=1,unicode.utf8.len(text) do -- decomposition of text
s=unicode.utf8.sub(text, i, i) -- actual character
isthere=nil -- initial value, no, character is not among letters
for j=1,unicode.utf8.len(letters) do -- test if it is
if unicode.utf8.sub(letters, j, j)==s then isthere=1; break end
end -- for, j, is character between selected letters?
if isthere then -- to be bold, or not?
towrite=towrite..markerbegin..s..markerend -- yes, it is to be empasized in bold
else
towrite=towrite..s -- no, that character is not among selected letters
end -- if, isthere
end -- for, i, decomposition of input text
-- combine the commands together
-- e.g. \malbf{a}\malbf{e} -> \malbf{ae}
towrite=unicode.utf8.gsub(towrite, markerend..markerbegin, "")
-- writing result to the terminal and to the document
io.write(towrite) -- information shipped to the terminal
tex.sprint(towrite) -- information shipped to the document
end -- function, boldme
\end{luacode*}
\def\malbf#1{\textbf{\color{red}#1}}
\def\markit#1{\toks0{#1}\directlua{boldme()}}
\def\tomark#1{\toks1{#1}}
\begin{document}
% Text in English, selected letters.
\tomark{aeiou}
Some text before. \markit{Hello World! You can say Hi as Hello.} More text after.
% An example with Czech graphemes.
\tomark{aáeéěiíoóuúůyý}
Text in the middle. \markit{Čau děcka, jak se daří?} End of story.
\end{document}