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

sile-typesetter / sile / 8288578143

14 Mar 2024 09:39PM UTC coverage: 64.155% (-10.6%) from 74.718%
8288578143

Pull #1904

github

alerque
chore(core): Fixup ec6ed657 which didn't shim old pack styles properly
Pull Request #1904: Merge develop into master (commit to next release being breaking)

1648 of 2421 new or added lines in 107 files covered. (68.07%)

1843 existing lines in 77 files now uncovered.

10515 of 16390 relevant lines covered (64.15%)

3306.56 hits per line

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

90.0
/inputters/sil.lua
1
local base = require("inputters.base")
92✔
2

3
local _variant = "epnf"
92✔
4
local parser
5
local function load_parser ()
6
   parser = require("inputters.sil-" .. _variant)
85✔
7
end
8

9
local inputter = pl.class(base)
92✔
10
inputter._name = "sil"
92✔
11

12
inputter.order = 50
92✔
13

14
inputter.appropriate = function (round, filename, doc)
15
  if not parser then load_parser() end
88✔
16
  if round == 1 then
88✔
17
    return filename:match(".sil$")
85✔
18
  elseif round == 2 then
3✔
19
    local sniff = doc:sub(1, 100)
2✔
20
    local promising = sniff:match("\\begin") or sniff:match("\\document") or sniff:match("\\sile")
2✔
21
    return promising and inputter.appropriate(3, filename, doc) or false
3✔
22
  elseif round == 3 then
1✔
23
    local status, _ = pcall(parser, doc)
1✔
24
    return status
1✔
25
  end
26
end
27

28
function inputter:_init (options)
92✔
29
  options = options or {}
83✔
30
  if options.variant then
83✔
NEW
31
    _variant = options.variant
×
NEW
32
    load_parser()
×
33
  else if not parser
83✔
NEW
34
     then load_parser() end
×
35
  end
36
  -- Save time when parsing strings by only setting up the grammar once per
37
  -- instantiation then re-using it on every use.
38
  self._parser = parser
83✔
39
  base._init(self)
83✔
40
end
41

42
local linecache = {}
92✔
43
local lno, col, lastpos
44
local function resetCache ()
45
  lno = 1
83✔
46
  col = 1
83✔
47
  lastpos = 0
83✔
48
  linecache = { { lno = 1, pos = 1} }
83✔
49
end
50

51
local function getline (str, pos)
52
  local start = 1
3,068✔
53
  lno = 1
3,068✔
54
  if pos > lastpos then
3,068✔
55
    lno = linecache[#linecache].lno
2,894✔
56
    start = linecache[#linecache].pos + 1
2,894✔
57
    col = 1
2,894✔
58
  else
59
    for j = 1, #linecache-1 do
1,972✔
60
      if linecache[j+1].pos >= pos then
1,972✔
61
        lno = linecache[j].lno
174✔
62
        col = pos - linecache[j].pos
174✔
63
        return lno, col
174✔
64
      end
65
    end
66
  end
67
  for i = start, pos do
78,682✔
68
    if string.sub( str, i, i ) == "\n" then
151,576✔
69
      lno = lno + 1
1,490✔
70
      col = 1
1,490✔
71
      linecache[#linecache+1] = { pos = i, lno = lno }
1,490✔
72
      lastpos = i
1,490✔
73
    end
74
    col = col + 1
75,788✔
75
  end
76
  return lno, col
2,894✔
77
end
78

79
local function massage_ast (tree, doc)
80
  if type(tree) == "string" then return tree end
4,538✔
81
  if tree.pos then
4,508✔
82
    tree.lno, tree.col = getline(doc, tree.pos)
6,136✔
83
    tree.pos = nil
3,068✔
84
  end
85
  SU.debug("inputter", "Processing ID:", tree.id)
4,508✔
NEW
86
  if false
×
87
    or tree.id == "comment"
4,508✔
88
    then
89
    SU.debug("inputter", ("Discarding comment:"), pl.stringx.strip(tree[1]))
236✔
90
    return {}
118✔
NEW
91
  elseif false
×
92
    or tree.id == "document"
4,390✔
93
    or tree.id == "braced_content"
4,390✔
94
    or tree.id == "passthrough_content"
4,137✔
95
    or tree.id == "braced_passthrough_content"
4,107✔
96
    or tree.id == "env_passthrough_content"
4,107✔
97
    then
98
    SU.debug("inputter", "Re-massage subtree", tree.id)
309✔
99
    return massage_ast(tree[1], doc)
309✔
NEW
100
  elseif false
×
101
    or tree.id == "text"
4,081✔
102
    or tree.id == "passthrough_text"
2,956✔
103
    or tree.id == "braced_passthrough_text"
2,956✔
104
    or tree.id == "env_passthrough_text"
2,926✔
105
    then
106
    SU.debug("inputter", "  - Collapse subtree")
1,181✔
107
    return tree[1]
1,181✔
NEW
108
  elseif false
×
109
    or tree.id == "content"
2,900✔
110
    or tree.id == "environment"
2,195✔
111
    or tree.id == "command" then
1,932✔
112
    SU.debug("inputter", "  - Massage in place", tree.id)
2,900✔
113
    for key, val in ipairs(tree) do
8,729✔
114
      SU.debug("inputter", "    -", val.id)
5,829✔
115
      if val.id == "content" then
5,829✔
116
        SU.splice(tree, key, key, massage_ast(val, doc))
1,107✔
117
      elseif val.id then -- requiring an id discards nodes with no content such as comments
5,460✔
118
        tree[key] = massage_ast(val, doc)
7,554✔
119
      end
120
    end
121
    return tree
2,900✔
122
  end
123
end
124

125
function inputter:parse (doc)
92✔
126
  local status, result = pcall(self._parser, doc)
83✔
127
  if not status then
83✔
NEW
128
    return SU.error(([[Unable to parse input document to an AST tree. Parser error:
×
129

NEW
130
%s  thrown from document beginning]]):format(pl.stringx.indent(result, 6)))
×
131
  end
132
  resetCache()
83✔
133
  local top = massage_ast(result[1], doc)
83✔
134
  local tree
135
  -- Content not part of a tagged command could either be part of a document
136
  -- fragment or junk (e.g. comments, whitespace) outside of a document tag. We
137
  -- need to either capture the document tag only or decide this is a fragment
138
  -- and wrap it in a document tag.
139
  for _, leaf in ipairs(top) do
83✔
140
    if leaf.command and (leaf.command == "document" or leaf.command == "sile") then
83✔
141
        tree = leaf
83✔
142
        break
83✔
143
    end
144
  end
145
  -- In the event we didn't isolate a top level document tag above, assume this
146
  -- is a fragment and wrap it in one.
147
  if not tree then
83✔
UNCOV
148
    tree = { top, command = "document" }
×
149
  end
150
  -- SU.dump(tree)
151
  return { tree }
83✔
152
end
153

154
return inputter
92✔
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