This repository has been archived on 2023-05-01. You can view files and clone it, but cannot push or open issues or pull requests.
gus/gemtext/parse_line.go

108 lines
2.0 KiB
Go

package gemtext
import "bytes"
// 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"),
}
}