github.com/shohhei1126/hugo@v0.42.2-0.20180623210752-3d5928889ad7/tpl/transform/remarshal.go (about) 1 package transform 2 3 import ( 4 "bytes" 5 "errors" 6 "strings" 7 8 "github.com/gohugoio/hugo/parser" 9 "github.com/spf13/cast" 10 ) 11 12 // Remarshal is used in the Hugo documentation to convert configuration 13 // examples from YAML to JSON, TOML (and possibly the other way around). 14 // The is primarily a helper for the Hugo docs site. 15 // It is not a general purpose YAML to TOML converter etc., and may 16 // change without notice if it serves a purpose in the docs. 17 // Format is one of json, yaml or toml. 18 func (ns *Namespace) Remarshal(format string, data interface{}) (string, error) { 19 from, err := cast.ToStringE(data) 20 if err != nil { 21 return "", err 22 } 23 24 from = strings.TrimSpace(from) 25 format = strings.TrimSpace(strings.ToLower(format)) 26 27 if from == "" { 28 return "", nil 29 } 30 31 mark, err := toFormatMark(format) 32 if err != nil { 33 return "", err 34 } 35 36 fromFormat, err := detectFormat(from) 37 if err != nil { 38 return "", err 39 } 40 41 var metaHandler func(d []byte) (map[string]interface{}, error) 42 43 switch fromFormat { 44 case "yaml": 45 metaHandler = parser.HandleYAMLMetaData 46 case "toml": 47 metaHandler = parser.HandleTOMLMetaData 48 case "json": 49 metaHandler = parser.HandleJSONMetaData 50 } 51 52 meta, err := metaHandler([]byte(from)) 53 if err != nil { 54 return "", err 55 } 56 57 var result bytes.Buffer 58 if err := parser.InterfaceToConfig(meta, mark, &result); err != nil { 59 return "", err 60 } 61 62 return result.String(), nil 63 } 64 65 func toFormatMark(format string) (rune, error) { 66 // TODO(bep) the parser package needs a cleaning. 67 switch format { 68 case "yaml": 69 return rune(parser.YAMLLead[0]), nil 70 case "toml": 71 return rune(parser.TOMLLead[0]), nil 72 case "json": 73 return rune(parser.JSONLead[0]), nil 74 } 75 76 return 0, errors.New("failed to detect target data serialization format") 77 } 78 79 func detectFormat(data string) (string, error) { 80 jsonIdx := strings.Index(data, "{") 81 yamlIdx := strings.Index(data, ":") 82 tomlIdx := strings.Index(data, "=") 83 84 if jsonIdx != -1 && (yamlIdx == -1 || jsonIdx < yamlIdx) && (tomlIdx == -1 || jsonIdx < tomlIdx) { 85 return "json", nil 86 } 87 88 if yamlIdx != -1 && (tomlIdx == -1 || yamlIdx < tomlIdx) { 89 return "yaml", nil 90 } 91 92 if tomlIdx != -1 { 93 return "toml", nil 94 } 95 96 return "", errors.New("failed to detect data serialization format") 97 98 }