Skip to content

Releases: sile-typesetter/sile


10 Jun 22:58
Choose a tag to compare

Summary of Improvements

This release fixes a regression in v0.15.0 involving 3rd party modules. We were not referencing the LUA_PATH (and LUA_CPATH) environment variables at run time, only at build time. This made it unreasonably difficult to install and use 3rd party modules to a user's $HOME directory and use them in SILE. We were finding modules installed at the system level or locally to a project, but other trees were not being seen.

With this fix, installing modules via luarocks --local install should be a viable workflow again. Before running SILE, make it aware of these modules with eval $(luarocks --local path). The same goes for any arbitrary luarocks --tree locations.

Bug Fixes

  • core: Allow LUA_PATH env var to take effect at runtime (e573c2d)


10 Jun 10:56
Choose a tag to compare

Summary of Improvements

The big v0.15.0 release had some rough edges. But we mentioned that in the v0.15.1 release notes already. The truth is we fumbled some of the sources in the source tarball again. Here is to being able to build cleanly from the source tarball again.

Bug Fixes

  • build: Bundle all assets in source distribution (5198641)


08 Jun 13:04
Choose a tag to compare

Summary of Improvements

The big v0.15.0 release had some rough edges. First the source tarball was missing a vendored source file needed to build against some Lua versions. This did not affect building from Git sources, but made downstream distro packaging difficult. Additionally the now completely removed legacy package manager was still asking for Git as a run time dependency, which is now obsolete.

Also the big changes to the way SIL sources are parsed revealed several order bugs in the book class. These were visible even in the SILE manual as a regression in the way indentation was (not) suppressed after chapters and sections. This was all cleaned up and hopefully paragraph handling is a bit more logical now. Note that per the breaking changes in v0.15.0 custom implementations of these functions will need to be adapted the same way.

Bug Fixes

  • build: Distribute vendored compat-5.3.c source file (3c469d6)
  • build: Remove Git from configure dependencies (352a125)
  • classes: Correct order of operations when paragraphs are ended manually (08f1a7b)
  • packages: Change retrograde package so 'target' version works as expected (6ad9b76)


06 Jun 23:15
Choose a tag to compare

Summary of Improvements

In the works for over a year with over 500 commits and 100 issues closed, please welcome the biggest single release in SILE history. This is the big “Rewrite it in Rust”! Caveat lector. In truth this is a big release but it is not a rewrite. All the typesetting internals of SILE are still written in Lua and 100% user modifiable at runtime. From an end user or 3rd party module developer standpoint little has changed. However SILE itself is now a compiled Rust application that includes its own Lua interpreter. The build process can (optionally) embed all the Lua and other resources files that makeup SILE and its dependencies in a single binary. This opens the door for improvements such as being able to leverage Rust libraries (including exposing their functions to Lua), write some parts of core functions in Rust for performance or preference, write modules in languages other than Lua or C, package SILE for platforms where Lua is not easy to get running, and much more.

The language change mostly affects building and packaging SILE itself. Once running, relatively little has changed with the way SILE interacts with documents. That being said quite a number of default settings have been changed. See the Usage section of these release notes and the retrograde module documentation for tips on how to transition smoothly.

For a transition period, the Lua based CLI is still available as sile-lua. This may be useful for scripting environments that generate inputs and/or parse the output of SILE itself. These should be transitioned to the new Rust CLI sile which has a few minor differences in argument handling and output message formatting. The Lua CLI will only be available for a limited number of future releases. Please do report any issues using the new CLI.

Extra thanks to @Omikhleia for lots contributions and input during the development cycle; and also to @ctrlcctrlv for generous sponsorships that enabled me to commit quite a bit more time to development.

Installation: For Anyone Installing From Packages

If you install SILE from your distro's package manager or other packaging, nothing about your process needs to change. Update via your system tools and enjoy.

Installation: For Distro Packagers and Source Installations

If you install from source or package SILE, the build command sequence is the same but there are new prerequisite dependencies. It now requires Rust tooling (cargo, rustc) as well as some more utilities (jq) to be available at build time. No new dependencies are needed at run time. In fact it is now no longer necessary to use a Lua VM available at runtime for the new CLI. SILE brings its own Lua VM along. (The legacy sile-lua CLI of course still uses Lua as before.) Optionally the build process can also be setup to embed all of its runtime dependencies in a single binary. See ./configure --enable-embedded-resources and ./configure --enable-static if you want to pursue the single binary route. Most users should use the defaults that install the Lua files and other assets separately as an easy reference for tinkering with and overriding them.

Another notable change is that the default Lua VM has been switched from whatever the system supplied to to LuaJIT. This has been an option for a while, but the default has been whatever the newest PUC Lua version was on the host system. LuaJIT is roughly equivalent to Lua 5.1 and doesn't have some small niceties from 5.4, but it is much much faster. Some of the differences are papered over since SILE depends on and provides the compat53 library compatibility layer. Of course build time SILE can still be configured to used any version of Lua of your choice. This can be used to match compatibility with 3rd party modules or other system components.


A number of command behaviours and default settings have been changed. This will likely cause documents to render with a different flow. It will also break support for some 3rd party modules which will need to be updated to match. Many (but not all) of the changes can be temporarily disabled to cause as few changes when rendering old documents as possible. A new module called retrograde can be loaded at run time that will reset defaults and even revert some commands and functions to their previous behavior. A target argument can be passed for the version of SILE your document was designed for. Any default setting changes and as much other functionality as practical that may have changed since that release will be reverted.

$ sile -u 'packages.retrograde[target=v0.14.17]' <INPUTS>

Since the Lua VM version used by default is different, you may need to reinstall 3rd party modules with a matching Lua version. You can first query SILE to understand what version of Lua it is using. With that information you can specify the Lua version you want when you install modules as LuaRocks to match. As a demonstration we'll install a Markdown input module in a project-local directory where SILE will find it without extra path configuration, then use it to render a PDF file:

$ sile -q -e 'print(SILE.lua_version); os.exit()'
$ luarocks --lua-version 5.1 --tree lua_modules install markdown.sile
$ echo 'Test *Markdown* rendering.' >
$ sile -u inputters.markdown

Without further ado, here is the nitty–gritty.


  • packages: Lists now respect the input document spacing and normal settings with regard to paragraphs breaks before, after, and inside lists. This is place of overriding the paragraph skip settings to match the list item spacing setting and always forcing paragraph breaks before and after lists.

  • classes: Hitherto SILE has cleared the current.parindent setting as soon as it used it at the beginning of a paragraph. With this release, the setting is not being cleared until a paragraph is explicitly ended. This will not have an affect on many documents, but could completely blow up layout code that implicitly relied on the effect. Normal paragraphs (e.g. separated by a blank line in the input) and any use cases that explicitly called far ending a paragraph (e.g. by calling \par) will be unaffected. But anywhere a paragraph break was simulated by adding vertical space, the indentation will not be applied the next start of a line. This means that calling any variant of \skip inline in a paragraph will result in content beginning on a new line without using the parindent setting.

    Fixing this change in behaviour requires either explicitly resetting the current.parindent setting after it is initially used or explicitly ending a paragraph before or after placing a vertical skip.

  • inputters: Input documents using the SIL language will now retain whitespace more consistently. Whitespace following environment blocks is no longer swallowed in differently than space following command syntax. Consecutive line breaks in the input will consistently trigger new paragraphs no matter what they follow.

    Note that this change cannot be patched over via the retrograde package settings because by the time your document could specify what packages to load or settings to set, the input document has already been parsed. To achieve the same rendering results where environments could be ended leaving any amount of blank lines and still joined to the following content as part of the same paragraphs, you will need to remove the extraneous whitespace.

  • core: Several top level instance creators of various names have been re-organized under SILE.types.

    Specifically SILE.color, SILE.measurement, and SILE.length have the same names, just under SILE.types.. Additionally SILE.nodefactory is now SILE.types.node and SILE.units is not SILE.types.unit.

    This brings a little bit of sanity to the naming schemes so that you can guess how to use something from the name, but it also makes room for 3rd party add ons to more easily extend or replace these functions. It also makes it easier to start substituting Rust bits where desired.

  • core: Use SILE.papersize() instead of SILE.paperSizeParser()

  • classes: The "center", "raggedleft" and "raggedright" environments formerly reset the margins (left or right skips), meaning they'd take the full frame width. They all cancelled the paragraph indent. The new behaviour honors the fixed part of the parent context's margins, meaning that if you have an environment playing with margins such as an epigraph or an indented quote, those margins are not lost. The raggedleft and raggedright environment also now no longer cancel the paragraph indent.

  • classes: The \script function was heavily overloaded to have many different functions at once and more targeted tools were introduced in SILE v0.14.0 To load 3rd party modules designed for use with SILE, use \use[module=...] instead of \script[src=...]. To run arbitrary Lua code inline use \lua{}; Lua code may be provided inline or externally via either a require= option to load a regular (non-SILE) Lua module using the Lua module path or src= option to load a file by file path.

  • core: For ... reasons ... the default width of spaces in SILE has been a highly opinionated and non-standard 1.2 spaces. While it can be argued that this makes some fonts and some documents look better, it is a very strange thing to have as a global default. Unfortunately setting it back to a more conventional 1 space is a major change and will cause many/most documents to re–flow.

    The old default can be recovered either in documents with:


    ...or even from the CLI when rendering a document:

    $ sile -e 'SILE.settings:set("shaper.spaceenlargementfactor", 1.2, true)'
Read more


07 Feb 18:52
Choose a tag to compare

Summary of Improvements

The "big v0.15" is still brewing, but we keep coming up with little improvements that easily fit in the v0.14 series. It turns out the special hyphenation handling we added to Polish (for explicitly hyphenated words) is used by quite a few languages. At this time we've applied it by default to Croatian, Czech, Portuguese, Slovak. and Spanish. Thanks to @Omikhleia for much of the research on this as well as @jodros, @DavidLRowe, @jakubkaczor, and @tomas-vl for domain expertise.

Additionally João contributed an option for columns command to more easily set up column frames with balancing turned on or off.


  • languages: Enable explicit hyphen repetition handling in Croatian (c29545d)
  • languages: Enable explicit hyphen repetition handling in Czech (b05d621)
  • languages: Enable explicit hyphen repetition handling in Portuguese (2a58d96)
  • languages: Enable explicit hyphen repetition handling in Slovak (82640b0)
  • languages: Enable explicit hyphen repetition handling in Spanish (8db7f23)
  • packages: Add balancing option to makecolums command (#1950) (b5ce8e6)


27 Jan 11:31
Choose a tag to compare

Summary of Improvements

If goofed up some of the merges involved in the release process for v0.14.15. This doesn't bring any user facing features or fixes, only a bit of refactoring intended to be in the last release. The main purpose is to straighten out the repository so the expected branch contains the release tags. Sorry for the noise.

Bug Fixes

  • tooling: Re-merge so release tag is on master branch (e8eaf11)


27 Jan 10:25
Choose a tag to compare

Summary of Improvements

In today's minor release we tinker with language support.

@Omikhleia contributed improvements to non-breaking space handling in French. He also setup handling of Catalan hyphenation at ela geminada and Polish hyphenation at existing hyphens. Turkish gained a new setting (on by default per the current Turkish Language Association guidelines) for handling hyphenation at apostrophes. The previous behaviour (used by some publisher style guides) is available by toggling off the new setting.

All languages gained an (on by default) setting that makes spaces after em-dashes at the start of paragraphs be fixed width. This is used in at least French and Turkish typography to typeset dialogue and the fixed spacing keeps everything lining up per expectations. Other languages may benefit as well, but also the feature can be disabled if flexible spacing is actually desired.

Details for each of these languages and their related settings are in the SILE manual.


  • languages: Accomodate alternate Turkish hyphenation guidelines at apostrophes (92904fc)
  • typesetters: Support for speaker change introduced by em-dash (2afa4cb)

Bug Fixes

  • languages: Break at ela geminada in Catalan cancels the punt vola (f8c4c1e)
  • languages: Break at explicit hyphen in Polish repeats the hyphen (0f8c7aa)
  • languages: Remove multiple repetitions of U+00A0 nbsp in French (0356a49)
  • languages: U+00A0 nbsp in French causes unexpected word breaks (b93975c)


23 Dec 18:47
Choose a tag to compare

Summary of Improvements

Merry Christmas!

Not this isn't the Rusty release you might want in your stocking. That is coming along nicely though, we're just including an abitioun rollup of breaking changes and going slow to do it right. You can preview the release notes or follow issues in the milestore for teasers. More notably there are already lots of ways to run the development release: Homebrew has --HEAD support, Docker images are available, the Nix flake works, Arch Linux has VCS packages, and more. If you want to start putting it through the paces go ahead.

Until the cookies are fully baked, this minor release has a few goodies that are not breaking changes. @Omikhleia contributed some updates to the dropcaps package to better handle fonts with descenders in their capitals. He also contributed some improvements to Unicode handling: soft hyphen and non-breaking spaces work as expected. SILE has perhaps more robust ways of defining custom hyphenation and glue nodes, but the Unicode handling is convenient is handy if you input content has such data anyway. For bonus points some CLI error messages have been dramatically improved to be more informative and less repetative.


  • cli: Change module load error to suggestion for how to install 3rd party modules (c280050)
  • languages: U+00A0 non-breaking space must be stretchable by default (b769a63)
  • typesetters: Support U+00AD soft hyphen as discretionary break (285507e)

Bug Fixes

  • backends: Fix plain text backend to work in LuaJIT/Lua 5.1 (b185d49)
  • cli: Stop outputting error messages twice on failure to process main file (da5d609)
  • core: Use nil-safe and Lua-version-robust table utils (2405b23)
  • packages: Adjust dropcap logic for letters with a depth (fd6963d)


30 Oct 10:28
Choose a tag to compare

Summary of Improvements

This minor release brings a couple improvements from a new contributor, @jodros. We have one new feature, a boolean option flag on our base class that enables landscape mode. Any paper orientation has been supported already, but the preset paper sizes only had the standard portrait orientation and landscape orientations required entering custom dimensions. This flag makes it a bit easier to swap the X and Y dimensions of the standard (or custom) value parsed from the papersize option. Additionally he fixed a bug in the frametricks package such that using the \makecolumns function doesn't break relative frame constraints used by, for example, footnote or folio frames. This fix only works for TTB-LTR automatic column setups for now.

Finally, some build system fixes and features were backported from v0.15.0 development work. Most significantly the handling of the SILE_PATH environment variable now allows multiple paths, which in turn allows a single project to utilize multiple external collections of 3rd party packages rather than having to collate them all into one location.


  • classes: Add landscape option to base class (#1892) (0fb9ade)
  • cli: Allow multiple runtime SILE_PATH segments (backport from develop branch) (e7c8fe2)

Bug Fixes

  • frames: Update frame constraints with new frame IDs after \makecolumns (b2d6b4f)


11 Oct 16:31
Choose a tag to compare

Summary of Improvements

This is another minor maintenance release. We throw a few less warning messages having dropped a few that were not actually informative. A few memory management bugs have been fixed, most notably affecting Lua 5.1. For the most part we hope you are on LuaJIT anyway (or your system's default Lua, hopefully newer than 5.1) but we do try to keep everything working smoothly on any platform. A few other minor improvements are noted below.

In other news, the v0.15.0 release is coming soon too. It is already stable enough to be used for real work and should play nice with most systems. Issue #1864 has some notes on how to run the development branch for it before it is released.


  • i18n: Add Portuguese localizations for bibtex package (#1859) (f716c35)
  • utilities: Add utility function for console messages without trace info (18526ce)

Bug Fixes

  • build: Make sure vendored luarocks isn't a phony target that runs repeatedly (713434d)
  • core: Allocate exactly what we use, not a guess with an extra just in case (640ded0)
  • core: Correct usage of HarfBuzz when passing a filtered list of shapers (f488643)
  • core: Fixup class loader so cache is all Lua module specs (#1863) (7efff5b)
  • packages: Don't warn on TOC content change if not actually used (87c443d)