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

sile-typesetter / sile / 14510870853

17 Apr 2025 07:55AM UTC coverage: 31.472% (-25.8%) from 57.267%
14510870853

push

github

web-flow
Merge pull request #2267 from Omikhleia/feat-csl-position

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

4871 existing lines in 34 files now uncovered.

6341 of 20148 relevant lines covered (31.47%)

2774.57 hits per line

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

86.61
/types/length.lua
1
--- SILE length type.
2
-- Lengths are composed of 3 `measurement`s: a length, a stretch, and a shrink. Each part internally is just
3
-- a measurement, but combined describe a flexible length that is allowed to grow up to the amount defined by stretch or
4
-- compress up to the amount defined by shrink.
5
-- @types length
6

7
local function _error_if_not_number (a)
8
   if type(a) ~= "number" then
8✔
9
      SU.error("We tried to do impossible arithmetic on a " .. SU.type(a) .. ". (That's a bug)", true)
×
10
   end
11
end
12

13
--- @type length
14
local length = pl.class()
20✔
15
length.type = "length"
20✔
16

17
length.length = nil
20✔
18
length.stretch = nil
20✔
19
length.shrink = nil
20✔
20

21
--- Constructor.
22
-- @tparam measurement spec A measurement or value that can be cast to a measurement.
23
-- @tparam[opt=0] measurement stretch A measurement describing how much the length is allowed to grow.
24
-- @tparam[opt=0] measurement shrink A measurement describing how much the length is allowed to grow.
25
-- @treturn length
26
-- @usage
27
-- SILE.types.length("6em", "4pt", "2pt")
28
-- SILE.types.length("6em plus 4pt minus 2pt")
29
-- SILE.types.length(30, 4, 2)
30
function length:_init (spec, stretch, shrink)
20✔
31
   if stretch or shrink then
30,663✔
32
      self.length = SILE.types.measurement(spec or 0)
10,464✔
33
      self.stretch = SILE.types.measurement(stretch or 0)
10,464✔
34
      self.shrink = SILE.types.measurement(shrink or 0)
10,464✔
35
   elseif type(spec) == "number" then
25,431✔
36
      self.length = SILE.types.measurement(spec)
18,080✔
37
   elseif SU.type(spec) == "measurement" then
32,782✔
38
      self.length = spec
353✔
39
   elseif SU.type(spec) == "glue" then
32,076✔
40
      self.length = SILE.types.measurement(spec.width.length or 0)
4✔
41
      self.stretch = SILE.types.measurement(spec.width.stretch or 0)
4✔
42
      self.shrink = SILE.types.measurement(spec.width.shrink or 0)
4✔
43
   elseif type(spec) == "table" then
16,036✔
44
      self.length = SILE.types.measurement(spec.length or 0)
9,560✔
45
      self.stretch = SILE.types.measurement(spec.stretch or 0)
9,560✔
46
      self.shrink = SILE.types.measurement(spec.shrink or 0)
9,560✔
47
   elseif type(spec) == "string" then
11,256✔
48
      local amount = tonumber(spec)
219✔
49
      if type(amount) == "number" then
219✔
50
         self:_init(amount)
4✔
51
      else
52
         local input = pl.stringx.strip(spec)
217✔
53
         local length_only_parser = SILE.parserBits.length * -1
217✔
54
         local parsed = length_only_parser:match(input)
217✔
55
         if not parsed then
217✔
56
            SU.error("Could not parse length '" .. spec .. "'")
×
57
         end
58
         self:_init(parsed)
217✔
59
      end
60
   end
61
   if not self.length then
30,663✔
62
      self.length = SILE.types.measurement()
22,074✔
63
   end
64
   if not self.stretch then
30,663✔
65
      self.stretch = SILE.types.measurement()
40,860✔
66
   end
67
   if not self.shrink then
30,663✔
68
      self.shrink = SILE.types.measurement()
40,860✔
69
   end
70
end
71

72
function length:absolute ()
20✔
73
   return SILE.types.length(self.length:tonumber(), self.stretch:tonumber(), self.shrink:tonumber())
11,512✔
74
end
75

76
function length:negate ()
20✔
77
   return self:__unm()
×
78
end
79

80
function length:tostring ()
20✔
81
   return self:__tostring()
×
82
end
83

84
function length:tonumber ()
20✔
85
   return self.length:tonumber()
25,594✔
86
end
87

88
function length:__tostring ()
20✔
89
   local str = tostring(self.length)
2✔
90
   if self.stretch.amount ~= 0 then
2✔
91
      str = str .. " plus " .. tostring(self.stretch)
2✔
92
   end
93
   if self.shrink.amount ~= 0 then
2✔
94
      str = str .. " minus " .. tostring(self.shrink)
×
95
   end
96
   return str
2✔
97
end
98

99
function length:__add (other)
20✔
100
   if type(self) == "number" then
1,804✔
101
      self, other = other, self
1,397✔
102
   end
103
   other = SU.cast("length", other)
3,608✔
104
   return SILE.types.length(self.length + other.length, self.stretch + other.stretch, self.shrink + other.shrink)
7,216✔
105
end
106

107
-- See usage comments on SILE.types.measurement:___add()
108
function length:___add (other)
20✔
109
   if SU.type(other) ~= "length" then
22,186✔
110
      self.length:___add(other)
920✔
111
   else
112
      self.length:___add(other.length)
10,633✔
113
      self.stretch:___add(other.stretch)
10,633✔
114
      self.shrink:___add(other.shrink)
10,633✔
115
   end
116
   return nil
11,093✔
117
end
118

119
function length:__sub (other)
20✔
120
   local result = SILE.types.length(self)
2,701✔
121
   other = SU.cast("length", other)
5,402✔
122
   result.length = result.length - other.length
5,402✔
123
   result.stretch = result.stretch - other.stretch
5,402✔
124
   result.shrink = result.shrink - other.shrink
5,402✔
125
   return result
2,701✔
126
end
127

128
-- See usage comments on SILE.types.measurement:___add()
129
function length:___sub (other)
20✔
130
   self.length:___sub(other.length)
763✔
131
   self.stretch:___sub(other.stretch)
763✔
132
   self.shrink:___sub(other.shrink)
763✔
133
   return nil
763✔
134
end
135

136
function length:__mul (other)
20✔
137
   if type(self) == "number" then
8✔
UNCOV
138
      self, other = other, self
×
139
   end
140
   _error_if_not_number(other)
8✔
141
   local result = SILE.types.length(self)
8✔
142
   result.length = result.length * other
16✔
143
   result.stretch = result.stretch * other
16✔
144
   result.shrink = result.shrink * other
16✔
145
   return result
8✔
146
end
147

148
function length:__div (other)
20✔
UNCOV
149
   local result = SILE.types.length(self)
×
UNCOV
150
   _error_if_not_number(other)
×
UNCOV
151
   result.length = result.length / other
×
UNCOV
152
   result.stretch = result.stretch / other
×
UNCOV
153
   result.shrink = result.shrink / other
×
UNCOV
154
   return result
×
155
end
156

157
function length:__unm ()
20✔
158
   local result = SILE.types.length(self)
4✔
159
   result.length = result.length:__unm()
8✔
160
   return result
4✔
161
end
162

163
function length:__lt (other)
20✔
164
   local a = SU.cast("number", self)
7,573✔
165
   local b = SU.cast("number", other)
7,573✔
166
   return a - b < 0
7,573✔
167
end
168

169
function length:__le (other)
20✔
170
   local a = SU.cast("number", self)
3✔
171
   local b = SU.cast("number", other)
3✔
172
   return a - b <= 0
3✔
173
end
174

175
function length:__eq (other)
20✔
176
   local a = SU.cast("length", self)
×
177
   local b = SU.cast("length", other)
×
178
   return a.length == b.length and a.stretch == b.stretch and a.shrink == b.shrink
×
179
end
180

181
return length
20✔
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