2018-08-02 20:49:41 +00:00
|
|
|
package parser
|
|
|
|
|
2018-08-13 17:21:00 +00:00
|
|
|
import (
|
|
|
|
"bytes"
|
2018-08-16 15:45:43 +00:00
|
|
|
"fmt"
|
2018-08-02 20:49:41 +00:00
|
|
|
|
2018-08-13 17:21:00 +00:00
|
|
|
"github.com/gomarkdown/markdown/ast"
|
|
|
|
)
|
|
|
|
|
|
|
|
// parse '(#r)', where r does not contain spaces. Or.
|
2018-08-02 20:49:41 +00:00
|
|
|
// (!item) (!item, subitem), for an index, (!!item) signals primary.
|
2018-08-02 21:45:41 +00:00
|
|
|
func maybeShortRefOrIndex(p *Parser, data []byte, offset int) (int, ast.Node) {
|
2018-08-02 20:49:41 +00:00
|
|
|
if len(data[offset:]) < 4 {
|
2018-08-02 21:45:41 +00:00
|
|
|
return 0, nil
|
2018-08-02 20:49:41 +00:00
|
|
|
}
|
|
|
|
// short ref first
|
|
|
|
data = data[offset:]
|
|
|
|
i := 1
|
2018-08-13 17:21:00 +00:00
|
|
|
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 == ':' {
|
|
|
|
i++
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
i = 0
|
|
|
|
break Loop
|
2018-08-02 21:45:41 +00:00
|
|
|
}
|
2018-08-13 17:21:00 +00:00
|
|
|
i++
|
|
|
|
}
|
2018-08-15 14:03:59 +00:00
|
|
|
if i >= len(data) {
|
|
|
|
return 0, nil
|
|
|
|
}
|
|
|
|
if data[i] != ')' {
|
2018-08-13 17:21:00 +00:00
|
|
|
return 0, nil
|
2018-08-02 20:49:41 +00:00
|
|
|
}
|
2018-08-13 17:21:00 +00:00
|
|
|
|
|
|
|
id := data[2:i]
|
|
|
|
node := &ast.CrossReference{}
|
|
|
|
node.Destination = id
|
|
|
|
|
2018-08-15 14:03:59 +00:00
|
|
|
return i + 1, node
|
2018-08-13 17:21:00 +00:00
|
|
|
|
|
|
|
case '!': // index
|
2018-08-02 21:45:41 +00:00
|
|
|
i++
|
2018-08-13 17:21:00 +00:00
|
|
|
start := i
|
|
|
|
i = skipUntilChar(data, start, ')')
|
2018-08-02 20:49:41 +00:00
|
|
|
|
2018-08-13 17:21:00 +00:00
|
|
|
// 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
|
|
|
|
}
|
2018-08-15 14:32:06 +00:00
|
|
|
|
2018-08-13 17:21:00 +00:00
|
|
|
idx := &ast.Index{}
|
2018-08-15 14:32:06 +00:00
|
|
|
|
2018-08-17 06:21:03 +00:00
|
|
|
idx.ID = fmt.Sprintf("idxref:%d", p.indexCnt)
|
2018-08-15 14:32:06 +00:00
|
|
|
p.indexCnt++
|
|
|
|
|
2018-08-13 17:21:00 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2018-08-02 21:45:41 +00:00
|
|
|
|
2018-08-13 17:21:00 +00:00
|
|
|
return 0, nil
|
2018-08-02 20:49:41 +00:00
|
|
|
}
|