Theming for MfGames Writing
One of the big parts about MfGames Writing[1] is the ability to customize the appearance of the generated files. If we didn't have that, then every book would look the same and I don't care for that. Books should allow for different themes, chapter numbers, and even spacing. To that regard, everything is funneled through a theme for formatting.
Series
I appear to be writing a short series of post about the tools I use for publication and writing.
- Semantic Versions and Releases[2]: Why semantic versioning helps with the writing process.
- Evolution of MfGames Writing[3]: A brief history and reasoning behind the tools.
- First Steps Using MfGames Writing[4]: Starting a new project with MfGames Writing.
- Adding Content to MfGames Writing[5]: Adding front and back matter to novels.
- Working with MfGames Writing, CI, and Docker[6]: Adding automatic building with commits.
- Additional Formats for MfGames Writing[7]: How to create PDF, MOBI, DOCX, and HTML versions.
- Theming for MfGames Writing: A light introduction on how to customize the output.
- Integrating Semantic Versioning into MfGames Writing[8]: Tying semantic releases into the process.
HTML
The entire theme system is built on HTML and CSS. In previous versions of this, I generated XeLaTeX files for PDF and used a custom conversion utility for Word documents. It also increased the complexity significantly. Switching to a HTML-based system simplified the theme creation and made debugging easier.
This is one case where looking at a reference implementation[9] will be helpful.
Components
In the content[10] post, there are quite a few references to `element` on each of the content items. These elements are Liquid-based stylesheets that are provided by the theme.
For example, the `title.xhtml` in the clean theme looks like this:
{{html}}
The `{{html}}` is where the contents in the `source` given on the content will be placed. In this case, the `element-page-break` is how I handle page rendering with WeasyPrint.
A more complicated example would be chapter.xhtml[11]:
{% if content.number %}Chapter {{content.number}}{% endif %}{{content.title}}
{{html}}
You can see more uses of the Liquid tags. In this case, if we have a `number` property in the content, it will insert the `Chapter #` above the title of the chapter (from the YAML header) and the contents of the body into `{{html}}`.
Recursive Templates
To reduce copy/paste, there are also recursive templates. For example, the colophon[12] template looks like this:
---
extends: simple-title
---
{{html}}
Once this page is rendered, the results are formatted by the simple-title[13]
{{content.title}}
{{html}}
It is recursive, so you can have one template extending another extending another.
Styling
You'll notice that there is very little styling in the HTML. Instead, most of it is done with a SASS template in the theme. The base style is called stylesheet.scss[14]:
p {
margin-bottom: 0;
margin-top: 0;
text-align: left;
text-indent: 2em;
}
Stylesheets can be overridden by specific formats. The most common is having a WeasyPrint-specific stylesheet[15]:
@import "stylesheet";
@page {
@bottom-center {
content: counter(page);
vertical-align: top;
padding-top: 1em;
}
size: letter portrait;
margin: 3cm 2cm;
}
To figure out overrides, the system looks for the format name first (`html.scss` or `weasyprint.scss`) and if it doesn't find one, goes to the base (`stylesheet.scss`).
Stylesheet Variables
Because I'm fond of single points of truth, SASS also lets us have variables so we can pull the version, or information from the edition data.
@page :right {
@top-right {
content: themeString("edition.title");
vertical-align: bottom;
padding-bottom: 1em;
}
padding-left: 1cm;
}
The `themeString` works just like the Liquid templates.
Creating New Themes
To create a new theme, I basically just copy all of the clean theme and start customizing.
Metadata
Categories:
Tags:
Footer
Below are various useful links within this site and to related sites (not all have been converted over to Gemini).