Skip to content

Commit

Permalink
feat(classes): Support frontmatter/mainmatter/backmatter divisions
Browse files Browse the repository at this point in the history
  • Loading branch information
Omikhleia authored and Didier Willis committed Jan 12, 2025
1 parent a5be6c0 commit 36b8667
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 22 deletions.
70 changes: 67 additions & 3 deletions classes/resilient/book.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ SILE.scratch.book.headers = {
none = true
}

local DIVISIONNAME = {
"frontmatter",
"mainmatter",
"backmatter"
}

-- CLASS DEFINITION

function class:_init (options)
base._init(self, options)
self.resilientState = {}

self:loadPackage("resilient.sectioning")
self:loadPackage("masters")
Expand Down Expand Up @@ -86,6 +93,7 @@ function class:_init (options)
-- Package "folio" is loaded by the plain class.
self:registerCommand("foliostyle", function (_, content)
local styleName = SILE.documentState.documentClass:oddPage() and "folio-odd" or "folio-even"
local division = self.resilientState.division or 2
SILE.call("style:apply:paragraph", { name = styleName }, {
-- Ensure proper baseline alignment with a strut rule.
-- The baseline placement depends on the line output algorithm, and we cannot
Expand All @@ -94,7 +102,10 @@ function class:_init (options)
-- aligned folios, but the 1 is smaller than the 6 and 7, the former ascends above,
-- and the latter descends below the baseline).
createCommand("strut", { method = "rule"}),
subContent(content)
createCommand("style:apply:number", {
name = "folio-" .. DIVISIONNAME[division],
text = SU.ast.contentToString(content),
})
})
end)

Expand Down Expand Up @@ -202,6 +213,18 @@ end
function class:registerStyles ()
base.registerStyles(self)

-- Front, main, back matter
local divisionFolio = {
frontmatter = "roman",
}
for _, name in ipairs(DIVISIONNAME) do
self:registerStyle("folio-" .. name, {}, {
numbering = {
display = divisionFolio[name] or "arabic"
}
})
end

-- Sectioning styles
self:registerStyle("sectioning-base", {}, {
paragraph = { before = { indent = false },
Expand Down Expand Up @@ -562,6 +585,42 @@ function class:registerCommands ()
end
end, "Text to appear on the top odd pages.")

-- front/main/back matter

self:registerCommand("internal:division", function (options, _)
local division = SU.required(options, "division", "internal:division")
-- Always start on an odd page, so as to be consistent with the folio numbering
-- in case it is reset.
SILE.call("open-on-odd-page")
self.resilientState.division = division
-- Previous section titles (in technical mode) or chapter title (in novel mode)
-- is no longer valid (and in none mode, it's not valid anyway).
SILE.scratch.headers.odd = nil
if self.headers == "technical" then
-- In novel mode, the book title is in the even header, and is still valid
-- So we don't reset it.
-- But in technical mode, even headers contain the current chapter title,
-- invalid upon a new part.
SILE.scratch.headers.even = nil
end
-- Reset folio counter if needed (i.e. on display format change)
local current = self:getCounter("folio")
local folioSty = self:resolveStyle("folio-" .. DIVISIONNAME[division])
local display = folioSty.numbering and folioSty.numbering.display or "arabic"
if current.display ~= display then
SILE.call("set-counter", { id = "folio", display = display, value = 1 })
end
end)

for div, name in ipairs(DIVISIONNAME) do
self:registerCommand(name, function (_, content)
if self.resilientState.division and self.resilientState.division >= div then
SU.error("\\" .. name .. " is not valid after a " .. DIVISIONNAME[self.resilientState.division])
end
SILE.call("internal:division", { division = div }, content)
end, "Switch to " .. DIVISIONNAME[div] .. " division.")
end

-- Sectioning hooks and commands

self:registerCommand("sectioning:part:hook", function (options, _)
Expand Down Expand Up @@ -615,11 +674,17 @@ function class:registerCommands ()
end, "Applies section hooks (footers and headers, etc.)")

self:registerCommand("part", function (options, content)
if self.resilientState.division and self.resilientState.division ~= 2 then
options.numbering = false
end
options.style = "sectioning-part"
SILE.call("sectioning", options, content)
end, "Begin a new part.")

self:registerCommand("chapter", function (options, content)
if self.resilientState.division and self.resilientState.division ~= 2 then
options.numbering = false
end
options.style = "sectioning-chapter"
SILE.call("sectioning", options, content)
end, "Begin a new chapter.")
Expand Down Expand Up @@ -821,8 +886,7 @@ function class:registerCommands ()
-- Kind of a hack dues to restrictions with frame parsers.
layout:setPaperHack(SILE.documentState.paperSize[1], SILE.documentState.paperSize[2])

SILE.call("supereject")
SILE.typesetter:leaveHmode()
SILE.call("open-on-any-page")

local oddFrameset, evenFrameset = layout:frameset()
self:defineMaster({
Expand Down
39 changes: 37 additions & 2 deletions examples/manual-classes/classes.sil
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ The class also defines two commands for manipulating the page headers.
\begin{row}
\cell[valign=top]{\autodoc:command{\odd-tracked-header{<content>}}}
\cell[valign=top]{Registers the content to be used in odd running headers, tracked.}
\end{row}
\end{row}
\end{ptable}
\caption{Commands for manipulating page headers.}
\end{table}
Expand All @@ -314,6 +314,39 @@ The environment relies on the same-named style for its styling and on the
\autodoc:setting{book.blockquote.margin} setting for its indentation (defaults to 2em). Indented
quotes can be nested.

\section{Front, main and back divisions}

The class supports the standard \autodoc:command{\frontmatter}, \autodoc:command{\mainmatter} and \autodoc:command{\backmatter} commands to switch between the different higher-level divisions of the document.
Obviously, these commands can only occur once in the document, and in the order given above.
They start a new page, and influence the style of folios.

\begin{table}
\begin[cols=40%fw 50%fw, header=true]{ptable}
\begin[background=#eee]{row}
\cell[valign=top]{Style}
\cell[valign=top]{Description}
\end{row}
\begin{row}
\cell[valign=top]{\code{folio-frontmatter}}
\cell[valign=top]{Numbering style applied to folios in the front matter.}
\end{row}
\begin{row}
\cell[valign=top]{\code{folio-mainmatter}}
\cell[valign=top]{Numbering style applied to folios in the main matter.}
\end{row}
\begin{row}
\cell[valign=top]{\code{folio-backmatter}}
\cell[valign=top]{Numbering style applied to folios in the back matter.}
\end{row}
\end{ptable}
\caption{Styles used for folios in different document divisions.}
\end{table}

Books not using these divisions assume "main" matter by default.
In the "front" and "back" matter divisions, parts and chapters are never numbered.
Not that this is not a configurable style decision, but the very definition of these divisions.
In "main" matter, they are numbered by default, although this can be changed either on the sectioning command itself, or globally with adequate styles.

\section{Other features}

The footnotes are based on the \autodoc:package{resilient.footnotes} package and therefore have the
Expand All @@ -330,7 +363,9 @@ available.
\medskip
A few layout-related commands are also provided.

The \autodoc:command{\layout[layout=<layout spec>]} command inserts a page break and changes the page layout from that point. An optional \autodoc:parameter{offset=<dimen>} may be specified to also alter the binding offset. By default, the global offset (that is, as possibly defined via the corresponding class option) is used.
The \autodoc:command{\layout[layout=<layout spec>]} command inserts a page break if needed, and changes the page layout from that point.
An optional \autodoc:parameter{offset=<dimen>} may be specified to also alter the binding offset.
By default, the global offset (that is, as possibly defined via the corresponding class option) is used.

Mostly intended for documentation, the \autodoc:command{\showlayout[layout=<layout spec>, papersize=<paper spec>]} command outputs an image representing the selected page layout and paper size.
Optional parameters are \autodoc:parameter{offset=<dimen>} for the binding offset (0, that is no offset, by default), \autodoc:parameter{ratio=<number>} for the image down-scaling (dividing the paper size by the specified amount, 6.5 by default), and \autodoc:parameter{rough=<boolean>} (false by default).
Expand Down
30 changes: 22 additions & 8 deletions examples/manual-styling/advanced/folio.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ folio-odd:
indent: false
```
That common parent style is where we would ideally define the font, for instance
to use old-style numbering. It is also where we can define the numbering format.
Robert Bringhurst says: "It is usual to set folios in the text size"---so we won't
change the font size.
That common parent style is where we would ideally define the font, for instance to use old-style numbering.
Robert Bringhurst says: "It is usual to set folios in the text size"---so we won't change the font size.
```yaml
folio-base:
Expand All @@ -36,7 +34,23 @@ folio-base:
display: "arabic"
```
::: {custom-style="admon"}
Frontmatter / mainmatter / backmatter sections are not implement yet.
So for now, the above only documents the "mainmatter" general styling.
:::
The numbering format is defined in another set of numbering styles.
The usual settings is to have roman numbers in the front matter, and arabic numbers in the main and back matters.
```yaml
folio-frontmatter:
style:
numbering:
display: "roman"
folio-mainmatter:
style:
numbering:
display: "arabic"
folio-backmatter:
style:
numbering:
display: "arabic"
```
In books without these high-level divisions, `folio-mainmatter` is implied for the whole document.
As all of these are numbering styles, you can also extend them further, would you want to style the page numbers differently in these divisions.
13 changes: 4 additions & 9 deletions examples/manual-styling/advanced/intro.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
# Advanced styling

Having read the previous chapter, you should now know how to edit styles and
modify them at your convenience. Some of the styles used by resilient collection
of classes and packages, however, are probably worth being depicted with more
details.
Having read the previous chapter, you should now know how to edit styles and modify them at your convenience.
Some of the styles used by the resilient collection of classes and packages, however, are probably worth being depicted with more details.

The aim of this chapter is to present these advanced use cases, and possibly
to answer some frequently asked questions.
Please bear in remind, however, that the style inheritance model is very flexible,
and that you can possibly modify the style hierarchy to make it quite different
from the default setup.
The aim of this chapter is to present these advanced use cases, and possibly to answer some frequently asked questions.
Please bear in remind, however, that the style inheritance model is very flexible, and that you can possibly modify the style hierarchy to make it quite different from the default setup.
18 changes: 18 additions & 0 deletions examples/sile-resilient-manual-styles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,12 @@ figure-caption-ref-number:
before:
text: "fig. "

folio-backmatter:
origin: "resilient.book"
style:
numbering:
display: "arabic"

folio-base:
origin: "resilient.book"
style:
Expand All @@ -312,6 +318,18 @@ folio-even:
before:
indent: false

folio-frontmatter:
origin: "resilient.book"
style:
numbering:
display: "roman"

folio-mainmatter:
origin: "resilient.book"
style:
numbering:
display: "arabic"

folio-odd:
inherit: "folio-base"
origin: "resilient.book"
Expand Down

0 comments on commit 36b8667

Please sign in to comment.