Documentation
¶
Overview ¶
Package tojson converts YAML, TOML, and JSON variants to standard JSON bytes.
The package converts source bytes to JSON, then they can be unmarshalled using standard json struct tags.
raw, err := tojson.FromYAML(src)
if err != nil { ... }
if err = json.Unmarshal(raw, &cfg); err != nil { ... }
The package exposes four top-level functions:
tojson.FromJSONVariant(src []byte) ([]byte, error) tojson.FromYAML(src []byte) ([]byte, error) tojson.FromTOML(src []byte) ([]byte, error) tojson.FromFrontMatter(src []byte) (meta []byte, body []byte, err error)
FromYAML intentionally supports a practical YAML subset for config files and front matter, not the full YAML specification.
FromFrontMatter handles documents that embed metadata in a front matter block before the main content, as used by Hugo, Jekyll, and similar static site generators. It detects the format from the opening sentinel and returns the metadata as JSON and the body separately:
meta, body, err := tojson.FromFrontMatter(src)
if err != nil { ... }
if meta != nil {
if err := json.Unmarshal(meta, &article); err != nil { ... }
}
// use body (markdown, etc.)
Parse failures are returned as *ParseError, which carries a 1-based line and column number and can be inspected with errors.As:
var pe *tojson.ParseError
if errors.As(err, &pe) {
fmt.Printf("line %d, column %d: %s\n", pe.Line, pe.Column, pe.Message)
}
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FromFrontMatter ¶
FromFrontMatter splits a document into a front matter block and a body, converts the front matter to JSON, and returns both.
Supported opening/closing sentinel pairs:
--- / --- YAML
---yaml / --- YAML (explicit qualifier)
---toml / --- TOML (explicit qualifier)
---json / --- JSON (explicit qualifier)
+++ / +++ TOML
{ / } JSON (each sentinel must be the only character on its line)
Trailing whitespace on sentinel lines is ignored on both open and close, since invisible characters cause hard-to-diagnose authoring errors.
A ---<qualifier> opening that is not one of the recognised qualifiers above returns an error rather than silently treating the file as having no front matter, so typos like "---yml" are caught immediately.
A missing closing sentinel is an error. Silently returning no metadata would risk leaking private front matter fields into the document body; silently parsing the entire file as metadata would produce a confusing error far from the actual problem.
On success, meta is compact JSON and body is the bytes after the closing sentinel line. If no recognised front matter opening is detected, meta is nil, body is the full input, and err is nil. Parse failures inside the front matter block are returned as *ParseError.
Example ¶
package main
import (
"encoding/json"
"fmt"
"github.com/client9/tojson"
)
func main() {
type Article struct {
Title string `json:"title"`
Author string `json:"author"`
}
src := []byte("---\ntitle: Hello World\nauthor: Alice\n---\nThis is the body.\n")
meta, body, err := tojson.FromFrontMatter(src)
if err != nil {
panic(err)
}
var article Article
if err := json.Unmarshal(meta, &article); err != nil {
panic(err)
}
fmt.Printf("title: %s\n", article.Title)
fmt.Printf("author: %s\n", article.Author)
fmt.Printf("body: %s", body)
}
Output: title: Hello World author: Alice body: This is the body.
func FromJSONVariant ¶
FromJSONVariant converts JSON and common JSON-derived variants to standard JSON. It handles JSON5/HuJSON/JWCC/JSONC/HanSON features such as trailing/leading commas, line and block comments, unquoted keys, single-quoted and backtick strings, and hex literals.
Example ¶
package main
import (
"fmt"
"github.com/client9/tojson"
)
func main() {
src := []byte(`
{
// comments are allowed
unquoted: 'value',
hex: 0x2a,
trailing: [1, 2, 3,],
}
`)
raw, err := tojson.FromJSONVariant(src)
if err != nil {
panic(err)
}
fmt.Println(string(raw))
}
Output: {"unquoted":"value","hex":42,"trailing":[1,2,3]}
func FromTOML ¶
FromTOML converts TOML to standard JSON. The output can be passed directly to encoding/json.Unmarshal using only json struct tags.
Example ¶
package main
import (
"encoding/json"
"fmt"
"github.com/client9/tojson"
)
func main() {
type Article struct {
Title string `json:"title"`
Author string `json:"author"`
}
src := []byte("title = \"hello-world\"\nauthor = \"alice\"\n")
raw, err := tojson.FromTOML(src)
if err != nil {
panic(err)
}
var article Article
if err := json.Unmarshal(raw, &article); err != nil {
panic(err)
}
fmt.Printf("%+v\n", article)
}
Output: {Title:hello-world Author:alice}
func FromYAML ¶
FromYAML converts a YAML subset to standard JSON. The output can be passed directly to encoding/json.Unmarshal using only json struct tags. Anchors/aliases, tags, and complex keys are not supported.
Example ¶
package main
import (
"encoding/json"
"fmt"
"github.com/client9/tojson"
)
func main() {
type Article struct {
Title string `json:"title"`
Author string `json:"author"`
Draft bool `json:"draft"`
}
src := []byte("title: hello-world\nauthor: alice\ndraft: false\n")
raw, err := tojson.FromYAML(src)
if err != nil {
panic(err)
}
var article Article
if err := json.Unmarshal(raw, &article); err != nil {
panic(err)
}
fmt.Printf("%+v\n", article)
}
Output: {Title:hello-world Author:alice Draft:false}
Types ¶
type ParseError ¶
type ParseError struct {
Line int // 1-based line number in the original input
Column int // 1-based column number
Message string // description of the problem
}
ParseError is returned by all From* functions when the input cannot be parsed. Line and Column are always 1-based.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/client9/tojson"
)
func main() {
_, err := tojson.FromJSONVariant([]byte("{ unclosed: [1, 2, }"))
if err != nil {
var pe *tojson.ParseError
if errors.As(err, &pe) {
fmt.Printf("line %d, column %d: %s\n", pe.Line, pe.Column, pe.Message)
}
}
}
Output: line 1, column 20: unmatched object end, level=2, stack="{["
func (*ParseError) Error ¶
func (e *ParseError) Error() string