在 James Felici 的书中The Complete Manual of Typography
,建议有时改变字母之间的间距,以免单词之间的间距过大。
我尝试使用Tracking
frommicrotype
包,但只能将其设置为常量值。LetterSpace
中也有选项fontspec
,但似乎效果差不多。
这可以在 完成吗LuaLaTeX
?
\documentclass{article}
\usepackage{lipsum}
\usepackage{fontspec}
\usepackage[
expansion = false,
tracking = alltext,
]{microtype}
\SetTracking{
family = *}{10}
\begin{document}
\lipsum
\end{document}
答案1
虽然印刷师们对此有不同的看法关于字母间距,当在窄列中设置对齐文本时,我们必须在某些地方做出一些妥协(包括考虑右对齐文本),字母间距似乎是可以接受的。因此,我很震惊该microtype
软件包似乎没有提供此功能;毕竟它在 Hàn Thế Thành 的论文中被广泛讨论过TeX 排版系统的微排版扩展microtype
。尽管我为了这个功能查看了好几次,但我仍然不确定我是否只是错过了文档中的某些内容。
无论如何,使用 LuaTeX 可以轻松实现这一点。有多种方法:例如,在换行之后(在 中post_linebreak_filter
),我们可以在节点之间添加适当的拉伸量(这是 Hàn Thế Thành 论文第 6.8 节中讨论的方法)。或者,在换行之前(在 中pre_linebreak_filter
),我们可以添加可拉伸的粘合节点。第二种方法在包中实现chickenize
,即\letterspaceadjust
。它只有几行代码,因此我们可以复制它并根据需要进行更改(在下面的代码示例中,我仅将letterspace_glue.stretch
0.5 pt 更改为 10pt)。
\documentclass{article}
\usepackage{lipsum}
\usepackage{fontspec}
\usepackage{luacode}
\usepackage{chickenize}
\begin{document}
\hsize=15em
\frenchspacing
\def\\{\penalty-10000}
\def\sample{
The results of the first round of\\
the elections shook the public\\
rigid, as it seemed impossible\\
that a candidate from the far\\
right wing---who indeed had\\
been a Nazi Party member dur-\\
ing his youth---ousted the cen-\\
ter-left candidate. The outcry\\
from the general public was\\
considerable but also considera-\\
bly too late. The run-up to the\\
election had been somnolent---and\\
people learned too late that the\\
unimaginable only seems that\\
way when people fail to use\\
their imagination.}
\noindent The default:
\sample
\lipsum[1]
\newpage
\noindent Best result without letter spacing:
\tolerance=9999 \hfuzz=0.1pt \emergencystretch=\hsize
\sample
\lipsum[1]
\newpage
\noindent With letter spacing:
\letterspaceadjust
\sample
\lipsum[1]
\newpage
\noindent Exaggerated letter spacing:
\unletterspaceadjust
\begin{luacode}
local nodeid = node.id
local nodenew = node.new
local nodecopy = node.copy
local nodetraverseid = node.traverse_id
local nodeinsertbefore = node.insert_before
local letterspace_glue = nodenew(nodeid"glue")
local letterspace_pen = nodenew(nodeid"penalty")
letterspace_glue.width = tex.sp"0pt"
letterspace_glue.stretch = tex.sp"10pt"
letterspace_pen.penalty = 10000
letterspaceadjust = function(head)
for glyph in nodetraverseid(nodeid"glyph", head) do
if glyph.prev and (glyph.prev.id == nodeid"glyph" or glyph.prev.id == nodeid"disc" or glyph.prev.id == nodeid"kern") then
local g = nodecopy(letterspace_glue)
nodeinsertbefore(head, glyph, g)
nodeinsertbefore(head, g, nodecopy(letterspace_pen))
end
end
return head
end
luatexbase.add_to_callback("pre_linebreak_filter",letterspaceadjust,"letterspaceadjust")
\end{luacode}
\sample
\lipsum[1]
\end{document}
为了清楚起见,这里再次列出相关代码,无需从包中加载。将以下内容放入名为的文件中letterspacing.lua
:
local interletter_glue = node.new('glue')
interletter_glue.width = tex.sp(0)
interletter_glue.stretch = tex.sp('0.5 pt') -- This number controls how much the space between letters can stretch.
local interletter_pen = node.new('penalty')
interletter_pen.penalty = 10000
add_interletter_glue = function(head)
-- Adds equivalent of "\penalty10000\hskip 0pt plus 0.5pt" (the above penalty and glue)
-- before every letter (glyph) that follows a glyph, discretionary (hyphen), or kern node.
for glyph in node.traverse_id(node.id('glyph'), head) do
if glyph.prev and (glyph.prev.id == node.id('glyph') or
glyph.prev.id == node.id('disc') or
glyph.prev.id == node.id('kern')) then
local g = node.copy(interletter_glue)
node.insert_before(head, glyph, g)
node.insert_before(head, g, node.copy(interletter_pen))
end
end
return head
end
luatexbase.add_to_callback("pre_linebreak_filter", add_interletter_glue, "Allow variable interletter spacing.")
现在,您可以使用以下方式排版文件lualatex
:
\documentclass{article}
\usepackage{lipsum} % For random text
\begin{document}
\hsize=10em \frenchspacing % Just to make the effects easier to see
\tolerance=9999 \emergencystretch=\maxdimen % Work harder, avoid overfull boxes
\lipsum % This is typeset without letter-spacing
\directlua{dofile('letterspacing.lua')} % Turn on letter-spacing
\lipsum % This is typeset with letter-spacing
\end{document}
interletter_glue.stretch
您可以通过更改(第三行)的值来控制允许的拉伸量letterspacing.lua
(但请注意,通过设置,\emergencystretch
我们明确告诉 TeX 在必要时超过该限制……但是,您通常不需要\emergencystretch
使用字母间距,而在很多情况下您会需要它)。