I am customizing document style to achieve numbered inline (a.ka., run-in) headings and am, in essence, satisfied with the result of the following.
Code:
#let indent = 1.0em
#let space_above_inline_heads = 1em
#set par(justify: true, first-line-indent: indent, spacing: 0.6em)
#let bodysize = 11pt
#set text(font: "New Computer Modern", size: bodysize)
#let widespace = " "
#set heading(numbering: "1.1." + widespace)
#show heading: it => block[
#counter(heading).display(it.numbering)#(it.body)
]
#show heading.where(level: 1): set align(center)
#show heading.where(level: 1): set text(size: 13pt, weight: "regular")
#show heading.where(level: 1): smallcaps
#show heading.where(level: 2): set text(
size: bodysize,
weight: "bold",
)
// https://typst.app/docs/reference/model/heading/ says to, When writing a rule that accesses the body field, wrap the content in a block to prevent headings from becoming orphans. Advice seems inapplicable to an inline heading, though.
#show heading.where(level: 2): it => {
v(space_above_inline_heads) + h(-indent) + counter(heading).display(it.numbering) + it.body + ".---" + context { h(-(measure([ ]).width)) }
}
#show heading.where(level: 3): set text(
size: bodysize,
weight: "regular",
)
#show heading.where(level: 3): it => {
v(space_above_inline_heads) + h(-indent) + emph[#{counter(heading).display(it.numbering) + it.body + ".---"}] + context { h(-(measure([ ]).width)) }
}
#show heading: it => {
// From https://github.com/typst/typst/issues/2953#issuecomment-3187505828 :
// Clever trick to reduce spacing between consecutive headings
let previous_headings = query(selector(heading).before(here(), inclusive: false))
if previous_headings.len() > 0 {
let ploc = previous_headings.last().location().position()
let iloc = it.location().position()
if (iloc.page == ploc.page and iloc.x == ploc.x and iloc.y - ploc.y < 30pt) { // threshold
v(-10pt) // amount to reduce spacing, could make this dependent on it.level
}
}
it
}
= Introduction
#lorem(25)
#lorem(15)
== Motivation
#lorem(20)
=== Subsubsection
#lorem(15)
== Etc.
=== Subsubsection
#lorem(20)
-
I dislike the use of negative horizontal spacing to prevent the inline headings being indented and to avoid a gratuitous space between the inline heading’s supplement (a dash in this case) and its following paragraph body text. Is there a better way? Especially measuring the width of a space and backing up that distance seems very hackish and I would prefer to simply omit the trailing space that is being automatically inserted between the inline heading and the paragraph. Is there a settable parameter for that?
-
Minor problem: in the output “1.1.1. Subsubsection.—Lorem […]” appears to have a bit of whitespace (kerning) between the period and the em dash.
-
Ideally, I would like an evanescent period that looks back to the last printed character and prints itself if and only if that prior character is not a period, question mark, or exclamation mark. I would also use this when inserting a variable’s value into markup. That is a lot to ask of a markup processor, though. My next addition to these inline-heading rules will be some code to scan
it.bodyto conditionally return the supplement.

