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

sile-typesetter / sile / 6713098919

31 Oct 2023 10:21PM UTC coverage: 52.831% (-21.8%) from 74.636%
6713098919

push

github

web-flow
Merge d0a2a1ee9 into b185d4972

45 of 45 new or added lines in 3 files covered. (100.0%)

8173 of 15470 relevant lines covered (52.83%)

6562.28 hits per line

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

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

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

6
local BALANCE_PENALTY = -17777
×
7

8
local unbalanced_buildPage
9

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

14
  local colCount = 0
×
15
  local target = SILE.length()
×
16
  while frame and frame.balanced == true do
×
17
    target = target + frame:height()
×
18
    colCount = colCount + 1
×
19
    if frame.next then frame = SILE.getFrame(frame.next) else break end
×
20
  end
21

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

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

75
function package:_init (class)
×
76
  base._init(self, class)
×
77
  self.class:registerPostinit(function(_)
×
78
    if not unbalanced_buildPage then
×
79
      unbalanced_buildPage = SILE.typesetter.buildPage
×
80
      SILE.typesetter.buildPage = buildPage
×
81
      SILE.typesetters.base.buildPage = buildPage
×
82
    end
83
  end)
84
end
85

86
function package:registerCommands ()
×
87

88
  self:registerCommand("balancecolumns", function (_, _)
×
89
    SILE.typesetter:leaveHmode()
×
90
    SILE.call("penalty", { penalty = BALANCE_PENALTY })
×
91
  end)
92

93
end
94

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

101
The current algorithm does not work particularly well, and a better solution to the column problem is being developed.
102
\end{document}
103
]]
×
104

105
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