123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- 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
- }
|