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

sile-typesetter / sile / 11534409649

26 Oct 2024 07:27PM UTC coverage: 33.196% (-28.7%) from 61.897%
11534409649

push

github

alerque
chore(tooling): Update editor-config key for stylua as accepted upstream

Our setting addition is still not in a tagged release, but the PR was
accepted into the default branch of stylua. This means you no longer
need to run my fork of Stylua to get this project's style, you just nead
any build from the main development branch. However the config key was
renamed as part of the acceptance, so this is the relevant adjustment.

5810 of 17502 relevant lines covered (33.2%)

1300.57 hits per line

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

71.88
/core/tracestack.lua
1
-- Represents a stack of stack frame objects,
2
-- which describe the call-stack stack of the currently processed document.
3
-- Stack frames are stored contiguously, treating this object as an array.
4
-- Most recent and relevant stack frames are in higher indices, up to #traceStack.
5
-- Do not manipulate the stack directly, use provided push<Type> and pop methods.
6
-- There are different types of stack frames, see pushFrame for more details.
7
local traceStack = pl.class({
36✔
8
   -- Stores the frame which was last popped. Reset after a push.
9
   -- Helps to further specify current location in the processed document.
10
   afterFrame = nil,
11
})
12

13
traceStack.defaultFrame = pl.class({
36✔
14

15
   location = function (self, relative)
16
      local str = ""
5✔
17
      if self.file and not relative then
5✔
18
         str = str .. self.file .. ":"
5✔
19
      end
20
      if self.lno then
5✔
21
         str = str .. self.lno .. ":"
2✔
22
         if self.col then
2✔
23
            str = str .. self.col .. ":"
2✔
24
         end
25
      end
26
      str = str .. (str:len() > 0 and " " or "") .. "in "
10✔
27
      str = str .. tostring(self)
10✔
28
      return str
5✔
29
   end,
30

31
   __tostring = function (self)
32
      self.file = nil
×
33
      self.lno = nil
×
34
      self.col = nil
×
35
      return #self > 0 and tostring(self) or ""
×
36
   end,
37
})
18✔
38

39
traceStack.documentFrame = pl.class(traceStack.defaultFrame)
36✔
40

41
local function oneline (str)
42
   return str:gsub("\n", "␤")
3✔
43
      :gsub("\r", "␍")
3✔
44
      :gsub("\f", "␊")
3✔
45
      :gsub("\a", "␇")
3✔
46
      :gsub("\b", "␈")
3✔
47
      :gsub("\t", "␉")
3✔
48
      :gsub("\v", "␋")
3✔
49
end
50

51
function traceStack.documentFrame:_init (file, snippet)
36✔
52
   self.command = "document"
25✔
53
   self.file = file
25✔
54
   self.snippet = snippet
25✔
55
end
56

57
function traceStack.documentFrame:__tostring ()
36✔
58
   return "<snippet>:\n\t\t[[" .. oneline(self.snippet) .. "]]"
6✔
59
end
60

61
traceStack.commandFrame = pl.class(traceStack.defaultFrame)
35✔
62

63
function traceStack.commandFrame:_init (command, content, options)
34✔
64
   self.command = command
233✔
65
   self.file = content.file or SILE.currentlyProcessingFile
233✔
66
   self.lno = content.lno
233✔
67
   self.col = content.col
233✔
68
   self.options = options or {}
233✔
69
end
70

71
function traceStack.commandFrame:__tostring ()
34✔
72
   local opts = pl.tablex.size(self.options) == 0 and ""
4✔
73
      or pl.pretty.write(self.options, ""):gsub("^{", "["):gsub("}$", "]")
4✔
74
   return "\\" .. tostring(self.command) .. opts
2✔
75
end
76

77
traceStack.contentFrame = pl.class(traceStack.commandFrame)
34✔
78

79
function traceStack.contentFrame:_init (command, content)
34✔
80
   self:super(command, content, content.options)
×
81
end
82

83
traceStack.textFrame = pl.class(traceStack.defaultFrame)
34✔
84

85
function traceStack.textFrame:_init (text)
34✔
86
   self.text = text
63✔
87
end
88

89
function traceStack.textFrame:__tostring ()
34✔
90
   if self.text:len() > 20 then
×
91
      self.text = luautf8.sub(self.text, 1, 18) .. "…"
×
92
   end
93
   self.text = oneline(self.text)
×
94
   return '"' .. self.text .. '"'
×
95
end
96

97
local function formatTraceLine (string)
98
   local prefix = "\t"
1✔
99
   return prefix .. string .. "\n"
1✔
100
end
101

102
-- Push a document processing run (input method) onto the stack
103
function traceStack:pushDocument (file, doc)
17✔
104
   if type(doc) == "table" then
25✔
105
      doc = tostring(doc)
×
106
   end
107
   local snippet = doc:sub(1, 100)
25✔
108
   local frame = traceStack.documentFrame(file, snippet)
25✔
109
   return self:pushFrame(frame)
25✔
110
end
111

112
-- Push a command frame on to the stack to record the execution trace for debugging.
113
-- Carries information about the command call, not the command itself.
114
-- Must be popped with `pop(returnOfPush)`.
115
function traceStack:pushCommand (command, content, options)
17✔
116
   if not command then
233✔
117
      SU.warn("Command should be specified for SILE.traceStack:pushCommand", true)
×
118
   end
119
   if type(content) == "function" then
233✔
120
      content = {}
5✔
121
   end
122
   local frame = traceStack.commandFrame(command, content, options)
233✔
123
   return self:pushFrame(frame)
233✔
124
end
125

126
-- Push a command frame on to the stack to record the execution trace for debugging.
127
-- Command arguments are inferred from AST content, any item may be overridden.
128
-- Must be popped with `pop(returnOfPush)`.
129
function traceStack:pushContent (content, command)
17✔
130
   if type(content) ~= "table" then
×
131
      SU.warn("Content parameter of SILE.traceStack:pushContent must be a table", true)
×
132
   end
133
   command = command or content.command
×
134
   if not command then
×
135
      SU.warn("Command should be specified or inferable for SILE.traceStack:pushContent", true)
×
136
   end
137
   local frame = traceStack.contentFrame(command, content)
×
138
   return self:pushFrame(frame)
×
139
end
140

141
-- Push a text that is going to get typeset on to the stack to record the execution trace for debugging.
142
-- Must be popped with `pop(returnOfPush)`.
143
function traceStack:pushText (text)
17✔
144
   local frame = traceStack.textFrame(text)
63✔
145
   return self:pushFrame(frame)
63✔
146
end
147

148
-- Internal: Push-pop balance checking ID
149
local lastPushId = 0
17✔
150

151
-- Push complete frame onto the stack.
152
-- Frame is a table with following optional fields:
153
-- .file = string - name of the file from which this originates
154
-- .lno = number - line in the file
155
-- .col = number - column on the line
156
-- .toStringHelper = function() that serializes extended information about the frame BESIDES location
157
function traceStack:pushFrame (frame)
17✔
158
   SU.debug("traceStack", function ()
642✔
159
      return string.rep(".", #self) .. "PUSH(" .. frame:location() .. ")"
×
160
   end)
161
   self[#self + 1] = frame
321✔
162
   self.afterFrame = nil
321✔
163
   lastPushId = lastPushId + 1
321✔
164
   frame._pushId = lastPushId
321✔
165
   return lastPushId
321✔
166
end
167

168
-- Pop previously pushed command from the stack.
169
-- Return value of `push` function must be provided as argument to check for balanced usage.
170
function traceStack:pop (pushId)
17✔
171
   if type(pushId) ~= "number" then
321✔
172
      SU.error("SILE.traceStack:pop's argument must be the result value of the corresponding push", true)
×
173
   end
174
   -- First verify that push/pop is balanced
175
   local popped = self[#self]
321✔
176
   if popped._pushId ~= pushId then
321✔
177
      local message = "Unbalanced content push/pop"
×
178
      if SILE.traceback or SU.debugging("traceStack") then
×
179
         message = message .. ". Expected " .. popped.pushId .. " - (" .. popped:location() .. "), got " .. pushId
×
180
      end
181
      SU.warn(message, true)
×
182
   else
183
      -- Correctly balanced: pop the frame
184
      self.afterFrame = popped
321✔
185
      self[#self] = nil
321✔
186
      SU.debug("traceStack", function ()
642✔
187
         return string.rep(".", #self) .. "POP(" .. popped:location() .. ")"
×
188
      end)
189
   end
190
end
191

192
-- Returns single line string with location of top most trace frame
193
function traceStack:locationHead ()
17✔
194
   local afterFrame = self.afterFrame
5✔
195
   local top = self[#self]
5✔
196
   if not top then
5✔
197
      -- Stack is empty, there is not much we can do
198
      return formatTraceLine(
1✔
199
         afterFrame and "after " .. afterFrame:location() or SILE.currentlyProcessingFile or "<nowhere>"
2✔
200
      )
1✔
201
   end
202
   local trace = top:location()
4✔
203
   local locationFrame = top
4✔
204
   -- Not all stack traces have to carry location information.
205
   -- If the first stack trace does not carry it, find a frame which does.
206
   -- Then append it, because its information may be useful.
207
   if not locationFrame.lno then
4✔
208
      for i = #self - 1, 1, -1 do
4✔
209
         if self[i].lno then
2✔
210
            locationFrame = self[i]
×
211
            trace = trace .. " near " .. locationFrame:location(locationFrame.file == top.file)
×
212
            break
213
         end
214
      end
215
   end
216
   -- Print after, if it is in a relevant file
217
   if afterFrame and (not locationFrame or afterFrame.file == locationFrame.file) then
4✔
218
      trace = trace .. " after " .. afterFrame:location(true)
×
219
   end
220
   return trace
4✔
221
end
222

223
-- Returns multiline trace string with locations of each frame up to maxdepth
224
function traceStack:locationTrace (maxdepth)
17✔
225
   local depth = maxdepth or #self
×
226
   local trace = formatTraceLine(self:locationHead())
×
227
   depth = depth - 1
×
228
   if depth > 1 then
×
229
      repeat
230
         trace = trace .. formatTraceLine(self[depth]:location())
×
231
         depth = depth - 1
×
232
      until depth == 1 -- stop at 1 (document) as not useful in trace
×
233
   end
234
   return trace
×
235
end
236

237
return traceStack
17✔
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