func findUrls(txt string) [][]int {
	var results [][]int
	lastWordBoundary := -1
	lastColon := -1
	lastSlash := -1
	inUrl := false
	maybeStripParens := func(end int) int {
		if lastWordBoundary > 1 &&
			txt[lastWordBoundary] == '(' &&
			txt[end-1] == ')' {
			end--
		}
		return end
	}
Outer:
	for i, r := range txt {
		switch {
		case 'a' <= r && r <= 'z' ||
			'A' <= r && r <= 'Z' ||
			'0' <= r && r <= '9':
		case r == ':':
			lastColon = i
		case r == '/':
			if lastColon > -1 && lastColon == i-2 && lastSlash == i-1 && lastWordBoundary < (lastColon-1) {
				inUrl = true
			}
			lastSlash = i
		default:
			if inUrl {
				switch r {
				case '-', '.', '_', '~', '?', '#', '[', ']', '@', '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=':
					continue Outer
				default:
					end := maybeStripParens(i)
					results = append(results, []int{lastWordBoundary + 1, end})
					inUrl = false
				}
			}
			lastWordBoundary = i
			lastSlash = -1
			lastColon = -1
		}
	}
	if inUrl {
		end := maybeStripParens(len(txt))
		results = append(results, []int{lastWordBoundary + 1, end})
	}
	return results
}
findUrls finds anything that roughly like a URL. Matches are
filtered by checking whether (net/url).Parse returns an error.
package convert
import (
	"bytes"
	"fmt"
	"io"
	"net/url"
	"sort"
	"strings"
	"golang.org/x/net/html"
)
var heading = map[string]bool{
	"h1": true,
	"h2": true,
	"h3": true,
	"h4": true,
	"h5": true,
	"h6": true,
}
func recurse(n *html.Node, f func(c *html.Node) error) error {
	c := n.FirstChild
	for c != nil {
		next := c.NextSibling
		if err := recurse(c, f); err != nil {
			return err
		}
		if err := f(c); err != nil {
			return err
		}
		c = next
	}
	return nil
}
type ref struct {
	pos  []int
	dest string
}
type byStart []ref
func (p byStart) Len() int {
	return len(p)
}
func (p byStart) Less(i, j int) bool {
	return p[i].pos[0] < p[j].pos[0]
}
func (p byStart) Swap(i, j int) {
	p[i], p[j] = p[j], p[i]
}
func findXrefs(txt string) [][]int {
	var results [][]int
	lastWordBoundary := -1
	lastOpeningParen := -1
	for i, r := range txt {
		switch {
		case 'a' <= r && r <= 'z' ||
			'A' <= r && r <= 'Z' ||
			'0' <= r && r <= '9' ||
			r == '-' ||
			r == '.' ||
			r == '_':
		case r == '(':
			lastOpeningParen = i
		case r == ')':
			if lastOpeningParen > -1 &&
				lastWordBoundary < (lastOpeningParen-1) {
				results = append(results, []int{lastWordBoundary + 1, i + 1})
			}
		default:
			lastWordBoundary = i
			lastOpeningParen = -1
		}
	}
	return results
}
func xrefMatches(txt string, resolve func(ref string) string) []ref {
	xrefm := findXrefs(txt)
	matches := make([]ref, 0, len(xrefm))
	for _, r := range xrefm {
		url := resolve(txt[r[0]:r[1]])
		if url == "" {
			continue
		}
		matches = append(matches, ref{
			pos:  r,
			dest: url})
	}
	return matches
}