• 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

83.15
/core/frame.lua
1
SILE.frames = {}
181✔
2

3
-- Buggy, relies on side effects
4
-- luacheck: ignore solver frame
5
-- See https://github.com/sile-typesetter/sile/issues/694
6

7
local cassowary = require("cassowary")
181✔
8
local solver = cassowary.SimplexSolver()
181✔
9
local solverNeedsReloading = true
181✔
10

11
local widthdims = pl.Set({ "left", "right", "width" })
181✔
12
local heightdims = pl.Set({ "top", "bottom", "height" })
181✔
13
local alldims = widthdims + heightdims
181✔
14

15
SILE.framePrototype = pl.class({
362✔
16
   direction = "LTR-TTB",
17
   enterHooks = {},
181✔
18
   leaveHooks = {},
181✔
19

20
   -- This gets called by Penlght when creating the frame instance
21
   _init = function (self, spec, dummy)
22
      local direction = SILE.documentState.direction
968✔
23
      if direction then
968✔
24
         self.direction = direction
21✔
25
      end
26
      self.constraints = {}
968✔
27
      self.variables = {}
968✔
28
      self.id = spec.id
968✔
29
      for k, v in pairs(spec) do
5,893✔
30
         if not alldims[k] then
4,925✔
31
            self[k] = v
1,113✔
32
         end
33
      end
34
      self.balanced = SU.boolean(self.balanced, false)
1,936✔
35
      if not dummy then
968✔
36
         for method in pairs(alldims) do
6,755✔
37
            self.variables[method] = cassowary.Variable({ name = spec.id .. "_" .. method })
11,580✔
38
            self[method] = function (instance_self)
39
               instance_self:solve()
8,469✔
40
               return SILE.measurement(instance_self.variables[method].value)
8,469✔
41
            end
42
         end
43
         -- Add definitions of width and height
44
         for method in pairs(alldims) do
6,755✔
45
            if spec[method] then
5,790✔
46
               self:constrain(method, spec[method])
3,812✔
47
            end
48
         end
49
      end
50
   end,
51

52
   -- This gets called by us in typesetter before we start to use the frame
53
   init = function (self, typesetter)
54
      self.state = { totals = { height = SILE.measurement(0) } }
990✔
55
      self:enter(typesetter)
495✔
56
      self:newLine(typesetter)
495✔
57
      if self:pageAdvanceDirection() == "TTB" then
990✔
58
         self.state.cursorY = self:top()
970✔
59
      elseif self:pageAdvanceDirection() == "LTR" then
20✔
60
         self.state.cursorX = self:left()
4✔
61
      elseif self:pageAdvanceDirection() == "RTL" then
16✔
62
         self.state.cursorX = self:right()
12✔
63
      elseif self:pageAdvanceDirection() == "BTT" then
4✔
64
         self.state.cursorY = self:bottom()
4✔
65
      end
66
   end,
67

68
   constrain = function (self, method, dimension)
69
      self.constraints[method] = tostring(dimension)
4,007✔
70
      self:invalidate()
3,898✔
71
   end,
72

73
   invalidate = function ()
74
      solverNeedsReloading = true
4,298✔
75
   end,
76

77
   relax = function (self, method)
78
      self.constraints[method] = nil
64✔
79
   end,
80

81
   reifyConstraint = function (self, solver, method, stay)
82
      local constraint = self.constraints[method]
6,958✔
83
      if not constraint then
6,958✔
NEW
84
         return
×
85
      end
86
      constraint = SU.type(constraint) == "measurement" and constraint:tonumber() or SILE.frameParser:match(constraint)
13,916✔
87
      SU.debug("frames", "Adding constraint", self.id, function ()
13,916✔
NEW
88
         return "(" .. method .. ") = " .. tostring(constraint)
×
89
      end)
90
      local eq = cassowary.Equation(self.variables[method], constraint)
6,958✔
91
      solver:addConstraint(eq)
6,958✔
92
      if stay then
6,958✔
93
         solver:addStay(eq)
1,460✔
94
      end
95
   end,
96

97
   addWidthHeightDefinitions = function (self, solver)
98
      local vars = self.variables
1,746✔
99
      solver:addConstraint(cassowary.Equation(vars.width, cassowary.minus(vars.right, vars.left)))
5,238✔
100
      solver:addConstraint(cassowary.Equation(vars.height, cassowary.minus(vars.bottom, vars.top)))
5,238✔
101
   end,
102

103
   -- This is hideously inefficient,
104
   -- but it's the easiest way to allow users to reconfigure frames at runtime.
105
   solve = function (_)
106
      if not solverNeedsReloading then
8,469✔
107
         return
8,104✔
108
      end
109
      SU.debug("frames", "Solving...")
365✔
110
      solver = cassowary.SimplexSolver()
730✔
111
      if SILE.frames.page then
365✔
112
         for method, _ in pairs(SILE.frames.page.constraints) do
1,825✔
113
            SILE.frames.page:reifyConstraint(solver, method, true)
1,460✔
114
         end
115
         SILE.frames.page:addWidthHeightDefinitions(solver)
365✔
116
      end
117
      for id, frame in pairs(SILE.frames) do
2,111✔
118
         if not (id == "page") then
1,746✔
119
            for method, _ in pairs(frame.constraints) do
6,879✔
120
               frame:reifyConstraint(solver, method)
5,498✔
121
            end
122
            frame:addWidthHeightDefinitions(solver)
1,381✔
123
         end
124
      end
125
      solver:solve()
365✔
126
      solverNeedsReloading = false
365✔
127
   end,
128

129
   writingDirection = function (self)
130
      return self.direction:match("^(%a+)") or "LTR"
91,779✔
131
   end,
132

133
   pageAdvanceDirection = function (self)
134
      return self.direction:match("-(%a+)$") or "TTB"
7,753✔
135
   end,
136

137
   advanceWritingDirection = function (self, length)
138
      local amount = SU.cast("number", length)
22,679✔
139
      if amount == 0 then
22,679✔
140
         return
3,255✔
141
      end
142
      if self:writingDirection() == "RTL" then
38,848✔
143
         self.state.cursorX = self.state.cursorX - amount
1,150✔
144
      elseif self:writingDirection() == "LTR" then
37,698✔
145
         self.state.cursorX = self.state.cursorX + amount
37,582✔
146
      elseif self:writingDirection() == "TTB" then
116✔
147
         self.state.cursorY = self.state.cursorY + amount
104✔
148
      elseif self:writingDirection() == "BTT" then
12✔
149
         self.state.cursorY = self.state.cursorY - amount
12✔
150
      end
151
   end,
152

153
   advancePageDirection = function (self, length)
154
      local amount = SU.cast("number", length)
5,576✔
155
      if amount == 0 then
5,576✔
156
         return
384✔
157
      end
158
      if self:pageAdvanceDirection() == "TTB" then
10,384✔
159
         self.state.cursorY = self.state.cursorY + amount
10,270✔
160
      elseif self:pageAdvanceDirection() == "RTL" then
114✔
161
         self.state.cursorX = self.state.cursorX - amount
74✔
162
      elseif self:pageAdvanceDirection() == "LTR" then
40✔
163
         self.state.cursorX = self.state.cursorX + amount
20✔
164
      elseif self:pageAdvanceDirection() == "BTT" then
20✔
165
         self.state.cursorY = self.state.cursorY - amount
20✔
166
      end
167
   end,
168

169
   newLine = function (self, _)
170
      if self:writingDirection() == "LTR" then
3,906✔
171
         self.state.cursorX = self:left()
3,748✔
172
      elseif self:writingDirection() == "RTL" then
158✔
173
         self.state.cursorX = self:right()
126✔
174
      elseif self:writingDirection() == "TTB" then
32✔
175
         self.state.cursorY = self:top()
24✔
176
      elseif self:writingDirection() == "BTT" then
8✔
177
         self.state.cursorY = self:bottom()
8✔
178
      end
179
   end,
180

181
   lineWidth = function (self)
182
      SU.warn("Method :lineWidth() is deprecated, please use :getLineWidth()")
×
183
      return self:getLineWidth()
×
184
   end,
185

186
   getLineWidth = function (self)
187
      if self:writingDirection() == "LTR" or self:writingDirection() == "RTL" then
2,112✔
188
         return self:width()
1,018✔
189
      else
190
         return self:height()
15✔
191
      end
192
   end,
193

194
   pageTarget = function (self)
195
      SU.warn("Method :pageTarget() is deprecated, please use :getTargetLength()")
×
196
      return self:getTargetLength()
×
197
   end,
198

199
   getTargetLength = function (self)
200
      local direction = self:pageAdvanceDirection()
1,959✔
201
      if direction == "TTB" or direction == "BTT" then
1,959✔
202
         return self:height()
1,929✔
203
      else
204
         return self:width()
30✔
205
      end
206
   end,
207

208
   enter = function (self, typesetter)
209
      for i = 1, #self.enterHooks do
600✔
210
         self.enterHooks[i](self, typesetter)
8✔
211
      end
212
   end,
213

214
   leave = function (self, typesetter)
215
      for i = 1, #self.leaveHooks do
537✔
216
         self.leaveHooks[i](self, typesetter)
18✔
217
      end
218
   end,
219

220
   isAbsoluteConstraint = function (self, method)
221
      if not self.constraints[method] then
300✔
222
         return false
4✔
223
      end
224
      local constraint = SILE.frameParser:match(self.constraints[method])
296✔
225
      if type(constraint) ~= "table" then
296✔
226
         return true
76✔
227
      end
228
      if not constraint.terms then
220✔
229
         return false
214✔
230
      end
231
      for clv, _ in pairs(constraint.terms) do
6✔
232
         if clv.name and not clv.name:match("^page_") then
4✔
233
            return false
4✔
234
         end
235
      end
236
      return true
2✔
237
   end,
238

239
   isMainContentFrame = function (self)
240
      local tpt = SILE.documentState.thisPageTemplate
74✔
241
      local frame = tpt.firstContentFrame
74✔
242
      while frame do
80✔
243
         if frame == self then
80✔
244
            return true
52✔
245
         end
246
         if frame.next then
28✔
247
            frame = SILE.getFrame(frame.next)
12✔
248
         else
249
            return false
22✔
250
         end
251
      end
252
      return false
×
253
   end,
254

255
   __tostring = function (self)
256
      local str = "<Frame: " .. self.id .. ": "
×
257
      str = str .. " next=" .. (self.next or "nil") .. " "
×
258
      for method, dimension in pairs(self.constraints) do
×
NEW
259
         str = str .. method .. "=" .. dimension .. "; "
×
260
      end
261
      if self.hanmen then
×
NEW
262
         str = str .. "tate=" .. (self.tate and "true" or "false") .. "; "
×
NEW
263
         str = str .. "gridsize=" .. self.gridsize .. "; "
×
NEW
264
         str = str .. "linegap=" .. self.linegap .. "; "
×
NEW
265
         str = str .. "linelength=" .. self.linelength .. "; "
×
NEW
266
         str = str .. "linecount=" .. self.linecount .. "; "
×
267
      end
268
      str = str .. ">"
×
269
      return str
×
270
   end,
271
})
181✔
272

273
SILE.newFrame = function (spec, prototype)
181✔
274
   SU.required(spec, "id", "frame declaration")
965✔
275
   prototype = prototype or SILE.framePrototype
965✔
276
   local frame = prototype(spec)
965✔
277
   SILE.frames[spec.id] = frame
965✔
278
   return frame
965✔
279
end
280

281
SILE.getFrame = function (id)
181✔
282
   if type(id) == "table" then
382✔
NEW
283
      SU.error("Passed a table, expected a string", true)
×
284
   end
285
   local frame, last_attempt
286
   while not frame do
764✔
287
      frame = SILE.frames[id]
383✔
288
      id = id:gsub("_$", "")
383✔
289
      if id == last_attempt then
383✔
290
         break
1✔
291
      end
292
      last_attempt = id
382✔
293
   end
294
   return frame or SU.warn("Couldn't find frame ID " .. id, true)
383✔
295
end
296

297
SILE.parseComplexFrameDimension = function (dimension)
181✔
NEW
298
   local length = SILE.frameParser:match(SU.cast("string", dimension))
×
NEW
299
   if type(length) == "table" then
×
NEW
300
      local g = cassowary.Variable({ name = "t" })
×
NEW
301
      local eq = cassowary.Equation(g, length)
×
NEW
302
      solverNeedsReloading = true
×
NEW
303
      solver:addConstraint(eq)
×
NEW
304
      SILE.frames.page:solve()
×
NEW
305
      solverNeedsReloading = true
×
NEW
306
      return g.value
×
307
   end
NEW
308
   return length
×
309
end
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