diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-08-31 20:16:16 -0600 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-08-31 20:16:16 -0600 |
commit | 0fe9ec0c90bfe82f637f1897e47fec07f90805ec (patch) | |
tree | c483fd2b4834a9ba281c92220bcf8adb9e13fb46 | |
parent | d3d5d0df7fcc353318feadb57e1775f10778d505 (diff) |
move gemtext->atom conversion into package atomconv like the other converters
-rw-r--r-- | gemini/gemtext/atomconv/convert.go (renamed from gemini/gemtext/sub.go) | 50 | ||||
-rw-r--r-- | gemini/gemtext/atomconv/convert_test.go (renamed from gemini/gemtext/sub_test.go) | 13 |
2 files changed, 33 insertions, 30 deletions
diff --git a/gemini/gemtext/sub.go b/gemini/gemtext/atomconv/convert.go index 269695f..30228f3 100644 --- a/gemini/gemtext/sub.go +++ b/gemini/gemtext/atomconv/convert.go @@ -1,4 +1,4 @@ -package gemtext +package atomconv import ( "bytes" @@ -13,44 +13,46 @@ import ( "time" "tildegit.org/tjp/sliderule/gemini" + "tildegit.org/tjp/sliderule/gemini/gemtext" "tildegit.org/tjp/sliderule/internal/types" ) -// GmisubToAtom converts a gemini document to Atom format. +// Convert turns a gemini document to Atom format. // // It identifies feed fields and entries according to the specification at // gemini://gemini.circumlunar.space/docs/companion/subscription.gmi -func GmisubToAtom(doc Document, location url.URL, out io.Writer) error { - if _, err := out.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>`)); err != nil { - return err +func Convert(wr io.Writer, doc gemtext.Document, location *url.URL) error { + if location == nil { + panic("atomconv.Convert: provided location was nil") } - if _, err := out.Write([]byte{'\n'}); err != nil { + + if _, err := wr.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>`)); err != nil { return err } - if err := atomTmpl.Execute(out, parseGemSub(doc, &location)); err != nil { + if _, err := wr.Write([]byte{'\n'}); err != nil { return err } - return nil + return atomTmpl.Execute(wr, parseGemSub(doc, location)) } -// AutoAtom is a middleware which builds atom feeds for any gemtext pages. +// Auto is a middleware which builds atom feeds for any gemtext pages. // // It looks for requests ending with the '.atom' extension, passes through the request // with the extension clipped off, then if the response is in gemtext it converts it to // an Atom feed according to the gmisub spec at // gemini://gemini.circumlunar.space/docs/companion/subscription.gmi -var AutoAtom = types.Middleware(func(h types.Handler) types.Handler { +var Auto = types.Middleware(func(h types.Handler) types.Handler { return types.HandlerFunc(func(ctx context.Context, request *types.Request) *types.Response { if request.Scheme != "gemini" || !strings.HasSuffix(request.Path, ".atom") { return h.Handle(ctx, request) } - req := *request + r := *request u := *request.URL - u.Path = strings.TrimSuffix(u.Path, ".atom") - req.URL = &u + u.Path = u.Path[:len(u.Path)-5] + r.URL = &u - response := h.Handle(ctx, &req) + response := h.Handle(ctx, &r) if response.Status != gemini.StatusSuccess { return response } @@ -64,13 +66,13 @@ var AutoAtom = types.Middleware(func(h types.Handler) types.Handler { _ = response.Close() }() - doc, err := Parse(response.Body) + doc, err := gemtext.Parse(response.Body) if err != nil { return gemini.Failure(err) } buf := &bytes.Buffer{} - if err := GmisubToAtom(doc, *request.URL, buf); err != nil { + if err := Convert(buf, doc, request.URL); err != nil { return gemini.Failure(err) } return gemini.Success("application/atom+xml; charset=utf-8", buf) @@ -94,18 +96,18 @@ type gmiSubEntry struct { var linkElemRE = regexp.MustCompile(`(\d{4})-([0-1]\d)-([0-3]\d)`) -func parseGemSub(doc Document, location *url.URL) *gmiSub { +func parseGemSub(doc gemtext.Document, location *url.URL) *gmiSub { sub := &gmiSub{ID: template.URL(location.String())} updated := time.Time{} for i, line := range doc { switch line.Type() { - case LineTypeHeading1: + case gemtext.LineTypeHeading1: if sub.Title != "" { continue } - sub.Title = line.(HeadingLine).Body() + sub.Title = line.(gemtext.HeadingLine).Body() for { // skip any empty lines i += 1 @@ -113,11 +115,11 @@ func parseGemSub(doc Document, location *url.URL) *gmiSub { break } } - if i < len(doc) && doc[i].Type() == LineTypeHeading2 { - sub.Subtitle = doc[i].(HeadingLine).Body() + if i < len(doc) && doc[i].Type() == gemtext.LineTypeHeading2 { + sub.Subtitle = doc[i].(gemtext.HeadingLine).Body() } - case LineTypeLink: - label := line.(LinkLine).Label() + case gemtext.LineTypeLink: + label := line.(gemtext.LinkLine).Label() if len(label) < 10 { continue } @@ -143,7 +145,7 @@ func parseGemSub(doc Document, location *url.URL) *gmiSub { entryTitle := strings.TrimLeft(strings.TrimPrefix(strings.TrimLeft(label[10:], " \t"), "-"), " \t") sub.Entries = append(sub.Entries, gmiSubEntry{ - ID: template.URL(line.(LinkLine).URL()), + ID: template.URL(line.(gemtext.LinkLine).URL()), Updated: entryUpdated.Format(time.RFC3339), Title: entryTitle, }) diff --git a/gemini/gemtext/sub_test.go b/gemini/gemtext/atomconv/convert_test.go index 9e0fcc8..8adaa2e 100644 --- a/gemini/gemtext/sub_test.go +++ b/gemini/gemtext/atomconv/convert_test.go @@ -1,4 +1,4 @@ -package gemtext +package atomconv import ( "bytes" @@ -10,10 +10,11 @@ import ( "tildegit.org/tjp/sliderule" "tildegit.org/tjp/sliderule/gemini" + "tildegit.org/tjp/sliderule/gemini/gemtext" "tildegit.org/tjp/sliderule/internal/types" ) -func TestGemsubToAtom(t *testing.T) { +func TestConvert(t *testing.T) { tests := []struct { url string input string @@ -50,7 +51,7 @@ func TestGemsubToAtom(t *testing.T) { for _, test := range tests { t.Run(test.url, func(t *testing.T) { - doc, err := Parse(bytes.NewBufferString(test.input)) + doc, err := gemtext.Parse(bytes.NewBufferString(test.input)) if err != nil { t.Fatal(err) } @@ -59,7 +60,7 @@ func TestGemsubToAtom(t *testing.T) { t.Fatal(err) } out := &bytes.Buffer{} - if err := GmisubToAtom(doc, *loc, out); err != nil { + if err := Convert(out, doc, loc); err != nil { t.Fatal(err) } if out.String() != test.output { @@ -69,7 +70,7 @@ func TestGemsubToAtom(t *testing.T) { } } -func TestAutoAtom(t *testing.T) { +func TestAuto(t *testing.T) { rout := &sliderule.Router{} rout.Route("/foo.gmi", types.HandlerFunc(func(ctx context.Context, request *types.Request) *types.Response { @@ -92,7 +93,7 @@ func TestAutoAtom(t *testing.T) { `[1:])) })) - h := AutoAtom(rout.Handler()) + h := Auto(rout.Handler()) response := h.Handle(context.Background(), &types.Request{URL: &url.URL{ Scheme: "gemini", |