hugo/tpl/transform/remarshal.go
Bjørn Erik Pedersen bfb9613a14
Add Goldmark as the new default markdown handler
This commit adds the fast and CommonMark compliant Goldmark as the new default markdown handler in Hugo.

If you want to continue using BlackFriday as the default for md/markdown extensions, you can use this configuration:

```toml
[markup]
defaultMarkdownHandler="blackfriday"
```

Fixes #5963
Fixes #1778
Fixes #6355
2019-11-23 14:12:24 +01:00

88 lines
2.1 KiB
Go

package transform
import (
"bytes"
"strings"
"github.com/pkg/errors"
"github.com/gohugoio/hugo/parser"
"github.com/gohugoio/hugo/parser/metadecoders"
"github.com/spf13/cast"
)
// Remarshal is used in the Hugo documentation to convert configuration
// examples from YAML to JSON, TOML (and possibly the other way around).
// The is primarily a helper for the Hugo docs site.
// It is not a general purpose YAML to TOML converter etc., and may
// change without notice if it serves a purpose in the docs.
// Format is one of json, yaml or toml.
func (ns *Namespace) Remarshal(format string, data interface{}) (string, error) {
var meta map[string]interface{}
format = strings.TrimSpace(strings.ToLower(format))
mark, err := toFormatMark(format)
if err != nil {
return "", err
}
if m, ok := data.(map[string]interface{}); ok {
meta = m
} else {
from, err := cast.ToStringE(data)
if err != nil {
return "", err
}
from = strings.TrimSpace(from)
if from == "" {
return "", nil
}
fromFormat := metadecoders.Default.FormatFromContentString(from)
if fromFormat == "" {
return "", errors.New("failed to detect format from content")
}
meta, err = metadecoders.Default.UnmarshalToMap([]byte(from), fromFormat)
if err != nil {
return "", err
}
}
// Make it so 1.0 float64 prints as 1 etc.
applyMarshalTypes(meta)
var result bytes.Buffer
if err := parser.InterfaceToConfig(meta, mark, &result); err != nil {
return "", err
}
return result.String(), nil
}
// The unmarshal/marshal dance is extremely type lossy, and we need
// to make sure that integer types prints as "43" and not "43.0" in
// all formats, hence this hack.
func applyMarshalTypes(m map[string]interface{}) {
for k, v := range m {
switch t := v.(type) {
case map[string]interface{}:
applyMarshalTypes(t)
case float64:
i := int64(t)
if t == float64(i) {
m[k] = i
}
}
}
}
func toFormatMark(format string) (metadecoders.Format, error) {
if f := metadecoders.FormatFromString(format); f != "" {
return f, nil
}
return "", errors.New("failed to detect target data serialization format")
}