go-org-orgwiki/org/footnote.go
Niklas Fasching ac2597af4c Refactor Footnotes: Exclude footnotes heading during export, not parsing
Until now the footnotes section was parsed but not included in the resulting
AST - his required rebuilding it in the OrgWriter. It feels cleaner to include
it in the AST and only exclude it in the export
2018-12-17 13:40:15 +01:00

63 lines
1.7 KiB
Go

package org
import (
"regexp"
)
type Footnotes struct {
Title string
Definitions map[string]*FootnoteDefinition
addOrder []string
}
type FootnoteDefinition struct {
Name string
Children []Node
Inline bool
}
var footnoteDefinitionRegexp = regexp.MustCompile(`^\[fn:([\w-]+)\](\s+(.+)|$)`)
func lexFootnoteDefinition(line string) (token, bool) {
if m := footnoteDefinitionRegexp.FindStringSubmatch(line); m != nil {
return token{"footnoteDefinition", 0, m[1], m}, true
}
return nilToken, false
}
func (d *Document) parseFootnoteDefinition(i int, parentStop stopFn) (int, Node) {
start, name := i, d.tokens[i].content
d.tokens[i] = tokenize(d.tokens[i].matches[2])
stop := func(d *Document, i int) bool {
return parentStop(d, i) ||
(isSecondBlankLine(d, i) && i > start+1) ||
d.tokens[i].kind == "headline" || d.tokens[i].kind == "footnoteDefinition"
}
consumed, nodes := d.parseMany(i, stop)
definition := FootnoteDefinition{name, nodes, false}
d.Footnotes.add(name, &definition)
return consumed, definition
}
func (fs *Footnotes) add(name string, definition *FootnoteDefinition) {
if definition != nil {
fs.Definitions[name] = definition
}
fs.addOrder = append(fs.addOrder, name)
}
func (fs *Footnotes) Ordered() []FootnoteDefinition {
m := map[string]bool{}
definitions, inlineDefinitions := []FootnoteDefinition{}, []FootnoteDefinition{}
for _, name := range fs.addOrder {
if isDuplicate := m[name]; !isDuplicate {
m[name] = true
if definition := *fs.Definitions[name]; definition.Inline {
inlineDefinitions = append(inlineDefinitions, definition)
} else {
definitions = append(definitions, definition)
}
}
}
return append(definitions, inlineDefinitions...)
}