fix link parsing

This commit is contained in:
Nico 2020-11-12 10:55:29 +00:00
parent 872459479c
commit c462020d16
2 changed files with 104 additions and 24 deletions

View File

@ -46,13 +46,13 @@ func addPrefix(pref string, link string) string {
// ParseLink takes a gemini link as a string and returns a GemtextObject and an error.
func ParseLink(l string) (GemtextObject, error) {
f := strings.Fields(l)
if f[0] != "=>" {
if !strings.HasPrefix(l, "=>") {
return GemtextObject{}, fmt.Errorf("Not a gemtext link!")
} else {
f := strings.Fields(l[2:])
link := GemtextObject{Type: LINK, Literal: l}
link.Path = f[1]
link.Text = strings.Join(f[2:]," ")
link.Path = f[0]
link.Text = strings.TrimSpace(l[3+len(f[0]):])
return link, nil
}
@ -61,11 +61,13 @@ func ParseLink(l string) (GemtextObject, error) {
// ParseHeading parses a gemtext heading, returns a HEADING GemtextObject if it is between levels 1-3 and TEXT otherwise.
func ParseHeading(l string) (GemtextObject, error) {
switch {
case strings.HasPrefix(l, "### "):
case strings.HasPrefix(l, "####"): // Fake headings
return GemtextObject{Type: TEXT, Text:l, Literal: l}, nil
case strings.HasPrefix(l, "###"):
return GemtextObject{Type: HEADING, Level: 3, Text: strings.TrimSpace(l[3:]), Literal: l},nil
case strings.HasPrefix(l, "## "):
case strings.HasPrefix(l, "##"):
return GemtextObject{Type: HEADING, Level: 2, Text: strings.TrimSpace(l[2:]), Literal: l},nil
case strings.HasPrefix(l, "# "):
case strings.HasPrefix(l, "#"):
return GemtextObject{Type: HEADING, Level: 1, Text: strings.TrimSpace(l[1:]), Literal: l},nil
}
return GemtextObject{Type: TEXT, Text:l, Literal: l}, nil
@ -74,22 +76,24 @@ func ParseHeading(l string) (GemtextObject, error) {
// ParseLine parses a gemtext line, and returns a GemtextObject representing it.
// "isPreformatted" takes a true if the line is in a preformatted block, else otherwise.
func ParseLine(line string, isPreformatted bool) (GemtextObject, error) {
l := strings.TrimSpace(line)
switch {
case strings.HasPrefix(l, "=>"):
return ParseLink(line)
case strings.HasPrefix(l, "```"):
return GemtextObject{Type: PREFORMATTED_TOGGLE, Literal: l}, nil
case strings.HasPrefix(l, "#"):
return ParseHeading(line)
case strings.HasPrefix(l, ">"):
return GemtextObject{Type: QUOTE, Text: strings.TrimSpace(l[1:]), Literal: l}, nil
case strings.HasPrefix(l, "*"):
return GemtextObject{Type: LIST, Text: strings.TrimSpace(l[1:]), Literal: l}, nil
case isPreformatted:
return GemtextObject{Type: PREFORMATTED_TEXT, Text: l, Literal: l}, nil
}
return GemtextObject{Type: TEXT, Text: l, Literal: l}, nil
if !isPreformatted {
switch {
case strings.HasPrefix(line, "=>"):
return ParseLink(line)
case strings.HasPrefix(line, "```"):
return GemtextObject{Type: PREFORMATTED_TOGGLE, Literal: line}, nil
case strings.HasPrefix(line, "#"):
return ParseHeading(line)
case strings.HasPrefix(line, ">"):
return GemtextObject{Type: QUOTE, Text: strings.TrimSpace(line[1:]), Literal: line}, nil
case strings.HasPrefix(line, "*"):
return GemtextObject{Type: LIST, Text: strings.TrimSpace(line[1:]), Literal: line}, nil
}
return GemtextObject{Type: TEXT, Text: line, Literal: line}, nil
} else {
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.

View File

@ -7,7 +7,7 @@ type LineCase struct {
Preformatted bool
Want GemtextObject
}
// These tests suck. They're not really tests.
// These tests suck.
func TestParseLine(t *testing.T) {
cases := []LineCase{
LineCase{Str: "```", Preformatted: false, Want: GemtextObject{Type: PREFORMATTED_TOGGLE, Literal: "```"}},
@ -54,6 +54,24 @@ func TestParseLine(t *testing.T) {
Text: "heading 3",
Level: 3},
},
LineCase{
Str: "###heading 3",
Preformatted: false,
Want: GemtextObject{
Type: HEADING,
Literal: "###heading 3",
Text: "heading 3",
Level: 3},
},
LineCase{
Str: "### heading 3",
Preformatted: false,
Want: GemtextObject{
Type: HEADING,
Literal: "### heading 3",
Text: "heading 3",
Level: 3},
},
LineCase{
Str: "#### heading 4",
Preformatted: false,
@ -78,6 +96,14 @@ func TestParseLine(t *testing.T) {
Literal: "* list item",
Text: "list item"},
},
LineCase{
Str: "* list item",
Preformatted: false,
Want: GemtextObject{
Type: LIST,
Literal: "* list item",
Text: "list item"},
},
LineCase{
Str: ">quote",
Preformatted: false,
@ -94,6 +120,56 @@ func TestParseLine(t *testing.T) {
Literal: "> quote",
Text: "quote"},
},
LineCase{
Str: "> quote",
Preformatted: false,
Want: GemtextObject{
Type: QUOTE,
Literal: "> quote",
Text: "quote"},
},
LineCase{
Str: "> quote",
Preformatted: true,
Want: GemtextObject{
Type: PREFORMATTED_TEXT,
Literal: "> quote",
Text: "> quote"},
},
LineCase{
Str: "=> https://example.com link",
Preformatted: true,
Want: GemtextObject{
Type: PREFORMATTED_TEXT,
Literal: "=> https://example.com link",
Text: "=> https://example.com link"},
},
LineCase{
Str: "=> https://example.com link",
Preformatted: false,
Want: GemtextObject{
Type: LINK,
Literal: "=> https://example.com link",
Text: "link",
Path: "https://example.com"},
},
LineCase{
Str: "=>https://example.com link",
Preformatted: false,
Want: GemtextObject{
Type: LINK,
Literal: "=>https://example.com link",
Text: "link",
Path: "https://example.com"},
},
LineCase{
Str: "\n",
Preformatted: false,
Want: GemtextObject{
Type: TEXT,
Literal: "\n",
Text: "\n"},
},
}
for _, c := range cases {
got, _ := ParseLine(c.Str, c.Preformatted)