summaryrefslogtreecommitdiff
path: root/gemtext/parse.go
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-01-14 09:57:16 -0700
committertjpcc <tjp@ctrl-c.club>2023-01-14 09:58:32 -0700
commit0d904f9f10590d3a9117af27151f8c4fe2aea5ff (patch)
tree95a6f1a0055bdb2120684c239a14c7466a3a117f /gemtext/parse.go
parentaa23984bc21f99e00b8552e928d23ef02bb745f3 (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.go109
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"),
- }
-}