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

sile-typesetter / sile / 14860011647

06 May 2025 12:44PM UTC coverage: 67.057% (+32.5%) from 34.559%
14860011647

push

github

alerque
chore(typesetters): Fixup access to class from typesetter functions

7 of 7 new or added lines in 2 files covered. (100.0%)

1344 existing lines in 103 files now uncovered.

14880 of 22190 relevant lines covered (67.06%)

11549.16 hits per line

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

88.0
/pagebuilders/base.lua
1
--- SILE pagebuilder class.
2
-- @interfaces pagebuilders
3

4
local module = require("types.module")
153✔
5
local pagebuilder = pl.class(module)
153✔
6
pagebuilder.type = "pagebuilder"
153✔
7

8
function pagebuilder:_init (typesetter)
153✔
9
   self.typesetter = typesetter
276✔
10
   module._init(self)
276✔
11
   self.awful_bad = 1073741823
276✔
12
   self.inf_bad = 10000
276✔
13
   self.eject_penalty = -self.inf_bad
276✔
14
   self.deplorable = 100000
276✔
15
end
16

17
function pagebuilder:collateVboxes (vboxlist)
153✔
18
   local output = SILE.types.node.vbox()
46✔
19
   output:append(vboxlist)
46✔
20
   return output
46✔
21
end
22

23
-- Note: Almost 1/3 of the time in a typical SILE in taken iterating through
24
-- this function. As a result there are some micro-optimizations here that
25
-- make it a-typical of preferred coding styles. In particular note that
26
-- we absolutize heavily iterated lengths as early as possible and make
27
-- make direct calls to their integer amounts, assumed to be in points by
28
-- the point they are called **without actually checking**!
29
function pagebuilder:findBestBreak (options)
153✔
30
   local vboxlist = SU.required(options, "vboxlist", "in findBestBreak")
2,311✔
31
   local target = SU.required(options, "target", "in findBestBreak", "length")
2,311✔
32
   local restart = options.restart or false
2,311✔
33
   local force = options.force or false
2,311✔
34
   local i = 0
2,311✔
35
   local totalHeight = SILE.types.length()
2,311✔
36
   local bestBreak = nil
2,311✔
37
   local started = false
2,311✔
38
   if restart and restart.target == target then
2,311✔
39
      totalHeight = restart.totalHeight
×
UNCOV
40
      i = restart.i
×
UNCOV
41
      started = restart.started
×
42
   end
43
   local leastC = self.inf_bad
2,311✔
44
   SU.debug("pagebuilder", function ()
4,622✔
45
      return "Page builder for frame "
×
46
         .. self.typesetter.frame.id
×
47
         .. " called with "
×
48
         .. #vboxlist
×
UNCOV
49
         .. " nodes, "
×
UNCOV
50
         .. tostring(target)
×
51
   end)
52
   if SU.debugging("vboxes") then
4,622✔
53
      for j, box in ipairs(vboxlist) do
×
UNCOV
54
         SU.debug("vboxes", function ()
×
UNCOV
55
            return (j == i and " >" or "  ") .. j .. ": " .. box
×
56
         end)
57
      end
58
   end
59
   while not started and i < #vboxlist do
5,285✔
60
      i = i + 1
5,201✔
61
      if not vboxlist[i].is_vglue then
5,201✔
62
         started = true
2,227✔
63
         i = i - 1
2,227✔
64
         break
2,227✔
65
      end
66
   end
67
   local pi
68
   while i < #vboxlist do
37,494✔
69
      i = i + 1
35,409✔
70
      local vbox = vboxlist[i]
35,409✔
71
      SU.debug("pagebuilder", "Dealing with VBox", vbox)
35,409✔
72
      if vbox.is_vbox then
35,409✔
73
         totalHeight:___add(vbox.height)
11,268✔
74
         totalHeight:___add(vbox.depth)
22,536✔
75
      elseif vbox.is_vglue then
24,141✔
76
         totalHeight:___add(vbox.height)
35,676✔
77
      elseif vbox.is_insertion then
6,303✔
78
         -- TODO: refactor as hook and without side effects!
79
         target = SILE.insertions.processInsertion(vboxlist, i, totalHeight, target)
422✔
80
         vbox = vboxlist[i]
211✔
81
      end
82
      local left = target - totalHeight
35,409✔
83
      SU.debug("pagebuilder", "I have", left, "left")
35,409✔
84
      -- if left < -20 then SU.error("\nCatastrophic page breaking failure!"); end
85
      pi = 0
35,409✔
86
      if vbox.is_penalty then
35,409✔
87
         pi = vbox.penalty
6,097✔
88
      end
89
      if
90
         vbox.is_penalty and vbox.penalty < self.inf_bad
35,409✔
91
         or (vbox.is_vglue and i > 1 and not vboxlist[i - 1].discardable)
31,472✔
92
      then
93
         local badness
94
         SU.debug("pagebuilder", "totalHeight", totalHeight, "with target", target)
11,821✔
95
         if totalHeight.length.amount < target.length.amount then -- TeX #1039
11,821✔
96
            -- Account for infinite stretch?
97
            badness = SU.rateBadness(self.inf_bad, left.length.amount, totalHeight.stretch.amount)
23,562✔
98
         elseif left.length.amount < totalHeight.shrink.amount then
40✔
99
            badness = self.awful_bad
39✔
100
         else
101
            badness = SU.rateBadness(self.inf_bad, -left.length.amount, totalHeight.shrink.amount)
2✔
102
         end
103

104
         local c
105
         if badness < self.awful_bad then
11,821✔
106
            if pi <= self.eject_penalty then
11,782✔
107
               c = pi
187✔
108
            elseif badness < self.inf_bad then
11,595✔
109
               c = badness + pi -- plus insert
630✔
110
            else
111
               c = self.deplorable
10,965✔
112
            end
113
         else
114
            c = badness
39✔
115
         end
116
         if c < leastC then
11,821✔
117
            leastC = c
737✔
118
            bestBreak = i
737✔
119
         else
120
            restart = { totalHeight = totalHeight, i = i, started = started, target = target }
11,084✔
121
         end
122

123
         SU.debug("pagebuilder", "Badness:", c)
11,821✔
124
         if c == self.awful_bad or pi <= self.eject_penalty then
11,821✔
125
            SU.debug("pagebuilder", "outputting")
226✔
126
            local onepage = {}
226✔
127
            if not bestBreak then
226✔
128
               bestBreak = i
24✔
129
            end
130
            for j = 1, bestBreak do
4,525✔
131
               onepage[j] = table.remove(vboxlist, 1)
8,598✔
132
            end
133
            while #onepage > 1 and onepage[#onepage].discardable do
488✔
134
               onepage[#onepage] = nil
262✔
135
            end
136
            return onepage, pi
226✔
137
         end
138
      end
139
   end
140
   SU.debug("pagebuilder", "No page break here")
2,085✔
141
   if force and bestBreak then
2,085✔
142
      local onepage = {}
1✔
143
      for j = 1, bestBreak do
9✔
144
         onepage[j] = table.remove(vboxlist, 1)
16✔
145
      end
146
      return onepage, pi
1✔
147
   end
148
   return false, restart
2,084✔
149
end
150

151
return pagebuilder
153✔
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