diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-01-14 09:57:16 -0700 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-01-14 09:58:32 -0700 |
commit | 0d904f9f10590d3a9117af27151f8c4fe2aea5ff (patch) | |
tree | 95a6f1a0055bdb2120684c239a14c7466a3a117f /gemtext/parse.go | |
parent | aa23984bc21f99e00b8552e928d23ef02bb745f3 (diff) |
Completed gemtext package.
resolves #2
- fuzz testing
- split out line parsing into a separate file
- changed line type-specific public []byte fields to string accessor methods
- added document parsing test for a stress test doc
- added dependency on stretchr/testify
Diffstat (limited to 'gemtext/parse.go')
-rw-r--r-- | gemtext/parse.go | 109 |
1 files changed, 2 insertions, 107 deletions
diff --git a/gemtext/parse.go b/gemtext/parse.go index 4a8c641..7041fde 100644 --- a/gemtext/parse.go +++ b/gemtext/parse.go @@ -2,7 +2,6 @@ package gemtext import ( "bufio" - "bytes" "io" ) @@ -22,12 +21,12 @@ func Parse(input io.Reader) (Document, error) { var line Line if inPFT && (len(raw) < 3 || raw[0] != '`' || raw[1] != '`' || raw[2] != '`') { - line = PreformattedTextLine{raw: raw} + line = PreformattedTextLine{raw: raw} } else { line = ParseLine(raw) } - if line.Type() == LineTypePreformatToggle { + if line != nil && line.Type() == LineTypePreformatToggle { if inPFT { toggle := line.(PreformatToggleLine) (&toggle).clearAlt() @@ -48,107 +47,3 @@ func Parse(input io.Reader) (Document, error) { return Document(lines), nil } - -// ParseLine parses a single line (including the trailing \n) into a gemtext.Line. -func ParseLine(line []byte) Line { - if len(line) == 0 { - return nil - } - - switch line[0] { - case '=': - if len(line) == 1 || line[1] != '>' { - break - } - return parseLinkLine(line) - case '`': - if len(line) < 3 || line[1] != '`' || line[2] != '`' { - break - } - return parsePreformatToggleLine(line) - case '#': - level := 1 - if len(line) > 1 && line[1] == '#' { - level += 1 - if len(line) > 2 && line[2] == '#' { - level += 1 - } - } - return parseHeadingLine(level, line) - case '*': - if len(line) == 1 || line[1] != ' ' { - break - } - return parseListItemLine(line) - case '>': - return parseQuoteLine(line) - } - - return TextLine{raw: line} -} - -func parseLinkLine(raw []byte) LinkLine { - line := LinkLine{raw: raw} - - // move past =>[<whitespace>] - raw = bytes.TrimLeft(raw[2:], " \t") - - // find the next space or tab - spIdx := bytes.IndexByte(raw, ' ') - tbIdx := bytes.IndexByte(raw, '\t') - idx := spIdx - if idx == -1 { - idx = tbIdx - } - if tbIdx >= 0 && tbIdx < idx { - idx = tbIdx - } - - if idx < 0 { - line.URL = bytes.TrimRight(raw, "\r\n") - return line - } - - line.URL = raw[:idx] - raw = raw[idx+1:] - - label := bytes.TrimRight(bytes.TrimLeft(raw, " \t"), "\r\n") - if len(label) > 0 { - line.Label = label - } - - return line -} - -func parsePreformatToggleLine(raw []byte) PreformatToggleLine { - line := PreformatToggleLine{raw: raw} - - raw = bytes.TrimRight(raw[3:], "\r\n") - if len(raw) > 0 { - line.AltText = raw - } - - return line -} - -func parseHeadingLine(level int, raw []byte) HeadingLine { - return HeadingLine{ - raw: raw, - lineType: LineTypeHeading1 - 1 + LineType(level), - Body: bytes.TrimRight(bytes.TrimLeft(raw[level:], " \t"), "\r\n"), - } -} - -func parseListItemLine(raw []byte) ListItemLine { - return ListItemLine{ - raw: raw, - Body: bytes.TrimRight(raw[2:], "\r\n"), - } -} - -func parseQuoteLine(raw []byte) QuoteLine { - return QuoteLine{ - raw: raw, - Body: bytes.TrimRight(raw[1:], "\r\n"), - } -} |