Skip to content

Instantly share code, notes, and snippets.

@iOliverNguyen
Last active March 4, 2021 03:16
Show Gist options
  • Save iOliverNguyen/e4f2ae778e997b40d524cdf7e2adb5e8 to your computer and use it in GitHub Desktop.
Save iOliverNguyen/e4f2ae778e997b40d524cdf7e2adb5e8 to your computer and use it in GitHub Desktop.
a function for batch processing regular expressions
func processRegex(
s string, rs []*regexp.Regexp,
fn func(string), funcs ...func(string, ...string),
) {
if len(rs) != len(funcs) {
panic("func and regex do not match")
}
for s != "" {
mi, minA, minB, mIdx := 0, len(s), len(s), []int(nil)
for i, re := range rs {
idx := re.FindStringSubmatchIndex(s)
if idx == nil {
continue
}
if idx[0] < minA {
mi, minA, minB, mIdx = i, idx[0], idx[1], idx
}
}
if minA == len(s) {
break
}
if minA > 0 {
ss := s[:minA]
if ss != "" {
fn(ss)
}
}
var parts []string
for i := 0; i < len(mIdx); i += 2 {
a, b := mIdx[i], mIdx[i+1]
// the part has no match
if a < 0 || b < 0 {
parts = append(parts, "")
} else {
parts = append(parts, s[a:b])
}
}
funcs[mi](s[minA:minB], parts...)
s = s[minB:]
}
ss := s
if ss != "" {
fn(ss)
}
}
// example usage
var reFootnote = regexp.MustCompile(`\[\[@([^[\]]+)]]`)
var reIntrLink = regexp.MustCompile(`\[\[([^[\]]+)]]`)
var reExtrLink = regexp.MustCompile(`\[([^[\]]+)]\(([^()]+)\)`)
func parseLinks(input string, footnotes []string, footnoteNumber *int) (nodes Nodes, _footnotes []string) {
processRegex(input, []*regexp.Regexp{reFootnote, reIntrLink, reExtrLink},
func(s string) {
nodes.append(&Node{Text: s})
},
func(s string, ss ...string) {
*footnoteNumber++
txt, numberTxt := ss[1], fmt.Sprintf("[%d]", *footnoteNumber)
href := fmt.Sprintf(`href="#note-%d"`, *footnoteNumber)
footnotes = append(footnotes, txt)
nodes.append(textNode("a", numberTxt, href, "data-flink"))
},
func(s string, ss ...string) {
txt, key := ss[1], convertKey(ss[1])
href := `href="/w/` + key + `"`
link := `data-ilink="` + key + `"`
nodes.append(textNode("a", txt, href, link))
},
func(s string, ss ...string) {
txt, link := ss[1], ss[2]
href := `href=` + strconv.Quote(link)
nodes.append(textNode("a", txt, href, "data-xlink"))
},
)
return nodes, footnotes
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment