tpl/transform: Add transform.Unmarshal func

Fixes #5428
This commit is contained in:
Bjørn Erik Pedersen
2018-12-21 16:21:13 +01:00
parent 43f9df0194
commit 822dc627a1
20 changed files with 633 additions and 74 deletions

View File

@@ -17,6 +17,8 @@ import (
"path/filepath"
"strings"
"github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/parser/pageparser"
)
@@ -55,6 +57,18 @@ func FormatFromString(formatStr string) Format {
}
// FormatFromMediaType gets the Format given a MIME type, empty string
// if unknown.
func FormatFromMediaType(m media.Type) Format {
for _, suffix := range m.Suffixes {
if f := FormatFromString(suffix); f != "" {
return f
}
}
return ""
}
// FormatFromFrontMatterType will return empty if not supported.
func FormatFromFrontMatterType(typ pageparser.ItemType) Format {
switch typ {
@@ -70,3 +84,39 @@ func FormatFromFrontMatterType(typ pageparser.ItemType) Format {
return ""
}
}
// FormatFromContentString tries to detect the format (JSON, YAML or TOML)
// in the given string.
// It return an empty string if no format could be detected.
func FormatFromContentString(data string) Format {
jsonIdx := strings.Index(data, "{")
yamlIdx := strings.Index(data, ":")
tomlIdx := strings.Index(data, "=")
if isLowerIndexThan(jsonIdx, yamlIdx, tomlIdx) {
return JSON
}
if isLowerIndexThan(yamlIdx, tomlIdx) {
return YAML
}
if tomlIdx != -1 {
return TOML
}
return ""
}
func isLowerIndexThan(first int, others ...int) bool {
if first == -1 {
return false
}
for _, other := range others {
if other != -1 && other < first {
return false
}
}
return true
}

View File

@@ -17,6 +17,8 @@ import (
"fmt"
"testing"
"github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/parser/pageparser"
"github.com/stretchr/testify/require"
@@ -41,6 +43,21 @@ func TestFormatFromString(t *testing.T) {
}
}
func TestFormatFromMediaType(t *testing.T) {
assert := require.New(t)
for i, test := range []struct {
m media.Type
expect Format
}{
{media.JSONType, JSON},
{media.YAMLType, YAML},
{media.TOMLType, TOML},
{media.CalendarType, ""},
} {
assert.Equal(test.expect, FormatFromMediaType(test.m), fmt.Sprintf("t%d", i))
}
}
func TestFormatFromFrontMatterType(t *testing.T) {
assert := require.New(t)
for i, test := range []struct {
@@ -56,3 +73,28 @@ func TestFormatFromFrontMatterType(t *testing.T) {
assert.Equal(test.expect, FormatFromFrontMatterType(test.typ), fmt.Sprintf("t%d", i))
}
}
func TestFormatFromContentString(t *testing.T) {
t.Parallel()
assert := require.New(t)
for i, test := range []struct {
data string
expect interface{}
}{
{`foo = "bar"`, TOML},
{` foo = "bar"`, TOML},
{`foo="bar"`, TOML},
{`foo: "bar"`, YAML},
{`foo:"bar"`, YAML},
{`{ "foo": "bar"`, JSON},
{`asdfasdf`, Format("")},
{``, Format("")},
} {
errMsg := fmt.Sprintf("[%d] %s", i, test.data)
result := FormatFromContentString(test.data)
assert.Equal(test.expect, result, errMsg)
}
}