背景
使用KeenWrite 主题(具体来说,Boschet 主题) 来排版章节,第一个字母是字母。这是使用\placeinitial
没有任何上下文来调用的(即,它是一种通用解决方案)。
使用 ConTeXt LMTX 版本:2023.06.04 18:58
问题
当第一段太短时,第二段会与正文重叠。
代码
梅威瑟:
\setupinitial[n=2]
\setuphead[chapter][
after={\placeinitial},
page=no,
]
\starttext
\chapter{one}
Kermit Ruffins
Meet me at the second line.
\chapter{two}
\input knuth
Meet me at the second line.
\stoptext
输出:
期望输出:
问题
您将如何指示 ConTeXt “保护” 文本框,以便无论第一段是否跨越多行,较短的第一段仍将阻止第二段与文本框重叠?(也就是说,设置应该在两种情况下都有效,而无需了解第一段的长度是否添加到第二段\starttext
和第三段之间。\stoptext
。)
答案1
在版本中后ConTeXt 2023.06.04,将实现以下目标:
\setupinitial[n=2,continue=yes]
从该版本及更早版本开始,这是一个基于 Lua 的解决方案:
\startluacode
userdata.hangindent = 0
function userdata.post_lettrine(head)
nodes.tasks.disableaction("finalizers", "userdata.post_lettrine")
if tex.prevgraf < math.abs(tex.hangafter) then
userdata.hangindent = tex.hangindent
nodes.tasks.enableaction("processors", "userdata.next_par")
end
return head
end
nodes.tasks.appendaction("finalizers", "before", "userdata.post_lettrine")
nodes.tasks.disableaction("finalizers", "userdata.post_lettrine")
function userdata.next_par(head)
nodes.tasks.disableaction("processors", "userdata.next_par")
if head.next.id == node.id("glue") and
head.next.subtype == 20
then
head.next.width = userdata.hangindent
end
return head
end
nodes.tasks.appendaction("processors", "before", "userdata.next_par")
nodes.tasks.disableaction("processors", "userdata.next_par")
local default = typesetters.initials.actions.default
function typesetters.initials.actions.default(...)
nodes.tasks.enableaction("finalizers", "userdata.post_lettrine")
return default(...)
end
\stopluacode
\setupinitial[n=2]
\setuphead[chapter][
after={\placeinitial},
page=no,
]
\starttext
\chapter{one}
Kermit Ruffins
Meet me at the second line.
\chapter{two}
\input knuth
Meet me at the second line.
\stoptext
通常在回调中操作节点是一种值得怀疑的做法,但在这种情况下,标准初始代码就是这样工作的。
我们还需要修改default
替代方案,因为\setupinitial
没有提供任何方法来设置不同的替代方案。更好的解决方案是提供一个新的替代方案,这样我们就不需要对基础代码进行可疑的覆盖。
输出与问题中的图像相同。