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

sile-typesetter / sile / 11135083927

01 Oct 2024 11:26PM UTC coverage: 62.071% (-7.3%) from 69.333%
11135083927

push

github

alerque
style: Reformat Lua with stylua

0 of 9 new or added lines in 2 files covered. (0.0%)

1678 existing lines in 57 files now uncovered.

11071 of 17836 relevant lines covered (62.07%)

5220.48 hits per line

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

93.27
/packages/parallel/init.lua
1
local base = require("packages.base")
1✔
2

3
local package = pl.class(base)
1✔
4
package._name = "parallel"
1✔
5

6
local typesetterPool = {}
1✔
7
local calculations = {}
1✔
8
local folioOrder = {}
1✔
9

10
local allTypesetters = function (callback)
11
   local oldtypesetter = SILE.typesetter
8✔
12
   for frame, typesetter in pairs(typesetterPool) do
24✔
13
      SILE.typesetter = typesetter
16✔
14
      callback(frame, typesetter)
16✔
15
   end
16
   SILE.typesetter = oldtypesetter
8✔
17
end
18

19
local nulTypesetter = pl.class(SILE.typesetters.base) -- we ignore this
1✔
20
nulTypesetter.outputLinesToPage = function () end
1✔
21

22
local parallelPagebreak = function ()
23
   for i = 1, #folioOrder do
2✔
24
      local thisPageFrames = folioOrder[i]
1✔
25
      for j = 1, #thisPageFrames do
3✔
26
         local frame = thisPageFrames[j]
2✔
27
         local typesetter = typesetterPool[frame]
2✔
28
         local thispage = {}
2✔
29
         SU.debug("parallel", "Dumping lines for page on typesetter", typesetter.id)
2✔
30
         if #typesetter.state.outputQueue > 0 and calculations[frame].mark == 0 then
2✔
31
            -- More than one page worth of stuff here.
32
            -- Just ship out one page and hope for the best.
33
            SILE.typesetters.base.buildPage(typesetter)
×
34
         else
35
            for l = 1, calculations[frame].mark do
7✔
36
               thispage[l] = table.remove(typesetter.state.outputQueue, 1)
10✔
37
               SU.debug("parallel", thispage[l])
5✔
38
            end
39
            typesetter:outputLinesToPage(thispage)
2✔
40
         end
41
      end
42
      SILE.documentState.documentClass:endPage()
1✔
43
      for l = 1, #thisPageFrames do
3✔
44
         local frame = thisPageFrames[l]
2✔
45
         local typesetter = typesetterPool[frame]
2✔
46
         typesetter:initFrame(typesetter.frame)
2✔
47
      end
48
      SILE.documentState.documentClass:newPage()
1✔
49
   end
50
end
51

52
local addBalancingGlue = function (height)
53
   allTypesetters(function (frame, typesetter)
4✔
54
      local glue = height - calculations[frame].heightOfNewMaterial
4✔
55
      if glue.length:tonumber() > 0 then
8✔
56
         SU.debug("parallel", "Adding", glue, "to", frame)
1✔
57
         typesetter:pushVglue({ height = glue })
1✔
58
      end
59
      calculations[frame].mark = #typesetter.state.outputQueue
4✔
60
   end)
61
end
62

63
function package:_init (options)
1✔
64
   base._init(self, options)
1✔
65
   SILE.typesetter = nulTypesetter(SILE.getFrame("page"))
3✔
66
   if type(options.frames) ~= "table" then
1✔
67
      SU.error([[
×
68
         Package parallel must be initialized with a set of appropriately named frames
69

70
         This package is usually intended to be loaded from some supporting class or
71
         from another package, responsible for correct initialization.
UNCOV
72
      ]])
×
73
   end
74
   for frame, typesetter in pairs(options.frames) do
3✔
75
      typesetterPool[frame] = SILE.typesetters.base(SILE.getFrame(typesetter))
6✔
76
      typesetterPool[frame].id = typesetter
2✔
77
      typesetterPool[frame].buildPage = function ()
2✔
78
         -- No thank you, I will do that.
79
      end
80
      -- Fixed leading here is obviously a bug, but n-way leading calculations
81
      -- get very complicated...
82
      -- typesetterPool[frame].leadingFor = function() return SILE.types.node.vglue(SILE.settings:get("document.lineskip")) end
83
      local fontcommand = frame .. ":font"
2✔
84
      self:registerCommand(frame, function (_, _) -- \left ...
4✔
85
         SILE.typesetter = typesetterPool[frame]
2✔
86
         SILE.call(fontcommand)
2✔
87
      end)
88
      if not SILE.Commands[fontcommand] then
2✔
89
         self:registerCommand(fontcommand, function (_, _) end) -- to be overridden
4✔
90
      end
91
   end
92
   if not options.folios then
1✔
93
      folioOrder = { {} }
1✔
94
      -- Note output order doesn't matter for PDF, but for our test suite it is
95
      -- essential that the output order is deterministic, hence this sort()
96
      for frame, _ in pl.tablex.sort(options.frames) do
7✔
97
         table.insert(folioOrder[1], frame)
2✔
98
      end
99
   else
UNCOV
100
      folioOrder = options.folios -- As usual we trust the user knows what they're doing
×
101
   end
102
   self.class.newPage = function (self_)
1✔
103
      allTypesetters(function (frame, _)
2✔
104
         calculations[frame] = { mark = 0 }
2✔
105
      end)
106
      self.class._base.newPage(self_)
1✔
107
      SILE.call("sync")
1✔
108
   end
109
   allTypesetters(function (frame, _)
2✔
110
      calculations[frame] = { mark = 0 }
2✔
111
   end)
112
   local oldfinish = self.class.finish
1✔
113
   self.class.finish = function (self_)
1✔
114
      parallelPagebreak()
1✔
115
      oldfinish(self_)
1✔
116
   end
117
end
118

119
function package:registerCommands ()
1✔
120
   self:registerCommand("sync", function (_, _)
2✔
121
      local anybreak = false
2✔
122
      local maxheight = SILE.types.length()
2✔
123
      SU.debug("parallel", "Trying a sync")
2✔
124
      allTypesetters(function (_, typesetter)
4✔
125
         SU.debug("parallel", "Leaving hmode on", typesetter.id)
4✔
126
         typesetter:leaveHmode(true)
4✔
127
         -- Now we have each typesetter's content boxed up onto the output stream
128
         -- but page breaking has not been run. See if page breaking would cause a
129
         -- break
130
         local lines = pl.tablex.copy(typesetter.state.outputQueue)
4✔
131
         if SILE.pagebuilder:findBestBreak({ vboxlist = lines, target = typesetter:getTargetLength() }) then
12✔
UNCOV
132
            anybreak = true
×
133
         end
134
      end)
135

136
      if anybreak then
2✔
UNCOV
137
         parallelPagebreak()
×
UNCOV
138
         return
×
139
      end
140

141
      allTypesetters(function (frame, typesetter)
4✔
142
         calculations[frame].heightOfNewMaterial = SILE.types.length()
8✔
143
         for i = calculations[frame].mark + 1, #typesetter.state.outputQueue do
8✔
144
            local thisHeight = typesetter.state.outputQueue[i].height + typesetter.state.outputQueue[i].depth
4✔
145
            calculations[frame].heightOfNewMaterial = calculations[frame].heightOfNewMaterial + thisHeight
8✔
146
         end
147
         if maxheight < calculations[frame].heightOfNewMaterial then
4✔
148
            maxheight = calculations[frame].heightOfNewMaterial
2✔
149
         end
150
         SU.debug(
8✔
151
            "parallel",
4✔
152
            frame,
4✔
153
            ": pre-sync content=",
4✔
154
            calculations[frame].mark,
4✔
155
            ", now",
4✔
156
            #typesetter.state.outputQueue,
4✔
157
            ", height of material:",
4✔
158
            calculations[frame].heightOfNewMaterial
4✔
159
         )
4✔
160
      end)
161
      addBalancingGlue(maxheight)
2✔
162
   end)
163
end
164

165
package.documentation = [[
166
\begin{document}
167
The \autodoc:package{parallel} package provides the mechanism for typesetting diglot or other parallel documents.
168
When used by a class such as \code{classes/diglot.lua}, it registers a command for each parallel frame, to allow you to select which frame you’re typesetting into.
169
It also defines the \autodoc:command{\sync} command, which adds vertical spacing to each frame such that the \em{next} set of text is vertically aligned.
170
See \url{https://sile-typesetter.org/examples/parallel.sil} and the source of \code{classes/diglot.lua} for examples which make the operation clear.
171
\end{document}
172
]]
1✔
173

174
return package
1✔
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