• 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

75.75
/core/sile.lua
1
-- Initialize SILE internals
2
SILE = {}
1✔
3

4
SILE.version = require("core.version")
1✔
5
SILE.features = require("core.features")
1✔
6

7
-- Initialize Lua environment and global utilities
8
SILE.lua_version = _VERSION:sub(-3)
2✔
9
-- luacheck: ignore jit
10
SILE.lua_isjit = type(jit) == "table"
1✔
11
SILE.full_version = string.format("SILE %s (%s)", SILE.version, SILE.lua_isjit and jit.version or _VERSION)
1✔
12

13
-- Backport of lots of Lua 5.3 features to Lua 5.[12]
14
if not SILE.lua_isjit and SILE.lua_version < "5.3" then
1✔
NEW
15
   require("compat53")
×
16
end
17

18
-- Penlight on-demand module loader, provided for SILE and document usage
19
pl = require("pl.import_into")()
2✔
20

21
-- For developer testing only, usually in CI
22
if os.getenv("SILE_COVERAGE") then
1✔
23
   require("luacov")
1✔
24
end
25

26
-- Lua 5.3+ has a UTF-8 safe string function module but it is somewhat
27
-- underwhelming. This module includes more functions and supports older Lua
28
-- versions. Docs: https://github.com/starwing/luautf8
29
luautf8 = require("lua-utf8")
182✔
30

31
-- Localization library, provided as global
32
fluent = require("fluent")()
363✔
33

34
-- Includes for _this_ scope
35
local lfs = require("lfs")
181✔
36

37
-- Developer tooling profiler
38
local ProFi
39

40
SILE.utilities = require("core.utilities")
181✔
41
SU = SILE.utilities -- regrettable global alias
181✔
42

43
-- On demand loader, allows modules to be loaded into a specific scope but
44
-- only when/if accessed.
45
local core_loader = function (scope)
46
   return setmetatable({}, {
1,267✔
47
      __index = function (self, key)
48
         -- local var = rawget(self, key)
49
         local m = require(("%s.%s"):format(scope, key))
1,462✔
50
         self[key] = m
1,462✔
51
         return m
1,462✔
52
      end,
53
   })
1,267✔
54
end
55

56
SILE.Commands = {}
181✔
57
SILE.Help = {}
181✔
58
SILE.debugFlags = {}
181✔
59
SILE.nodeMakers = {}
181✔
60
SILE.tokenizers = {}
181✔
61
SILE.status = {}
181✔
62
SILE.scratch = {}
181✔
63
SILE.documentState = {}
181✔
64
SILE.rawHandlers = {}
181✔
65

66
-- User input values, currently from CLI options, potentially all the inuts
67
-- needed for a user to use a SILE-as-a-library version to produce documents
68
-- programmatically.
69
SILE.input = {
181✔
70
   filenames = {},
181✔
71
   evaluates = {},
181✔
72
   evaluateAfters = {},
181✔
73
   includes = {},
181✔
74
   uses = {},
181✔
75
   options = {},
181✔
76
   preambles = {},
181✔
77
   postambles = {},
181✔
78
}
181✔
79

80
-- Internal libraries that are idempotent and return classes that need instantiation
81
SILE.inputters = core_loader("inputters")
362✔
82
SILE.shapers = core_loader("shapers")
362✔
83
SILE.outputters = core_loader("outputters")
362✔
84
SILE.classes = core_loader("classes")
362✔
85
SILE.packages = core_loader("packages")
362✔
86
SILE.typesetters = core_loader("typesetters")
362✔
87
SILE.pagebuilders = core_loader("pagebuilders")
362✔
88

89
-- Internal libraries that don't make assumptions on load, only use
90
SILE.traceStack = require("core.tracestack")()
362✔
91
SILE.parserBits = require("core.parserbits")
181✔
92
SILE.frameParser = require("core.frameparser")
181✔
93
SILE.color = require("core.color")
181✔
94
SILE.units = require("core.units")
181✔
95
SILE.fontManager = require("core.fontmanager")
181✔
96

97
-- Internal libraries that assume globals, may be picky about load order
98
SILE.measurement = require("core.measurement")
181✔
99
SILE.length = require("core.length")
181✔
100
SILE.papersize = require("core.papersize")
181✔
101
SILE.nodefactory = require("core.nodefactory")
181✔
102

103
-- NOTE:
104
-- See remainaing internal libraries loaded at the end of this file because
105
-- they run core SILE functions on load instead of waiting to be called (or
106
-- depend on others that do).
107

108
local function runEvals (evals, arg)
109
   for _, snippet in ipairs(evals) do
362✔
NEW
110
      local pId = SILE.traceStack:pushText(snippet)
×
NEW
111
      local status, func = pcall(load, snippet)
×
NEW
112
      if status then
×
NEW
113
         func()
×
114
      else
NEW
115
         SU.error(("Error parsing code provided in --%s snippet: %s"):format(arg, func))
×
116
      end
NEW
117
      SILE.traceStack:pop(pId)
×
118
   end
119
end
120

121
SILE.init = function ()
181✔
122
   if not SILE.backend then
181✔
123
      SILE.backend = "libtexpdf"
181✔
124
   end
125
   if SILE.backend == "libtexpdf" then
181✔
126
      SILE.shaper = SILE.shapers.harfbuzz()
543✔
127
      SILE.outputter = SILE.outputters.libtexpdf()
543✔
NEW
128
   elseif SILE.backend == "cairo" then
×
NEW
129
      SILE.shaper = SILE.shapers.pango()
×
NEW
130
      SILE.outputter = SILE.outputters.cairo()
×
NEW
131
   elseif SILE.backend == "debug" then
×
NEW
132
      SILE.shaper = SILE.shapers.harfbuzz()
×
NEW
133
      SILE.outputter = SILE.outputters.debug()
×
NEW
134
   elseif SILE.backend == "text" then
×
NEW
135
      SILE.shaper = SILE.shapers.harfbuzz()
×
NEW
136
      SILE.outputter = SILE.outputters.text()
×
NEW
137
   elseif SILE.backend == "dummy" then
×
NEW
138
      SILE.shaper = SILE.shapers.harfbuzz()
×
NEW
139
      SILE.outputter = SILE.outputters.dummy()
×
140
   end
141
   SILE.pagebuilder = SILE.pagebuilders.base()
543✔
142
   io.stdout:setvbuf("no")
181✔
143
   if SU.debugging("profile") then
362✔
NEW
144
      ProFi = require("ProFi")
×
NEW
145
      ProFi:start()
×
146
   end
147
   if SILE.makeDeps then
181✔
148
      SILE.makeDeps:add(_G.executablePath)
181✔
149
   end
150
   runEvals(SILE.input.evaluates, "evaluate")
181✔
151
end
152

153
local function suggest_luarocks (module)
NEW
154
   local guessed_module_name = module:gsub(".*%.", "") .. ".sile"
×
NEW
155
   return ([[
×
156

157
    If the expected module is a 3rd party extension you may need to install it
158
    using LuaRocks. The details of how to do this are highly dependent on
159
    your system and preferred installation method, but as an example installing
160
    a 3rd party SILE module to a project-local tree where might look like this:
161

162
        luarocks --lua-version %s --tree lua_modules install %s
163

164
    This will install the LuaRocks to your project, then you need to tell your
165
    shell to pass along that info about available LuaRocks paths to SILE. This
166
    only needs to be done once in each shell.
167

168
        eval $(luarocks --lua-version %s --tree lua_modules path)
169

170
    Thereafter running SILE again should work as expected:
171

172
       sile %s
173

NEW
174
    ]]):format(SILE.lua_version, guessed_module_name, SILE.lua_version, pl.stringx.join(" ", _G.arg))
×
175
end
176

177
SILE.use = function (module, options)
181✔
178
   local status, pack
179
   if type(module) == "string" then
108✔
180
      status, pack = pcall(require, module)
107✔
181
      if not status then
107✔
NEW
182
         SU.error(
×
NEW
183
            ("Unable to use '%s':\n%s%s"):format(
×
184
               module,
NEW
185
               SILE.traceback and ("    Lua " .. pack) or "",
×
NEW
186
               suggest_luarocks(module)
×
187
            )
188
         )
189
      end
190
   elseif type(module) == "table" then
1✔
191
      pack = module
1✔
192
   end
193
   local name = pack._name
108✔
194
   local class = SILE.documentState.documentClass
108✔
195
   if not pack.type then
108✔
NEW
196
      SU.error("Modules must declare their type")
×
197
   elseif pack.type == "class" then
108✔
NEW
198
      SILE.classes[name] = pack
×
NEW
199
      if class then
×
NEW
200
         SU.error("Cannot load a class after one is already instantiated")
×
201
      end
NEW
202
      SILE.scratch.class_from_uses = pack
×
203
   elseif pack.type == "inputter" then
108✔
NEW
204
      SILE.inputters[name] = pack
×
NEW
205
      SILE.inputter = pack(options)
×
206
   elseif pack.type == "outputter" then
108✔
NEW
207
      SILE.outputters[name] = pack
×
NEW
208
      SILE.outputter = pack(options)
×
209
   elseif pack.type == "shaper" then
108✔
NEW
210
      SILE.shapers[name] = pack
×
NEW
211
      SILE.shaper = pack(options)
×
212
   elseif pack.type == "typesetter" then
108✔
NEW
213
      SILE.typesetters[name] = pack
×
NEW
214
      SILE.typesetter = pack(options)
×
215
   elseif pack.type == "pagebuilder" then
108✔
NEW
216
      SILE.pagebuilders[name] = pack
×
NEW
217
      SILE.pagebuilder = pack(options)
×
218
   elseif pack.type == "package" then
108✔
219
      SILE.packages[name] = pack
108✔
220
      if class then
108✔
221
         pack(options)
216✔
222
      else
NEW
223
         table.insert(SILE.input.preambles, { pack = pack, options = options })
×
224
      end
225
   end
226
end
227

228
SILE.require = function (dependency, pathprefix, deprecation_ack)
181✔
229
   if pathprefix and not deprecation_ack then
202✔
NEW
230
      local notice = string.format(
×
NEW
231
         [[
×
232
  Please don't use the path prefix mechanism; it was intended to provide
233
  alternate paths to override core components but never worked well and is
234
  causing portability problems. Just use Lua idiomatic module loading:
235
      SILE.require("%s", "%s") → SILE.require("%s.%s")]],
236
         dependency,
237
         pathprefix,
238
         pathprefix,
239
         dependency
240
      )
NEW
241
      SU.deprecated("SILE.require", "SILE.require", "0.13.0", nil, notice)
×
242
   end
243
   dependency = dependency:gsub(".lua$", "")
202✔
244
   local status, lib
245
   if pathprefix then
202✔
246
      -- Note this is not a *path*, it is a module identifier:
247
      -- https://github.com/sile-typesetter/sile/issues/1861
248
      status, lib = pcall(require, pl.stringx.join(".", { pathprefix, dependency }))
362✔
249
   end
250
   if not status then
202✔
251
      local prefixederror = lib
21✔
252
      status, lib = pcall(require, dependency)
21✔
253
      if not status then
21✔
NEW
254
         SU.error(
×
NEW
255
            ("Unable to find module '%s'%s"):format(
×
256
               dependency,
NEW
257
               SILE.traceback and ((pathprefix and "\n  " .. prefixederror or "") .. "\n  " .. lib) or ""
×
258
            )
259
         )
260
      end
261
   end
262
   local class = SILE.documentState.documentClass
202✔
263
   if not class and not deprecation_ack then
202✔
NEW
264
      SU.warn(string.format(
×
NEW
265
         [[
×
266
  Use of SILE.require() is only supported in documents, packages, or class
267
  init functions. It will not function fully before the class is instantiated.
268
  Please just use the Lua require() function directly:
269
      SILE.require("%s") → require("%s")]],
270
         dependency,
271
         dependency
272
      ))
273
   end
274
   if type(lib) == "table" and class then
202✔
275
      if lib.type == "package" then
21✔
276
         lib(class)
42✔
277
      else
NEW
278
         class:initPackage(lib)
×
279
      end
280
   end
281
   return lib
202✔
282
end
283

284
SILE.process = function (ast)
181✔
285
   if not ast then
1,493✔
286
      return
4✔
287
   end
288
   if SU.debugging("ast") then
2,978✔
NEW
289
      SU.debugAST(ast, 0)
×
290
   end
291
   if type(ast) == "function" then
1,489✔
292
      return ast()
396✔
293
   end
294
   for _, content in ipairs(ast) do
5,090✔
295
      if type(content) == "string" then
3,997✔
296
         SILE.typesetter:typeset(content)
4,714✔
297
      elseif type(content) == "function" then
1,640✔
298
         content()
2✔
299
      elseif SILE.Commands[content.command] then
1,639✔
300
         SILE.call(content.command, content.options, content)
3,256✔
301
      elseif content.id == "texlike_stuff" or (not content.command and not content.id) then
11✔
302
         local pId = SILE.traceStack:pushContent(content, "texlike_stuff")
11✔
303
         SILE.process(content)
11✔
304
         SILE.traceStack:pop(pId)
22✔
NEW
305
      elseif type(content) ~= "nil" then
×
NEW
306
         local pId = SILE.traceStack:pushContent(content)
×
NEW
307
         SU.error("Unknown command " .. (tostring(content.command or content.id)))
×
NEW
308
         SILE.traceStack:pop(pId)
×
309
      end
310
   end
311
end
312

313
local preloadedinputters = { "xml", "lua", "sil" }
181✔
314

315
local function detectFormat (doc, filename)
316
   -- Preload default reader types so content detection has something to work with
317
   if #SILE.inputters == 0 then
182✔
318
      for _, format in ipairs(preloadedinputters) do
728✔
319
         local _ = SILE.inputters[format]
546✔
320
      end
321
   end
322
   local contentDetectionOrder = {}
182✔
323
   for _, inputter in pairs(SILE.inputters) do
728✔
324
      if inputter.order then
546✔
325
         table.insert(contentDetectionOrder, inputter)
546✔
326
      end
327
   end
328
   table.sort(contentDetectionOrder, function (a, b)
364✔
329
      return a.order < b.order
546✔
330
   end)
331
   local initialround = filename and 1 or 2
182✔
332
   for round = initialround, 3 do
185✔
333
      for _, inputter in ipairs(contentDetectionOrder) do
369✔
334
         SU.debug("inputter", "Running content type detection round", round, "with", inputter._name)
366✔
335
         if inputter.appropriate(round, filename, doc) then
732✔
336
            return inputter._name
182✔
337
         end
338
      end
339
   end
NEW
340
   SU.error(("Unable to pick inputter to process input from '%s'"):format(filename))
×
341
end
342

343
function SILE.processString (doc, format, filename, options)
362✔
344
   local cpf
345
   if not filename then
251✔
346
      cpf = SILE.currentlyProcessingFile
69✔
347
      local caller = debug.getinfo(2, "Sl")
69✔
348
      SILE.currentlyProcessingFile = caller.short_src .. ":" .. caller.currentline
69✔
349
   end
350
   -- In the event we're processing the master file *and* the user gave us
351
   -- a specific inputter to use, use it at the exclusion of all content type
352
   -- detection
353
   local inputter
354
   if
355
      filename
356
      and pl.path.normcase(pl.path.normpath(filename)) == pl.path.normcase(SILE.input.filenames[1])
797✔
357
      and SILE.inputter
181✔
358
   then
NEW
359
      inputter = SILE.inputter
×
360
   else
361
      format = format or detectFormat(doc, filename)
433✔
362
      if not SILE.quiet then
251✔
363
         io.stderr:write(("<%s> as %s\n"):format(SILE.currentlyProcessingFile, format))
251✔
364
      end
365
      inputter = SILE.inputters[format](options)
502✔
366
      -- If we did content detection *and* this is the master file, save the
367
      -- inputter for posterity and postambles
368
      if filename and pl.path.normcase(filename) == pl.path.normcase(SILE.input.filenames[1]:gsub("^-$", "STDIN")) then
615✔
369
         SILE.inputter = inputter
181✔
370
      end
371
   end
372
   local pId = SILE.traceStack:pushDocument(SILE.currentlyProcessingFile, doc)
251✔
373
   inputter:process(doc)
251✔
374
   SILE.traceStack:pop(pId)
251✔
375
   if cpf then
251✔
376
      SILE.currentlyProcessingFile = cpf
69✔
377
   end
378
end
379

380
function SILE.processFile (filename, format, options)
362✔
381
   local doc
382
   if filename == "-" then
182✔
NEW
383
      filename = "STDIN"
×
NEW
384
      doc = io.stdin:read("*a")
×
385
   else
386
      -- Turn slashes around in the event we get passed a path from a Windows shell
387
      filename = filename:gsub("\\", "/")
182✔
388
      if not SILE.masterFilename then
182✔
389
         SILE.masterFilename = pl.path.splitext(pl.path.normpath(filename))
724✔
390
      end
391
      if SILE.input.filenames[1] and not SILE.masterDir then
182✔
392
         SILE.masterDir = pl.path.dirname(SILE.input.filenames[1])
362✔
393
      end
394
      if SILE.masterDir and SILE.masterDir:len() >= 1 then
364✔
395
         _G.extendSilePath(SILE.masterDir)
182✔
396
      end
397
      filename = SILE.resolveFile(filename) or SU.error("Could not find file")
364✔
398
      local mode = lfs.attributes(filename).mode
182✔
399
      if mode ~= "file" and mode ~= "named pipe" then
182✔
NEW
400
         SU.error(filename .. " isn't a file or named pipe, it's a " .. mode .. "!")
×
401
      end
402
      if SILE.makeDeps then
182✔
403
         SILE.makeDeps:add(filename)
182✔
404
      end
405
      local file, err = io.open(filename)
182✔
406
      if not file then
182✔
NEW
407
         print("Could not open " .. filename .. ": " .. err)
×
NEW
408
         return
×
409
      end
410
      doc = file:read("*a")
182✔
411
   end
412
   local cpf = SILE.currentlyProcessingFile
182✔
413
   SILE.currentlyProcessingFile = filename
182✔
414
   local pId = SILE.traceStack:pushDocument(filename, doc)
182✔
415
   local ret = SILE.processString(doc, format, filename, options)
182✔
416
   SILE.traceStack:pop(pId)
182✔
417
   SILE.currentlyProcessingFile = cpf
182✔
418
   return ret
182✔
419
end
420

421
-- TODO: this probably needs deprecating, moved here just to get out of the way so
422
-- typesetters classing works as expected
423
SILE.typesetNaturally = function (frame, func)
181✔
424
   local saveTypesetter = SILE.typesetter
97✔
425
   if SILE.typesetter.frame then
97✔
426
      SILE.typesetter.frame:leave(SILE.typesetter)
97✔
427
   end
428
   SILE.typesetter = SILE.typesetters.base(frame)
194✔
429
   SILE.settings:temporarily(func)
97✔
430
   SILE.typesetter:leaveHmode()
97✔
431
   SILE.typesetter:chuck()
97✔
432
   SILE.typesetter.frame:leave(SILE.typesetter)
97✔
433
   SILE.typesetter = saveTypesetter
97✔
434
   if SILE.typesetter.frame then
97✔
435
      SILE.typesetter.frame:enter(SILE.typesetter)
97✔
436
   end
437
end
438

439
-- Sort through possible places files could be
440
function SILE.resolveFile (filename, pathprefix)
362✔
441
   local candidates = {}
187✔
442
   -- Start with the raw file name as given prefixed with a path if requested
443
   if pathprefix then
187✔
NEW
444
      candidates[#candidates + 1] = pl.path.join(pathprefix, "?")
×
445
   end
446
   -- Also check the raw file name without a path
447
   candidates[#candidates + 1] = "?"
187✔
448
   -- Iterate through the directory of the master file, the SILE_PATH variable, and the current directory
449
   -- Check for prefixed paths first, then the plain path in that fails
450
   if SILE.masterDir then
187✔
451
      for path in SU.gtoke(SILE.masterDir .. ";" .. tostring(os.getenv("SILE_PATH")), ";") do
935✔
452
         if path.string and path.string ~= "nil" then
561✔
453
            if pathprefix then
187✔
NEW
454
               candidates[#candidates + 1] = pl.path.join(path.string, pathprefix, "?")
×
455
            end
456
            candidates[#candidates + 1] = pl.path.join(path.string, "?")
374✔
457
         end
458
      end
459
   end
460
   -- Return the first candidate that exists, also checking the .sil suffix
461
   local path = table.concat(candidates, ";")
187✔
462
   local resolved, err = package.searchpath(filename, path, "/")
187✔
463
   if resolved then
187✔
464
      if SILE.makeDeps then
187✔
465
         SILE.makeDeps:add(resolved)
187✔
466
      end
NEW
467
   elseif SU.debugging("paths") then
×
NEW
468
      SU.debug("paths", ("Unable to find file '%s': %s"):format(filename, err))
×
469
   end
470
   return resolved
187✔
471
end
472

473
function SILE.call (command, options, content)
362✔
474
   options = options or {}
4,697✔
475
   content = content or {}
4,697✔
476
   if SILE.traceback and type(content) == "table" and not content.lno then
4,697✔
477
      -- This call is from code (no content.lno) and we want to spend the time
478
      -- to determine everything we need about the caller
NEW
479
      local caller = debug.getinfo(2, "Sl")
×
NEW
480
      content.file, content.lno = caller.short_src, caller.currentline
×
481
   end
482
   local pId = SILE.traceStack:pushCommand(command, content, options)
4,697✔
483
   if not SILE.Commands[command] then
4,697✔
NEW
484
      SU.error("Unknown command " .. command)
×
485
   end
486
   local result = SILE.Commands[command](options, content)
4,697✔
487
   SILE.traceStack:pop(pId)
4,697✔
488
   return result
4,697✔
489
end
490

491
function SILE.registerCommand (name, func, help, pack, cheat)
362✔
492
   local class = SILE.documentState.documentClass
1,109✔
493
   if not cheat then
1,109✔
494
      SU.deprecated(
24✔
495
         "SILE.registerCommand",
12✔
496
         "class:registerCommand",
12✔
497
         "0.14.0",
12✔
498
         "0.16.0",
12✔
499
         [[Commands are being scoped to the document classes they are loaded into rather than being globals.]]
500
      )
12✔
501
   end
502
   -- Shimming until we have all scope cheating removed from core
503
   if not cheat or not class or class.type ~= "class" then
1,109✔
504
      return SILE.classes.base.registerCommand(nil, name, func, help, pack)
1,288✔
505
   end
506
   return class:registerCommand(name, func, help, pack)
2✔
507
end
508

509
function SILE.setCommandDefaults (command, defaults)
362✔
NEW
510
   local oldCommand = SILE.Commands[command]
×
NEW
511
   SILE.Commands[command] = function (options, content)
×
NEW
512
      for k, v in pairs(defaults) do
×
NEW
513
         options[k] = options[k] or v
×
514
      end
NEW
515
      return oldCommand(options, content)
×
516
   end
517
end
518

519
function SILE.registerUnit (unit, spec)
362✔
520
   -- If a unit exists already, clear it first so we get fresh meta table entries, see #1607
521
   if SILE.units[unit] then
12✔
NEW
522
      SILE.units[unit] = nil
×
523
   end
524
   SILE.units[unit] = spec
12✔
525
end
526

527
function SILE.paperSizeParser (size)
362✔
528
   -- SU.deprecated("SILE.paperSizeParser", "SILE.papersize", "0.10.0", nil)
NEW
529
   return SILE.papersize(size)
×
530
end
531

532
function SILE.finish ()
362✔
533
   if SILE.makeDeps then
181✔
534
      SILE.makeDeps:write()
181✔
535
   end
536
   SILE.documentState.documentClass:finish()
181✔
537
   SILE.font.finish()
181✔
538
   runEvals(SILE.input.evaluateAfters, "evaluate-after")
181✔
539
   if not SILE.quiet then
181✔
540
      io.stderr:write("\n")
181✔
541
   end
542
   if SU.debugging("profile") then
362✔
NEW
543
      ProFi:stop()
×
NEW
544
      ProFi:writeReport(pl.path.splitext(SILE.input.filenames[1]) .. ".profile.txt")
×
545
   end
546
   if SU.debugging("versions") then
362✔
547
      SILE.shaper:debugVersions()
181✔
548
   end
549
end
550

551
-- Internal libraries that run core SILE functions on load
552
SILE.settings = require("core.settings")()
362✔
553
require("core.hyphenator-liang")
181✔
554
require("core.languages")
181✔
555
require("core.packagemanager")
181✔
556
SILE.linebreak = require("core.break")
181✔
557
require("core.frame")
181✔
558
SILE.cli = require("core.cli")
181✔
559
SILE.repl = require("core.repl")
181✔
560
SILE.font = require("core.font")
181✔
561

562
-- For warnings and shims scheduled for removal that are easier to keep track
563
-- of when they are not spead across so many locations...
564
require("core/deprecations")
181✔
565

566
return SILE
181✔
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

© 2026 Coveralls, Inc