mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parser/metadecoders: Add CSV lazyQuotes option to transform.Unmarshal
If true, a quote may appear in an unquoted field and a non-doubled quote may appear in a quoted field. It defaults to false. Closes #11884
This commit is contained in:
parent
911bc60a7a
commit
912c6576bb
3 changed files with 36 additions and 0 deletions
|
@ -125,6 +125,9 @@ delimiter
|
||||||
comment
|
comment
|
||||||
: (`string`) The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.
|
: (`string`) The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.
|
||||||
|
|
||||||
|
lazyQuotes
|
||||||
|
: (`bool`) If true, a quote may appear in an unquoted field and a non-doubled quote may appear in a quoted field. Default is `false`.
|
||||||
|
|
||||||
```go-html-template
|
```go-html-template
|
||||||
{{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }}
|
{{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }}
|
||||||
```
|
```
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/herrors"
|
"github.com/gohugoio/hugo/common/herrors"
|
||||||
|
@ -41,6 +42,10 @@ type Decoder struct {
|
||||||
// Comment, if not 0, is the comment character used in the CSV decoder. Lines beginning with the
|
// Comment, if not 0, is the comment character used in the CSV decoder. Lines beginning with the
|
||||||
// Comment character without preceding whitespace are ignored.
|
// Comment character without preceding whitespace are ignored.
|
||||||
Comment rune
|
Comment rune
|
||||||
|
|
||||||
|
// If true, a quote may appear in an unquoted field and a non-doubled quote
|
||||||
|
// may appear in a quoted field. It defaults to false.
|
||||||
|
LazyQuotes bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// OptionsKey is used in cache keys.
|
// OptionsKey is used in cache keys.
|
||||||
|
@ -48,6 +53,7 @@ func (d Decoder) OptionsKey() string {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
sb.WriteRune(d.Delimiter)
|
sb.WriteRune(d.Delimiter)
|
||||||
sb.WriteRune(d.Comment)
|
sb.WriteRune(d.Comment)
|
||||||
|
sb.WriteString(strconv.FormatBool(d.LazyQuotes))
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +211,7 @@ func (d Decoder) unmarshalCSV(data []byte, v any) error {
|
||||||
r := csv.NewReader(bytes.NewReader(data))
|
r := csv.NewReader(bytes.NewReader(data))
|
||||||
r.Comma = d.Delimiter
|
r.Comma = d.Delimiter
|
||||||
r.Comment = d.Comment
|
r.Comment = d.Comment
|
||||||
|
r.LazyQuotes = d.LazyQuotes
|
||||||
|
|
||||||
records, err := r.ReadAll()
|
records, err := r.ReadAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -107,3 +107,29 @@ disableKinds = ['page','rss','section','sitemap','taxonomy','term']
|
||||||
_, err := b.BuildE()
|
_, err := b.BuildE()
|
||||||
b.Assert(err.Error(), qt.Contains, "error calling highlight: invalid Highlight option: 0")
|
b.Assert(err.Error(), qt.Contains, "error calling highlight: invalid Highlight option: 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #11884
|
||||||
|
func TestUnmarshalCSVLazyDecoding(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
|
||||||
|
-- assets/pets.csv --
|
||||||
|
name,description,age
|
||||||
|
Spot,a nice dog,3
|
||||||
|
Rover,"a big dog",5
|
||||||
|
Felix,a "malicious" cat,7
|
||||||
|
Bella,"an "evil" cat",9
|
||||||
|
Scar,"a "dead cat",11
|
||||||
|
-- layouts/index.html --
|
||||||
|
{{ $opts := dict "lazyQuotes" true }}
|
||||||
|
{{ $data := resources.Get "pets.csv" | transform.Unmarshal $opts }}
|
||||||
|
{{ printf "%v" $data | safeHTML }}
|
||||||
|
`
|
||||||
|
b := hugolib.Test(t, files)
|
||||||
|
|
||||||
|
b.AssertFileContent("public/index.html", `
|
||||||
|
[[name description age] [Spot a nice dog 3] [Rover a big dog 5] [Felix a "malicious" cat 7] [Bella an "evil" cat 9] [Scar a "dead cat 11]]
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue