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

sile-typesetter / sile / 11170735472

03 Oct 2024 10:32PM UTC coverage: 58.612% (-4.5%) from 63.103%
11170735472

push

github

web-flow
Merge bcab25790 into 783083345

15 of 64 new or added lines in 5 files covered. (23.44%)

828 existing lines in 41 files now uncovered.

10478 of 17877 relevant lines covered (58.61%)

2029.7 hits per line

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

0.0
/packages/balanced-frames/init.lua
UNCOV
1
local base = require("packages.base")
×
2

UNCOV
3
local package = pl.class(base)
×
UNCOV
4
package._name = "balanced-frames"
×
5

UNCOV
6
local BALANCE_PENALTY = -17777
×
7

8
local unbalanced_buildPage
9

10
local function buildPage (typesetter, independent)
UNCOV
11
   local frame = typesetter.frame
×
UNCOV
12
   if not (frame.balanced == true) then
×
UNCOV
13
      return unbalanced_buildPage(typesetter, independent)
×
14
   end
15

UNCOV
16
   local colCount = 0
×
UNCOV
17
   local target = SILE.types.length()
×
UNCOV
18
   while frame and frame.balanced == true do
×
UNCOV
19
      target = target + frame:height()
×
UNCOV
20
      colCount = colCount + 1
×
UNCOV
21
      if frame.next then
×
UNCOV
22
         frame = SILE.getFrame(frame.next)
×
23
      else
24
         break
25
      end
26
   end
27

28
   -- Really, try and avoid doing anything, where possible.
UNCOV
29
   if colCount == 1 then
×
30
      return unbalanced_buildPage(typesetter, independent)
×
31
   end
32
   -- If the total amount of stuff on the output list is greater then the total
33
   -- of frame space on the page, and there are no magic requests to balance the
34
   -- columns, then we have a full page. Just send it out normally.
UNCOV
35
   local q = typesetter.state.outputQueue
×
UNCOV
36
   local totalHeight = SILE.types.length()
×
UNCOV
37
   local mustBalance = 0
×
UNCOV
38
   for i = 1, #q do
×
UNCOV
39
      totalHeight = totalHeight + q[i].height + q[i].depth
×
UNCOV
40
      if q[i].is_penalty and q[i].penalty <= BALANCE_PENALTY then
×
UNCOV
41
         mustBalance = i
×
42
         break
43
      end
44
   end
UNCOV
45
   if totalHeight.length > target.length and mustBalance == 0 and not independent then
×
46
      return unbalanced_buildPage(typesetter, independent)
×
47
   end
48

49
   -- Have we been explicitly asked to find a pagebreak at this point?
50
   -- If not, don't bother
UNCOV
51
   if mustBalance == 0 and not independent then
×
UNCOV
52
      return false
×
53
   end
UNCOV
54
   SU.debug("balancer", "Balancing", totalHeight, "of material over", colCount, "frames (total of", target, ")")
×
UNCOV
55
   SU.debug("balancer", "Must balance because mustBalance =", mustBalance, "and independent =", independent)
×
56
   -- OK. Now we have to balance the frames. We are going to cheat and
57
   -- adjust the height of each frame to be an appropriate fraction of
58
   -- the content height
UNCOV
59
   frame = typesetter.frame
×
UNCOV
60
   SU.debug("balancer", "Each column is now", totalHeight.length / colCount)
×
UNCOV
61
   while frame and frame.balanced == true do
×
UNCOV
62
      frame:relax("bottom")
×
UNCOV
63
      frame:constrain("height", totalHeight.length / colCount)
×
UNCOV
64
      if frame.next then
×
UNCOV
65
         frame = SILE.getFrame(frame.next)
×
66
      else
67
         break
68
      end
69
   end
UNCOV
70
   typesetter.state.lastPenalty = 0
×
UNCOV
71
   local oldPageBuilder = SILE.pagebuilder
×
UNCOV
72
   SILE.pagebuilder = SILE.pagebuilders.base()
×
UNCOV
73
   while typesetter.frame and typesetter.frame.balanced do
×
UNCOV
74
      unbalanced_buildPage(typesetter, true)
×
UNCOV
75
      if typesetter.frame.next and SILE.getFrame(typesetter.frame.next).balanced == true then
×
UNCOV
76
         typesetter:initFrame(SILE.getFrame(typesetter.frame.next))
×
UNCOV
77
         typesetter:runHooks("newframe")
×
78
      else
79
         break -- Break early, because when we return
80
      end
81
   end
UNCOV
82
   SILE.pagebuilder = oldPageBuilder
×
UNCOV
83
   SU.debug("balancer", "Finished this balance, frame id is now", typesetter.frame)
×
84
   -- SILE.typesetter:debugState()
85
   -- We're done.
UNCOV
86
   return true
×
87
end
88

UNCOV
89
function package:_init (options)
×
UNCOV
90
   base._init(self, options)
×
UNCOV
91
   self.class:registerPostinit(function (_)
×
UNCOV
92
      if not unbalanced_buildPage then
×
UNCOV
93
         unbalanced_buildPage = SILE.typesetter.buildPage
×
UNCOV
94
         SILE.typesetter.buildPage = buildPage
×
UNCOV
95
         SILE.typesetters.base.buildPage = buildPage
×
96
      end
97
   end)
98
end
99

UNCOV
100
function package:registerCommands ()
×
UNCOV
101
   self:registerCommand("balancecolumns", function (_, _)
×
102
      SILE.typesetter:leaveHmode()
×
103
      SILE.call("penalty", { penalty = BALANCE_PENALTY })
×
104
   end)
105
end
106

107
package.documentation = [[
108
\begin{document}
109
This package attempts to ensure that the main content frames on a page are balanced; that is, that they have the same height.
110
In your frame definitions for the columns, you will need to ensure that they have the parameter \autodoc:parameter{balanced} set to \code{true}.
111
See the example in \code{tests/balanced.sil}.
112

113
The current algorithm does not work particularly well, and a better solution to the column problem is being developed.
114
\end{document}
UNCOV
115
]]
×
116

UNCOV
117
return package
×
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