• 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

88.66
/languages/unicode-nodemaker.lua
1
local base = require("languages.base-nodemaker")
42✔
2

3
local icu = require("justenoughicu")
42✔
4
local chardata = require("char-def")
42✔
5

6
local nodemaker = pl.class(base)
42✔
7
nodemaker._name = "unicode"
42✔
8

9
function nodemaker:_init (language, options)
42✔
10
   base._init(self, language, options)
1,937✔
11
   self.breakingTypes = { ba = true, zw = true }
1,937✔
12
   self.puctuationTypes = { po = true }
1,937✔
13
   self.quoteTypes = {} -- quote linebreak category is ambiguous depending on the language
1,937✔
14
   self.spaceTypes = { sp = true }
1,937✔
15
   self.wordTypes = { cm = true }
1,937✔
16
end
17

18
function nodemaker:dealWith (item)
42✔
19
   local char = item.text
9,323✔
20
   local cp = SU.codepoint(char)
9,323✔
21
   local thistype = chardata[cp] and chardata[cp].linebreak
9,323✔
22
   if self:isSpace(item.text) then
18,646✔
UNCOV
23
      self:makeToken()
×
UNCOV
24
      self:makeGlue(item)
×
25
   elseif self:isActiveNonBreakingSpace(item.text) then
18,646✔
26
      self:makeToken()
×
27
      self:makeNonBreakingSpace()
×
28
   elseif self:isBreaking(item.text) then
18,646✔
UNCOV
29
      self:addToken(char, item)
×
UNCOV
30
      self:makeToken()
×
UNCOV
31
      self:makePenalty(0)
×
32
   elseif self:isQuote(item.text) then
18,646✔
UNCOV
33
      self:addToken(char, item)
×
UNCOV
34
      self:makeToken()
×
35
   elseif self.lasttype and (thistype and thistype ~= self.lasttype and not self:isWord(thistype)) then
9,393✔
36
      self:addToken(char, item)
140✔
37
   else
38
      self:letterspace()
9,253✔
39
      self:addToken(char, item)
9,253✔
40
   end
41
   self.lasttype = thistype
9,323✔
42
end
43

44
function nodemaker:handleInitialGlue (items)
42✔
45
   local i = 1
1,937✔
46
   while i <= #items do
2,001✔
47
      local item = items[i]
1,989✔
48
      if self:isSpace(item.text) then
3,978✔
49
         self:makeGlue(item)
128✔
50
      else
51
         break
52
      end
53
      i = i + 1
64✔
54
   end
55
   return i, items
1,937✔
56
end
57

58
function nodemaker:letterspace ()
42✔
59
   if not self.language.settings:get("document.letterspaceglue") then
27,759✔
60
      return
9,237✔
61
   end
62
   if self.token then
16✔
63
      self:makeToken()
16✔
64
   end
65
   if self.lastnode and self.lastnode ~= "glue" then
16✔
66
      local w = self.language.settings:get("document.letterspaceglue").width
45✔
67
      SU.debug("tokenizer", "Letter space glue:", w)
15✔
68
      coroutine.yield(SILE.types.node.kern({ width = w }))
30✔
69
      self.lastnode = "glue"
15✔
70
      self.lasttype = "sp"
15✔
71
   end
72
end
73

74
function nodemaker.isICUBreakHere (_, chunks, item)
42✔
75
   return chunks[1] and (item.index >= chunks[1].index)
12,124✔
76
end
77

78
function nodemaker:handleICUBreak (chunks, item)
42✔
79
   -- The ICU library has told us there is a breakpoint at
80
   -- this index. We need to...
81
   local bp = chunks[1]
2,801✔
82
   -- ... remove this breakpoint (and any out of order ones)
83
   -- from the ICU breakpoints array so that chunks[1] is
84
   -- the next index point for comparison against the string...
85
   while chunks[1] and item.index >= chunks[1].index do
5,602✔
86
      table.remove(chunks, 1)
5,602✔
87
   end
88
   -- ...decide which kind of breakpoint we have here and
89
   -- handle it appropriately.
90
   if bp.type == "word" then
2,801✔
91
      self:handleWordBreak(item)
3,088✔
92
   elseif bp.type == "line" then
1,257✔
93
      self:handleLineBreak(item, bp.subtype)
1,257✔
94
   end
95
   return chunks
2,801✔
96
end
97

98
function nodemaker:handleWordBreak (item)
42✔
99
   self:makeToken()
1,544✔
100
   if self:isSpace(item.text) then
3,088✔
101
      -- Spacing word break
102
      self:makeGlue(item)
2,586✔
103
   elseif self:isActiveNonBreakingSpace(item.text) then
502✔
104
      -- Non-breaking space word break
105
      self:makeNonBreakingSpace()
14✔
106
   else
107
      -- a word break which isn't a space
108
      self:addToken(item.text, item)
244✔
109
   end
110
end
111

112
function nodemaker:handleLineBreak (item, subtype)
42✔
113
   -- Because we are in charge of paragraphing, we
114
   -- will override space-type line breaks, and treat
115
   -- them just as ordinary word spaces.
116
   if self:isSpace(item.text) or self:isActiveNonBreakingSpace(item.text) then
3,771✔
117
      self:handleWordBreak(item)
×
118
      return
×
119
   end
120
   -- But explicit line breaks we will turn into
121
   -- soft and hard breaks.
122
   self:makeToken()
1,257✔
123
   self:makePenalty(subtype == "soft" and 0 or -1000)
1,257✔
124
   local char = item.text
1,257✔
125
   self:addToken(char, item)
1,257✔
126
   local cp = SU.codepoint(char)
1,257✔
127
   self.lasttype = chardata[cp] and chardata[cp].linebreak
1,257✔
128
end
129

130
function nodemaker:iterator (items)
42✔
131
   local fulltext = ""
1,937✔
132
   for i = 1, #items do
14,125✔
133
      fulltext = fulltext .. items[i].text
12,188✔
134
   end
135
   local chunks = { icu.breakpoints(fulltext, self.options.language) }
1,937✔
136
   table.remove(chunks, 1)
1,937✔
137
   return coroutine.wrap(function ()
1,937✔
138
      local i
139
      i, self.items = self:handleInitialGlue(items)
3,874✔
140
      for j = i, #items do
14,061✔
141
         self.i = j
12,124✔
142
         self.item = self.items[self.i]
12,124✔
143
         if self:isICUBreakHere(chunks, self.item) then
24,248✔
144
            chunks = self:handleICUBreak(chunks, self.item)
5,602✔
145
         else
146
            self:dealWith(self.item)
9,323✔
147
         end
148
      end
149
      self:makeToken()
1,937✔
150
   end)
151
end
152

153
return nodemaker
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

© 2026 Coveralls, Inc