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

sile-typesetter / sile / 9304060604

30 May 2024 02:07PM UTC coverage: 74.124% (-0.6%) from 74.707%
9304060604

push

github

alerque
style: Reformat Lua with stylua

8104 of 11995 new or added lines in 184 files covered. (67.56%)

15 existing lines in 11 files now uncovered.

12444 of 16788 relevant lines covered (74.12%)

7175.1 hits per line

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

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

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

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

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

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

73
   self:registerCommand("math", function (options, content)
24✔
74
      local mode = (options and options.mode) and options.mode or "text"
45✔
75
      local mbox
76
      xpcall(function ()
90✔
77
         mbox = self:ConvertMathML(self:compileToMathML({}, self:convertTexlike(content)))
180✔
78
      end, function (err)
90✔
NEW
79
         print(err)
×
NEW
80
         print(debug.traceback())
×
81
      end)
82
      self:handleMath(mbox, mode)
45✔
83
   end)
84
end
85

86
package.documentation = [[
87
\begin{document}
88
\use[module=packages.math]
89
\set[parameter=math.font.family, value=Libertinus Math]
90
\set[parameter=math.font.size, value=11]
91
% Default verbatim font (Hack) is missing a few math symbols
92
\use[module=packages.font-fallback]
93
\font:add-fallback[family=Symbola]
94
\define[command=paragraph]{\smallskip\em{\process.}\novbreak\par}
95
The \autodoc:package{math} package provides typesetting of formulas directly in a SILE document.
96

97
\autodoc:note{Mathematical typesetting in SILE is still in its infancy.
98
As such, it lacks some features and may contain bugs.
99
Feedback and contributions are always welcome.}
100

101
\noindent To typeset mathematics, you will need an OpenType math font installed on your system.%
102
%\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}}
103
By default, this package uses Libertinus Math, so it will fail if Libertinus Math can’t be found.
104
Another font may be specified via the setting \autodoc:setting{math.font.family}.
105
If required, you can set the font style and weight via \autodoc:setting{math.font.style} and \autodoc:setting{math.font.weight}.
106
The font size can be set via \autodoc:setting{math.font.size}.
107

108
\paragraph{MathML}
109
The first way to typeset math formulas is to enter them in the MathML format.
110
MathML is a standard for encoding mathematical notation for the Web and for other types of digital documents.
111
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).
112

113
To render an equation encoded in MathML, simply put it in a \code{mathml} command.
114
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:
115

116
\begin[type=autodoc:codeblock]{raw}
117
\mathml{
118
    \mrow{
119
        \msup{\mi{a}\mn{2}}
120
        \mo{+}
121
        \msup{\mi{b}\mn{2}}
122
        \mo{=}
123
        \msup{\mi{c}\mn{2}}
124
    }
125
}
126
\end{raw}
127

128
\noindent In an XML document, we could use the more classical XML syntax:
129

130
\begin[type=autodoc:codeblock]{raw}
131
<mathml>
132
    <mrow>
133
        <msup> <mi>a</mi> <mn>2</mn> </msup>
134
        <mo>+</mo>
135
        <msup> <mi>b</mi> <mn>2</mn> </msup>
136
        <mo>=</mo>
137
        <msup> <mi>c</mi> <mn>2</mn> </msup>
138
    </mrow>
139
</mathml>
140
\end{raw}
141

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

145
\mathml[mode=display]{
146
    \mrow{
147
        \msup{\mi{a}\mn{2}}
148
        \mo{+}
149
        \msup{\mi{b}\mn{2}}
150
        \mo{=}
151
        \msup{\mi{c}\mn{2}}
152
    }
153
}
154

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

160
Here is a slightly more involved equation:
161

162
\begin[type=autodoc:codeblock]{raw}
163
\begin[mode=display]{math}
164
    \sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}
165
\end{math}
166
\end{raw}
167

168
\noindent This renders as:
169

170
\begin[mode=display]{math}
171
    \sum_{n=1}^\infty \frac{1}{n^2} = \frac{\pi^2}{6}
172
\end{math}
173

174
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.
175
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}.
176

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

181
\code{\{formula\}} is a shorthand for \code{\\mrow\{formula\}}.
182
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:
183

184
\begin[type=autodoc:codeblock]{raw}
185
\Gamma (\frac{\zeta}{2}) + x^2(x+1)
186
\end{raw}
187

188
\noindent renders as
189

190
\begin[mode=display]{math}
191
    \Gamma (\frac{\zeta}{2}) + x^2(x+1)
192
\end{math}
193

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

197
\begin[type=autodoc:codeblock]{raw}
198
\Gamma (\frac{\zeta}{2}) + x^2{(x+1)}
199
\end{raw}
200

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

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

207
\paragraph{Token kinds}
208
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}).
209
If this does not suit you, you can explicitly use the \code{\\mi}, \code{\\mn}, or \code{\\mo} tags.
210
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.
211
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)}.
212
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)}.
213

214
\paragraph{Atom types and spacing}
215
Each token automatically gets assigned an atom type from the list below:
216
\begin{itemize}
217
  \item{\code{ord}: \code{mi} and \code{mn} tokens, as well as unclassified operators}
218
  \item{\code{big}: big operators like ‘\math{\sum}’ or ‘\math{\prod}’}
219
  \item{\code{bin}: binary operators like ‘\math{+}’ or ‘\math{\%}’}
220
  \item{\code{rel}: relation operators like ‘\math{=}’ or ‘\math{<}’}
221
  \item{\code{open}: opening operators like ‘\math{(}’ or ‘\math{[}’}
222
  \item{\code{close}: closing operators like ‘\math{)}’ or ‘\math{]}’}
223
  \item{\code{punct}: punctuation operators like ‘\math{,}’}
224
  % TODO: Those are defined in the 'math' package but appear to be unused
225
  %\item{\code{inner}}
226
  %\item{\code{over}}
227
  %\item{\code{under}}
228
  %\item{\code{accent}}
229
  %\item{\code{radical}}
230
  %\item{\code{vcenter}}
231
\end{itemize}
232
\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.
233
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.}
234

235
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).
236
Standard spaces inserted automatically between tokens come in three varieties: thin (3 mu), medium (4 mu) and thick (5 mu).
237
If needed, you can insert them manually with the \code{\\thinspace} (or \code{\\,}), \code{\\medspace} (or \code{\\>}), and \code{\\thickspace} (or \code{\\;}) commands.
238
Negative space counterparts are available as \code{\\negthinspace} (or \code{\\!}), \code{\\negmedspace}, and \code{\\negthickspace}.
239
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.
240
Finally, you can add a space of any size using the \code{\\mspace[width=<dimension>]} command.
241

242
\paragraph{Macros}
243
To save you some typing, the math syntax lets you define macros with the following syntax:
244

245
\begin[type=autodoc:codeblock]{raw}
246
\def{macro-name}{macro-body}
247
\end{raw}
248

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

252
\begin[type=autodoc:codeblock]{raw}
253
\begin[mode=display]{math}
254
    \def{diff}{\mfrac{\mo{d}#1}{\mo{d}#2}}
255
    \def{bi}{\mi[mathvariant=bold-italic]{#1}}
256

257
    \diff{\bi{p}}{t} = ∑_i \bi{F}_i
258
\end{math}
259
\end{raw}
260

261
\noindent results in:
262

263
\begin[mode=display]{math}
264
  \def{diff}{\mfrac{\mo{d}#1}{\mo{d}#2}}
265
  \def{bi}{\mi[mathvariant=bold-italic]{#1}}
266
  \diff{\bi{p}}{t} = ∑_i \bi{F}_i
267
\end{math}
268

269
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.
270
\code{shape} must define the \code{width}, \code{height} and \code{depth} attributes of the element, while \code{output} must draw the actual output.
271
An \code{mbox} may have one or more children (for instance, a fraction has two children—its numerator and denominator).
272
The \code{shape} and \code{output} methods of the children are called automatically.
273

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

278
\begin[type=autodoc:codeblock]{raw}
279
\begin[mode=display]{math}
280
    (
281
    \table{
282
        1 & 2 & 7 \\
283
        0 & 5 & 3 \\
284
        8 & 2 & 1 \\
285
    }
286
    )
287
\end{math}
288
\end{raw}
289

290
\noindent will yield:
291

292
\begin[mode=display]{math}
293
  (\table{
294
       1 & 2 & 7 \\
295
       0 & 5 & 3 \\
296
       8 & 2 & 1 \\
297
  })
298
\end{math}
299

300
\noindent Tables may also be used to control the alignment of formulas:
301

302
\begin[type=autodoc:codeblock]{raw}
303
\begin[mode=display]{math}
304
    \{
305
    \table[columnalign=right center left]{
306
        u_0 &=& 1 \\
307
        u_1 &=& 1 \\
308
        u_n &=& u_{n−1} + u_{n−2}, \forall n ⩾ 2 \\
309
    }
310
\end{math}
311
\end{raw}
312

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

322
\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.
323

324
Finally, here is a little secret. This notation:
325

326
\begin[type=autodoc:codeblock]{raw}
327
\table{
328
    1 & 2 & 7 \\
329
    0 & 5 & 3 \\
330
    8 & 2 & 1 \\
331
}
332
\end{raw}
333

334
\noindent is strictly equivalent to this one:
335

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

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

349
\paragraph{Missing features}
350
This package still lacks support for some mathematical constructs, but hopefully we’ll get there.
351
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.
352

353
\font:remove-fallback
354
\end{document}
355
]]
12✔
356

357
return package
12✔
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