1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package parser
import (
"bytes"
"fmt"
"github.com/gomarkdown/markdown/ast"
)
// parse '(#r, text)', where r does not contain spaces, but text may (similar to a citation). Or. (!item) (!item,
// subitem), for an index, (!!item) signals primary.
func maybeShortRefOrIndex(p *Parser, data []byte, offset int) (int, ast.Node) {
if len(data[offset:]) < 4 {
return 0, nil
}
// short ref first
data = data[offset:]
i := 1
switch data[i] {
case '#': // cross ref
i++
Loop:
for i < len(data) {
c := data[i]
switch {
case c == ')':
break Loop
case !IsAlnum(c):
if c == '_' || c == '-' || c == ':' || c == ' ' || c == ',' {
i++
continue
}
i = 0
break Loop
}
i++
}
if i >= len(data) {
return 0, nil
}
if data[i] != ')' {
return 0, nil
}
id := data[2:i]
node := &ast.CrossReference{}
node.Destination = id
if c := bytes.Index(id, []byte(",")); c > 0 {
idpart := id[:c]
suff := id[c+1:]
suff = bytes.TrimSpace(suff)
node.Destination = idpart
node.Suffix = suff
}
if bytes.Index(node.Destination, []byte(" ")) > 0 {
// no spaces allowed in id
return 0, nil
}
if bytes.Index(node.Destination, []byte(",")) > 0 {
// nor comma
return 0, nil
}
return i + 1, node
case '!': // index
i++
start := i
i = skipUntilChar(data, start, ')')
// did we reach the end of the buffer without a closing marker?
if i >= len(data) {
return 0, nil
}
if len(data[start:i]) < 1 {
return 0, nil
}
idx := &ast.Index{}
idx.ID = fmt.Sprintf("idxref:%d", p.indexCnt)
p.indexCnt++
idx.Primary = data[start] == '!'
buf := data[start:i]
if idx.Primary {
buf = buf[1:]
}
items := bytes.Split(buf, []byte(","))
switch len(items) {
case 1:
idx.Item = bytes.TrimSpace(items[0])
return i + 1, idx
case 2:
idx.Item = bytes.TrimSpace(items[0])
idx.Subitem = bytes.TrimSpace(items[1])
return i + 1, idx
}
}
return 0, nil
}
|