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

sile-typesetter / sile / 14908152066

08 May 2025 01:49PM UTC coverage: 61.309% (-5.7%) from 67.057%
14908152066

push

github

alerque
chore(registries): Touchup command registry deprecation shims

1 of 2 new or added lines in 2 files covered. (50.0%)

1379 existing lines in 46 files now uncovered.

13556 of 22111 relevant lines covered (61.31%)

11834.23 hits per line

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

92.37
/types/unit.lua
1
--- SILE unit type.
2
-- @types unit
3

4
local bits = require("core.parserbits")
42✔
5

6
local unittypes = {
42✔
7
   pt = {
42✔
8
      relative = false,
9
      value = 1,
10
   },
42✔
11
}
12

13
setmetatable(unittypes, {
84✔
14
   __newindex = function (self, unit, spec)
15
      local def = SU.required(spec, "definition", "registering unit " .. unit)
1,065✔
16
      local relative = SU.boolean(spec.relative, false)
1,065✔
17
      if type(def) == "string" then
1,065✔
18
         local input = pl.stringx.strip(def)
420✔
19
         local measurement_only_parser = bits.measurement * -1
420✔
20
         local parsed = measurement_only_parser:match(input)
420✔
21
         if not parsed then
420✔
22
            SU.error("Could not parse unit definition '" .. def .. "'")
×
23
         end
24
         if not self[parsed.unit] then
420✔
25
            SU.error("Unit " .. unit .. " defined in terms of unknown unit " .. parsed.unit)
×
26
         elseif self[parsed.unit].relative then
420✔
27
            rawset(self, unit, {
84✔
28
               relative = true,
29
               converter = function (value)
30
                  return value * self[parsed.unit].converter(parsed.amount)
16✔
31
               end,
32
            })
42✔
33
         else
34
            rawset(self, unit, {
756✔
35
               relative = false,
36
               value = parsed.amount * self[parsed.unit].value,
378✔
37
            })
38
         end
39
      elseif type(def) == "function" then
645✔
40
         rawset(self, unit, {
1,290✔
41
            relative = relative,
645✔
42
            converter = def,
645✔
43
         })
44
      end
45
   end,
46
})
47

48
unittypes["twip"] = {
42✔
49
   definition = "0.05pt",
50
}
42✔
51

52
unittypes["mm"] = {
42✔
53
   definition = "2.8346457pt",
54
}
42✔
55

56
unittypes["cm"] = {
42✔
57
   definition = "10mm",
58
}
42✔
59

60
unittypes["m"] = {
42✔
61
   definition = "100cm",
62
}
42✔
63

64
unittypes["hm"] = {
42✔
65
   definition = "0.01mm",
66
}
42✔
67

68
unittypes["in"] = {
42✔
69
   definition = "72pt",
70
}
42✔
71

72
unittypes["ft"] = {
42✔
73
   definition = "12in",
74
}
42✔
75

76
-- Picas are 1/6 inch, used in Docbook images
77
unittypes["pc"] = {
42✔
78
   definition = "0.166666667in",
79
}
42✔
80

81
-- Pixel, by convention 1px = 1/96in = 0.75pt
82
-- (CSS Values and Units Module Level 3, §5.2)
83
-- Used in MathML, etc.
84
unittypes["px"] = {
42✔
85
   definition = "0.75pt",
86
}
42✔
87

88
local checkPaperDefined = function ()
89
   if not SILE.documentState or not SILE.documentState.orgPaperSize then
709✔
90
      SU.error("A measurement tried to measure the paper size before the paper was defined", true)
×
91
   end
92
end
93

94
local checkFrameDefined = function ()
95
   if not SILE.typesetter.frame then
10✔
96
      SU.error("A measurement tried to measure the frame before the frame was defined", true)
×
97
   end
98
end
99

100
unittypes["%pw"] = {
42✔
101
   relative = true,
102
   definition = function (value)
103
      checkPaperDefined()
257✔
104
      return value / 100 * SILE.documentState.orgPaperSize[1]
257✔
105
   end,
106
}
42✔
107

108
unittypes["%ph"] = {
42✔
109
   relative = true,
110
   definition = function (value)
111
      checkPaperDefined()
448✔
112
      return value / 100 * SILE.documentState.orgPaperSize[2]
448✔
113
   end,
114
}
42✔
115

116
unittypes["%pmin"] = {
42✔
117
   relative = true,
118
   definition = function (value)
119
      checkPaperDefined()
2✔
120
      return value / 100 * SU.min(SILE.documentState.orgPaperSize[1], SILE.documentState.orgPaperSize[2])
4✔
121
   end,
122
}
42✔
123

124
unittypes["%pmax"] = {
42✔
125
   relative = true,
126
   definition = function (value)
127
      checkPaperDefined()
2✔
128
      return value / 100 * SU.max(SILE.documentState.orgPaperSize[1], SILE.documentState.orgPaperSize[2])
4✔
129
   end,
130
}
42✔
131

132
unittypes["%fw"] = {
42✔
133
   relative = true,
134
   definition = function (value)
135
      checkFrameDefined()
1✔
136
      return value / 100 * SILE.typesetter.frame:width():tonumber()
3✔
137
   end,
138
}
42✔
139

140
unittypes["%fh"] = {
42✔
141
   relative = true,
142
   definition = function (value)
143
      checkFrameDefined()
1✔
144
      return value / 100 * SILE.typesetter.frame:height():tonumber()
3✔
145
   end,
146
}
42✔
147

148
unittypes["%fmin"] = {
42✔
149
   relative = true,
150
   definition = function (value)
151
      checkFrameDefined()
2✔
152
      return value / 100 * SU.min(SILE.typesetter.frame:width():tonumber(), SILE.typesetter.frame:height():tonumber())
12✔
153
   end,
154
}
42✔
155

156
unittypes["%fmax"] = {
42✔
157
   relative = true,
158
   definition = function (value)
159
      checkFrameDefined()
2✔
160
      return value / 100 * SU.max(SILE.typesetter.frame:width():tonumber(), SILE.typesetter.frame:height():tonumber())
12✔
161
   end,
162
}
42✔
163

164
unittypes["%lw"] = {
42✔
165
   relative = true,
166
   definition = function (value)
167
      local lskip = SILE.settings:get("document.lskip")
8✔
168
      local rskip = SILE.settings:get("document.rskip")
8✔
169
      local left = lskip and lskip.width:tonumber() or 0
7✔
170
      local right = rskip and rskip.width:tonumber() or 0
7✔
171
      checkFrameDefined()
4✔
172
      return value / 100 * SILE.typesetter.frame:getLineWidth():tonumber() - left - right
12✔
173
   end,
174
}
42✔
175

176
unittypes["ps"] = {
42✔
177
   relative = true,
178
   definition = function (value)
179
      local ps = SILE.settings:get("document.parskip")
×
180
      ps = ps.height:tonumber() or 0
×
181
      return value * ps
×
182
   end,
183
}
42✔
184

185
unittypes["bs"] = {
42✔
186
   relative = true,
187
   definition = function (value)
188
      local bs = SILE.settings:get("document.baselineskip")
26✔
189
      bs = bs.height:tonumber() or 0
26✔
190
      return value * bs
13✔
191
   end,
192
}
42✔
193

194
unittypes["em"] = {
42✔
195
   relative = true,
196
   definition = function (value)
197
      return value * SILE.settings:get("font.size")
2,325✔
198
   end,
199
}
42✔
200

201
unittypes["ex"] = {
42✔
202
   relative = true,
203
   definition = function (value)
204
      return value * SILE.shaper:measureChar("x").height
3,656✔
205
   end,
206
}
42✔
207

208
unittypes["spc"] = {
42✔
209
   relative = true,
210
   definition = function (value)
211
      return value * SILE.shaper:measureChar(" ").width
20✔
212
   end,
213
}
42✔
214

215
unittypes["en"] = {
42✔
216
   relative = true,
217
   definition = "0.5em",
218
}
42✔
219

220
-- jlreq measures distances in units of 1em, but also assumes that an em is the
221
-- width of a full-width character. In SILE terms it isn't: measuring an "m" in
222
-- a 10pt Japanese font gets you 5 points. So we measure a full-width character
223
-- and use that as a unit. We call it zw following ptex (zenkaku width)
224
unittypes["zw"] = {
42✔
225
   relative = true,
226
   definition = function (v)
227
      local zenkakuchar = SILE.settings:get("document.zenkakuchar")
4✔
228
      local measurable, zenkaku, found = pcall(SILE.shaper.measureChar, SILE.shaper, zenkakuchar)
2✔
229
      if not found or not measurable then
2✔
UNCOV
230
         SU.warn(([[
×
231
            Zenkaku width (全角幅) unit zw is falling back to 1em == 1zw as we cannot measure %s
232

233
            Either change this char to one suitable for your language, or load a font that
234
            has it.
UNCOV
235
         ]]):format(zenkakuchar))
×
236
      end
237
      local width = found and measurable and zenkaku.width or SILE.settings:get("font.size")
2✔
238
      return v * width
2✔
239
   end,
240
}
42✔
241

242
return unittypes
42✔
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