答案1
使用 XeTeX 的方法\XeTeXinterchartoks
(即使用 编译以下内容xelatex
):
\documentclass{article}
\usepackage{lipsum}
\input{random}
\newcount\randnum
\newcommand{\randkern}{%
\setrannum{\randnum}{-30}{30}%
\kern \dimexpr(\randnum pt/10)\relax
}
\XeTeXinterchartokenstate = 1
\XeTeXinterchartoks 0 0 = {\randkern}
\begin{document}
\lipsum[1]
\end{document}
如果您希望错误字号不那么大,可以缩小范围,例如{-30}{30}
改为{-10}{20}
:
这个想法很简单,就是在任意两个字符之间插入一个随机的字距。例如,如果我们输入如下内容:
L\kern 0.4pt o\kern 1.3pt r\kern -1.0pt e\kern -0.4pt m
等等,我们就会得到上图的结果。上面的代码就是这么做的,有两个快捷方式:
- 定义一个
\randkern
使用包random
生成随机数,以及\dimexpr
在电子特克斯)。 - 用途
\XeTeXinterchartoks
(记录在XeTeX 参考指南)。设置\XeTeXinterchartoks 0 0
为 会在任意两个 0 类字符之间\randkern
插入标记\randkern
(默认情况下,大多数字符属于 0 类)。例如,当我们的文本包含 字符,L
后面跟着 字符 时o
,XeTeX 会将其视为您在它们之间输入了标记\randkern
(如输入L\randkern o
)。
答案2
LuaTeXkerning
提供了一个回调函数,我们可以用它来实现这个目的。虽然没有内置的等效函数\XeTeXinterchartoks
,但 LuaTeX 的吸引力在于我们可以在 Lua 中自己实现许多此类功能。我们可以得到:
使用(使用 编译以下内容lualatex
)
\documentclass{article}
\usepackage{lipsum}
\directlua{dofile('randomkern.lua')}
\begin{document}
\lipsum[1]
\end{document}
哪里randomkern.lua
:
function rekern(head)
local i = head
while i~=nil do
j = i.next
-- Skip over discretionary (hyphen) nodes
while j~=nil and node.type(j.id)=='disc' do
j = j.next
end
-- Insert a kern node between successive glyph nodes
if node.type(i.id)=='glyph' and j~=nil and node.type(j.id)=='glyph' then
k = node.new(node.id('kern'))
head, i = node.insert_after(head, i, k)
assert(node.type(i.id)=='kern')
end
-- Tweak existing kerns (including ones we inserted) by a random amount
if node.type(i.id)=='kern' then
i.kern = i.kern + math.random(65536*-1, 65536*2)
end
i = i.next
end
end
luatexbase.add_to_callback('kerning', rekern, 'Introduce random kern nodes')
这个想法是kerning
回调获取一个节点列表:例如,
temp
local_par
hlist indent {}
glyph L
glyph o
glyph r
glyph e
glyph m
glue <spaceskip: 218235 plus 109117^0 minus 72745^0>
glyph i
glyph p
disc
glyph s
glyph u
glyph m
glue <spaceskip: 218235 plus 109117^0 minus 72745^0>
glyph d
glyph o
disc
glyph l
glyph o
glyph r
glue <spaceskip: 218235 plus 109117^0 minus 72745^0>
glyph s
glyph i
glyph t
等等。我们只需遍历此列表,并在每两个连续glyph
节点(可能disc
在它们之间有一个节点)之间插入一个kern
节点,并赋予它一个随机值。(TeX 将所有尺寸(长度等)内部存储在缩放点中,其中 65536 sp = 1 pt。)
请注意,此版本会自动处理连字:只有字距会发生变化;有效连字或换行点集保持不变。