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

mlange-42 / modo / 12759040435

14 Jan 2025 01:08AM CUT coverage: 34.065% (-0.7%) from 34.783%
12759040435

Pull #33

github

web-flow
Merge 13c24c5d4 into b2b3f2790
Pull Request #33: Add CSS to mdBook for line wrapping in code

2 of 18 new or added lines in 2 files covered. (11.11%)

1 existing line in 1 file now uncovered.

264 of 775 relevant lines covered (34.06%)

1.96 hits per line

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

30.53
/document/links.go
1
package document
2

3
import (
4
        "fmt"
5
        "log"
6
        "path"
7
        "regexp"
8
        "strings"
9
        "text/template"
10
)
11

12
const regexString = `(?s)(?:(` + "```.*?```)|(`.*?`" + `))|(\[.*?\])`
13

14
func findLinks(text string) ([]int, error) {
2✔
15
        re, err := regexp.Compile(regexString)
2✔
16
        if err != nil {
2✔
17
                return nil, err
×
18
        }
×
19
        links := []int{}
2✔
20
        results := re.FindAllStringSubmatchIndex(text, -1)
2✔
21
        for _, r := range results {
12✔
22
                if r[6] >= 0 {
18✔
23
                        if len(text) > r[7] && string(text[r[7]]) == "(" {
9✔
24
                                continue
1✔
25
                        }
26
                        links = append(links, r[6], r[7])
7✔
27
                }
28
        }
29

30
        return links, nil
2✔
31
}
32

33
func ProcessLinks(doc *Docs, t *template.Template) error {
×
34
        lookup := collectPaths(doc)
×
35
        //for k, v := range lookup {
×
36
        //        fmt.Println(k, v.Elements)
×
37
        //}
×
38
        return processLinksPackage(doc.Decl, []string{}, lookup, t)
×
39
}
×
40

41
func processLinksPackage(p *Package, elems []string, lookup map[string]elemPath, t *template.Template) error {
×
42
        newElems := appendNew(elems, p.GetName())
×
43

×
44
        var err error
×
45
        p.Summary, err = replaceLinks(p.Summary, newElems, len(newElems), lookup, t)
×
46
        if err != nil {
×
47
                return err
×
48
        }
×
49
        p.Description, err = replaceLinks(p.Description, newElems, len(newElems), lookup, t)
×
50
        if err != nil {
×
51
                return err
×
52
        }
×
53

54
        for _, pkg := range p.Packages {
×
55
                processLinksPackage(pkg, newElems, lookup, t)
×
56
        }
×
57
        for _, mod := range p.Modules {
×
58
                processLinksModule(mod, newElems, lookup, t)
×
59
        }
×
60

61
        return nil
×
62
}
63

64
func processLinksModule(m *Module, elems []string, lookup map[string]elemPath, t *template.Template) error {
×
65
        newElems := appendNew(elems, m.GetName())
×
66

×
67
        var err error
×
68
        m.Summary, err = replaceLinks(m.Summary, newElems, len(newElems), lookup, t)
×
69
        if err != nil {
×
70
                return err
×
71
        }
×
72
        m.Description, err = replaceLinks(m.Description, newElems, len(newElems), lookup, t)
×
73
        if err != nil {
×
74
                return err
×
75
        }
×
76

77
        for _, f := range m.Functions {
×
78
                err := processLinksFunction(f, newElems, lookup, t)
×
79
                if err != nil {
×
80
                        return err
×
81
                }
×
82
        }
83
        for _, s := range m.Structs {
×
84
                err := processLinksStruct(s, newElems, lookup, t)
×
85
                if err != nil {
×
86
                        return err
×
87
                }
×
88
        }
89
        for _, tr := range m.Traits {
×
90
                err := processLinksTrait(tr, newElems, lookup, t)
×
91
                if err != nil {
×
92
                        return err
×
93
                }
×
94
        }
95

96
        return nil
×
97
}
98

99
func processLinksStruct(s *Struct, elems []string, lookup map[string]elemPath, t *template.Template) error {
×
100
        newElems := appendNew(elems, s.GetName())
×
101

×
102
        var err error
×
103
        s.Summary, err = replaceLinks(s.Summary, newElems, len(elems), lookup, t)
×
104
        if err != nil {
×
105
                return err
×
106
        }
×
107
        s.Description, err = replaceLinks(s.Description, newElems, len(elems), lookup, t)
×
108
        if err != nil {
×
109
                return err
×
110
        }
×
111

112
        for _, p := range s.Parameters {
×
113
                p.Description, err = replaceLinks(p.Description, newElems, len(elems), lookup, t)
×
114
                if err != nil {
×
115
                        return err
×
116
                }
×
117
        }
118
        for _, f := range s.Fields {
×
119
                f.Summary, err = replaceLinks(f.Summary, newElems, len(elems), lookup, t)
×
120
                if err != nil {
×
121
                        return err
×
122
                }
×
123
                f.Description, err = replaceLinks(f.Description, newElems, len(elems), lookup, t)
×
124
                if err != nil {
×
125
                        return err
×
126
                }
×
127
        }
128
        for _, f := range s.Functions {
×
129
                if err := processLinksMethod(f, elems, lookup, t); err != nil {
×
130
                        return err
×
131
                }
×
132
        }
133

134
        return nil
×
135
}
136

137
func processLinksTrait(tr *Trait, elems []string, lookup map[string]elemPath, t *template.Template) error {
×
138
        newElems := appendNew(elems, tr.GetName())
×
139

×
140
        var err error
×
141
        tr.Summary, err = replaceLinks(tr.Summary, newElems, len(elems), lookup, t)
×
142
        if err != nil {
×
143
                return err
×
144
        }
×
145
        tr.Description, err = replaceLinks(tr.Description, newElems, len(elems), lookup, t)
×
146
        if err != nil {
×
147
                return err
×
148
        }
×
149

150
        // TODO: add when traits support parameters
151
        /*for _, p := range tr.Parameters {
152
                p.Description, err = replaceLinks(p.Description, newElems, len(elems), lookup, t)
153
                if err != nil {
154
                        return err
155
                }
156
        }*/
157
        for _, f := range tr.Fields {
×
158
                f.Summary, err = replaceLinks(f.Summary, newElems, len(elems), lookup, t)
×
159
                if err != nil {
×
160
                        return err
×
161
                }
×
162
                f.Description, err = replaceLinks(f.Description, newElems, len(elems), lookup, t)
×
163
                if err != nil {
×
164
                        return err
×
165
                }
×
166
        }
167
        for _, f := range tr.Functions {
×
168
                if err := processLinksMethod(f, elems, lookup, t); err != nil {
×
169
                        return err
×
170
                }
×
171
        }
172

173
        return nil
×
174
}
175

176
func processLinksFunction(f *Function, elems []string, lookup map[string]elemPath, t *template.Template) error {
×
177
        newElems := appendNew(elems, f.GetName())
×
178

×
179
        var err error
×
180
        f.Summary, err = replaceLinks(f.Summary, newElems, len(elems), lookup, t)
×
181
        if err != nil {
×
182
                return err
×
183
        }
×
184
        f.Description, err = replaceLinks(f.Description, newElems, len(elems), lookup, t)
×
185
        if err != nil {
×
186
                return err
×
187
        }
×
188
        f.ReturnsDoc, err = replaceLinks(f.ReturnsDoc, newElems, len(elems), lookup, t)
×
189
        if err != nil {
×
190
                return err
×
191
        }
×
192
        f.RaisesDoc, err = replaceLinks(f.RaisesDoc, newElems, len(elems), lookup, t)
×
193
        if err != nil {
×
194
                return err
×
195
        }
×
196

197
        for _, a := range f.Args {
×
198
                a.Description, err = replaceLinks(a.Description, newElems, len(elems), lookup, t)
×
199
                if err != nil {
×
200
                        return err
×
201
                }
×
202
        }
203
        for _, p := range f.Parameters {
×
204
                p.Description, err = replaceLinks(p.Description, newElems, len(elems), lookup, t)
×
205
                if err != nil {
×
206
                        return err
×
207
                }
×
208
        }
209

210
        for _, o := range f.Overloads {
×
211
                err := processLinksFunction(o, elems, lookup, t)
×
212
                if err != nil {
×
213
                        return err
×
214
                }
×
215
        }
216

217
        return nil
×
218
}
219

220
func processLinksMethod(f *Function, elems []string, lookup map[string]elemPath, t *template.Template) error {
×
221
        var err error
×
222
        f.Summary, err = replaceLinks(f.Summary, elems, len(elems), lookup, t)
×
223
        if err != nil {
×
224
                return err
×
225
        }
×
226
        f.Description, err = replaceLinks(f.Description, elems, len(elems), lookup, t)
×
227
        if err != nil {
×
228
                return err
×
229
        }
×
230
        f.ReturnsDoc, err = replaceLinks(f.ReturnsDoc, elems, len(elems), lookup, t)
×
231
        if err != nil {
×
232
                return err
×
233
        }
×
234
        f.RaisesDoc, err = replaceLinks(f.RaisesDoc, elems, len(elems), lookup, t)
×
235
        if err != nil {
×
236
                return err
×
237
        }
×
238

239
        for _, a := range f.Args {
×
240
                a.Description, err = replaceLinks(a.Description, elems, len(elems), lookup, t)
×
241
                if err != nil {
×
242
                        return err
×
243
                }
×
244
        }
245
        for _, p := range f.Parameters {
×
246
                p.Description, err = replaceLinks(p.Description, elems, len(elems), lookup, t)
×
247
                if err != nil {
×
248
                        return err
×
249
                }
×
250
        }
251

252
        for _, o := range f.Overloads {
×
253
                err := processLinksMethod(o, elems, lookup, t)
×
254
                if err != nil {
×
255
                        return err
×
256
                }
×
257
        }
258

259
        return nil
×
260
}
261

262
func replaceLinks(text string, elems []string, modElems int, lookup map[string]elemPath, t *template.Template) (string, error) {
1✔
263
        indices, err := findLinks(text)
1✔
264
        if err != nil {
1✔
265
                return "", err
×
266
        }
×
267
        if len(indices) == 0 {
1✔
268
                return text, nil
×
269
        }
×
270
        for i := len(indices) - 2; i >= 0; i -= 2 {
6✔
271
                start, end := indices[i], indices[i+1]
5✔
272
                link := text[start+1 : end-1]
5✔
273

5✔
274
                entry, linkText, parts, ok := toLink(link, elems, modElems, lookup)
5✔
275
                if !ok {
5✔
276
                        continue
×
277
                }
278

279
                var basePath string
5✔
280
                if entry.IsSection {
6✔
281
                        basePath = path.Join(parts[:len(parts)-1]...)
1✔
282
                } else {
5✔
283
                        basePath = path.Join(parts...)
4✔
284
                }
4✔
285
                pathStr := strings.Builder{}
5✔
286
                err := t.ExecuteTemplate(&pathStr, entry.Kind+"_path.md", basePath)
5✔
287
                if err != nil {
5✔
288
                        return "", err
×
289
                }
×
290
                if entry.IsSection {
6✔
291
                        pathStr.WriteString(parts[len(parts)-1])
1✔
292
                }
1✔
293
                text = fmt.Sprintf("%s[%s](%s)%s", text[:start], linkText, pathStr.String(), text[end:])
5✔
294
        }
295
        return text, nil
1✔
296
}
297

298
func toLink(link string, elems []string, modElems int, lookup map[string]elemPath) (entry *elemPath, text string, parts []string, ok bool) {
16✔
299
        linkParts := strings.SplitN(link, " ", 2)
16✔
300
        if strings.HasPrefix(link, ".") {
25✔
301
                entry, text, parts, ok = toRelLink(linkParts[0], elems, modElems, lookup)
9✔
302
        } else {
16✔
303
                entry, text, parts, ok = toAbsLink(linkParts[0], elems, modElems, lookup)
7✔
304
        }
7✔
305
        if len(linkParts) > 1 {
17✔
306
                text = linkParts[1]
1✔
307
        } else {
16✔
308
                text = fmt.Sprintf("`%s`", text)
15✔
309
        }
15✔
310
        return
16✔
311
}
312

313
func toRelLink(link string, elems []string, modElems int, lookup map[string]elemPath) (*elemPath, string, []string, bool) {
9✔
314
        dots := 0
9✔
315
        fullPath := []string{}
9✔
316
        for strings.HasPrefix(link[dots:], ".") {
21✔
317
                if dots > 0 {
15✔
318
                        fullPath = append(fullPath, "..")
3✔
319
                }
3✔
320
                dots++
12✔
321
        }
322
        if dots > modElems {
9✔
323
                log.Printf("WARNING: Too many leading dots in cross ref '%s' in %s", link, strings.Join(elems, "."))
×
324
                return nil, "", nil, false
×
325
        }
×
326
        linkText := link[dots:]
9✔
327
        subElems := elems[:modElems-(dots-1)]
9✔
328
        var fullLink string
9✔
329
        if len(subElems) == 0 {
9✔
330
                fullLink = linkText
×
331
        } else {
9✔
332
                fullLink = strings.Join(subElems, ".") + "." + linkText
9✔
333
        }
9✔
334

335
        elemPath, ok := lookup[fullLink]
9✔
336
        if !ok {
9✔
337
                log.Printf("WARNING: Can't resolve cross ref '%s' (%s) in %s", link, fullLink, strings.Join(elems, "."))
×
338
                return nil, "", nil, false
×
339
        }
×
340

341
        fullPath = append(fullPath, elemPath.Elements[len(subElems):]...)
9✔
342
        return &elemPath, link[dots:], fullPath, true
9✔
343
}
344

345
func toAbsLink(link string, elems []string, modElems int, lookup map[string]elemPath) (*elemPath, string, []string, bool) {
7✔
346
        elemPath, ok := lookup[link]
7✔
347
        if !ok {
8✔
348
                log.Printf("WARNING: Can't resolve cross ref '%s' in %s", link, strings.Join(elems, "."))
1✔
349
                return nil, "", nil, false
1✔
350
        }
1✔
351
        skip := 0
6✔
352
        for range modElems {
18✔
353
                if len(elemPath.Elements) <= skip {
12✔
354
                        break
×
355
                }
356
                if elemPath.Elements[skip] == elems[skip] {
21✔
357
                        skip++
9✔
358
                } else {
12✔
359
                        break
3✔
360
                }
361
        }
362
        fullPath := []string{}
6✔
363
        for range modElems - skip {
9✔
364
                fullPath = append(fullPath, "..")
3✔
365
        }
3✔
366
        fullPath = append(fullPath, elemPath.Elements[skip:]...)
6✔
367
        return &elemPath, link, fullPath, true
6✔
368
}
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