如何避免 Lua(La)TeX 中逗号前换行?

如何避免 Lua(La)TeX 中逗号前换行?

这是(有点晚了)对这个问题的后续跟进如何避免逗号前换行?@MostlyHarmless 表明,在以连字符结尾的单词后可以插入换行符,即使该单词后跟逗号。

在该问题的评论部分,@topskip 说:

如果您使用 LuaTeX,我们可以为您提供一个禁止在逗号前换行的解决方案。

所以在这里我想在 Lua(La)TeX 中找到一个解决方案。

要使用的 MWE 是相同的:

\documentclass[11pt, a4paper]{scrartcl}
\usepackage[ngerman]{babel}
\begin{document}

aaDas ist ein Absatz. Das ist ein Absatz. Das ist ein Absatz. Es gibt zeit-, temperatur-,  und weggesteuerte Verfahren ein Absatz. Das ist ein Absatz.Das ist ein Absatz. Das ist ein Absatz.Das ist ein Absatz. Das ist ein Absatz.Das ist ein Absatz. Das ist ein Absatz.Das ist ein Absatz. Das ist ein Absatz.

\end{document}

并且输出也是一样的: 逗号前换行

答案1

您可以使用简单的节点处理回调来执行此操作。我创建了一个包含此类回调的简单包,hyphencomma.sty

\ProvidesPackage{hyphencomma}

\RequirePackage{luacode}

\begin{luacode*}
local glyph_id = node.id "glyph"
local penalty_id = node.id "penalty"
local hyphenc  = string.byte "-"
local commac   = string.byte ","
local function prevent_hyphencomma(head)
  for n in node.traverse_id(glyph_id,head) do
    if n.char == hyphenc then
      -- we need to find node after the next node. directly following is automaticaly inserted discretionary
      local next = n.next.next
      if next.id == glyph_id and next.char == commac then
        -- create penalty node
        local penalty = node.new("penalty")
        penalty.penalty = 10000
        -- remove discretionary
        head = node.remove(head,n.next)
        -- insert penalty
        head = node.insert_after(head, n, penalty)
      end
    end
  end
  return head
end


luatexbase.add_to_callback("pre_linebreak_filter", prevent_hyphencomma, "Prevent hyphen comma")

\end{luacode*}

\endinput

prevent_hypencomma函数处理换行符前每个段落的节点。节点类型有很多,但最重要的是glyph包含特定字符的节点。要匹配这种类型的节点,我们必须知道它的节点 ID,我们可以使用以下命令找到它:

local glyph_id = node.id "glyph"

使用node.traverse_id迭代器,我们处理节点列表,仅过滤具有glyphid 的节点。每个节点都有一些字段,具体取决于其类型。我们可以使用字段找到glyphs 字符代码char。它是字符编号,而不是字符串,因此我们必须测试连字符字符代码,而不是-。对于 ASCII 字符,我们可以使用函数获取字符代码string.byte

每个连字符后面discretionary都会插入一个节点,所以我们需要跳过它来查找下一个节点并测试它是否是逗号glyph。如果是,我们必须删除该discretionary节点并插入penalty以防止换行。

结果:

在此处输入图片描述

相关内容