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

sile-typesetter / sile / 9507147410

13 Jun 2024 09:40PM UTC coverage: 50.521% (-18.7%) from 69.177%
9507147410

push

github

web-flow
Merge pull request #2062 from alerque/plug-fluent-leak

Link document.language setting more closely with Fluent locale

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

3244 existing lines in 65 files now uncovered.

8586 of 16995 relevant lines covered (50.52%)

4659.09 hits per line

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

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

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

UNCOV
6
local _odd = true
×
7

8
local mirrorMaster = function (_, existing, new)
9
   -- Frames in one master can't "see" frames in another, so we have to get creative
10
   -- XXX This knows altogether too much about the implementation of masters
UNCOV
11
   if not SILE.scratch.masters[new] then
×
UNCOV
12
      SILE.scratch.masters[new] = { frames = {} }
×
13
   end
UNCOV
14
   if not SILE.scratch.masters[existing] then
×
15
      SU.error("Can't find master " .. existing)
×
16
   end
UNCOV
17
   for name, frame in pairs(SILE.scratch.masters[existing].frames) do
×
UNCOV
18
      local newframe = pl.tablex.deepcopy(frame)
×
UNCOV
19
      if frame:isAbsoluteConstraint("right") then
×
UNCOV
20
         newframe.constraints.left = "100%pw-(" .. frame.constraints.right .. ")"
×
21
      end
UNCOV
22
      if frame:isAbsoluteConstraint("left") then
×
UNCOV
23
         newframe.constraints.right = "100%pw-(" .. frame.constraints.left .. ")"
×
24
      end
UNCOV
25
      SILE.scratch.masters[new].frames[name] = newframe
×
UNCOV
26
      if frame == SILE.scratch.masters[existing].firstContentFrame then
×
UNCOV
27
         SILE.scratch.masters[new].firstContentFrame = newframe
×
28
      end
29
   end
30
end
31

UNCOV
32
function package.oddPage (_)
×
UNCOV
33
   return _odd
×
34
end
35

36
local function switchPage (class)
UNCOV
37
   _odd = not class:oddPage()
×
UNCOV
38
   local nextmaster = _odd and class.oddPageMaster or class.evenPageMaster
×
UNCOV
39
   class:switchMaster(nextmaster)
×
40
end
41

42
local _deprecate = [[
43
  Directly calling master switch handling functions is no longer necessary. All
44
  the SILE core classes and anything inheriting from them will take care of this
45
  automatically using hooks. Custom classes that override the class:newPage()
46
  function may need to handle this in other ways. By calling this hook directly
47
  you are likely causing it to run twice and duplicate entries.
UNCOV
48
]]
×
49

UNCOV
50
local spread_counter = 0
×
51
local spreadHook = function ()
UNCOV
52
   spread_counter = spread_counter + 1
×
53
end
54

UNCOV
55
function package:_init (options)
×
UNCOV
56
   base._init(self)
×
UNCOV
57
   if not SILE.scratch.masters then
×
58
      SU.error("Cannot load twoside package before masters.")
×
59
   end
UNCOV
60
   self:export("oddPage", self.oddPage)
×
UNCOV
61
   self:export("mirrorMaster", mirrorMaster)
×
UNCOV
62
   self:export("switchPage", function ()
×
63
      SU.deprecated("class:switchPage", nil, "0.13.0", "0.15.0", _deprecate)
×
64
   end)
UNCOV
65
   self.class.oddPageMaster = options.oddPageMaster
×
UNCOV
66
   self.class.evenPageMaster = options.evenPageMaster
×
UNCOV
67
   self.class:registerPostinit(function (class)
×
68
      -- TODO: Refactor this to make mirroring a separate package / option
UNCOV
69
      if not SILE.scratch.masters[options.evenPageMaster] then
×
UNCOV
70
         class:mirrorMaster(options.oddPageMaster, options.evenPageMaster)
×
71
      end
72
   end)
UNCOV
73
   self.class:registerHook("newpage", spreadHook)
×
UNCOV
74
   self.class:registerHook("newpage", switchPage)
×
75
end
76

UNCOV
77
function package:registerCommands ()
×
UNCOV
78
   self:registerCommand("open-double-page", function ()
×
UNCOV
79
      SILE.call("open-spread", { double = false, odd = true, blank = false })
×
80
   end)
81

UNCOV
82
   self:registerCommand("open-spread-eject", function ()
×
UNCOV
83
      SILE.call("supereject")
×
84
   end)
85

86
   -- This is upstreamed from CaSILE. Similar to the original open-double-page,
87
   -- but can disable headers and folios on blank pages and allows opening the
88
   -- even side (with or without a leading blank).
UNCOV
89
   self:registerCommand("open-spread", function (options)
×
UNCOV
90
      local odd = SU.boolean(options.odd, true)
×
UNCOV
91
      local double = SU.boolean(options.double, true)
×
UNCOV
92
      local blank = SU.boolean(options.blank, true)
×
93
      local optionsMet = function ()
UNCOV
94
         return (not double or spread_counter > 1) and (odd == self.class:oddPage())
×
95
      end
UNCOV
96
      spread_counter = 0
×
UNCOV
97
      SILE.typesetter:leaveHmode()
×
98
      -- Output a box, then remove it and see where we are. Without adding
99
      -- content we can't prove on which page we would land because the page
100
      -- breaker *might* be stuffed almost full but still sitting on the last
101
      -- line happy to *maybe* accept more letter (but not a line). If this check
102
      -- gets us to the desired page nuke the vertical space so we don't leak it
103
      -- into the final content, otherwise just leave it be since we want to be
104
      -- forced to the next page anyway.
UNCOV
105
      SILE.call("hbox")
×
UNCOV
106
      SILE.typesetter:leaveHmode()
×
UNCOV
107
      table.remove(SILE.typesetter.state.nodes)
×
UNCOV
108
      if spread_counter == 1 and optionsMet() then
×
UNCOV
109
         SILE.typesetter.state.outputQueue = {}
×
UNCOV
110
         return
×
111
      end
UNCOV
112
      local startedattop = #SILE.typesetter.state.outputQueue == 2 and #SILE.typesetter.state.nodes == 0
×
UNCOV
113
      local spread_counter_at_start = spread_counter
×
114
      repeat
UNCOV
115
         if spread_counter > 0 then
×
UNCOV
116
            SILE.call("hbox")
×
UNCOV
117
            SILE.typesetter:leaveHmode()
×
118
            -- Note: before you think you can simplify this, make sure all the
119
            -- pages before chapter starts in the manual have headers if they have
120
            -- content and not if empty. Combined with the workaround for just
121
            -- barely full pages above it's tricky to get right.
UNCOV
122
            if blank and not (spread_counter == spread_counter_at_start and not startedattop) then
×
UNCOV
123
               SILE.scratch.headers.skipthispage = true
×
UNCOV
124
               SILE.call("nofoliothispage")
×
125
            end
126
         end
UNCOV
127
         SILE.call("open-spread-eject")
×
UNCOV
128
         SILE.typesetter:leaveHmode()
×
UNCOV
129
      until optionsMet()
×
130
   end)
131
end
132

133
package.documentation = [[
134
\begin{document}
135
A book-like class usually sets up left and right mirrored page masters.
136
The \autodoc:package{twoside} package is then responsible for swapping between the two left and right frames, running headers, and so on.
137
As it is normally loaded and initialized by a document class, its main function in mirroring master frames does not provide any user-serviceable parts.
138
It does supply a few user-facing commands for convenience.
139

140
The \autodoc:command{\open-double-page} ejects whatever page is currently being processed, then checks if it landed on an even page.
141
If so, it ejects another page to assure content starts on an odd page.
142

143
The \autodoc:command{\open-spread} is similar but a bit more tailored to use in book layouts.
144
By default, headers and folios will be suppressed automatically on any empty pages ejected, making them blank.
145
It can also accept three parameters.
146
The \autodoc:parameter{odd} parameter (default \code{true}) can be used to disable the opening page being odd, hence opening an even page spread.
147
The \autodoc:parameter{double} parameter (default \code{true}) can be used to always output at least one empty even page before the starting an odd page.
148
The \autodoc:parameter{blank} parameter (default \code{true}) can be used to not suppress headers and folios on otherwise empty pages.
149

150
Lastly the \autodoc:command{\open-spread-eject} command can be overridden to customize the output of blank pages.
151
By default it just runs \autodoc:command{\supereject}, but you could potentially add decorative content or other features in the otherwise empty space.
152
\end{document}
UNCOV
153
]]
×
154

UNCOV
155
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

© 2026 Coveralls, Inc