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

sile-typesetter / sile / 9414689691

07 Jun 2024 09:15AM UTC coverage: 71.828% (+2.4%) from 69.448%
9414689691

push

github

alerque
chore(core): Update deprecated usage of \rightalign with \raggedleft

1 of 1 new or added line in 1 file covered. (100.0%)

137 existing lines in 12 files now uncovered.

12445 of 17326 relevant lines covered (71.83%)

6664.76 hits per line

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

81.04
/classes/plain.lua
1
--- plain document class.
2
-- @use classes.plain
3

4
local base = require("classes.base")
187✔
5

6
local class = pl.class(base)
187✔
7
class._name = "plain"
187✔
8

9
class.defaultFrameset = {
187✔
10
   content = {
187✔
11
      left = "5%pw",
12
      right = "95%pw",
13
      top = "5%ph",
14
      bottom = "top(footnotes)",
15
   },
187✔
16
   folio = {
187✔
17
      left = "left(content)",
18
      right = "right(content)",
19
      top = "bottom(footnotes)+2%ph",
20
      bottom = "97%ph",
21
   },
187✔
22
   footnotes = {
187✔
23
      left = "left(content)",
24
      right = "right(content)",
25
      height = "0",
26
      bottom = "90%ph",
27
   },
187✔
28
}
187✔
29
class.firstContentFrame = "content"
187✔
30

31
local skips = {
187✔
32
   small = "3pt plus 1pt minus 1pt",
33
   med = "6pt plus 2pt minus 2pt",
34
   big = "12pt plus 4pt minus 4pt",
35
}
36

37
function class:_init (options)
187✔
38
   base._init(self, options)
187✔
39
   self:loadPackage("bidi")
187✔
40
   self:loadPackage("folio")
187✔
41
end
42

43
function class:declareOptions ()
187✔
44
   base.declareOptions(self)
187✔
45
   self:declareOption("direction", function (_, value)
374✔
46
      if value then
6✔
47
         SILE.documentState.direction = value
6✔
48
         SILE.settings:set("font.direction", value, true)
6✔
49
         for _, frame in pairs(self.defaultFrameset) do
24✔
50
            if not frame.direction then
18✔
51
               frame.direction = value
18✔
52
            end
53
         end
54
      end
55
      return SILE.documentState.direction
6✔
56
   end)
57
end
58

59
function class:setOptions (options)
187✔
60
   -- TODO: set a default direction here?
61
   base.setOptions(self, options)
187✔
62
end
63

64
function class:declareSettings ()
187✔
65
   base.declareSettings(self)
187✔
66
   for k, v in pairs(skips) do
748✔
67
      SILE.settings:declare({
1,122✔
68
         parameter = "plain." .. k .. "skipamount",
561✔
69
         type = "vglue",
70
         default = SILE.types.node.vglue(v),
1,122✔
71
         help = "The amount of a \\" .. k .. "skip",
561✔
72
      })
73
   end
74
end
75

76
function class:registerCommands ()
187✔
77
   SILE.classes.base.registerCommands(self)
187✔
78

79
   self:registerCommand("noindent", function (_, content)
374✔
80
      if #SILE.typesetter.state.nodes ~= 0 then
110✔
81
         SU.warn(
2✔
82
            "\\noindent called after nodes already received in a paragraph, the setting will have no effect because the parindent (if any) has already been output"
83
         )
1✔
84
      end
85
      SILE.settings:set("current.parindent", SILE.types.node.glue())
220✔
86
      SILE.process(content)
110✔
87
   end, "Do not add an indent to the start of this paragraph")
297✔
88

89
   self:registerCommand("neverindent", function (_, content)
374✔
90
      SILE.settings:set("current.parindent", SILE.types.node.glue())
134✔
91
      SILE.settings:set("document.parindent", SILE.types.node.glue())
134✔
92
      SILE.process(content)
67✔
93
   end, "Turn off all indentation")
254✔
94

95
   self:registerCommand("indent", function (_, content)
374✔
96
      SILE.settings:set("current.parindent", SILE.settings:get("document.parindent"))
8✔
97
      SILE.process(content)
4✔
98
   end, "Do add an indent to the start of this paragraph, even if previously told otherwise")
191✔
99

100
   for k, _ in pairs(skips) do
748✔
101
      self:registerCommand(k .. "skip", function (_, _)
1,122✔
102
         SILE.typesetter:leaveHmode()
55✔
103
         SILE.typesetter:pushExplicitVglue(SILE.settings:get("plain." .. k .. "skipamount"))
110✔
104
      end, "Skip vertically by a " .. k .. " amount")
1,177✔
105
   end
106

107
   self:registerCommand("hfill", function (_, _)
374✔
108
      SILE.typesetter:pushExplicitGlue(SILE.types.node.hfillglue())
48✔
109
   end, "Add a huge horizontal glue")
211✔
110

111
   self:registerCommand("vfill", function (_, _)
374✔
112
      SILE.typesetter:leaveHmode()
391✔
113
      SILE.typesetter:pushExplicitVglue(SILE.types.node.vfillglue())
782✔
114
   end, "Add huge vertical glue")
578✔
115

116
   self:registerCommand("hss", function (_, _)
374✔
117
      SILE.typesetter:pushGlue(SILE.types.node.hssglue())
×
118
      table.insert(SILE.typesetter.state.nodes, SILE.types.node.zerohbox())
×
119
   end, "Add glue which stretches and shrinks horizontally (good for centering)")
187✔
120

121
   self:registerCommand("vss", function (_, _)
374✔
122
      SILE.typesetter:pushExplicitVglue(SILE.types.node.vssglue())
×
123
   end, "Add glue which stretches and shrinks vertically")
187✔
124

125
   local _thinspacewidth = SILE.types.measurement(0.16667, "em")
187✔
126

127
   self:registerCommand("thinspace", function (_, _)
374✔
128
      SILE.call("glue", { width = _thinspacewidth })
×
129
   end)
130

131
   self:registerCommand("negthinspace", function (_, _)
374✔
132
      SILE.call("glue", { width = -_thinspacewidth })
×
133
   end)
134

135
   self:registerCommand("enspace", function (_, _)
374✔
136
      SILE.call("glue", { width = SILE.types.measurement(1, "en") })
×
137
   end)
138

139
   self:registerCommand("relax", function (_, _) end)
187✔
140

141
   self:registerCommand("enskip", function (_, _)
374✔
142
      SILE.call("enspace")
×
143
   end)
144

145
   local _quadwidth = SILE.types.measurement(1, "em")
187✔
146

147
   self:registerCommand("quad", function (_, _)
374✔
148
      SILE.call("glue", { width = _quadwidth })
1✔
149
   end)
150

151
   self:registerCommand("qquad", function (_, _)
374✔
152
      SILE.call("glue", { width = _quadwidth * 2 })
90✔
153
   end)
154

155
   self:registerCommand("slash", function (_, _)
374✔
156
      SILE.typesetter:typeset("/")
×
157
      SILE.call("penalty", { penalty = 50 })
×
158
   end)
159

160
   self:registerCommand("break", function (_, _)
374✔
161
      SILE.call("penalty", { penalty = -10000 })
45✔
162
   end, "Requests a frame break (if in vertical mode) or a line break (if in horizontal mode)")
232✔
163

164
   self:registerCommand("cr", function (_, _)
374✔
165
      SILE.call("hfill")
3✔
166
      SILE.call("break")
3✔
167
   end, "Fills a line with a stretchable glue and then requests a line break")
190✔
168

169
   -- Despite their name, in older versions, \framebreak and \pagebreak worked badly in horizontal
170
   -- mode. The former was a linebreak, and the latter did nothing. That was surely not intended.
171
   -- There are many ways, though to assume what's wrong or what the user's intent ought to be.
172
   -- We now warn, and terminate the paragraph, but to all extents this might be a wrong approach to
173
   -- reconsider at some point.
174

175
   self:registerCommand("framebreak", function (_, _)
374✔
176
      if not SILE.typesetter:vmode() then
22✔
177
         SU.warn("framebreak was not intended to work in horizontal mode. Behaviour may change in future versions")
×
178
      end
179
      SILE.call("penalty", { penalty = -10000, vertical = true })
11✔
180
   end, "Requests a frame break (switching to vertical mode if needed)")
198✔
181

182
   self:registerCommand("pagebreak", function (_, _)
374✔
183
      if not SILE.typesetter:vmode() then
10✔
184
         SU.warn("pagebreak was not intended to work in horizontal mode. Behaviour may change in future versions")
×
185
      end
186
      SILE.call("penalty", { penalty = -20000, vertical = true })
5✔
187
   end, "Requests a non-negotiable page break (switching to vertical mode if needed)")
192✔
188

189
   self:registerCommand("nobreak", function (_, _)
374✔
190
      SILE.call("penalty", { penalty = 10000 })
×
191
   end, "Inhibits a frame break (if in vertical mode) or a line break (if in horizontal mode)")
187✔
192

193
   self:registerCommand("novbreak", function (_, _)
374✔
194
      SILE.call("penalty", { penalty = 10000, vertical = true })
7✔
195
   end, "Inhibits a frame break (switching to vertical mode if needed)")
194✔
196

197
   self:registerCommand(
374✔
198
      "allowbreak",
187✔
199
      function (_, _)
200
         SILE.call("penalty", { penalty = 0 })
×
201
      end,
202
      "Allows a page break (if in vertical mode) or a line break (if in horizontal mode) at a point would not be considered as suitable for breaking"
203
   )
187✔
204

205
   -- THIS SEEMS BROKEN BUT THE COMMAND NOT MENTIONED IN THE SILE MANUAL
206
   -- In TeX, "\filbreak" compensates the vertical fill if no break actually occurs
207
   -- (\def\filbreak{\par\vfil\penalty-200\vfilneg)
208
   self:registerCommand("filbreak", function (_, _)
374✔
209
      SILE.call("vfill")
×
210
      SILE.call("penalty", { penalty = -200 })
×
211
   end, "I HAVE THE SAME NAME AS A TEX COMMAND BUT DON'T SEEM TO BE THE SAME")
187✔
212

213
   -- NOTE: TeX's "\goodbreak" does a \par first, so always switches to vertical mode.
214
   -- SILE differs here, allowing it both within a paragraph (line breaking) and between
215
   -- paragraphs (page breaking).
216
   self:registerCommand("goodbreak", function (_, _)
374✔
217
      SILE.call("penalty", { penalty = -500 })
4✔
218
   end, "Indicates a good potential point to break a frame (if in vertical mode) or a line (if in horizontal mode")
191✔
219

220
   self:registerCommand("eject", function (_, _)
374✔
221
      SILE.call("vfill")
3✔
222
      SILE.call("break")
3✔
223
   end, "Fills the page with stretchable vglue and then request a page break")
190✔
224

225
   self:registerCommand("supereject", function (_, _)
374✔
226
      SILE.call("vfill")
197✔
227
      SILE.call("penalty", { penalty = -20000 })
197✔
228
   end, "Fills the page with stretchable vglue and then requests a non-negotiable page break")
384✔
229

230
   self:registerCommand("em", function (_, content)
374✔
231
      local style = SILE.settings:get("font.style")
90✔
232
      local toggle = (style and style:lower() == "italic") and "Regular" or "Italic"
180✔
233
      SILE.call("font", { style = toggle }, content)
90✔
234
   end, "Emphasizes its contents by switching the font style to italic (or back to regular if already italic)")
277✔
235

236
   self:registerCommand("strong", function (_, content)
374✔
237
      SILE.call("font", { weight = 700 }, content)
×
238
   end, "Sets the font weight to bold (700)")
187✔
239

240
   self:registerCommand("code", function (options, content)
374✔
241
      -- IMPLEMENTATION NOTE:
242
      -- The \code command came from the url package, though used in plenty of
243
      -- places. It was referring to the verbatim:font from the verbatim
244
      -- package, which _should_ be sort of unrelated.
245
      -- Trying to untangle the things here, by introducing the
246
      -- definition from the former, but it's of sub-quality...
247
      -- The ugly -3 size is a HACK of sorts.
248
      options.family = options.family or "Hack"
1✔
249
      options.size = options.size or SILE.settings:get("font.size") - 3
2✔
250
      SILE.call("font", options, content)
1✔
251
   end)
252

253
   self:registerCommand("nohyphenation", function (_, content)
374✔
254
      SILE.call("font", { language = "und" }, content)
×
255
   end)
256

257
   self:registerCommand("center", function (_, content)
374✔
258
      if #SILE.typesetter.state.nodes ~= 0 then
31✔
259
         SU.warn("\\center environment started after other nodes in a paragraph, may not center as expected")
×
260
      end
261
      SILE.settings:temporarily(function ()
62✔
262
         local lskip = SILE.settings:get("document.lskip") or SILE.types.node.glue()
62✔
263
         local rskip = SILE.settings:get("document.rskip") or SILE.types.node.glue()
62✔
264
         SILE.settings:set("document.parindent", SILE.types.node.glue())
62✔
265
         SILE.settings:set("current.parindent", SILE.types.node.glue())
62✔
266
         SILE.settings:set("document.lskip", SILE.types.node.hfillglue(lskip.width.length))
62✔
267
         SILE.settings:set("document.rskip", SILE.types.node.hfillglue(rskip.width.length))
62✔
268
         SILE.settings:set("typesetter.parfillskip", SILE.types.node.glue())
62✔
269
         SILE.settings:set("document.spaceskip", SILE.types.length("1spc", 0, 0))
62✔
270
         SILE.process(content)
31✔
271
         SILE.call("par")
31✔
272
      end)
273
   end, "Typeset its contents in a centered block (keeping margins).")
218✔
274

275
   self:registerCommand("raggedright", function (_, content)
374✔
276
      SILE.settings:temporarily(function ()
14✔
277
         local lskip = SILE.settings:get("document.lskip") or SILE.types.node.glue()
14✔
278
         local rskip = SILE.settings:get("document.rskip") or SILE.types.node.glue()
14✔
279
         SILE.settings:set("document.lskip", SILE.types.node.glue(lskip.width.length))
14✔
280
         SILE.settings:set("document.rskip", SILE.types.node.hfillglue(rskip.width.length))
14✔
281
         SILE.settings:set("typesetter.parfillskip", SILE.types.node.glue())
14✔
282
         SILE.settings:set("document.spaceskip", SILE.types.length("1spc", 0, 0))
14✔
283
         SILE.process(content)
7✔
284
         SILE.call("par")
7✔
285
      end)
286
   end, "Typeset its contents in a left aligned block (keeping margins).")
194✔
287

288
   self:registerCommand("raggedleft", function (_, content)
374✔
289
      SILE.settings:temporarily(function ()
10✔
290
         local lskip = SILE.settings:get("document.lskip") or SILE.types.node.glue()
10✔
291
         local rskip = SILE.settings:get("document.rskip") or SILE.types.node.glue()
10✔
292
         SILE.settings:set("document.lskip", SILE.types.node.hfillglue(lskip.width.length))
10✔
293
         SILE.settings:set("document.rskip", SILE.types.node.glue(rskip.width.length))
10✔
294
         SILE.settings:set("typesetter.parfillskip", SILE.types.node.glue())
10✔
295
         SILE.settings:set("document.spaceskip", SILE.types.length("1spc", 0, 0))
10✔
296
         SILE.process(content)
5✔
297
         SILE.call("par")
5✔
298
      end)
299
   end, "Typeset its contents in a right aligned block (keeping margins).")
192✔
300

301
   self:registerCommand("justified", function (_, content)
374✔
302
      SILE.settings:temporarily(function ()
2✔
303
         local lskip = SILE.settings:get("document.lskip") or SILE.types.node.glue()
2✔
304
         local rskip = SILE.settings:get("document.rskip") or SILE.types.node.glue()
2✔
305
         -- Keep the fixed part of the margins for nesting but remove the stretchability.
306
         SILE.settings:set("document.lskip", SILE.types.node.glue(lskip.width.length))
2✔
307
         SILE.settings:set("document.rskip", SILE.types.node.glue(rskip.width.length))
2✔
308
         -- Reset parfillskip to its default value, in case the surrounding context
309
         -- is ragged and cancelled it.
310
         SILE.settings:set("typesetter.parfillskip", nil, false, true)
1✔
311
         SILE.settings:set("document.spaceskip", nil)
1✔
312
         SILE.process(content)
1✔
313
         SILE.call("par")
1✔
314
      end)
315
   end, "Typeset its contents in a justified block (keeping margins).")
188✔
316

317
   self:registerCommand("ragged", function (options, content)
374✔
318
      -- Fairly dubious command for compatibility
319
      local l = SU.boolean(options.left, false)
1✔
320
      local r = SU.boolean(options.right, false)
1✔
321
      if l and r then
1✔
322
         SILE.call("center", {}, content)
2✔
323
      elseif r then
×
324
         SILE.call("raggedleft", {}, content)
×
325
      elseif l then
×
326
         SILE.call("raggedright", {}, content)
×
327
      else
328
         SILE.call("justified", {}, content)
×
329
      end
330
   end)
331

332
   self:registerCommand("rightalign", function (_, content)
374✔
UNCOV
333
      SU.deprecated("\\rightalign", "\\raggedleft", "0.15.0", "0.17.0")
×
UNCOV
334
      SILE.call("raggedleft", {}, content)
×
335
   end)
336

337
   self:registerCommand("blockquote", function (_, content)
374✔
338
      SILE.call("smallskip")
1✔
339
      SILE.typesetter:leaveHmode()
1✔
340
      SILE.settings:temporarily(function ()
2✔
341
         local indent = SILE.types.measurement("2em"):absolute()
2✔
342
         local lskip = SILE.settings:get("document.lskip") or SILE.types.node.glue()
2✔
343
         local rskip = SILE.settings:get("document.rskip") or SILE.types.node.glue()
2✔
344
         -- We keep the stretcheability of the lskip and rskip: honoring text alignment
345
         -- from the parent context.
346
         SILE.settings:set("document.lskip", SILE.types.node.glue(lskip.width + indent))
3✔
347
         SILE.settings:set("document.rskip", SILE.types.node.glue(rskip.width + indent))
3✔
348
         SILE.settings:set("font.size", SILE.settings:get("font.size") * 0.95)
2✔
349
         SILE.process(content)
1✔
350
         SILE.typesetter:leaveHmode()
1✔
351
      end)
352
      SILE.call("smallskip")
1✔
353
   end, "A blockquote environment")
188✔
354

355
   self:registerCommand("quote", function (_, content)
374✔
356
      SU.deprecated(
×
357
         "\\quote",
358
         "\\pullquote or \\blockquote",
359
         "0.14.5",
360
         "0.16.0",
361
         [[
×
362
  The \quote command has *such* bad output it is being completely
363
  deprecated as unsuitable for general purpose use.
364
  The pullquote package (\use[module=packages.pullquote]) provides one
365
  alternative, and the blockquote environment provides another.
366
  But you can also copy and adapt the original source from the plain
367
  class if you need to maintain exact output past SILE v0.16.0.]]
×
368
      )
369
      SILE.call("smallskip")
×
370
      SILE.call("par")
×
371
      local margin = SILE.types.measurement(2.5, "em")
×
372
      SILE.settings:set("document.lskip", margin)
×
373
      SILE.settings:set("document.lskip", margin)
×
374
      SILE.call("font", { size = SILE.types.measurement(0.8, "em") }, function ()
×
375
         SILE.call("noindent")
×
376
         SILE.process(content)
×
377
      end)
378
      SILE.call("par")
×
379
      SILE.settings:set("document.lskip", nil)
×
380
      SILE.settings:set("document.rskip", nil)
×
381
      SILE.call("smallskip")
×
382
   end)
383

384
   self:registerCommand("listitem", function (_, content)
374✔
385
      SU.deprecated(
×
386
         "\\listitem",
387
         "\\item",
388
         "0.14.6",
389
         "0.16.0",
390
         [[
×
391
  The new list package (\use[module=packages.lists) has much better
392
  typography for lists. If you want to maintain the exact output of listitem
393
  past SILE v0.16.0 copy the source of \listitem from the plain class into
394
  your project.]]
×
395
      )
396
      SILE.call("medskip")
×
397
      SILE.typesetter:typeset("• ")
×
398
      SILE.process(content)
×
399
      SILE.call("medskip")
×
400
   end)
401

402
   self:registerCommand("sloppy", function (_, _)
374✔
403
      SILE.settings:set("linebreak.tolerance", 9999)
×
404
   end)
405

406
   self:registerCommand("awful", function (_, _)
374✔
407
      SILE.settings:set("linebreak.tolerance", 10000)
×
408
   end)
409

410
   self:registerCommand("hbox", function (_, content)
374✔
411
      local hbox, hlist = SILE.typesetter:makeHbox(content)
71✔
412
      SILE.typesetter:pushHbox(hbox)
71✔
413
      if #hlist > 0 then
71✔
414
         SU.warn("Hbox has migrating content (ignored for now, but likely to break in future versions)")
×
415
         -- Ugly shim:
416
         -- One day we ought to do SILE.typesetter:pushHlist(hlist) here, so as to push
417
         -- back the migrating contents from within the hbox'ed content.
418
         -- However, old Lua code assumed the hbox to be returned, and sometimes removed it
419
         -- from the typesetter queue (for measuring, etc.), assuming it was the last
420
         -- element in the queue...
421
      end
422
      return hbox
71✔
423
   end, "Compiles all the enclosed horizontal-mode material into a single hbox")
187✔
424

425
   self:registerCommand("vbox", function (options, content)
374✔
426
      local vbox
427
      SILE.settings:temporarily(function ()
90✔
428
         if options.width then
45✔
429
            SILE.settings:set("typesetter.breakwidth", SILE.types.length(options.width))
×
430
         end
431
         SILE.typesetter:pushState()
45✔
432
         SILE.process(content)
45✔
433
         SILE.typesetter:leaveHmode(1)
45✔
434
         vbox = SILE.pagebuilder:collateVboxes(SILE.typesetter.state.outputQueue)
90✔
435
         SILE.typesetter:popState()
45✔
436
      end)
437
      return vbox
45✔
438
   end, "Compiles all the enclosed material into a single vbox")
187✔
439
end
440

441
return class
187✔
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