mirror of
https://github.com/wader/fq.git
synced 2024-11-21 23:04:07 +03:00
yaml,toml: Add indent option for to_{toml,yaml}
This commit is contained in:
parent
6ac571300a
commit
ed872d4b07
48
doc/usage.md
48
doc/usage.md
@ -682,18 +682,20 @@ name: Afghanistan
|
|||||||
zip> ^D
|
zip> ^D
|
||||||
```
|
```
|
||||||
|
|
||||||
- `from_xml`/`from_xml($opts)` Parse XML into jq value.<br>
|
- `from_xml`/`from_xml($opts)` Parse XML into jq value. `$opts` are:
|
||||||
`{seq: true}` preserve element ordering if more than one sibling.<br>
|
- `{seq: true}` preserve element ordering if more than one sibling.<br>
|
||||||
`{array: true}` use nested `[name, attributes, children]` arrays to represent elements. Attributes will be `null` if none and children will be `[]` if none, this is to make it easier to work with as the array as 3 values. `to_xml` does not require this.<br>
|
- `{array: true}` use nested `[name, attributes, children]` arrays to represent elements. Attributes will be `null` if none and children will be `[]` if none, this is to make it easier to work with as the array as 3 values. `to_xml` does not require this.<br>
|
||||||
- `from_html`/`from_html($opts)` Parse HTML into jq value.<br>
|
- `from_html`/`from_html($opts)` Parse HTML into jq value.<br>
|
||||||
Similar to `from_xml` but parses html5 in non-script mode. Will always have a `html` root with `head` and `body` elements.<br>
|
Similar to `from_xml` but parses html5 in non-script mode. Will always have a `html` root with `head` and `body` elements.<br>
|
||||||
`{array: true}` use nested arrays to represent elements.<br>
|
`$opts` are:
|
||||||
`{seq: true}` preserve element ordering if more than one sibling.<br>
|
- `{array: true}` use nested arrays to represent elements.<br>
|
||||||
|
- `{seq: true}` preserve element ordering if more than one sibling.<br>
|
||||||
- `to_xml`/`to_xml($opts})` Serialize jq value into XML.<br>
|
- `to_xml`/`to_xml($opts})` Serialize jq value into XML.<br>
|
||||||
`{indent: number}` indent child elements.<br>
|
|
||||||
Assumes object representation if input is an object, and nested arrays if input is an array.<br>
|
Assumes object representation if input is an object, and nested arrays if input is an array.<br>
|
||||||
Will automatically add a root `doc` element if jq value has more then one root element.<br>
|
Will automatically add a root `doc` element if jq value has more then one root element.<br>
|
||||||
If a `#seq` is found on at least one element all siblings will be sort by sequence number. Attributes are always sorted.<br>
|
If a `#seq` is found on at least one element all siblings will be sort by sequence number. Attributes are always sorted.<br>
|
||||||
|
`$opts` are:
|
||||||
|
- `{indent: number}` indent child elements.<br>
|
||||||
|
|
||||||
XML elements can be represented as jq value in two ways, as objects (inspired by [mxj](https://github.com/clbanning/mxj) and [xml.com's Converting Between XML and JSON
|
XML elements can be represented as jq value in two ways, as objects (inspired by [mxj](https://github.com/clbanning/mxj) and [xml.com's Converting Between XML and JSON
|
||||||
](https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html)) or nested arrays. Both representations are lossy and might lose ordering of elements, text nodes and comments. In object representation `from_xml`, `from_html` and `to_xml` support `{seq:true}` option to parse/serialize `{"#seq"=<number>}` attributes to preserve element sibling ordering.
|
](https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html)) or nested arrays. Both representations are lossy and might lose ordering of elements, text nodes and comments. In object representation `from_xml`, `from_html` and `to_xml` support `{seq:true}` option to parse/serialize `{"#seq"=<number>}` attributes to preserve element sibling ordering.
|
||||||
@ -801,12 +803,11 @@ zip> ^D
|
|||||||
|
|
||||||
JSON and jq-flavoured JSON
|
JSON and jq-flavoured JSON
|
||||||
- `fromjson` Parse JSON into jq value.
|
- `fromjson` Parse JSON into jq value.
|
||||||
- `tojson`/`tojson($opt)` Serialize jq value into JSON.<br>
|
- `tojson`/`tojson($opts)` Serialize jq value into JSON. `$opts` are:
|
||||||
`{indent: number}` indent array/object values.<br>
|
- `{indent: number}` Indent depth.
|
||||||
- `from_jq` Parse jq-flavoured JSON into jq value.
|
- `from_jq` Parse jq-flavoured JSON into jq value.
|
||||||
- `to_jq`/`to_jq($opt)` Serialize jq value into jq-flavoured JSON<br>
|
- `to_jq`/`to_jq($opts)` Serialize jq value into jq-flavoured JSON. jq-flavoured JSON has optional key quotes, `#` comments and can have trailing comma in arrays. `$opts` are:
|
||||||
`{indent: number}` indent array/object values.<br>
|
- `{indent: number}` Indent depth.
|
||||||
jq-flavoured JSON has optional key quotes, `#` comments and can have trailing comma in arrays.
|
|
||||||
- `from_jsonl` Parse JSON lines into jq array.
|
- `from_jsonl` Parse JSON lines into jq array.
|
||||||
- `to_jsonl` Serialize jq array into JSONL.
|
- `to_jsonl` Serialize jq array into JSONL.
|
||||||
|
|
||||||
@ -814,19 +815,22 @@ Note that `fromjson` and `tojson` use different naming conventions as they origi
|
|||||||
|
|
||||||
YAML
|
YAML
|
||||||
- `from_yaml` Parse YAML into jq value.
|
- `from_yaml` Parse YAML into jq value.
|
||||||
- `to_yaml` Serialize jq value into YAML.
|
- `to_yaml`/`to_yaml($opts)` Serialize jq value into YAML. `$opts` are:
|
||||||
|
- `{indent: number}` Indent depth.
|
||||||
|
|
||||||
TOML
|
TOML
|
||||||
- `from_toml` Parse TOML into jq value.
|
- `from_toml` Parse TOML into jq value.
|
||||||
- `to_toml` Serialize jq value into TOML.
|
- `to_toml`/`to_toml($opts)` Serialize jq value into TOML. `$opts` are:
|
||||||
|
- `{indent: number}` Indent depth.
|
||||||
|
|
||||||
CSV
|
CSV
|
||||||
- `from_csv`/`from_cvs($opts)` Parse CSV into jq value.<br>
|
- `from_csv`/`from_cvs($opts)` Parse CSV into jq value.<br>
|
||||||
`{comma: string}` field separator, default ",".<br>
|
To work with tab separated values you can use `fromcvs({comma: "\t"})` or `fq -d csv -o 'comma="\t"'`<br>
|
||||||
`{comment: string}` comment line character, default "#".<br>
|
`$opts` are:
|
||||||
To work with tab separated values you can use `fromcvs({comma: "\t"})` or `fq -d csv -o 'comma="\t"'`
|
- `{comma: string}` field separator, default ",".<br>
|
||||||
- `to_csv`/`to_csv($opts)` Serialize jq value into CSV.<br>
|
- `{comment: string}` comment line character, default "#".<br>
|
||||||
`{comma: string}` field separator, default ",".<br>
|
- `to_csv`/`to_csv($opts)` Serialize jq value into CSV. `$opts` are:
|
||||||
|
- `{comma: string}` field separator, default ",".<br>
|
||||||
|
|
||||||
XML encoding
|
XML encoding
|
||||||
- `from_xmlentities` Decode XML entities.
|
- `from_xmlentities` Decode XML entities.
|
||||||
@ -862,10 +866,10 @@ URL parts and XML encodings
|
|||||||
Binary encodings like hex and base64
|
Binary encodings like hex and base64
|
||||||
- `from_hex` Decode hex string to binary.
|
- `from_hex` Decode hex string to binary.
|
||||||
- `to_hex` Encode binary into hex string.
|
- `to_hex` Encode binary into hex string.
|
||||||
- `from_base64`/`from_base64($opts)` Decode base64 encodings into binary.<br>
|
- `from_base64`/`from_base64($opts)` Decode base64 encodings into binary. `$opts` are:
|
||||||
`{encoding:string}` encoding variant: `std` (default), `url`, `rawstd` or `rawurl`
|
- `{encoding:string}` encoding variant: `std` (default), `url`, `rawstd` or `rawurl`
|
||||||
- `to_base64`/`to_base64($opts)` Encode binary into base64 encodings.<br>
|
- `to_base64`/`to_base64($opts)` Encode binary into base64 encodings. `$opts` are:
|
||||||
`{encoding:string}` encoding variant: `std` (default), `url`, `rawstd` or `rawurl`
|
- `{encoding:string}` encoding variant: `std` (default), `url`, `rawstd` or `rawurl`
|
||||||
|
|
||||||
Hash functions
|
Hash functions
|
||||||
- `to_md4` Hash binary using md4.
|
- `to_md4` Hash binary using md4.
|
||||||
|
29
format/toml/testdata/indent.fqtest
vendored
Normal file
29
format/toml/testdata/indent.fqtest
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
$ fq -rn "{a: {b: 123}} | to_toml"
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
$ fq -rn "{a: {b: 123}} | to_toml({indent: range(8)})"
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
||||||
|
[a]
|
||||||
|
b = 123
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
@ -31,7 +32,7 @@ func init() {
|
|||||||
Functions: []string{"_todisplay"},
|
Functions: []string{"_todisplay"},
|
||||||
})
|
})
|
||||||
interp.RegisterFS(tomlFS)
|
interp.RegisterFS(tomlFS)
|
||||||
interp.RegisterFunc0("to_toml", toTOML)
|
interp.RegisterFunc1("_to_toml", toTOML)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeTOMLSeekFirstValidRune(br io.ReadSeeker) error {
|
func decodeTOMLSeekFirstValidRune(br io.ReadSeeker) error {
|
||||||
@ -88,13 +89,19 @@ func decodeTOML(d *decode.D) any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTOML(_ *interp.Interp, c any) any {
|
type ToTOMLOpts struct {
|
||||||
|
Indent int `default:"2"` // 2 is default for BurntSushi/toml
|
||||||
|
}
|
||||||
|
|
||||||
|
func toTOML(_ *interp.Interp, c any, opts ToTOMLOpts) any {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return gojqx.FuncTypeError{Name: "to_toml", V: c}
|
return gojqx.FuncTypeError{Name: "to_toml", V: c}
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
if err := toml.NewEncoder(b).Encode(gojqx.Normalize(c)); err != nil {
|
e := toml.NewEncoder(b)
|
||||||
|
e.Indent = strings.Repeat(" ", opts.Indent)
|
||||||
|
if err := e.Encode(gojqx.Normalize(c)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return b.String()
|
return b.String()
|
||||||
|
@ -1 +1,3 @@
|
|||||||
def _toml__todisplay: tovalue;
|
def _toml__todisplay: tovalue;
|
||||||
|
def to_toml($opts): _to_toml($opts);
|
||||||
|
def to_toml: _to_toml(null);
|
||||||
|
29
format/yaml/testdata/indent.fqtest
vendored
Normal file
29
format/yaml/testdata/indent.fqtest
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
$ fq -rn "{a: {b: 123}} | to_yaml"
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
$ fq -rn "{a: {b: 123}} | to_yaml({indent: range(8)})"
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
||||||
|
a:
|
||||||
|
b: 123
|
||||||
|
|
@ -3,6 +3,7 @@ package yaml
|
|||||||
// TODO: yaml type eval? walk eval?
|
// TODO: yaml type eval? walk eval?
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"embed"
|
"embed"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
@ -30,7 +31,7 @@ func init() {
|
|||||||
Functions: []string{"_todisplay"},
|
Functions: []string{"_todisplay"},
|
||||||
})
|
})
|
||||||
interp.RegisterFS(yamlFS)
|
interp.RegisterFS(yamlFS)
|
||||||
interp.RegisterFunc0("to_yaml", toYAML)
|
interp.RegisterFunc1("_to_yaml", toYAML)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeYAML(d *decode.D) any {
|
func decodeYAML(d *decode.D) any {
|
||||||
@ -61,10 +62,20 @@ func decodeYAML(d *decode.D) any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toYAML(_ *interp.Interp, c any) any {
|
type ToYAMLOpts struct {
|
||||||
b, err := yaml.Marshal(gojqx.Normalize(c))
|
Indent int `default:"4"` // 4 is default for gopkg.in/yaml.v3
|
||||||
if err != nil {
|
}
|
||||||
|
|
||||||
|
func toYAML(_ *interp.Interp, c any, opts ToYAMLOpts) any {
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
e := yaml.NewEncoder(b)
|
||||||
|
// yaml.SetIndent panics if < 0
|
||||||
|
if opts.Indent >= 0 {
|
||||||
|
e.SetIndent(opts.Indent)
|
||||||
|
}
|
||||||
|
if err := e.Encode(gojqx.Normalize(c)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return string(b)
|
|
||||||
|
return b.String()
|
||||||
}
|
}
|
||||||
|
@ -1 +1,3 @@
|
|||||||
def _yaml__todisplay: tovalue;
|
def _yaml__todisplay: tovalue;
|
||||||
|
def to_yaml($opts): _to_yaml($opts);
|
||||||
|
def to_yaml: _to_yaml(null);
|
||||||
|
Loading…
Reference in New Issue
Block a user