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

sile-typesetter / sile / 9428907827

08 Jun 2024 12:56PM UTC coverage: 57.223% (-11.0%) from 68.206%
9428907827

push

github

alerque
chore(release): 0.15.1

9741 of 17023 relevant lines covered (57.22%)

4415.41 hits per line

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

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

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

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

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

46
unittypes["twip"] = {
39✔
47
   definition = "0.05pt",
48
}
39✔
49

50
unittypes["mm"] = {
39✔
51
   definition = "2.8346457pt",
52
}
39✔
53

54
unittypes["cm"] = {
39✔
55
   definition = "10mm",
56
}
39✔
57

58
unittypes["m"] = {
39✔
59
   definition = "100cm",
60
}
39✔
61

62
unittypes["hm"] = {
39✔
63
   definition = "0.01mm",
64
}
39✔
65

66
unittypes["in"] = {
39✔
67
   definition = "72pt",
68
}
39✔
69

70
unittypes["ft"] = {
39✔
71
   definition = "12in",
72
}
39✔
73

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

79
local checkPaperDefined = function ()
80
   if not SILE.documentState or not SILE.documentState.orgPaperSize then
443✔
81
      SU.error("A measurement tried to measure the paper size before the paper was defined", true)
×
82
   end
83
end
84

85
local checkFrameDefined = function ()
86
   if not SILE.typesetter.frame then
×
87
      SU.error("A measurement tried to measure the frame before the frame was defined", true)
×
88
   end
89
end
90

91
unittypes["%pw"] = {
39✔
92
   relative = true,
93
   definition = function (value)
94
      checkPaperDefined()
149✔
95
      return value / 100 * SILE.documentState.orgPaperSize[1]
149✔
96
   end,
97
}
39✔
98

99
unittypes["%ph"] = {
39✔
100
   relative = true,
101
   definition = function (value)
102
      checkPaperDefined()
294✔
103
      return value / 100 * SILE.documentState.orgPaperSize[2]
294✔
104
   end,
105
}
39✔
106

107
unittypes["%pmin"] = {
39✔
108
   relative = true,
109
   definition = function (value)
110
      checkPaperDefined()
×
111
      return value / 100 * SU.min(SILE.documentState.orgPaperSize[1], SILE.documentState.orgPaperSize[2])
×
112
   end,
113
}
39✔
114

115
unittypes["%pmax"] = {
39✔
116
   relative = true,
117
   definition = function (value)
118
      checkPaperDefined()
×
119
      return value / 100 * SU.max(SILE.documentState.orgPaperSize[1], SILE.documentState.orgPaperSize[2])
×
120
   end,
121
}
39✔
122

123
unittypes["%fw"] = {
39✔
124
   relative = true,
125
   definition = function (value)
126
      checkFrameDefined()
×
127
      return value / 100 * SILE.typesetter.frame:width():tonumber()
×
128
   end,
129
}
39✔
130

131
unittypes["%fh"] = {
39✔
132
   relative = true,
133
   definition = function (value)
134
      checkFrameDefined()
×
135
      return value / 100 * SILE.typesetter.frame:height():tonumber()
×
136
   end,
137
}
39✔
138

139
unittypes["%fmin"] = {
39✔
140
   relative = true,
141
   definition = function (value)
142
      checkFrameDefined()
×
143
      return value / 100 * SU.min(SILE.typesetter.frame:width():tonumber(), SILE.typesetter.frame:height():tonumber())
×
144
   end,
145
}
39✔
146

147
unittypes["%fmax"] = {
39✔
148
   relative = true,
149
   definition = function (value)
150
      checkFrameDefined()
×
151
      return value / 100 * SU.max(SILE.typesetter.frame:width():tonumber(), SILE.typesetter.frame:height():tonumber())
×
152
   end,
153
}
39✔
154

155
unittypes["%lw"] = {
39✔
156
   relative = true,
157
   definition = function (value)
158
      local lskip = SILE.settings:get("document.lskip")
×
159
      local rskip = SILE.settings:get("document.rskip")
×
160
      local left = lskip and lskip.width:tonumber() or 0
×
161
      local right = rskip and rskip.width:tonumber() or 0
×
162
      checkFrameDefined()
×
163
      return value / 100 * SILE.typesetter.frame:getLineWidth():tonumber() - left - right
×
164
   end,
165
}
39✔
166

167
unittypes["ps"] = {
39✔
168
   relative = true,
169
   definition = function (value)
170
      local ps = SILE.settings:get("document.parskip")
×
171
      ps = ps.height:tonumber() or 0
×
172
      return value * ps
×
173
   end,
174
}
39✔
175

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

185
unittypes["em"] = {
39✔
186
   relative = true,
187
   definition = function (value)
188
      return value * SILE.settings:get("font.size")
382✔
189
   end,
190
}
39✔
191

192
unittypes["ex"] = {
39✔
193
   relative = true,
194
   definition = function (value)
195
      return value * SILE.shaper:measureChar("x").height
1,228✔
196
   end,
197
}
39✔
198

199
unittypes["spc"] = {
39✔
200
   relative = true,
201
   definition = function (value)
202
      return value * SILE.shaper:measureChar(" ").width
4✔
203
   end,
204
}
39✔
205

206
unittypes["en"] = {
39✔
207
   relative = true,
208
   definition = "0.5em",
209
}
39✔
210

211
-- jlreq measures distances in units of 1em, but also assumes that an em is the
212
-- width of a full-width character. In SILE terms it isn't: measuring an "m" in
213
-- a 10pt Japanese font gets you 5 points. So we measure a full-width character
214
-- and use that as a unit. We call it zw following ptex (zenkaku width)
215
unittypes["zw"] = {
39✔
216
   relative = true,
217
   definition = function (v)
218
      local zenkakuchar = SILE.settings:get("document.zenkakuchar")
1✔
219
      local measureable, zenkaku = pcall(SILE.shaper.measureChar, SILE.shaper, zenkakuchar)
1✔
220
      if not measureable then
1✔
221
         SU.warn(string.format(
×
222
            [[Zenkaku width (全角幅) unit zw is falling back to 1em == 1zw as we
×
223
  cannot measure %s. Either change this char to one suitable for your
224
  language, or load a font that has it.]],
225
            zenkakuchar
226
         ))
227
      end
228
      local width = measureable and zenkaku.width or SILE.settings:get("font.size")
1✔
229
      return v * width
1✔
230
   end,
231
}
39✔
232

233
return unittypes
39✔
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