fontspec 和 lua 之间奇怪的交互

fontspec 和 lua 之间奇怪的交互

我注意到包和 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
[...]

相关内容