diff options
| author | Shulhan <m.shulhan@gmail.com> | 2020-10-31 04:01:41 +0700 |
|---|---|---|
| committer | Shulhan <m.shulhan@gmail.com> | 2020-10-31 04:01:41 +0700 |
| commit | 45e1e54c75bda5591cf02ea8bc899a8150b3dcfc (patch) | |
| tree | 2119c2076af4dc4d738064946a3e7995538218bc /parser_inline.go | |
| parent | ee78188ea91964725f58cc3d8c472cc9ab2f5c36 (diff) | |
| download | asciidoctor-go-45e1e54c75bda5591cf02ea8bc899a8150b3dcfc.tar.xz | |
all: implement parser for block anchor and inline anchor
Diffstat (limited to 'parser_inline.go')
| -rw-r--r-- | parser_inline.go | 102 |
1 files changed, 100 insertions, 2 deletions
diff --git a/parser_inline.go b/parser_inline.go index abdc18b..197482e 100644 --- a/parser_inline.go +++ b/parser_inline.go @@ -19,18 +19,20 @@ type parserInline struct { container *adocNode current *adocNode content []byte + doc *Document x int state *parserInlineState prev, c, nextc byte isEscaped bool } -func newParserInline(content []byte) (pi *parserInline) { +func newParserInline(doc *Document, content []byte) (pi *parserInline) { pi = &parserInline{ container: &adocNode{ kind: nodeKindText, }, content: bytes.TrimRight(content, "\n"), + doc: doc, state: &parserInlineState{}, } pi.current = pi.container @@ -193,11 +195,39 @@ func (pi *parserInline) do() { if pi.parseFormat(nodeKindTextMono, styleTextMono) { continue } + } else if pi.c == '[' { + if pi.isEscaped { + pi.escape() + continue + } + if pi.nextc == '[' { + if pi.parseInlineID() { + continue + } + } else if pi.nextc == '#' { + if pi.parseInlineIDShort() { + continue + } + } + } else if pi.c == '#' { + if pi.isEscaped { + pi.escape() + continue + } + // Do we have the beginning? + if pi.state.has(nodeKindInlineIDShort) { + pi.terminate(nodeKindInlineIDShort, 0) + pi.x++ + pi.prev = 0 + continue + } } pi.current.WriteByte(pi.c) pi.x++ pi.prev = pi.c } + + pi.container.removeLastIfEmpty() } func (pi *parserInline) escape() { @@ -220,6 +250,74 @@ func (pi *parserInline) getBackMacroName() (macroName string, lastc byte) { } // +// parseInlineID parse the ID and optional label between "[[" "]]". +// +func (pi *parserInline) parseInlineID() bool { + // Check if we have term at the end. + raw := pi.content[pi.x+2:] + raw, idx := indexUnescape(raw, []byte("]]")) + if idx < 0 { + return false + } + id, label := parseIDLabel(string(raw)) + if len(id) == 0 { + return false + } + + pi.doc.registerAnchor(id, label) + + node := &adocNode{ + ID: id, + kind: nodeKindInlineID, + } + pi.current.addChild(node) + node = &adocNode{ + kind: nodeKindText, + } + pi.current.addChild(node) + pi.current = node + pi.x += 2 + len(raw) + 2 + pi.prev = 0 + return true +} + +// +// parseInlineIDShort parse the ID and optional label between "[#", "]#", and +// "#". +// +func (pi *parserInline) parseInlineIDShort() bool { + // Check if we have term at the end. + raw := pi.content[pi.x+2:] + id, idx := indexUnescape(raw, []byte("]#")) + if idx < 0 { + return false + } + + stringID := string(id) + if !isValidID(stringID) { + return false + } + + // Check if we have "#" + _, idx = indexByteUnescape(raw[idx+2:], '#') + if idx < 0 { + return false + } + + pi.doc.registerAnchor(stringID, "") + + node := &adocNode{ + ID: stringID, + kind: nodeKindInlineIDShort, + } + pi.state.push(nodeKindInlineIDShort) + pi.current.addChild(node) + pi.current = node + pi.x += 2 + len(id) + 2 + return true +} + +// // parseQuoteBegin check if the double quote curve ("`) is valid (does not // followed by space) and has an end (`"). // @@ -649,7 +747,7 @@ func (pi *parserInline) parseURL(scheme string) (node *adocNode) { text = strings.TrimRight(text, "^") node.Attrs[attrNameRel] = attrValueNoopener } - child := parseInlineMarkup([]byte(text)) + child := parseInlineMarkup(pi.doc, []byte(text)) node.addChild(child) } if len(attrs) >= 2 { |
