![fontspec 和 lua 之间奇怪的交互](https://linux22.com/image/443343/fontspec%20%E5%92%8C%20lua%20%E4%B9%8B%E9%97%B4%E5%A5%87%E6%80%AA%E7%9A%84%E4%BA%A4%E4%BA%92.png)
我注意到包和 lua 代码之间存在奇怪的交互fontspec
。一段时间以来,我一直在使用在这个网站上找到的 lua 代码,该代码可以防止由单个字母(法语中的“a”、“à”和“y”)组成的单词“单独”出现在行尾。
令人惊讶的是,如果我用 加载字体fontspec
,使用这个 lua 代码,并且其中一个章节以这些单字母单词之一开头,则标题中的运行标题不会像它应该的那样用小写字母组成。
如果我不加载新字体或激活 lua 代码,则不会出现此问题。问题仅出现在标题中,如果我简单地输入\textsc{A ...}
,则不会出现问题。
这很奇怪,我完全不明白发生了什么。你知道吗?
示例:左侧的页眉的章节名称以“a”开头,且不是小写的;右侧的页眉为普通页眉:
\documentclass{book}
\usepackage{lipsum, luacode, fontspec}
\setmainfont{LibertinusSerif}
\begin{luacode}
local GLYPH = node.id("glyph")
local GLUE = node.id("glue")
local prevent_single_letter = function (head)
while head do
if (head.id == GLYPH) then
if unicode.utf8.match(unicode.utf8.char(head.char), "[aAàÀyY]") then
if ((head.prev.id == GLUE
or (head.prev.id == GLYPH
and unicode.utf8.match(unicode.utf8.char(head.prev.char), "[%[%]()%{%}]")))
and head.next.id == GLUE) then
local p = node.new("penalty")
p.penalty = 10000
node.insert_after(head, head, p)
end
end
end
head = head.next
end
return true
end
function single_letter_enable ()
luatexbase.add_to_callback("pre_shaping_filter", prevent_single_letter, "singleletter")
end
\end{luacode}
\directlua{single_letter_enable()}
\makeatletter
\def\ps@headings{
\def\@evenhead{{\scshape\rightmark}\hfil}
\def\chaptermark##1{\markright{##1}}
}
\makeatother
\pagestyle{headings}
\begin{document}
\chapter*{A test}\chaptermark{A test}
\lipsum[1-7]
\chapter*{Test}\chaptermark{Test}
\lipsum[1-7]
\textsc{A test}
\end{document}
编辑
根据user187802的提议,修改了lua代码。
\documentclass{book}
\usepackage{lipsum, luacode, fontspec}
\setmainfont{LibertinusSerif}
\begin{luacode}
local GLYPH = node.id("glyph")
local GLUE = node.id("glue")
local prevent_single_letter = function (head)
while head do
if (head.id == GLYPH) then
if head.prev then. -- !!!!!!!
if unicode.utf8.match(unicode.utf8.char(head.char), "[aAàÀyY]") then -- and head.prev.id ~= GLUE then
if ((head.prev.id == GLUE
or (head.prev.id == GLYPH
and unicode.utf8.match(unicode.utf8.char(head.prev.char), "[%[%]()%{%}]")))
and head.next.id == GLUE) then
local p = node.new("penalty")
p.penalty = 10000
node.insert_after(head, head, p)
end
end
end
end
head = head.next
end
return true
end
function single_letter_enable ()
luatexbase.add_to_callback("pre_shaping_filter", prevent_single_letter, "singleletter")
end
\end{luacode}
\directlua{single_letter_enable()}
\makeatletter
\def\ps@headings{
\def\@evenhead{{\scshape\rightmark}\hfil}
\def\chaptermark##1{\markright{##1}}
}
\makeatother
\pagestyle{headings}
\begin{document}
Le titre courant est un rappel du titre de l’ouvrage, du chapitre, parfois abrégé, a % "a" should not be alone at the end of the line, but should be sent to the next line
placé dans la marge supérieure ou inférieure d’une page.
\chapter*{A test}\chaptermark{A test}
\lipsum[1-7]
\chapter*{Test}\chaptermark{Test}
\lipsum[1-7]
\end{document}
但是代码似乎不再能完成它被创建的目的。例如在下面的文本中,单词“a”不应该单独出现在行末,而应该被推到下一行的开头。
答案1
检查它是否不是第一个字母:
local prevent_single_letter = function (head)
while head do
if (head.id == GLYPH) then
if head.prev then -- !!!!!!!
if unicode.utf8.match(unicode.utf8.char(head.char), "[aAàÀyY]") then
if ((head.prev.id == GLUE
[...]