diff --git a/docs/src/flatten-unflatten.md b/docs/src/flatten-unflatten.md index c0cb6fe6b..d876dea09 100644 --- a/docs/src/flatten-unflatten.md +++ b/docs/src/flatten-unflatten.md @@ -14,11 +14,11 @@ Quick links: Release docs -# Flatten/unflatten: converting between JSON and tabular formats +# Flatten/unflatten: converting between JSON/YAML and tabular formats Miller has long supported reading and writing multiple [file -formats](file-formats.md) including CSV and JSON, as well as converting back -and forth between them. Two things new in [Miller 6](new-in-miller-6-md), +formats](file-formats.md) including CSV, JSON, and YAML, as well as converting +back and forth between them. Two things new in [Miller 6](new-in-miller-6-md), though, are that [arrays are now fully supported](reference-main-arrays.md), and that [record values are typed](new-in-miller-6.md#improved-numeric-conversion) throughout Miller's processing chain from input through [verbs](reference-verbs.md) @@ -26,9 +26,10 @@ to output -- which includes improved handling for [maps](reference-main-maps.md) [arrays](reference-main-arrays.md) as record values. This raises the question, though, of how to handle maps and arrays as record values. -For [JSON files](file-formats.md#json), this is easy -- JSON is a nested format where values -can be maps or arrays, which can contain other maps or arrays, and so on, with the nesting -happily indicated by curly braces: +For [JSON](file-formats.md#json) or [YAML](file-formats.md#yaml) files, this is easy -- +both are nested formats where values can be maps or arrays, which can contain other maps +or arrays, and so on, with the nesting happily indicated by curly braces (JSON) or +indentation (YAML):
 cat data/map-values.json
@@ -60,11 +61,11 @@ happily indicated by curly braces:
 
 How can we represent these in CSV files?
 
-Miller's [non-JSON formats](file-formats.md), such as CSV, are all non-nested -- a
-cell in a CSV row can't contain another entire row. As we'll see in this
-section, there are two main ways to **flatten** nested data structures down to
-individual CSV cells -- either by _key-spreading_ (which is the default), or by
-_JSON-stringifying_:
+Miller's non-JSON/YAML [file formats](file-formats.md), such as CSV, are all
+non-nested -- a cell in a CSV row can't contain another entire row. As we'll
+see in this section, there are two main ways to **flatten** nested data
+structures down to individual CSV cells -- either by _key-spreading_ (which
+is the default), or by _JSON-stringifying_:
 
 * **Key-spreading** is when the single map-valued field
 `b={"x": 2, "y": 3}` spreads into multiple fields `b.x=2,b.y=3`;
@@ -73,7 +74,7 @@ _JSON-stringifying_:
 Miller intends to provide intuitive default behavior for these conversions, while also
 providing you with more control when you need it.
 
-## Converting maps between JSON and non-JSON
+## Converting maps between JSON/YAML and non-JSON/YAML
 
 Let's first look at the default behavior with map-valued fields. Miller's
 default behavior is to spread the map values into multiple keys -- using
@@ -152,7 +153,7 @@ a b.s.w b.s.x b.t.y b.t.z
 6 7     8     9     10
 
-**Unflattening** is simply the reverse -- from non-JSON back to JSON: +**Unflattening** is simply the reverse -- from non-JSON/YAML back to JSON or YAML:
 cat data/map-values.json
@@ -199,7 +200,7 @@ a,b.x,b.y
 ]
 
-## Converting arrays between JSON and non-JSON +## Converting arrays between JSON/YAML and non-JSON/YAML If the input data contains arrays, these are also flattened similarly: the [1-up array indices](reference-main-arrays.md#1-up-indexing) `1,2,3,...` become string keys @@ -257,7 +258,7 @@ In the nested-data examples shown here, nested map values are shown containing maps, and nested array values are shown containing arrays -- of course (even though not shown here) nested map values can contain arrays, and vice versa. -**Unflattening** arrays is, again, simply the reverse -- from non-JSON back to JSON: +**Unflattening** arrays is, again, simply the reverse -- from non-JSON/YAML back to JSON or YAML:
 cat data/array-values.json
@@ -352,7 +353,7 @@ a.1,a.3,a.5
 
 An additional heuristic is that if a field name starts with a `.`, ends with
 a `.`, or has two or more consecutive `.` characters, no attempt is made
-to unflatten it on conversion from non-JSON to JSON.
+to unflatten it on conversion from non-JSON/YAML to JSON or YAML.
 
 
 cat data/flatten-dots.csv
@@ -403,13 +404,13 @@ unflattening (if the defaults aren't working for us in a particular situation),
 let's first look a little into how they're implemented.
 
 * There are two [verbs](reference-verbs.md) called [flatten](reference-verbs.md#flatten) and [unflatten](reference-verbs.md#unflatten).
-* When the output format is not JSON, if you've specified `mlr ... cat then sort ...` (some [chain](reference-main-then-chaining.md) of verbs) then Miller appends, in effect, `then flatten` to the end of the chain.
+* When the output format is not JSON or YAML, if you've specified `mlr ... cat then sort ...` (some [chain](reference-main-then-chaining.md) of verbs) then Miller appends, in effect, `then flatten` to the end of the chain.
     * This behavior is on by default but it can be suppressed using the `--no-auto-flatten` [flag](reference-main-flag-list.md#flatten-unflatten-flags).
-* When the output format is JSON and the input format is not JSON, then (similarly) appends, in effect, `then unflatten`   to the end of the chain.
+* When the output format is JSON or YAML and the input format is neither, then (similarly) Miller appends, in effect, `then unflatten` to the end of the chain.
     * This behavior is on by default but it can be suppressed using the `--no-auto-unflatten` [flag](reference-main-flag-list.md#flatten-unflatten-flags).
 
 Note in particular that auto-flatten happens even when the input format and the
-output format are both non-JSON, e.g. even for CSV-to-CSV processing. This is
+output format are both non-JSON/non-YAML, e.g. even for CSV-to-CSV processing. This is
 because
 [map](reference-main-maps.md)-valued/[array](reference-main-arrays.md)-valued
 fields can be produced using [DSL statements](miller-programming-language.md):
diff --git a/docs/src/flatten-unflatten.md.in b/docs/src/flatten-unflatten.md.in
index 951ea1f58..f61d64aa3 100644
--- a/docs/src/flatten-unflatten.md.in
+++ b/docs/src/flatten-unflatten.md.in
@@ -1,8 +1,8 @@
-# Flatten/unflatten: converting between JSON and tabular formats
+# Flatten/unflatten: converting between JSON/YAML and tabular formats
 
 Miller has long supported reading and writing multiple [file
-formats](file-formats.md) including CSV and JSON, as well as converting back
-and forth between them. Two things new in [Miller 6](new-in-miller-6-md),
+formats](file-formats.md) including CSV, JSON, and YAML, as well as converting
+back and forth between them. Two things new in [Miller 6](new-in-miller-6-md),
 though, are that [arrays are now fully supported](reference-main-arrays.md),
 and that [record values are typed](new-in-miller-6.md#improved-numeric-conversion)
 throughout Miller's processing chain from input through [verbs](reference-verbs.md)
@@ -10,9 +10,10 @@ to output -- which includes improved handling for [maps](reference-main-maps.md)
 [arrays](reference-main-arrays.md) as record values.
 
 This raises the question, though, of how to handle maps and arrays as record values.
-For [JSON files](file-formats.md#json), this is easy -- JSON is a nested format where values
-can be maps or arrays, which can contain other maps or arrays, and so on, with the nesting
-happily indicated by curly braces:
+For [JSON](file-formats.md#json) or [YAML](file-formats.md#yaml) files, this is easy --
+both are nested formats where values can be maps or arrays, which can contain other maps
+or arrays, and so on, with the nesting happily indicated by curly braces (JSON) or
+indentation (YAML):
 
 GENMD-RUN-COMMAND
 cat data/map-values.json
@@ -24,11 +25,11 @@ GENMD-EOF
 
 How can we represent these in CSV files?
 
-Miller's [non-JSON formats](file-formats.md), such as CSV, are all non-nested -- a
-cell in a CSV row can't contain another entire row. As we'll see in this
-section, there are two main ways to **flatten** nested data structures down to
-individual CSV cells -- either by _key-spreading_ (which is the default), or by
-_JSON-stringifying_:
+Miller's non-JSON/YAML [file formats](file-formats.md), such as CSV, are all
+non-nested -- a cell in a CSV row can't contain another entire row. As we'll
+see in this section, there are two main ways to **flatten** nested data
+structures down to individual CSV cells -- either by _key-spreading_ (which
+is the default), or by _JSON-stringifying_:
 
 * **Key-spreading** is when the single map-valued field
 `b={"x": 2, "y": 3}` spreads into multiple fields `b.x=2,b.y=3`;
@@ -37,7 +38,7 @@ _JSON-stringifying_:
 Miller intends to provide intuitive default behavior for these conversions, while also
 providing you with more control when you need it.
 
-## Converting maps between JSON and non-JSON
+## Converting maps between JSON/YAML and non-JSON/YAML
 
 Let's first look at the default behavior with map-valued fields. Miller's
 default behavior is to spread the map values into multiple keys -- using
@@ -76,7 +77,7 @@ GENMD-RUN-COMMAND
 mlr --ijson --opprint cat data/map-values-nested.json
 GENMD-EOF
 
-**Unflattening** is simply the reverse -- from non-JSON back to JSON:
+**Unflattening** is simply the reverse -- from non-JSON/YAML back to JSON or YAML:
 
 GENMD-RUN-COMMAND
 cat data/map-values.json
@@ -90,7 +91,7 @@ GENMD-RUN-COMMAND
 mlr --ijson --ocsv cat data/map-values.json | mlr --icsv --ojson cat
 GENMD-EOF
 
-## Converting arrays between JSON and non-JSON
+## Converting arrays between JSON/YAML and non-JSON/YAML
 
 If the input data contains arrays, these are also flattened similarly: the
 [1-up array indices](reference-main-arrays.md#1-up-indexing) `1,2,3,...` become string keys
@@ -118,7 +119,7 @@ In the nested-data examples shown here, nested map values are shown containing
 maps, and nested array values are shown containing arrays -- of course (even
 though not shown here) nested map values can contain arrays, and vice versa.
 
-**Unflattening** arrays is, again, simply the reverse -- from non-JSON back to JSON:
+**Unflattening** arrays is, again, simply the reverse -- from non-JSON/YAML back to JSON or YAML:
 
 GENMD-RUN-COMMAND
 cat data/array-values.json
@@ -160,7 +161,7 @@ GENMD-EOF
 
 An additional heuristic is that if a field name starts with a `.`, ends with
 a `.`, or has two or more consecutive `.` characters, no attempt is made
-to unflatten it on conversion from non-JSON to JSON.
+to unflatten it on conversion from non-JSON/YAML to JSON or YAML.
 
 GENMD-RUN-COMMAND
 cat data/flatten-dots.csv
@@ -181,13 +182,13 @@ unflattening (if the defaults aren't working for us in a particular situation),
 let's first look a little into how they're implemented.
 
 * There are two [verbs](reference-verbs.md) called [flatten](reference-verbs.md#flatten) and [unflatten](reference-verbs.md#unflatten).
-* When the output format is not JSON, if you've specified `mlr ... cat then sort ...` (some [chain](reference-main-then-chaining.md) of verbs) then Miller appends, in effect, `then flatten` to the end of the chain.
+* When the output format is not JSON or YAML, if you've specified `mlr ... cat then sort ...` (some [chain](reference-main-then-chaining.md) of verbs) then Miller appends, in effect, `then flatten` to the end of the chain.
     * This behavior is on by default but it can be suppressed using the `--no-auto-flatten` [flag](reference-main-flag-list.md#flatten-unflatten-flags).
-* When the output format is JSON and the input format is not JSON, then (similarly) appends, in effect, `then unflatten`   to the end of the chain.
+* When the output format is JSON or YAML and the input format is neither, then (similarly) Miller appends, in effect, `then unflatten` to the end of the chain.
     * This behavior is on by default but it can be suppressed using the `--no-auto-unflatten` [flag](reference-main-flag-list.md#flatten-unflatten-flags).
 
 Note in particular that auto-flatten happens even when the input format and the
-output format are both non-JSON, e.g. even for CSV-to-CSV processing. This is
+output format are both non-JSON/non-YAML, e.g. even for CSV-to-CSV processing. This is
 because
 [map](reference-main-maps.md)-valued/[array](reference-main-arrays.md)-valued
 fields can be produced using [DSL statements](miller-programming-language.md):
diff --git a/docs/src/manpage.md b/docs/src/manpage.md
index 5c216d509..0b643ea59 100644
--- a/docs/src/manpage.md
+++ b/docs/src/manpage.md
@@ -479,7 +479,7 @@ This is simply a copy of what you should see on running `man mlr` at a command p
                                 csv` is the same as `--ocsv`.
 
 1mFLATTEN-UNFLATTEN FLAGS0m
-       These flags control how Miller converts record values which are maps or arrays, when input is JSON and output is non-JSON (flattening) or input is non-JSON and output is JSON (unflattening).
+       These flags control how Miller converts record values which are maps or arrays, when input is JSON/YAML and output is not (flattening) or input is not JSON/YAML and output is JSON/YAML (unflattening).
 
        See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatten-unflatten for more information.
 
@@ -487,16 +487,17 @@ This is simply a copy of what you should see on running `man mlr` at a command p
                                 Separator for flattening multi-level JSON keys, e.g.
                                 `{"a":{"b":3}}` becomes `a:b => 3` for non-JSON
                                 formats. Defaults to `.`.
-       --no-auto-flatten        When output is non-JSON, suppress the default
+       --no-auto-flatten        When output is not JSON or YAML, suppress the default
                                 auto-flatten behavior. Default: if `$y = [7,8,9]`
                                 then this flattens to `y.1=7,y.2=8,y.3=9`, and
                                 similarly for maps. With `--no-auto-flatten`, instead
                                 we get `$y=[1, 2, 3]`.
-       --no-auto-unflatten      When input is non-JSON and output is JSON, suppress
-                                the default auto-unflatten behavior. Default: if the
-                                input has `y.1=7,y.2=8,y.3=9` then this unflattens to
-                                `$y=[7,8,9]`. With `--no-auto-flatten`, instead we
-                                get `${y.1}=7,${y.2}=8,${y.3}=9`.
+       --no-auto-unflatten      When input is not JSON or YAML and output is JSON or
+                                YAML, suppress the default auto-unflatten behavior.
+                                Default: if the input has `y.1=7,y.2=8,y.3=9` then
+                                this unflattens to `$y=[7,8,9]`. With
+                                `--no-auto-flatten`, instead we get
+                                `${y.1}=7,${y.2}=8,${y.3}=9`.
 
 1mFORMAT-CONVERSION KEYSTROKE-SAVER FLAGS0m
        As keystroke-savers for format-conversion you may use the following.
@@ -4159,5 +4160,5 @@ This is simply a copy of what you should see on running `man mlr` at a command p
        MIME Type for Comma-Separated Values (CSV) Files, the Miller docsite
        https://miller.readthedocs.io
 
-                                  2026-07-14                         4mMILLER24m(1)
+                                  2026-07-15                         4mMILLER24m(1)
 
diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index b235fea97..5cde2e3fb 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -458,7 +458,7 @@ csv` is the same as `--ocsv`. 1mFLATTEN-UNFLATTEN FLAGS0m - These flags control how Miller converts record values which are maps or arrays, when input is JSON and output is non-JSON (flattening) or input is non-JSON and output is JSON (unflattening). + These flags control how Miller converts record values which are maps or arrays, when input is JSON/YAML and output is not (flattening) or input is not JSON/YAML and output is JSON/YAML (unflattening). See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatten-unflatten for more information. @@ -466,16 +466,17 @@ Separator for flattening multi-level JSON keys, e.g. `{"a":{"b":3}}` becomes `a:b => 3` for non-JSON formats. Defaults to `.`. - --no-auto-flatten When output is non-JSON, suppress the default + --no-auto-flatten When output is not JSON or YAML, suppress the default auto-flatten behavior. Default: if `$y = [7,8,9]` then this flattens to `y.1=7,y.2=8,y.3=9`, and similarly for maps. With `--no-auto-flatten`, instead we get `$y=[1, 2, 3]`. - --no-auto-unflatten When input is non-JSON and output is JSON, suppress - the default auto-unflatten behavior. Default: if the - input has `y.1=7,y.2=8,y.3=9` then this unflattens to - `$y=[7,8,9]`. With `--no-auto-flatten`, instead we - get `${y.1}=7,${y.2}=8,${y.3}=9`. + --no-auto-unflatten When input is not JSON or YAML and output is JSON or + YAML, suppress the default auto-unflatten behavior. + Default: if the input has `y.1=7,y.2=8,y.3=9` then + this unflattens to `$y=[7,8,9]`. With + `--no-auto-flatten`, instead we get + `${y.1}=7,${y.2}=8,${y.3}=9`. 1mFORMAT-CONVERSION KEYSTROKE-SAVER FLAGS0m As keystroke-savers for format-conversion you may use the following. @@ -4138,4 +4139,4 @@ MIME Type for Comma-Separated Values (CSV) Files, the Miller docsite https://miller.readthedocs.io - 2026-07-14 4mMILLER24m(1) + 2026-07-15 4mMILLER24m(1) diff --git a/docs/src/reference-main-flag-list.md b/docs/src/reference-main-flag-list.md index d9b09cf0a..17b0de7df 100644 --- a/docs/src/reference-main-flag-list.md +++ b/docs/src/reference-main-flag-list.md @@ -210,7 +210,7 @@ are overridden in all cases by setting output format to `format2`. ## Flatten-unflatten flags -These flags control how Miller converts record values which are maps or arrays, when input is JSON and output is non-JSON (flattening) or input is non-JSON and output is JSON (unflattening). +These flags control how Miller converts record values which are maps or arrays, when input is JSON/YAML and output is not (flattening) or input is not JSON/YAML and output is JSON/YAML (unflattening). See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatten-unflatten for more information. @@ -218,8 +218,8 @@ See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatt **Flags:** * `--flatsep or --jflatsep {string}`: Separator for flattening multi-level JSON keys, e.g. `{"a":{"b":3}}` becomes `a:b => 3` for non-JSON formats. Defaults to `.`. -* `--no-auto-flatten`: When output is non-JSON, suppress the default auto-flatten behavior. Default: if `$y = [7,8,9]` then this flattens to `y.1=7,y.2=8,y.3=9`, and similarly for maps. With `--no-auto-flatten`, instead we get `$y=[1, 2, 3]`. -* `--no-auto-unflatten`: When input is non-JSON and output is JSON, suppress the default auto-unflatten behavior. Default: if the input has `y.1=7,y.2=8,y.3=9` then this unflattens to `$y=[7,8,9]`. With `--no-auto-flatten`, instead we get `${y.1}=7,${y.2}=8,${y.3}=9`. +* `--no-auto-flatten`: When output is not JSON or YAML, suppress the default auto-flatten behavior. Default: if `$y = [7,8,9]` then this flattens to `y.1=7,y.2=8,y.3=9`, and similarly for maps. With `--no-auto-flatten`, instead we get `$y=[1, 2, 3]`. +* `--no-auto-unflatten`: When input is not JSON or YAML and output is JSON or YAML, suppress the default auto-unflatten behavior. Default: if the input has `y.1=7,y.2=8,y.3=9` then this unflattens to `$y=[7,8,9]`. With `--no-auto-flatten`, instead we get `${y.1}=7,${y.2}=8,${y.3}=9`. ## Format-conversion keystroke-saver flags diff --git a/man/manpage.txt b/man/manpage.txt index b235fea97..5cde2e3fb 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -458,7 +458,7 @@ csv` is the same as `--ocsv`. 1mFLATTEN-UNFLATTEN FLAGS0m - These flags control how Miller converts record values which are maps or arrays, when input is JSON and output is non-JSON (flattening) or input is non-JSON and output is JSON (unflattening). + These flags control how Miller converts record values which are maps or arrays, when input is JSON/YAML and output is not (flattening) or input is not JSON/YAML and output is JSON/YAML (unflattening). See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatten-unflatten for more information. @@ -466,16 +466,17 @@ Separator for flattening multi-level JSON keys, e.g. `{"a":{"b":3}}` becomes `a:b => 3` for non-JSON formats. Defaults to `.`. - --no-auto-flatten When output is non-JSON, suppress the default + --no-auto-flatten When output is not JSON or YAML, suppress the default auto-flatten behavior. Default: if `$y = [7,8,9]` then this flattens to `y.1=7,y.2=8,y.3=9`, and similarly for maps. With `--no-auto-flatten`, instead we get `$y=[1, 2, 3]`. - --no-auto-unflatten When input is non-JSON and output is JSON, suppress - the default auto-unflatten behavior. Default: if the - input has `y.1=7,y.2=8,y.3=9` then this unflattens to - `$y=[7,8,9]`. With `--no-auto-flatten`, instead we - get `${y.1}=7,${y.2}=8,${y.3}=9`. + --no-auto-unflatten When input is not JSON or YAML and output is JSON or + YAML, suppress the default auto-unflatten behavior. + Default: if the input has `y.1=7,y.2=8,y.3=9` then + this unflattens to `$y=[7,8,9]`. With + `--no-auto-flatten`, instead we get + `${y.1}=7,${y.2}=8,${y.3}=9`. 1mFORMAT-CONVERSION KEYSTROKE-SAVER FLAGS0m As keystroke-savers for format-conversion you may use the following. @@ -4138,4 +4139,4 @@ MIME Type for Comma-Separated Values (CSV) Files, the Miller docsite https://miller.readthedocs.io - 2026-07-14 4mMILLER24m(1) + 2026-07-15 4mMILLER24m(1) diff --git a/man/mlr.1 b/man/mlr.1 index 3c5b28c52..a7b882e2a 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2026-07-14 +.\" Date: 2026-07-15 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2026-07-14" "\ \&" "\ \&" +.TH "MILLER" "1" "2026-07-15" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -554,7 +554,7 @@ are overridden in all cases by setting output format to `format2`. .RS 0 .\} .nf -These flags control how Miller converts record values which are maps or arrays, when input is JSON and output is non-JSON (flattening) or input is non-JSON and output is JSON (unflattening). +These flags control how Miller converts record values which are maps or arrays, when input is JSON/YAML and output is not (flattening) or input is not JSON/YAML and output is JSON/YAML (unflattening). See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatten-unflatten for more information. @@ -562,16 +562,17 @@ See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatt Separator for flattening multi-level JSON keys, e.g. `{"a":{"b":3}}` becomes `a:b => 3` for non-JSON formats. Defaults to `.`. ---no-auto-flatten When output is non-JSON, suppress the default +--no-auto-flatten When output is not JSON or YAML, suppress the default auto-flatten behavior. Default: if `$y = [7,8,9]` then this flattens to `y.1=7,y.2=8,y.3=9`, and similarly for maps. With `--no-auto-flatten`, instead we get `$y=[1, 2, 3]`. ---no-auto-unflatten When input is non-JSON and output is JSON, suppress - the default auto-unflatten behavior. Default: if the - input has `y.1=7,y.2=8,y.3=9` then this unflattens to - `$y=[7,8,9]`. With `--no-auto-flatten`, instead we - get `${y.1}=7,${y.2}=8,${y.3}=9`. +--no-auto-unflatten When input is not JSON or YAML and output is JSON or + YAML, suppress the default auto-unflatten behavior. + Default: if the input has `y.1=7,y.2=8,y.3=9` then + this unflattens to `$y=[7,8,9]`. With + `--no-auto-flatten`, instead we get + `${y.1}=7,${y.2}=8,${y.3}=9`. .fi .if n \{\ .RE diff --git a/pkg/cli/flatten_unflatten.go b/pkg/cli/flatten_unflatten.go index bd2593f2a..d256494bc 100644 --- a/pkg/cli/flatten_unflatten.go +++ b/pkg/cli/flatten_unflatten.go @@ -5,7 +5,7 @@ package cli // // PROBLEM TO BE SOLVED: // -// JSON has nested structures and CSV et al. do not. For example: +// JSON and YAML have nested structures and CSV et al. do not. For example: // { // "req" : { // "method": "GET", @@ -22,7 +22,9 @@ package cli // // APPROACH: // -// Use the Principle of Least Surprise (POLS). +// Use the Principle of Least Surprise (POLS). Below, "JSON" stands for any +// format capable of representing nested structures natively -- currently +// JSON, JSON Lines, and YAML. // // * If input is JSON and output is JSON: // o Records can be nested from record-read @@ -54,11 +56,24 @@ package cli // flatten, don't undo that by putting an unflatten right after. // +// isNestable returns true for formats which can represent nested/array +// structures natively, and thus don't need auto-flatten/auto-unflatten. +func isNestable(format string) bool { + return format == "json" || format == "jsonl" || format == "yaml" +} + func DecideFinalFlatten(writerOptions *TWriterOptions) bool { ofmt := writerOptions.OutputFileFormat if writerOptions.AutoFlatten { - // Preserve nested/array structure for formats that support it. - if ofmt != "json" && ofmt != "jsonl" && ofmt != "dcf" { + // JSON/YAML/JSON-Lines preserve nested/array structure natively, so + // they never need flattening. + // + // DCF is excluded for a different reason: it's not nestable, but it + // has its own hardcoded comma-list serialization for a fixed set of + // field names (Depends, Recommends, etc. -- see + // pkg/output/record_writer_dcf.go), which generic key-spreading + // flatten would clobber. + if !isNestable(ofmt) && ofmt != "dcf" { return true } } @@ -85,8 +100,8 @@ func DecideFinalUnflatten( ofmt := options.WriterOptions.OutputFileFormat if options.WriterOptions.AutoUnflatten { - if ifmt != "json" { - if ofmt == "json" { + if !isNestable(ifmt) { + if isNestable(ofmt) { return true } } diff --git a/pkg/cli/option_parse.go b/pkg/cli/option_parse.go index 08b707ff7..5cf197194 100644 --- a/pkg/cli/option_parse.go +++ b/pkg/cli/option_parse.go @@ -3300,7 +3300,7 @@ var OutputColorizationFlagSection = FlagSection{ // FLATTEN/UNFLATTEN FLAGS func FlattenUnflattenPrintInfo() { - fmt.Println("These flags control how Miller converts record values which are maps or arrays, when input is JSON and output is non-JSON (flattening) or input is non-JSON and output is JSON (unflattening).") + fmt.Println("These flags control how Miller converts record values which are maps or arrays, when input is JSON/YAML and output is not (flattening) or input is not JSON/YAML and output is JSON/YAML (unflattening).") fmt.Println() fmt.Println("See the flatten/unflatten doc page https://miller.readthedocs.io/en/latest/flatten-unflatten for more information.") } @@ -3326,7 +3326,7 @@ var FlattenUnflattenFlagSection = FlagSection{ { name: "--no-auto-flatten", - help: "When output is non-JSON, suppress the default auto-flatten behavior. Default: if `$y = [7,8,9]` then this flattens to `y.1=7,y.2=8,y.3=9`, and similarly for maps. With `--no-auto-flatten`, instead we get `$y=[1, 2, 3]`.", + help: "When output is not JSON or YAML, suppress the default auto-flatten behavior. Default: if `$y = [7,8,9]` then this flattens to `y.1=7,y.2=8,y.3=9`, and similarly for maps. With `--no-auto-flatten`, instead we get `$y=[1, 2, 3]`.", parser: func(args []string, argc int, pargi *int, options *TOptions) { options.WriterOptions.AutoFlatten = false *pargi += 1 @@ -3335,7 +3335,7 @@ var FlattenUnflattenFlagSection = FlagSection{ { name: "--no-auto-unflatten", - help: "When input is non-JSON and output is JSON, suppress the default auto-unflatten behavior. Default: if the input has `y.1=7,y.2=8,y.3=9` then this unflattens to `$y=[7,8,9]`. With `--no-auto-flatten`, instead we get `${y.1}=7,${y.2}=8,${y.3}=9`.", + help: "When input is not JSON or YAML and output is JSON or YAML, suppress the default auto-unflatten behavior. Default: if the input has `y.1=7,y.2=8,y.3=9` then this unflattens to `$y=[7,8,9]`. With `--no-auto-flatten`, instead we get `${y.1}=7,${y.2}=8,${y.3}=9`.", parser: func(args []string, argc int, pargi *int, options *TOptions) { options.WriterOptions.AutoUnflatten = false *pargi += 1 diff --git a/test/cases/io-yaml-io/0005/cmd b/test/cases/io-yaml-io/0005/cmd new file mode 100644 index 000000000..84ada0c8e --- /dev/null +++ b/test/cases/io-yaml-io/0005/cmd @@ -0,0 +1 @@ +mlr --icsv --oyaml cat ${CASEDIR}/input diff --git a/test/cases/io-yaml-io/0005/experr b/test/cases/io-yaml-io/0005/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/io-yaml-io/0005/expout b/test/cases/io-yaml-io/0005/expout new file mode 100644 index 000000000..c40c130f9 --- /dev/null +++ b/test/cases/io-yaml-io/0005/expout @@ -0,0 +1,8 @@ +- a: 1 + b: + - 2 + - 3 +- a: 4 + b: + - 5 + - 6 diff --git a/test/cases/io-yaml-io/0005/input b/test/cases/io-yaml-io/0005/input new file mode 100644 index 000000000..d17ad1a6d --- /dev/null +++ b/test/cases/io-yaml-io/0005/input @@ -0,0 +1,3 @@ +a,b.1,b.2 +1,2,3 +4,5,6 diff --git a/test/cases/io-yaml-io/0006/cmd b/test/cases/io-yaml-io/0006/cmd new file mode 100644 index 000000000..5c51bf61a --- /dev/null +++ b/test/cases/io-yaml-io/0006/cmd @@ -0,0 +1 @@ +mlr --ijson --oyaml cat ${CASEDIR}/input diff --git a/test/cases/io-yaml-io/0006/experr b/test/cases/io-yaml-io/0006/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/io-yaml-io/0006/expout b/test/cases/io-yaml-io/0006/expout new file mode 100644 index 000000000..9aeb886e1 --- /dev/null +++ b/test/cases/io-yaml-io/0006/expout @@ -0,0 +1,4 @@ +- a: 1 + req: + method: GET + path: api/check diff --git a/test/cases/io-yaml-io/0006/input b/test/cases/io-yaml-io/0006/input new file mode 100644 index 000000000..a9c61b51a --- /dev/null +++ b/test/cases/io-yaml-io/0006/input @@ -0,0 +1,3 @@ +[ +{"a": 1, "req": {"method": "GET", "path": "api/check"}} +] diff --git a/test/cases/io-yaml-io/0007/cmd b/test/cases/io-yaml-io/0007/cmd new file mode 100644 index 000000000..6fd32a30b --- /dev/null +++ b/test/cases/io-yaml-io/0007/cmd @@ -0,0 +1 @@ +mlr --iyaml --ocsv cat ${CASEDIR}/input diff --git a/test/cases/io-yaml-io/0007/experr b/test/cases/io-yaml-io/0007/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/io-yaml-io/0007/expout b/test/cases/io-yaml-io/0007/expout new file mode 100644 index 000000000..d17ad1a6d --- /dev/null +++ b/test/cases/io-yaml-io/0007/expout @@ -0,0 +1,3 @@ +a,b.1,b.2 +1,2,3 +4,5,6 diff --git a/test/cases/io-yaml-io/0007/input b/test/cases/io-yaml-io/0007/input new file mode 100644 index 000000000..c40c130f9 --- /dev/null +++ b/test/cases/io-yaml-io/0007/input @@ -0,0 +1,8 @@ +- a: 1 + b: + - 2 + - 3 +- a: 4 + b: + - 5 + - 6