2

Background

Using KeenWrite Themes (specifically, the Boschet theme) to typeset a chapter, with the first letter being a lettrine. This is invoked using \placeinitial without any context (i.e., it is meant to be a general-purpose solution).

Using ConTeXt LMTX version: 2023.06.04 18:58

Problem

When the first paragraph is too short, the second paragraph overlaps the lettrine.

Code

MWE:

\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

Output:

document output

Desired output:

expected document output

Question

How would you instruct ConTeXt to "protect" the lettrine such that regardless of whether the first paragraph spans multiple lines, a short first paragraph will still prevent the second paragraph from overlapping the lettrine? (That is, the setups should work in both cases, without any knowledge about the first paragraph length being added between \starttext and \stoptext.)

0

1 Answer 1

1

In the version after ConTeXt 2023.06.04, the following will be possible:

\setupinitial[n=2,continue=yes]

From that version and earlier, here's a Lua-based solution:

\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

Normally manipulating nodes inside the callbacks is a questionable way to do something, but in this case, that's exactly how the standard initial code works.

We also need to modify the default alternative since \setupinitial provides no way for us to set a different alternative. A better solution would be to provide a new alternative so we wouldn't need to make questionable overrides to the base code.

The output is identical to the image in the question.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .