Browse Source

implement fileparser

master
Wojciech Kwolek 2 months ago
parent
commit
efecf83998
2 changed files with 127 additions and 0 deletions
  1. +28
    -0
      gemini/gemini.go
  2. +99
    -0
      gemini/gemini_test.go

+ 28
- 0
gemini/gemini.go View File

@ -1,6 +1,9 @@
package gemini
import (
"bufio"
"fmt"
"io"
"strings"
)
@ -39,3 +42,28 @@ func (l *LineParser) ParseLine(lineStr string) Line {
return ParseTextLine(lineStr)
}
type FileParser struct {
file *bufio.Scanner
p LineParser
}
func NewFileParser(f io.Reader) *FileParser {
p := &FileParser{}
p.p = LineParser{}
p.file = bufio.NewScanner(f)
return p
}
// Next returns the next parsed line, or nil on EOF.
func (fp *FileParser) Next() (Line, error) {
if fp.file.Scan() {
return fp.p.ParseLine(fp.file.Text()), nil
}
if err := fp.file.Err(); err != nil {
return nil, fmt.Errorf("Scanner error: %w", err)
}
return nil, nil
}

+ 99
- 0
gemini/gemini_test.go View File

@ -1,6 +1,7 @@
package gemini_test
import (
"strings"
"testing"
"git.r23s.eu/wojciech/gm2html/gemini"
@ -101,3 +102,101 @@ func TestParseQuoteLine(t *testing.T) {
assert.Equal(t, test.content, l.Content(), test.line)
}
}
func TestFileParser(t *testing.T) {
f := `# heading 1
## heading 2
### heading 3
> quote
>quote
* listitem
* list item
=> link
=> https://google.com
=>https://example.com Example link
` + "```" + `
preformatted line 1
preformatted line 2
` + "```" + `
that was an empty line
now some regular text lines `
r := strings.NewReader(f)
fp := gemini.NewFileParser(r)
tts := []struct {
t interface{}
content string
extra func(o interface{})
}{
{
gemini.HeadingLine{}, "heading 1",
func(l interface{}) {
assert.Equal(t, 1, l.(gemini.HeadingLine).Level(), "Incorrect heading level: %+v", l)
},
},
{
gemini.HeadingLine{}, "heading 2",
func(l interface{}) {
assert.Equal(t, 2, l.(gemini.HeadingLine).Level(), "Incorrect heading level: %+v", l)
},
},
{
gemini.HeadingLine{}, "heading 3",
func(l interface{}) {
assert.Equal(t, 3, l.(gemini.HeadingLine).Level(), "Incorrect heading level: %+v", l)
},
},
{gemini.QuoteLine{}, "quote", nil},
{gemini.QuoteLine{}, "quote", nil},
{gemini.ListItemLine{}, "listitem", nil},
{gemini.ListItemLine{}, "list item", nil},
{
gemini.LinkLine{}, "=> link",
func(l interface{}) {
link := l.(gemini.LinkLine)
assert.Equal(t, "link", link.Href())
assert.Equal(t, "link", link.Title())
},
},
{
gemini.LinkLine{}, "=> https://google.com",
func(l interface{}) {
link := l.(gemini.LinkLine)
assert.Equal(t, "https://google.com", link.Href())
assert.Equal(t, "https://google.com", link.Title())
},
},
{
gemini.LinkLine{}, "=>https://example.com Example link",
func(l interface{}) {
link := l.(gemini.LinkLine)
assert.Equal(t, "https://example.com", link.Href())
assert.Equal(t, "Example link", link.Title())
},
},
{gemini.PreformattingToggleLine{}, "", nil},
{gemini.PreformattedTextLine{}, "preformatted line 1", nil},
{gemini.PreformattedTextLine{}, " preformatted line 2 ", nil},
{gemini.PreformattingToggleLine{}, "", nil},
{gemini.TextLine{}, "", nil},
{gemini.TextLine{}, "↑ that was an empty line", nil},
{gemini.TextLine{}, "now some regular text lines", nil},
{nil, "", nil},
}
for _, tt := range tts {
line, err := fp.Next()
assert.Nil(t, err)
assert.IsType(t, tt.t, line)
if tt.t != nil {
assert.NotNil(t, line)
assert.Equal(t, tt.content, line.Content())
}
if tt.extra != nil {
tt.extra(line)
}
}
}

Loading…
Cancel
Save