~sircmpwn/kineto

857f8c97ebc5724f4c34931ba497425e7653894e — nytpu 1 year, 1 month ago a8c54c1 master
Generate anchor links for headings

This will generate `id` attributes for all heading levels.  The labels
are generated using steps 1-4 of the gitlab flavored markdown algorithm
which seems to be pretty standard for generating anchors:
https://docs.gitlab.com/ee/user/markdown.html#header-ids-and-links

A unique ID isn't appended to avoid having to store a list of previous
headers to compare against.
1 files changed, 23 insertions(+), 6 deletions(-)

M main.go
M main.go => main.go +23 -6
@@ 13,6 13,7 @@ import (
	"os"
	"strings"
	"time"
	"unicode"

	"git.sr.ht/~adnano/go-gemini"
	"git.sr.ht/~sircmpwn/getopt"


@@ 24,11 25,11 @@ var gemtextPage = template.Must(template.
		"heading": func(line gemini.Line) *GemtextHeading {
			switch l := line.(type) {
			case gemini.LineHeading1:
				return &GemtextHeading{1, string(l)}
				return &GemtextHeading{1, string(l), createAnchor(string(l))}
			case gemini.LineHeading2:
				return &GemtextHeading{2, string(l)}
				return &GemtextHeading{2, string(l), createAnchor(string(l))}
			case gemini.LineHeading3:
				return &GemtextHeading{3, string(l)}
				return &GemtextHeading{3, string(l), createAnchor(string(l))}
			default:
				return nil
			}


@@ 147,7 148,7 @@ var gemtextPage = template.Must(template.

	{{- with . | heading }}
	{{- $isList = false -}}
	<h{{.Level}}>{{.Text}}</h{{.Level}}>
	<h{{.Level}} id="{{.Anchor}}">{{.Text}}</h{{.Level}}>
	{{- end -}}

	{{- with . | link }}


@@ 388,8 389,24 @@ type InputContext struct {
}

type GemtextHeading struct {
	Level int
	Text  string
	Level  int
	Text   string
	Anchor string
}

func createAnchor(heading string) string {
	var anchor strings.Builder
	prev := '-'
	for _, c := range heading {
		if unicode.IsLetter(c) || unicode.IsDigit(c) {
			anchor.WriteRune(unicode.ToLower(c))
			prev = c
		} else if (unicode.IsSpace(c) || c == '-') && prev != '-' {
			anchor.WriteRune('-')
			prev = '-'
		}
	}
	return strings.ToLower(anchor.String())
}

func proxyGemini(req gemini.Request, external bool, root *url.URL,