From e14436a8e9f83e1b2f8a840402bedaafedfabdf7 Mon Sep 17 00:00:00 2001 From: nihilazo Date: Thu, 12 Nov 2020 14:53:35 +0000 Subject: [PATCH] fix preformatted text in parser, reorganise --- parser.go | 26 ++++++++------------------ parser_test.go | 2 +- render.go | 11 +++++++++++ 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/parser.go b/parser.go index b23970b..615634c 100644 --- a/parser.go +++ b/parser.go @@ -4,7 +4,6 @@ package gemtext import ( "strings" "fmt" - "path/filepath" ) type ObjectType int64 @@ -28,21 +27,9 @@ type GemtextObject struct { Level int // Populated if object is a heading } -// type GemtextPage represents a gemtext page. +// type GemtextPage represents a gemtext page. It is equivalent to a slice of GemtextObjects. type GemtextPage []GemtextObject - -// addPrefix adds the prefix "pref" to a path if it is absolute -// this is to allow protocol-independent absolute links -// in input files. -func addPrefix(pref string, link string) string { - if filepath.IsAbs(link) { - return filepath.Join(pref, link) - } else { - return link - } -} - // ParseLink takes a gemini link as a string and returns a GemtextObject and an error. func ParseLink(l string) (GemtextObject, error) { if !strings.HasPrefix(l, "=>") { @@ -51,7 +38,7 @@ func ParseLink(l string) (GemtextObject, error) { f := strings.Fields(l[2:]) link := GemtextObject{Type: LINK, Literal: l} link.Path = f[0] - link.Text = strings.TrimSpace(l[3+len(f[0]):]) + link.Text = strings.TrimSpace(l[3+len(f[0]):]) // text that remains after removing the URL and link marker return link, nil } @@ -85,30 +72,33 @@ func ParseLine(line string, isPreformatted bool) (GemtextObject, error) { return ParseHeading(line) case strings.HasPrefix(line, ">"): return GemtextObject{Type: QUOTE, Text: strings.TrimSpace(line[1:]), Literal: line}, nil - case strings.HasPrefix(line, "* "): // Bullets require a space, per the spec + case strings.HasPrefix(line, "* "): // Bullets require a space in the spec return GemtextObject{Type: LIST, Text: line[2:], Literal: line}, nil } return GemtextObject{Type: TEXT, Text: line, Literal: line}, nil } else { + if strings.HasPrefix(line, "```") { // toggles are the only special line type in preformatted mode + return GemtextObject{Type: PREFORMATTED_TOGGLE, Literal: line, Text: line[3:]}, nil + } return GemtextObject{Type: PREFORMATTED_TEXT, Text: line, Literal: line}, nil } } // ParsePage takes a string containing the contents of a gemtext page and returns a GemtextPage. -func ParsePage(p string) (GemtextPage, error) { // TODO fix preformatted text +func ParsePage(p string) (GemtextPage, error) { preformatted := false lines := strings.Split(p, "\n") var page GemtextPage for _, line := range lines { l, err := ParseLine(line, preformatted) + page = append(page, l) if err != nil { return GemtextPage{}, err } if l.Type == PREFORMATTED_TOGGLE { preformatted = !preformatted } - page = append(page, l) } return page, nil } diff --git a/parser_test.go b/parser_test.go index 22c1dcd..1712ea5 100644 --- a/parser_test.go +++ b/parser_test.go @@ -214,7 +214,7 @@ func TestParsePage(t *testing.T) { output, _ := ParsePage(input) for i, _ := range output { if output[i] != want[i] { - t.Errorf("Wanted: %#v, got: %#v on line %d", want[i], output[i], i) + t.Errorf("Wanted: %#v, got: %#v at index %d", want[i], output[i], i) } } } diff --git a/render.go b/render.go index 54e00f7..6beeaa4 100644 --- a/render.go +++ b/render.go @@ -2,8 +2,19 @@ package gemtext import ( "fmt" + "path/filepath" ) +// addPrefix adds the prefix "pref" to a path if it is absolute +// this is to allow protocol-independent absolute links. +func addPrefix(pref string, link string) string { + if filepath.IsAbs(link) { + return filepath.Join(pref, link) + } else { + return link + } +} + // RenderLink takes a GemtextObject and returns a gemini link as a string or an error if the object is not a link. func RenderLink(obj GemtextObject) (string, error) { if obj.Type != LINK {