• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sile-typesetter / sile / 9428435077

08 Jun 2024 11:35AM UTC coverage: 64.56% (-9.9%) from 74.46%
9428435077

push

github

web-flow
Merge pull request #2047 from alerque/end-pars

23 of 46 new or added lines in 5 files covered. (50.0%)

1684 existing lines in 60 files now uncovered.

11145 of 17263 relevant lines covered (64.56%)

4562.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.78
/packages/math/init.lua
1
local base = require("packages.base")
10✔
2

3
local package = pl.class(base)
10✔
4
package._name = "math"
10✔
5

6
function package:_init ()
10✔
7
   base._init(self)
10✔
8
   local typesetter = require("packages.math.typesetter")
10✔
9
   self.ConvertMathML, self.handleMath = typesetter[1], typesetter[2]
10✔
10
   local texlike = require("packages.math.texlike")
10✔
11
   self.convertTexlike, self.compileToMathML = texlike[1], texlike[2]
10✔
12
   -- Register a new unit that is 1/18th of the current math font size
13
   SILE.registerUnit("mu", {
20✔
14
      relative = true,
15
      definition = function (value)
16
         return value * SILE.settings:get("math.font.size") / 18
1,150✔
17
      end,
18
   })
19
   self:loadPackage("counters")
10✔
20
end
21

22
function package.declareSettings (_)
10✔
23
   SILE.settings:declare({
10✔
24
      parameter = "math.font.family",
25
      type = "string",
26
      default = "Libertinus Math",
27
   })
28
   SILE.settings:declare({
10✔
29
      parameter = "math.font.style",
30
      type = "string",
31
      default = "Regular",
32
   })
33
   SILE.settings:declare({
10✔
34
      parameter = "math.font.weight",
35
      type = "integer",
36
      default = 400,
37
   })
38
   SILE.settings:declare({
10✔
39
      parameter = "math.font.filename",
40
      type = "string",
41
      default = "",
42
   })
43
   SILE.settings:declare({
10✔
44
      parameter = "math.font.size",
45
      type = "integer",
46
      default = 10,
47
   })
48
   -- Whether to show debug boxes around mboxes
49
   SILE.settings:declare({
10✔
50
      parameter = "math.debug.boxes",
51
      type = "boolean",
52
      default = false,
53
   })
54
   SILE.settings:declare({
20✔
55
      parameter = "math.displayskip",
56
      type = "VGlue",
57
      default = SILE.types.node.vglue("2ex plus 1pt"),
20✔
58
   })
59
end
60

61
function package:registerCommands ()
10✔
62
   self:registerCommand("mathml", function (options, content)
20✔
63
      local mbox
64
      xpcall(function ()
44✔
65
         mbox = self:ConvertMathML(content)
44✔
66
      end, function (err)
44✔
67
         print(err)
×
68
         print(debug.traceback())
×
69
      end)
70
      self:handleMath(mbox, options)
22✔
71
   end)
72

73
   self:registerCommand("math", function (options, content)
20✔
74
      local mbox
75
      xpcall(function ()
80✔
76
         mbox = self:ConvertMathML(self:compileToMathML({}, self:convertTexlike(content)))
160✔
77
      end, function (err)
80✔
78
         print(err)
×
79
         print(debug.traceback())
×
80
      end)
81
      self:handleMath(mbox, options)
40✔
82
   end)
83

84
   self:registerCommand("math:numberingstyle", function (options, _)
20✔
UNCOV
85
      SILE.typesetter:typeset("(")
×
UNCOV
86
      if options.counter then
×
UNCOV
87
         SILE.call("show-counter", { id = options.counter })
×
UNCOV
88
      elseif options.number then
×
UNCOV
89
         SILE.typesetter:typeset(options.number)
×
90
      end
UNCOV
91
      SILE.typesetter:typeset(")")
×
92
   end)
93
end
94

95
package.documentation = [[
96
\begin{document}
97
\use[module=packages.math]
98
\set[parameter=math.font.family, value=Libertinus Math]
99
\set[parameter=math.font.size, value=11]
100
% Default verbatim font (Hack) is missing a few math symbols
101
\use[module=packages.font-fallback]
102
\font:add-fallback[family=Symbola]
103
\define[command=paragraph]{\smallskip\em{\process.}\novbreak\par}
104
The \autodoc:package{math} package provides typesetting of formulas directly in a SILE document.
105

106
\autodoc:note{Mathematical typesetting in SILE is still in its infancy.
107
As such, it lacks some features and may contain bugs.
108
Feedback and contributions are always welcome.}
109

110
\noindent To typeset mathematics, you will need an OpenType math font installed on your system.%
111
%\footnote{A list of freely available math fonts can be found at \href[src=https://www.ctan.org/pkg/unicode-math]{https://www.ctan.org/pkg/unicode-math}}
112
By default, this package uses Libertinus Math, so it will fail if Libertinus Math can’t be found.
113
Another font may be specified via the setting \autodoc:setting{math.font.family}.
114
If required, you can set the font style and weight via \autodoc:setting{math.font.style} and \autodoc:setting{math.font.weight}.
115
The font size can be set via \autodoc:setting{math.font.size}.
116

117
\paragraph{MathML}
118
The first way to typeset math formulas is to enter them in the MathML format.
119
MathML is a standard for encoding mathematical notation for the Web and for other types of digital documents.
120
It is supported by a wide range of tools and represents the most promising format for unifying the encoding of mathematical notation, as well as improving its accessibility (e.g., to blind users).
121

122
To render an equation encoded in MathML, simply put it in a \code{mathml} command.
123
For example, the formula \mathml{\mrow{\msup{\mi{a}\mn{2}} \mo{+} \msup{\mi{b}\mn{2}} \mo{=} \msup{\mi{c}\mn{2}}}} was typeset by the following command:
124

125
\begin[type=autodoc:codeblock]{raw}
126
\mathml{
127
    \mrow{
128
        \msup{\mi{a}\mn{2}}
129
        \mo{+}
130
        \msup{\mi{b}\mn{2}}
131
        \mo{=}
132
        \msup{\mi{c}\mn{2}}
133
    }
134
}
135
\end{raw}
136

137
\noindent In an XML document, we could use the more classical XML syntax:
138

139
\begin[type=autodoc:codeblock]{raw}
140
<mathml>
141
    <mrow>
142
        <msup> <mi>a</mi> <mn>2</mn> </msup>
143
        <mo>+</mo>
144
        <msup> <mi>b</mi> <mn>2</mn> </msup>
145
        <mo>=</mo>
146
        <msup> <mi>c</mi> <mn>2</mn> </msup>
147
    </mrow>
148
</mathml>
149
\end{raw}
150

151
\noindent By default, formulas are integrated into the flow of text.
152
To typeset them on their own line, use the \autodoc:parameter{mode=display} option:
153

154
\mathml[mode=display]{
155
    \mrow{
156
        \msup{\mi{a}\mn{2}}
157
        \mo{+}
158
        \msup{\mi{b}\mn{2}}
159
        \mo{=}
160
        \msup{\mi{c}\mn{2}}
161
    }
162
}
163

164
\paragraph{TeX-like syntax}
165
As the previous examples illustrate, MathML is not really intended to be written by humans and quickly becomes very verbose.
166
That is why this package also provides a \code{math} command, which understands a syntax similar to the math syntax of TeX.
167
To typeset the above equation, one only has to type \code{\\math\{a^2 + b^2 = c^2\}}.
168

169
Here is a slightly more involved equation:
170

171
\begin[type=autodoc:codeblock]{raw}
172
\begin[mode=display]{math}
173
    \sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}
174
\end{math}
175
\end{raw}
176

177
\noindent This renders as:
178

179
\begin[mode=display]{math}
180
    \sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}
181
\end{math}
182

183
The general philosophy of the TeX-like syntax is to be a simple layer on top of MathML, and not to mimic perfectly the syntax of the LaTeX tool.
184
Its main difference from the SILE syntax is that \code{\\mycommand\{arg1\}\{arg2\}\{arg3\}} is translated into MathML as \code{<mycommand> arg1 arg2 arg3 </mycommand>} whereas in normal SILE syntax, the XML equivalent would be \code{<mycommand>arg1</mycommand> arg2 arg3}.
185

186
\code{\\sum}, \code{\\infty}, and \code{\\pi} are only shorthands for the Unicode characters \math{\sum}, \math{\infty} and \math{\pi}.
187
If it’s more convenient, you can use these Unicode characters directly.
188
The symbol shorthands are the same as in the TeX package \href[src=https://www.ctan.org/pkg/unicode-math]{\code{unicode-math}}.
189

190
\code{\{formula\}} is a shorthand for \code{\\mrow\{formula\}}.
191
Since parentheses—among other glyphs—stretch vertically to the size of their englobing \code{mrow}, this is useful to typeset parentheses of different sizes on the same line:
192

193
\begin[type=autodoc:codeblock]{raw}
194
\Gamma (\frac{\zeta}{2}) + x^2(x+1)
195
\end{raw}
196

197
\noindent renders as
198

199
\begin[mode=display]{math}
200
    \Gamma (\frac{\zeta}{2}) + x^2(x+1)
201
\end{math}
202

203
\noindent which is ugly.
204
To keep parentheses around \math{x+1} small, you should put braces around the expression:
205

206
\begin[type=autodoc:codeblock]{raw}
207
\Gamma (\frac{\zeta}{2}) + x^2{(x+1)}
208
\end{raw}
209

210
\begin[mode=display]{math}
211
    \Gamma (\frac{\zeta}{2}) + x^2{(x+1)}
212
\end{math}
213

214
\noindent To print a brace in a formula, you need to escape it with a backslash.
215

216
\paragraph{Token kinds}
217
In the \code{math} syntax, every individual letter is an identifier (MathML tag \code{mi}), every number is a… number (tag \code{mn}) and all other characters are operators (tag \code{mo}).
218
If this does not suit you, you can explicitly use the \code{\\mi}, \code{\\mn}, or \code{\\mo} tags.
219
For instance, \code{sin(x)} will be rendered as \math{sin(x)}, because SILE considers the letters s, i and n to be individual identifiers, and identifiers made of one character are italicized by default.
220
To avoid that, you can specify that \math{\mi{sin}} is an identifier by writing \code{\\mi\{sin\}(x)} and get: \math{\mi{sin}(x)}.
221
If you prefer it in “double struck” style, this is permitted by the \code{mathvariant} attribute: \code{\\mi[mathvariant=double-struck]\{sin\}(x)} renders as \math{\mi[mathvariant=double-struck]{sin}(x)}.
222

223
\paragraph{Atom types and spacing}
224
Each token automatically gets assigned an atom type from the list below:
225
\begin{itemize}
226
  \item{\code{ord}: \code{mi} and \code{mn} tokens, as well as unclassified operators}
227
  \item{\code{big}: big operators like ‘\math{\sum}’ or ‘\math{\prod}’}
228
  \item{\code{bin}: binary operators like ‘\math{+}’ or ‘\math{\%}’}
229
  \item{\code{rel}: relation operators like ‘\math{=}’ or ‘\math{<}’}
230
  \item{\code{open}: opening operators like ‘\math{(}’ or ‘\math{[}’}
231
  \item{\code{close}: closing operators like ‘\math{)}’ or ‘\math{]}’}
232
  \item{\code{punct}: punctuation operators like ‘\math{,}’}
233
  % TODO: Those are defined in the 'math' package but appear to be unused
234
  %\item{\code{inner}}
235
  %\item{\code{over}}
236
  %\item{\code{under}}
237
  %\item{\code{accent}}
238
  %\item{\code{radical}}
239
  %\item{\code{vcenter}}
240
\end{itemize}
241
\noindent The spacing between any two successive tokens is set automatically based on their atom types, and hence may not reflect the actual spacing used in the input.
242
To make an operator behave like it has a certain atom type, you can use the \code{atom} attribute. For example, \code{a \\mo[atom=bin]\{div\} b} renders as \math[mode=display]{a \mo[atom=bin]{div} b.}
243

244
Spaces in math mode are defined in “math units” (mu), which are 1/18 of an em of the current \em{math} font (and are independent of the current text font size).
245
Standard spaces inserted automatically between tokens come in three varieties: thin (3 mu), medium (4 mu) and thick (5 mu).
246
If needed, you can insert them manually with the \code{\\thinspace} (or \code{\\,}), \code{\\medspace} (or \code{\\>}), and \code{\\thickspace} (or \code{\\;}) commands.
247
Negative space counterparts are available as \code{\\negthinspace} (or \code{\\!}), \code{\\negmedspace}, and \code{\\negthickspace}.
248
The \code{\\enspace}, \code{\\quad}, and \code{\\qquad} commands from normal text mode are also available, but the spaces they insert scale relative to the text font size.
249
Finally, you can add a space of any size using the \code{\\mspace[width=<dimension>]} command.
250

251
\paragraph{Macros}
252
To save you some typing, the math syntax lets you define macros with the following syntax:
253

254
\begin[type=autodoc:codeblock]{raw}
255
\def{macro-name}{macro-body}
256
\end{raw}
257

258
\noindent where in the macro’s body \code{#1}, \code{#2}, etc. will be replaced by the macro’s arguments.
259
For instance:
260

261
\begin[type=autodoc:codeblock]{raw}
262
\begin[mode=display]{math}
263
    \def{diff}{\mfrac{\mo{d}#1}{\mo{d}#2}}
264
    \def{bi}{\mi[mathvariant=bold-italic]{#1}}
265

266
    \diff{\bi{p}}{t} = ∑_i \bi{F}_i
267
\end{math}
268
\end{raw}
269

270
\noindent results in:
271

272
\begin[mode=display]{math}
273
  \def{diff}{\mfrac{\mo{d}#1}{\mo{d}#2}}
274
  \def{bi}{\mi[mathvariant=bold-italic]{#1}}
275
  \diff{\bi{p}}{t} = ∑_i \bi{F}_i
276
\end{math}
277

278
When macros are not enough, creating new mathematical elements is quite simple: one only needs to create a new class deriving from \code{mbox} (defined in \code{packages/math/base-elements.lua}) and define the \code{shape} and \code{output} methods.
279
\code{shape} must define the \code{width}, \code{height} and \code{depth} attributes of the element, while \code{output} must draw the actual output.
280
An \code{mbox} may have one or more children (for instance, a fraction has two children—its numerator and denominator).
281
The \code{shape} and \code{output} methods of the children are called automatically.
282

283
\paragraph{Matrices, aligned equations, and other tables}
284
Tabular math can be typeset using the \code{table} command (or equivalently the \code{mtable} MathML tag).
285
For instance, to typeset a matrix:
286

287
\begin[type=autodoc:codeblock]{raw}
288
\begin[mode=display]{math}
289
    (
290
    \table{
291
        1 & 2 & 7 \\
292
        0 & 5 & 3 \\
293
        8 & 2 & 1 \\
294
    }
295
    )
296
\end{math}
297
\end{raw}
298

299
\noindent will yield:
300

301
\begin[mode=display]{math}
302
  (\table{
303
       1 & 2 & 7 \\
304
       0 & 5 & 3 \\
305
       8 & 2 & 1 \\
306
  })
307
\end{math}
308

309
\noindent Tables may also be used to control the alignment of formulas:
310

311
\begin[type=autodoc:codeblock]{raw}
312
\begin[mode=display]{math}
313
    \{
314
    \table[columnalign=right center left]{
315
        u_0 &=& 1 \\
316
        u_1 &=& 1 \\
317
        u_n &=& u_{n−1} + u_{n−2}, \forall n ⩾ 2 \\
318
    }
319
\end{math}
320
\end{raw}
321

322
\begin[mode=display]{math}
323
    \{
324
    \table[columnalign=right center left]{
325
        u_0 &=& 1 \\
326
        u_1 &=& 1 \\
327
        u_n &=& u_{n−1} + u_{n−2}, \forall n ⩾ 2 \\
328
    }
329
\end{math}
330

331
\noindent Tables currently do not support all attributes required by the MathML standard, but they do allow to control spacing using the \code{rowspacing} and \code{columnspacing} options.
332

333
Finally, here is a little secret. This notation:
334

335
\begin[type=autodoc:codeblock]{raw}
336
\table{
337
    1 & 2 & 7 \\
338
    0 & 5 & 3 \\
339
    8 & 2 & 1 \\
340
}
341
\end{raw}
342

343
\noindent is strictly equivalent to this one:
344

345
\begin[type=autodoc:codeblock]{raw}
346
\table{
347
        {1} {2} {7}
348
    }{
349
        {0} {5} {3}
350
    }{
351
        {8} {2} {1}
352
    }
353
}
354
\end{raw}
355

356
\noindent In other words, the notation using \code{&} and \code{\\\\} is only a syntactic sugar for a two-dimensional array constructed with braces.
357

358
\paragraph{Numbered equations}
359
Equations can be numbered in display mode.
360

361
When \autodoc:parameter{numbered=true}, equations are numbered using a default “equation” counter:
362
\math[mode=display, numbered=true]{e^{i\pi} = -1}
363

364
A different counter can be set by using the option \autodoc:parameter{counter=<id>}, and this setting will also enable numbering.
365

366
It is also possible to impose direct numbering using the \autodoc:parameter{number=<value>} option.
367

368
The default numbering format is \autodoc:example{(n)}, but this style may be overridden by defining a custom \autodoc:command{\math:numberingstyle} command.
369
The \code{counter} or the direct value \code{number} is passed as a parameter to this hook, as well as any other options.
370

371
\paragraph{Missing features}
372
This package still lacks support for some mathematical constructs, but hopefully we’ll get there.
373
Among unsupported constructs are: decorating symbols with so-called accents, such as arrows or hats, “over” or “under” braces, and line breaking inside a formula.
374

375
\font:remove-fallback
376
\end{document}
377
]]
10✔
378

379
return package
10✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc