diff --git a/ini.go b/ini.go index 93424f6..b1f7c88 100644 --- a/ini.go +++ b/ini.go @@ -170,6 +170,8 @@ type LoadOptions struct { UnparseableSections []string // KeyValueDelimiters is the sequence of delimiters that are used to separate key and value. By default, it is "=:". KeyValueDelimiters string + // PreserveSurroundedQuote indicates whether to preserve surrounded quote + PreserveSurroundedQuote bool } func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) { diff --git a/ini_test.go b/ini_test.go index a8c257b..7ec7038 100644 --- a/ini_test.go +++ b/ini_test.go @@ -1248,3 +1248,35 @@ key2!value2 So(f.Section("section").Key("key2").String(), ShouldEqual, "value2") }) } + +func Test_PreserveSurroundedQuote(t *testing.T) { + Convey("Preserve surrounded quote test", t, func() { + f, err := ini.LoadSources(ini.LoadOptions{ + PreserveSurroundedQuote: true, + }, []byte(` +[section] +key1 = "value1" +key2 = value2 +`)) + So(err, ShouldBeNil) + So(f, ShouldNotBeNil) + + So(f.Section("section").Key("key1").String(), ShouldEqual, "\"value1\"") + So(f.Section("section").Key("key2").String(), ShouldEqual, "value2") + }) + + Convey("Preserve surrounded quote test inverse test", t, func() { + f, err := ini.LoadSources(ini.LoadOptions{ + PreserveSurroundedQuote: false, + }, []byte(` +[section] +key1 = "value1" +key2 = value2 +`)) + So(err, ShouldBeNil) + So(f, ShouldNotBeNil) + + So(f.Section("section").Key("key1").String(), ShouldEqual, "value1") + So(f.Section("section").Key("key2").String(), ShouldEqual, "value2") + }) +} diff --git a/parser.go b/parser.go index 24cf11c..f20073d 100644 --- a/parser.go +++ b/parser.go @@ -198,7 +198,7 @@ func hasSurroundedQuote(in string, quote byte) bool { func (p *parser) readValue(in []byte, parserBufferSize int, - ignoreContinuation, ignoreInlineComment, unescapeValueDoubleQuotes, unescapeValueCommentSymbols, allowPythonMultilines, spaceBeforeInlineComment bool) (string, error) { + ignoreContinuation, ignoreInlineComment, unescapeValueDoubleQuotes, unescapeValueCommentSymbols, allowPythonMultilines, spaceBeforeInlineComment, preserveSurroundedQuote bool) (string, error) { line := strings.TrimLeftFunc(string(in), unicode.IsSpace) if len(line) == 0 { @@ -259,8 +259,8 @@ func (p *parser) readValue(in []byte, } // Trim single and double quotes - if hasSurroundedQuote(line, '\'') || - hasSurroundedQuote(line, '"') { + if (hasSurroundedQuote(line, '\'') || + hasSurroundedQuote(line, '"')) && !preserveSurroundedQuote { line = line[1 : len(line)-1] } else if len(valQuote) == 0 && unescapeValueCommentSymbols { if strings.Contains(line, `\;`) { @@ -433,7 +433,8 @@ func (f *File) parse(reader io.Reader) (err error) { f.options.UnescapeValueDoubleQuotes, f.options.UnescapeValueCommentSymbols, f.options.AllowPythonMultilineValues, - f.options.SpaceBeforeInlineComment) + f.options.SpaceBeforeInlineComment, + f.options.PreserveSurroundedQuote) if err != nil { return err } @@ -467,7 +468,8 @@ func (f *File) parse(reader io.Reader) (err error) { f.options.UnescapeValueDoubleQuotes, f.options.UnescapeValueCommentSymbols, f.options.AllowPythonMultilineValues, - f.options.SpaceBeforeInlineComment) + f.options.SpaceBeforeInlineComment, + f.options.PreserveSurroundedQuote) if err != nil { return err }