package syw import ( "embed" "net/url" "strings" "text/template" ) var ( //go:embed templates/*.gmi templates/*.gmi.txt geminiTemplateFS embed.FS geminiTemplate = template.Must(template.ParseFS( geminiTemplateFS, "templates/*.gmi", "templates/*.gmi.txt", )) ) var ( //go:embed templates/*.gph templates/*.gph.txt gopherTemplateFS embed.FS gopherTemplate = template.Must( template.New("gopher").Funcs(template.FuncMap{ "combine": gopherCombine, "join": gopherJoin, "rawtext": gopherRawtext, }).ParseFS( gopherTemplateFS, "templates/*.gph", "templates/*.gph.txt", ), ) ) func gopherCombine(base string, relative ...string) (string, error) { bu, err := url.Parse(base) if err != nil { return "", err } for _, rel := range relative { ru, err := url.Parse(rel) if err != nil { return "", err } bu = bu.ResolveReference(ru) } return bu.Path, nil } func gopherJoin(base string, relative ...string) (string, error) { bu, err := url.Parse(base) if err != nil { return "", err } return bu.JoinPath(relative...).Path, nil } func gopherRawtext(selector, host, port, text string) string { trailer := "\t" + selector + "\t" + host + "\t" + port + "\r\n" lines := strings.Split(text, "\n") for i := range lines { lines[i] = "i" + strings.TrimRight(strings.ReplaceAll(lines[i], "\t", " "), "\r\n") + trailer } return strings.Join(lines, "") } func addTemplates(base *template.Template, additions *template.Template) (*template.Template, error) { base, err := base.Clone() if err != nil { return nil, err } if additions == nil { return base, nil } for _, addition := range additions.Templates() { if _, err := base.AddParseTree(addition.Name(), addition.Tree); err != nil { return nil, err } } return base, nil }