aboutsummaryrefslogtreecommitdiff
path: root/internal/ini
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ini')
-rw-r--r--internal/ini/ini.go27
-rw-r--r--internal/ini/ini_test.go13
2 files changed, 19 insertions, 21 deletions
diff --git a/internal/ini/ini.go b/internal/ini/ini.go
index b4fc955..36277e0 100644
--- a/internal/ini/ini.go
+++ b/internal/ini/ini.go
@@ -1,7 +1,10 @@
// Package ini is a tiny dependency-free reader for the boring INI files lectio
// uses for config and calendar data: [sections] (including "a/b" subsections),
-// "key = value" pairs (keys may be dotted, e.g. name.pl), and "#"/";" comments.
-// It preserves order and never interprets values beyond trimming.
+// "key = value" pairs (keys may be dotted, e.g. name.pl), and full-line
+// "#"/";" comments. Comments are FULL-LINE only (a line whose first non-blank
+// character is # or ;); values are kept verbatim so scripture citations may
+// contain ";" and "#". It preserves order and never interprets values beyond
+// trimming surrounding whitespace.
package ini
import (
@@ -27,10 +30,9 @@ func Parse(data []byte) ([]Section, error) {
line := 0
for sc.Scan() {
line++
- raw := stripComment(sc.Text())
- s := strings.TrimSpace(raw)
- if s == "" {
- continue
+ s := strings.TrimSpace(sc.Text())
+ if s == "" || strings.HasPrefix(s, "#") || strings.HasPrefix(s, ";") {
+ continue // blank or full-line comment
}
if strings.HasPrefix(s, "[") {
if !strings.HasSuffix(s, "]") {
@@ -45,24 +47,13 @@ func Parse(data []byte) ([]Section, error) {
return nil, fmt.Errorf("ini: line %d: expected key = value, got %q", line, s)
}
key := strings.TrimSpace(s[:eq])
- val := strings.TrimSpace(s[eq+1:])
+ val := strings.TrimSpace(s[eq+1:]) // verbatim (may contain ';' or '#')
cur := &secs[len(secs)-1]
cur.Pairs = append(cur.Pairs, Pair{key, val})
}
return secs, sc.Err()
}
-// stripComment removes a trailing "#" or ";" comment (our values never contain
-// an unescaped # or ;).
-func stripComment(line string) string {
- for i := 0; i < len(line); i++ {
- if line[i] == '#' || line[i] == ';' {
- return line[:i]
- }
- }
- return line
-}
-
// List splits a comma-separated value, trimming spaces and dropping empties.
func List(val string) []string {
var out []string
diff --git a/internal/ini/ini_test.go b/internal/ini/ini_test.go
index d454388..16aef7b 100644
--- a/internal/ini/ini_test.go
+++ b/internal/ini/ini_test.go
@@ -4,13 +4,15 @@ import "testing"
func TestParseSectionsAndPairs(t *testing.T) {
in := []byte(`
-# a comment
-lectionary = new ; trailing comment
+# a full-line comment
+; another full-line comment
+lectionary = new
[assumption]
date = 08-15
-name.pl = Wniebowzięcie ; unicode ok
+name.pl = Wniebowzięcie
rank= solemnity
+reading.first = Rev 11:19; 12:1-6.10
[assumption/vigil]
reading.gospel = Łk 11,27-28
@@ -29,6 +31,11 @@ reading.gospel = Łk 11,27-28
if secs[1].Pairs[2] != (Pair{"rank", "solemnity"}) {
t.Fatalf("no-space key = %+v", secs[1].Pairs[2])
}
+ // a semicolon inside a value (scripture citation) is preserved, not treated
+ // as a comment.
+ if got := secs[1].Pairs[3]; got != (Pair{"reading.first", "Rev 11:19; 12:1-6.10"}) {
+ t.Fatalf("citation with ';' mangled: %+v", got)
+ }
if secs[2].Name != "assumption/vigil" {
t.Fatalf("subsection = %q", secs[2].Name)
}