There are a handful of examples on the website and (as of just before the v0.12.0 release) the examples are in the website’s GitHub source repository here so they are open for contributions. There isn’t a really good large showcase document yet –just some examples of handling languages and samples of what packages do– but with time we’d like to turn the website example gallery into a more complete general purpose showcase.

Also as of today I just opened up GitHub Discussions on the project repository which has a Show and tell category. We’d be happy to field questions there.

SILE doesn’t mess about much with pixels, the default canvas output is (vector based) PDF. Here is a minimalist example. If you put the following in a text file called math.sil:

Then assuming you have the default math font Libertinus Math on your system, the process of rendering it from the command line looks like this:

$ sile math.sil
SILE v0.12.0 (Lua 5.4)
<math.sil>
options.family = Libertinus Math
[1]

That output shows it successfully rendered 1 page which you will find in a file called math.pdf with your formula drawn on the page canvas (not in pixels, but you get the idea). In this tweet you can see a side-by-side of a more advanced math input and output.

The project readme and manual not only have installation instructions but also two was to run sile without installing it at all (via Docker or Nix). Packages are available for Homebrew, Ubuntu, Arch Linux, NixOS, and others.

Note the input can also be XML, like this math.xml you can render with sile math.xml:

Ah, I realized that I am being confusing here, sorry! What I am interested in is the algorithm the tool internally use to position math glyphs, not the algorithm to use the tool as a black box.

I understand (in very general terms) how we go from a paragraph of utf8 encoded text to a picture of paragraph (selecting gliphs for symbols/ligatures, arranging glyphs into a line, line-breaking and hyphenating it into a paragraph). What I don’t understand even on conceptual level is how to do this with a math formula, where the input is a tree, and not a sequence, and the output is two dimensional, instead of being just a sequence of lines.

In that case you probably already understand more than you think you do. Rendering math is not so very different from rendering text. But at the same time you probably underestimate how complicated it is to “shape” input text into a regular paragraph. Consider what happens when a word in the paragraph is drawn with a bigger font. The height of the entire line has to grow to accommodate it, right? What happens if the line is all n’s (“nnnnnn…”) vs. if if has letters with ascenders and descenders (“afdgL…”)? The line has to move anything above or below that word just a touch more to accommodate the shape of those letters. Down to the letter level positions of letters change relative to each other. Kerning space between v and a might be different than m and a. Those minute adjustments may end up changing where a line wraps. Naive implementations (M$ Word, browsers) only make an attempt to adjust in one directly, content only ever gets pushed later and later, previous lines do not get adjusted to work better with later ones. More advanced typesetting (LaTeX, SILE, etc.) will analyze whole paragraphs or pages to find the best combination of breaks and space adjustments to fit everything together. Most languages are even more complex, for example many languages have parts that stack on top of each other to form characters (Javanese example.

All of this means that the process of shaping text (even non-math text) as you know it already involves 2D space and lots of positioning rules based on letter, accent, syllable, word, line, and other group relationships. This process even for a normal single word (much less paragraph) is already much more complex than people suspect. See for example Text Rendering Hates You.

One you have all the tooling in place to do that properly, math isn’t a far reach. All the parts are already there. For SILE’s implementation it just builds on tooling that already exists. On a very general level, MathML is a widely used language for marking up pieces of a formula and describes how each piece relates to others around it. The symbols and glyphs themselves then have context (for example “inside a subscript” or “a function symbol 4 lines tall”) and font (with OpenType math features) takes care of serving up the right glyph shapes for that context. SILE then takes those glyph shapes, uses the MathML descriptions for how bits of a formula relate, and translates it to sizes and positions for the boxes it already uses to position bits of text.

Thank you for the thorough reply, it is really helpful!

“a function symbol 4 lines tall”

That was the key for me! So by the time we get to SILE, we already have such “structural” information. And that information presumably can be computed from formula AST, and is independent of particular front, size and various other presentation properties. For some reason, I thought that deterring that “4 lines tall” needs to be done in SILE, but now I see that that can be done independently.

Correct, by the time final placement of glyphs is done lots questions have been answered outside of SILE. SILE reads the input, figures out the font size, paper properties etc., groups things based on their relation in MathML, then asks the font (via a font shaper, Harfbuzz) for relevant info. For example it might ask “How tall is a 4 line integral symbol in Libertinus Math at 16pt?”, and it would get an answer back, then use that height to know where to typeset the related box of glyphs in a subscript.

I’m really excited by SILE, I feel that it gives a breeze of fresh air to the typesetter space.

However what I’m missing is a place with showcases of what SILE can do, like this stackexchange question for Tex.

I know that it still is in the “alpha/beta” phase, but that would be helpful for me to get started.

There are a handful of examples on the website and (as of just before the v0.12.0 release) the examples are in the website’s GitHub source repository here so they are open for contributions. There isn’t a really good large showcase document yet –just some examples of handling languages and samples of what packages do– but with time we’d like to turn the website example gallery into a more complete general purpose showcase.

Also as of today I just opened up GitHub Discussions on the project repository which has a Show and tell category. We’d be happy to field questions there.

Is there some recommended post which explains the overall algorithm for getting from a math formula to canvas with pixels?

SILE doesn’t mess about much with pixels, the default canvas output is (vector based) PDF. Here is a minimalist example. If you put the following in a text file called

`math.sil`

:Then assuming you have the default math font

Libertinus Mathon your system, the process of rendering it from the command line looks like this:That output shows it successfully rendered 1 page which you will find in a file called

`math.pdf`

with your formula drawn on the page canvas (not in pixels, but you get the idea). In this tweet you can see a side-by-side of a more advanced math input and output.The project readme and manual not only have installation instructions but also two was to run

`sile`

without installing it at all (via Docker or Nix). Packages are available for Homebrew, Ubuntu, Arch Linux, NixOS, and others.Note the input can also be XML, like this

`math.xml`

you can render with`sile math.xml`

:Ah, I realized that I am being confusing here, sorry! What I am interested in is the algorithm the tool internally use to position math glyphs, not the algorithm to use the tool as a black box.

I understand (in very general terms) how we go from a paragraph of utf8 encoded text to a picture of paragraph (selecting gliphs for symbols/ligatures, arranging glyphs into a line, line-breaking and hyphenating it into a paragraph). What I don’t understand even on conceptual level is how to do this with a math formula, where the input is a tree, and not a sequence, and the output is two dimensional, instead of being just a sequence of lines.

In that case you probably already understand more than you think you do. Rendering math is not

so verydifferent from rendering text. But at the same time you probably underestimate how complicated it is to “shape” input text into a regular paragraph. Consider what happens when a word in the paragraph is drawn with a bigger font. The height of the entire line has to grow to accommodate it, right? What happens if the line is all n’s (“nnnnnn…”) vs. if if has letters with ascenders and descenders (“afdgL…”)? The line has to move anything above or below that word just a touch more to accommodate the shape of those letters. Down to the letter level positions of letters change relative to each other. Kerning space between`v`

and`a`

might be different than`m`

and`a`

. Those minute adjustments may end up changing where a line wraps. Naive implementations (M$ Word, browsers) only make an attempt to adjust in one directly, content only ever gets pushed later and later, previous lines do not get adjusted to work better with later ones. More advanced typesetting (LaTeX, SILE, etc.) will analyze whole paragraphs or pages to find the best combination of breaks and space adjustments to fit everything together. Most languages are even more complex, for example many languages have parts that stack on top of each other to form characters (Javanese example.All of this means that the process of shaping text (even non-math text) as you know it already involves 2D space and lots of positioning rules based on letter, accent, syllable, word, line, and other group relationships. This process even for a normal single word (much less paragraph) is already much more complex than people suspect. See for example Text Rendering Hates You.

One you have all the tooling in place to do that properly, math isn’t a far reach. All the parts are already there. For SILE’s implementation it just builds on tooling that already exists. On a very general level, MathML is a widely used language for marking up pieces of a formula and describes how each piece relates to others around it. The symbols and glyphs themselves then have context (for example “inside a subscript” or “a function symbol 4 lines tall”) and font (with OpenType math features) takes care of serving up the right glyph shapes for that context. SILE then takes those glyph shapes, uses the MathML descriptions for how bits of a formula relate, and translates it to sizes and positions for the boxes it already uses to position bits of text.

Thank you for the thorough reply, it is really helpful!

That was the key for me! So by the time we get to SILE, we already have such “structural” information. And that information presumably can be computed from formula AST, and is independent of particular front, size and various other presentation properties. For some reason, I thought that deterring that “4 lines tall” needs to be done in SILE, but now I see that that can be done independently.

Correct, by the time final placement of glyphs is done lots questions have been answered outside of SILE. SILE reads the input, figures out the font size, paper properties etc., groups things based on their relation in MathML, then asks the font (via a font shaper, Harfbuzz) for relevant info. For example it might ask “How tall is a 4 line integral symbol in Libertinus Math at 16pt?”, and it would get an answer back, then use that height to know where to typeset the related box of glyphs in a subscript.