commit 2f3a44489405719c60f6bd9c29de99f17f0e947b
parent 0a5905e8e6dda95a77cb337806aad4cdbc8116cc
Author: Byron Torres <b@torresjrjr.com>
Date: Sun, 2 May 2021 23:40:32 +0100
Fixed empty key bug, error msg bug
Diffstat:
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/nestedtext.go b/nestedtext.go
@@ -17,7 +17,7 @@ var (
reLeadingWs = regexp.MustCompile(`^\s*`)
reComment = regexp.MustCompile(`^\s*(#.*)?$`)
reKeyValue = regexp.MustCompile(`^\s*[^:]*: .*$`)
- reKeyEmpty = regexp.MustCompile(`^\s*[^:]*: ?$`)
+ reKeyEmpty = regexp.MustCompile(`^\s*[^:]*:$`)
reListValue = regexp.MustCompile(`^\s*- .*$`)
reListEmpty = regexp.MustCompile(`^\s*- ?$`)
reMultiline = regexp.MustCompile(`^\s*>( .*)?$`)
@@ -43,11 +43,11 @@ func main() {
func UnmarshalNestedText(r io.Reader) (interface{}, error) {
scanner := bufio.NewScanner(r)
lineNumber := 0
- return parseNestedText(scanner, "", &lineNumber, true)
+ return parseNestedText(scanner, &lineNumber, "", Unknown)
}
func parseNestedText(
- scanner *bufio.Scanner, parentIndent string, lineNum *int, root bool,
+ scanner *bufio.Scanner, lineNum *int, parentIndent string, parentType BlockType,
) (interface{}, error) {
var blockType BlockType = Unknown
var dict map[string]interface{}
@@ -56,16 +56,17 @@ func parseNestedText(
var localIndentDefined bool
var localIndent string
- var skip bool
+ var skipNextScan bool
for {
- if !skip {
- if !scanner.Scan() {
+ if skipNextScan {
+ skipNextScan = false
+ } else {
+ ok := scanner.Scan()
+ if !ok {
break
}
*lineNum++
- } else {
- skip = false
}
rawLine := scanner.Text()
@@ -78,12 +79,20 @@ func parseNestedText(
if !localIndentDefined {
localIndent = currentIndent
localIndentDefined = true
- } else if (currentIndent != localIndent) ||
- !strings.HasPrefix(localIndent, parentIndent) {
+ } else if currentIndent != localIndent {
// indented leftwards, leaf has finished.
break
}
+ if parentType != Unknown && currentIndent == parentIndent {
+ // previous line was a list '-\n' or key ':\n' marker
+ // but this line is not the value of the previous line
+ // as it is on the same indentation level.
+ // As such, that list element or key's value should be
+ // interpreted as "".
+ return "", nil
+ }
+
// the effective current line
line := strings.TrimPrefix(rawLine, localIndent)
@@ -135,24 +144,24 @@ func parseNestedText(
}
key = strings.TrimSpace(key)
- child, err := parseNestedText(scanner, localIndent, lineNum, false)
+ child, err := parseNestedText(scanner, lineNum, localIndent, blockType)
if err != nil {
return nil, err
}
dict[key] = child
- skip = true
+ skipNextScan = true
case reListValue.MatchString(line):
value := strings.TrimPrefix(line, "- ")
list = append(list, value)
case reListEmpty.MatchString(line):
- child, err := parseNestedText(scanner, localIndent, lineNum, false)
+ child, err := parseNestedText(scanner, lineNum, localIndent, blockType)
if err != nil {
return nil, err
}
list = append(list, child)
- skip = true
+ skipNextScan = true
case reMultiline.MatchString(line):
var oneline string
@@ -163,7 +172,7 @@ func parseNestedText(
default:
errmsg := "Internal error - unknown linetype of line %d"
- return nil, fmt.Errorf(errmsg, &lineNum)
+ return nil, fmt.Errorf(errmsg, *lineNum)
}
}
@@ -179,7 +188,7 @@ func parseNestedText(
case Multiline:
return multiline, nil
default:
- return nil, fmt.Errorf("Internal error - line %d", &lineNum)
+ return nil, fmt.Errorf("Internal error - line %d", *lineNum)
}
}