Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typesetter and package support for constructs spanning multiple lines #1977

Merged
merged 7 commits into from
Feb 2, 2024
Prev Previous commit
Next Next commit
feat(packages): Strikethrough and underline can span multiple lines
Omikhleia authored and Didier Willis committed Feb 1, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 3eb1a1f944594283bb68e5876eeaf692dd92678a
42 changes: 14 additions & 28 deletions packages/rules/init.lua
Original file line number Diff line number Diff line change
@@ -126,22 +126,14 @@ function package:registerCommands ()
self:registerCommand("underline", function (_, content)
local underlinePosition, underlineThickness = getUnderlineParameters()

local hbox, hlist = SILE.typesetter:makeHbox(content)
-- Re-wrap the hbox in another hbox responsible for boxing it at output
-- time, when we will know the line contribution and can compute the scaled width
-- of the box, taking into account possible stretching and shrinking.
SILE.typesetter:pushHbox({
inner = hbox,
width = hbox.width,
height = hbox.height,
depth = hbox.depth,
outputYourself = function (node, typesetter, line)
SILE.typesetter:liner("underline", content,
function (box, typesetter, line)
local oldX = typesetter.frame.state.cursorX
local Y = typesetter.frame.state.cursorY

-- Build the original hbox.
-- Build the content.
-- Cursor will be moved by the actual definitive size.
node.inner:outputYourself(SILE.typesetter, line)
box:outputContent(typesetter, line)
local newX = typesetter.frame.state.cursorX

-- Output a line.
@@ -150,36 +142,28 @@ function package:registerCommands ()
-- should expand downwards
SILE.outputter:drawRule(oldX, Y - underlinePosition, newX - oldX, underlineThickness)
end
})
SILE.typesetter:pushHlist(hlist)
)
end, "Underlines some content")

self:registerCommand("strikethrough", function (_, content)
local yStrikeoutPosition, yStrikeoutSize = getStrikethroughParameters()

local hbox, hlist = SILE.typesetter:makeHbox(content)
-- Re-wrap the hbox in another hbox responsible for boxing it at output
-- time, when we will know the line contribution and can compute the scaled width
-- of the box, taking into account possible stretching and shrinking.
SILE.typesetter:pushHbox({
inner = hbox,
width = hbox.width,
height = hbox.height,
depth = hbox.depth,
outputYourself = function (node, typesetter, line)
SILE.typesetter:liner("strikethrough", content,
function (box, typesetter, line)
local oldX = typesetter.frame.state.cursorX
local Y = typesetter.frame.state.cursorY
-- Build the original hbox.

-- Build the content.
-- Cursor will be moved by the actual definitive size.
node.inner:outputYourself(SILE.typesetter, line)
box:outputContent(typesetter, line)
local newX = typesetter.frame.state.cursorX

-- Output a line.
-- NOTE: The OpenType spec is not explicit regarding how the size
-- (thickness) affects the position. We opt to distribute evenly
SILE.outputter:drawRule(oldX, Y - yStrikeoutPosition - yStrikeoutSize / 2, newX - oldX, yStrikeoutSize)
end
})
SILE.typesetter:pushHlist(hlist)
)
end, "Strikes out some content")

self:registerCommand("boxaround", function (_, content)
@@ -237,6 +221,8 @@ The \autodoc:command{\underline} command \underline{underlines} its content.

The \autodoc:command{\strikethrough} command \strikethrough{strikes} its content.

Both commands support paragraph content spanning multiple lines.

\autodoc:note{The position and thickness of the underlines and strikethroughs are based on the metrics of the current font, honoring the values defined by the type designer.}

The \autodoc:command{\hrulefill} inserts an infinite horizontal rubber, similar to an \autodoc:command{\hfill}, but—as its name implies—filled with a rule (that is, a solid line).