diff --git a/docs/src/file-formats.md b/docs/src/file-formats.md
index 8aad25eb4..ef1eacd8b 100644
--- a/docs/src/file-formats.md
+++ b/docs/src/file-formats.md
@@ -531,6 +531,46 @@ Since Miller 6.11.0, you can use `--barred-input` with pprint input format:
]
+Use `--right` to right-align all cells, or `--right-align-numeric` to right-align only the cells
+having numeric values, leaving other cells (and the header line) left-aligned:
+
+
+mlr --icsv --opprint --right-align-numeric cat example.csv
+
+
+color shape flag k index quantity rate
+yellow triangle true 1 11 43.6498 9.8870
+red square true 2 15 79.2778 0.0130
+red circle true 3 16 13.8103 2.9010
+red square false 4 48 77.5542 7.4670
+purple triangle false 5 51 81.2290 8.5910
+red square false 6 64 77.1991 9.5310
+purple triangle false 7 65 80.1405 5.8240
+yellow circle true 8 73 63.9785 4.2370
+yellow circle true 9 87 63.5058 8.3350
+purple square false 10 91 72.3735 8.2430
+
+
+
+mlr --icsv --opprint --barred --right-align-numeric cat example.csv
+
+
++--------+----------+-------+----+-------+----------+--------+
+| color | shape | flag | k | index | quantity | rate |
++--------+----------+-------+----+-------+----------+--------+
+| yellow | triangle | true | 1 | 11 | 43.6498 | 9.8870 |
+| red | square | true | 2 | 15 | 79.2778 | 0.0130 |
+| red | circle | true | 3 | 16 | 13.8103 | 2.9010 |
+| red | square | false | 4 | 48 | 77.5542 | 7.4670 |
+| purple | triangle | false | 5 | 51 | 81.2290 | 8.5910 |
+| red | square | false | 6 | 64 | 77.1991 | 9.5310 |
+| purple | triangle | false | 7 | 65 | 80.1405 | 5.8240 |
+| yellow | circle | true | 8 | 73 | 63.9785 | 4.2370 |
+| yellow | circle | true | 9 | 87 | 63.5058 | 8.3350 |
+| purple | square | false | 10 | 91 | 72.3735 | 8.2430 |
++--------+----------+-------+----+-------+----------+--------+
+
+
## Markdown tabular
Markdown format looks like this:
@@ -580,6 +620,30 @@ do not need to pass `--md` in addition:
mlr --md-aligned cat data/small
+The `--right-align-numeric` flag also applies to markdown output: numeric columns get a
+right-alignment marker (`---:`) in the header-separator line, so they render right-aligned in
+Markdown viewers. With `--omd`, since output is streaming, the marker for each column is chosen
+from the first record of each same-schema group; with `--omd-aligned`, a column gets the marker
+when all its values are numeric, and its cell text is right-justified in the raw markdown as well:
+
+
+mlr --icsv --omd-aligned --right-align-numeric cat example.csv
+
+
+| color | shape | flag | k | index | quantity | rate |
+| --- | --- | --- | ---: | ---: | ---: | ---: |
+| yellow | triangle | true | 1 | 11 | 43.6498 | 9.8870 |
+| red | square | true | 2 | 15 | 79.2778 | 0.0130 |
+| red | circle | true | 3 | 16 | 13.8103 | 2.9010 |
+| red | square | false | 4 | 48 | 77.5542 | 7.4670 |
+| purple | triangle | false | 5 | 51 | 81.2290 | 8.5910 |
+| red | square | false | 6 | 64 | 77.1991 | 9.5310 |
+| purple | triangle | false | 7 | 65 | 80.1405 | 5.8240 |
+| yellow | circle | true | 8 | 73 | 63.9785 | 4.2370 |
+| yellow | circle | true | 9 | 87 | 63.5058 | 8.3350 |
+| purple | square | false | 10 | 91 | 72.3735 | 8.2430 |
+
+
## XTAB: Vertical tabular
This is perhaps most useful for looking a very wide and/or multi-column data which causes line-wraps on the screen (but see also
diff --git a/docs/src/file-formats.md.in b/docs/src/file-formats.md.in
index 607f5da7f..90cfc846f 100644
--- a/docs/src/file-formats.md.in
+++ b/docs/src/file-formats.md.in
@@ -212,6 +212,17 @@ GENMD-RUN-COMMAND
mlr -o pprint --barred cat data/small | mlr -i pprint --barred-input -o json filter '$b == "pan"'
GENMD-EOF
+Use `--right` to right-align all cells, or `--right-align-numeric` to right-align only the cells
+having numeric values, leaving other cells (and the header line) left-aligned:
+
+GENMD-RUN-COMMAND
+mlr --icsv --opprint --right-align-numeric cat example.csv
+GENMD-EOF
+
+GENMD-RUN-COMMAND
+mlr --icsv --opprint --barred --right-align-numeric cat example.csv
+GENMD-EOF
+
## Markdown tabular
Markdown format looks like this:
@@ -243,6 +254,16 @@ GENMD-RUN-COMMAND
mlr --md-aligned cat data/small
GENMD-EOF
+The `--right-align-numeric` flag also applies to markdown output: numeric columns get a
+right-alignment marker (`---:`) in the header-separator line, so they render right-aligned in
+Markdown viewers. With `--omd`, since output is streaming, the marker for each column is chosen
+from the first record of each same-schema group; with `--omd-aligned`, a column gets the marker
+when all its values are numeric, and its cell text is right-justified in the raw markdown as well:
+
+GENMD-RUN-COMMAND
+mlr --icsv --omd-aligned --right-align-numeric cat example.csv
+GENMD-EOF
+
## XTAB: Vertical tabular
This is perhaps most useful for looking a very wide and/or multi-column data which causes line-wraps on the screen (but see also
diff --git a/docs/src/manpage.md b/docs/src/manpage.md
index d05ef2c42..17c8fdf14 100644
--- a/docs/src/manpage.md
+++ b/docs/src/manpage.md
@@ -801,6 +801,11 @@ This is simply a copy of what you should see on running `man mlr` at a command p
right-align-multi-word
--fw {string} Shortcut for --fixed left-align-multi-word
--right Right-justifies all fields for PPRINT output.
+ --right-align-numeric Right-justifies fields with numeric values for PPRINT
+ output, leaving other fields (and header lines)
+ left-justified. Also applies to markdown output,
+ where numeric columns get right-alignment markers
+ (`---:`) in the header-separator line.
1mPROFILING FLAGS0m
These are flags for profiling Miller performance.
diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt
index 068e64a1f..307a8bb39 100644
--- a/docs/src/manpage.txt
+++ b/docs/src/manpage.txt
@@ -780,6 +780,11 @@
right-align-multi-word
--fw {string} Shortcut for --fixed left-align-multi-word
--right Right-justifies all fields for PPRINT output.
+ --right-align-numeric Right-justifies fields with numeric values for PPRINT
+ output, leaving other fields (and header lines)
+ left-justified. Also applies to markdown output,
+ where numeric columns get right-alignment markers
+ (`---:`) in the header-separator line.
1mPROFILING FLAGS0m
These are flags for profiling Miller performance.
diff --git a/docs/src/reference-main-flag-list.md b/docs/src/reference-main-flag-list.md
index 5147d6af1..c2f26e842 100644
--- a/docs/src/reference-main-flag-list.md
+++ b/docs/src/reference-main-flag-list.md
@@ -415,6 +415,7 @@ These are flags which are applicable to PPRINT format.
* `--fixed {string}`: Fixed width specification. One of 'widths:,,...', left-align, left-align-multi-word, right-align, right-align-multi-word
* `--fw {string}`: Shortcut for --fixed left-align-multi-word
* `--right`: Right-justifies all fields for PPRINT output.
+* `--right-align-numeric`: Right-justifies fields with numeric values for PPRINT output, leaving other fields (and header lines) left-justified. Also applies to markdown output, where numeric columns get right-alignment markers (`---:`) in the header-separator line.
## Profiling flags
diff --git a/man/manpage.txt b/man/manpage.txt
index 068e64a1f..307a8bb39 100644
--- a/man/manpage.txt
+++ b/man/manpage.txt
@@ -780,6 +780,11 @@
right-align-multi-word
--fw {string} Shortcut for --fixed left-align-multi-word
--right Right-justifies all fields for PPRINT output.
+ --right-align-numeric Right-justifies fields with numeric values for PPRINT
+ output, leaving other fields (and header lines)
+ left-justified. Also applies to markdown output,
+ where numeric columns get right-alignment markers
+ (`---:`) in the header-separator line.
1mPROFILING FLAGS0m
These are flags for profiling Miller performance.
diff --git a/man/mlr.1 b/man/mlr.1
index 6744ca31b..56ad0cb92 100644
--- a/man/mlr.1
+++ b/man/mlr.1
@@ -932,6 +932,11 @@ These are flags which are applicable to PPRINT format.
right-align-multi-word
--fw {string} Shortcut for --fixed left-align-multi-word
--right Right-justifies all fields for PPRINT output.
+--right-align-numeric Right-justifies fields with numeric values for PPRINT
+ output, leaving other fields (and header lines)
+ left-justified. Also applies to markdown output,
+ where numeric columns get right-alignment markers
+ (`---:`) in the header-separator line.
.fi
.if n \{\
.RE
diff --git a/pkg/cli/option_parse.go b/pkg/cli/option_parse.go
index f5c27841c..97ec7a66e 100644
--- a/pkg/cli/option_parse.go
+++ b/pkg/cli/option_parse.go
@@ -534,6 +534,18 @@ var PPRINTOnlyFlagSection = FlagSection{
},
},
+ {
+ name: "--right-align-numeric",
+ help: "Right-justifies fields with numeric values for PPRINT output, leaving " +
+ "other fields (and header lines) left-justified. Also applies to markdown " +
+ "output, where numeric columns get right-alignment markers (`---:`) in the " +
+ "header-separator line.",
+ parser: func(args []string, argc int, pargi *int, options *TOptions) {
+ options.WriterOptions.RightAlignNumericOutput = true
+ *pargi += 1
+ },
+ },
+
{
name: "--barred",
altNames: []string{"--barred-output"},
diff --git a/pkg/cli/option_types.go b/pkg/cli/option_types.go
index 451fc142b..fd9e8963d 100644
--- a/pkg/cli/option_types.go
+++ b/pkg/cli/option_types.go
@@ -102,6 +102,9 @@ type TWriterOptions struct {
RightAlignedPPRINTOutput bool
RightAlignedXTABOutput bool
MarkdownAlignedOutput bool
+ // Right-align numeric values in PPRINT output; for markdown output,
+ // use `---:` alignment markers for all-numeric columns.
+ RightAlignNumericOutput bool
// JSON output: --jlistwrap on, --jvstack on
// JSON Lines output: --jlistwrap off, --jvstack off
diff --git a/pkg/output/record_writer_markdown.go b/pkg/output/record_writer_markdown.go
index cf41bb877..51cfa971a 100644
--- a/pkg/output/record_writer_markdown.go
+++ b/pkg/output/record_writer_markdown.go
@@ -79,7 +79,15 @@ func (writer *RecordWriterMarkdown) writeStreaming(
bufferedOutputStream.WriteString("|")
for pe := outrec.Head; pe != nil; pe = pe.Next {
- bufferedOutputStream.WriteString(" --- |")
+ // In streaming mode the header-separator line must be emitted
+ // before subsequent records are seen, so with
+ // --right-align-numeric the alignment marker is chosen from this
+ // first record's value.
+ if writer.writerOptions.RightAlignNumericOutput && pe.Value.IsNumeric() {
+ bufferedOutputStream.WriteString(" ---: |")
+ } else {
+ bufferedOutputStream.WriteString(" --- |")
+ }
}
bufferedOutputStream.WriteString(writer.writerOptions.ORS)
@@ -138,10 +146,30 @@ func (writer *RecordWriterMarkdown) flushBatch(
first := writer.batch[0]
- // Floor of 3 so "---" never overflows the column.
+ // With --right-align-numeric, a column gets a right-alignment marker
+ // (`---:`) when every value in the batch's column is numeric.
+ columnRightAligned := make(map[string]bool)
+ if writer.writerOptions.RightAlignNumericOutput {
+ for pe := first.Head; pe != nil; pe = pe.Next {
+ columnRightAligned[pe.Key] = true
+ }
+ for _, rec := range writer.batch {
+ for pe := rec.Head; pe != nil; pe = pe.Next {
+ if !pe.Value.IsNumeric() {
+ columnRightAligned[pe.Key] = false
+ }
+ }
+ }
+ }
+
+ // Floor of 3 so "---" never overflows the column -- or 4 for "---:".
maxWidths := make(map[string]int)
for pe := first.Head; pe != nil; pe = pe.Next {
- maxWidths[pe.Key] = max(lib.DisplayWidth(pe.Key), 3)
+ minWidth := 3
+ if columnRightAligned[pe.Key] {
+ minWidth = 4
+ }
+ maxWidths[pe.Key] = max(lib.DisplayWidth(pe.Key), minWidth)
}
for _, rec := range writer.batch {
for pe := rec.Head; pe != nil; pe = pe.Next {
@@ -166,8 +194,13 @@ func (writer *RecordWriterMarkdown) flushBatch(
// Separator
bufferedOutputStream.WriteString("|")
for pe := first.Head; pe != nil; pe = pe.Next {
- bufferedOutputStream.WriteString(" ---")
- writePadding(bufferedOutputStream, maxWidths[pe.Key]-3)
+ if columnRightAligned[pe.Key] {
+ writePadding(bufferedOutputStream, maxWidths[pe.Key]-4)
+ bufferedOutputStream.WriteString(" ---:")
+ } else {
+ bufferedOutputStream.WriteString(" ---")
+ writePadding(bufferedOutputStream, maxWidths[pe.Key]-3)
+ }
bufferedOutputStream.WriteString(" |")
}
bufferedOutputStream.WriteString(writer.writerOptions.ORS)
@@ -178,8 +211,13 @@ func (writer *RecordWriterMarkdown) flushBatch(
for pe := rec.Head; pe != nil; pe = pe.Next {
value := strings.ReplaceAll(pe.Value.String(), "|", "\\|")
bufferedOutputStream.WriteString(" ")
- bufferedOutputStream.WriteString(colorizer.MaybeColorizeValue(value, outputIsStdout))
- writePadding(bufferedOutputStream, maxWidths[pe.Key]-lib.DisplayWidth(value))
+ if columnRightAligned[pe.Key] {
+ writePadding(bufferedOutputStream, maxWidths[pe.Key]-lib.DisplayWidth(value))
+ bufferedOutputStream.WriteString(colorizer.MaybeColorizeValue(value, outputIsStdout))
+ } else {
+ bufferedOutputStream.WriteString(colorizer.MaybeColorizeValue(value, outputIsStdout))
+ writePadding(bufferedOutputStream, maxWidths[pe.Key]-lib.DisplayWidth(value))
+ }
bufferedOutputStream.WriteString(" |")
}
bufferedOutputStream.WriteString(writer.writerOptions.ORS)
diff --git a/pkg/output/record_writer_pprint.go b/pkg/output/record_writer_pprint.go
index 332fac389..cd1718be0 100644
--- a/pkg/output/record_writer_pprint.go
+++ b/pkg/output/record_writer_pprint.go
@@ -185,7 +185,7 @@ func (writer *RecordWriterPPRINT) writeHeterogenousListNonBarred(
if s == "" {
s = "-"
}
- if !writer.writerOptions.RightAlignedPPRINTOutput { // left-align
+ if !writer.cellIsRightAligned(pe.Value) { // left-align
if pe.Next != nil {
// Data line, left-align, not last column
bufferedOutputStream.WriteString(colorizer.MaybeColorizeValue(s, outputIsStdout))
@@ -343,7 +343,7 @@ func (writer *RecordWriterPPRINT) writeHeterogenousListBarred(
bufferedOutputStream.WriteString(bc.verticalStart)
for pe := outrec.Head; pe != nil; pe = pe.Next {
s := pe.Value.String()
- if !writer.writerOptions.RightAlignedPPRINTOutput { // left-align
+ if !writer.cellIsRightAligned(pe.Value) { // left-align
bufferedOutputStream.WriteString(colorizer.MaybeColorizeValue(s, outputIsStdout))
writer.writePadding(s, maxWidths[pe.Key], bufferedOutputStream)
} else { // right-align
@@ -379,6 +379,16 @@ func (writer *RecordWriterPPRINT) writeHeterogenousListBarred(
}
}
+// cellIsRightAligned decides the alignment of a single data cell: everything
+// with --right; numeric values only with --right-align-numeric. Header cells
+// are not passed through here -- they right-align only with --right.
+func (writer *RecordWriterPPRINT) cellIsRightAligned(value *mlrval.Mlrval) bool {
+ if writer.writerOptions.RightAlignedPPRINTOutput {
+ return true
+ }
+ return writer.writerOptions.RightAlignNumericOutput && value.IsNumeric()
+}
+
func (writer *RecordWriterPPRINT) writePadding(
text string,
fieldWidth int,
diff --git a/test/cases/io-markdown/0003/cmd b/test/cases/io-markdown/0003/cmd
new file mode 100644
index 000000000..e18c3c97d
--- /dev/null
+++ b/test/cases/io-markdown/0003/cmd
@@ -0,0 +1 @@
+mlr --icsv --omd --right-align-numeric cat ${CASEDIR}/input
diff --git a/test/cases/io-markdown/0003/experr b/test/cases/io-markdown/0003/experr
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/cases/io-markdown/0003/expout b/test/cases/io-markdown/0003/expout
new file mode 100644
index 000000000..bf03eaedf
--- /dev/null
+++ b/test/cases/io-markdown/0003/expout
@@ -0,0 +1,6 @@
+| a | b | i | x |
+| --- | --- | ---: | ---: |
+| pan | pan | 1 | 0.34679000 |
+| eks | wye | 10000 | 0.75868000 |
+| wye | hat | -3 | N/A |
+| hat | zee | 5 | |
diff --git a/test/cases/io-markdown/0003/input b/test/cases/io-markdown/0003/input
new file mode 100644
index 000000000..983929e6c
--- /dev/null
+++ b/test/cases/io-markdown/0003/input
@@ -0,0 +1,5 @@
+a,b,i,x
+pan,pan,1,0.34679
+eks,wye,10000,0.75868
+wye,hat,-3,N/A
+hat,zee,5,
diff --git a/test/cases/io-markdown/0004/cmd b/test/cases/io-markdown/0004/cmd
new file mode 100644
index 000000000..38e071e0e
--- /dev/null
+++ b/test/cases/io-markdown/0004/cmd
@@ -0,0 +1 @@
+mlr --icsv --omd-aligned --right-align-numeric cat ${CASEDIR}/input
diff --git a/test/cases/io-markdown/0004/experr b/test/cases/io-markdown/0004/experr
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/cases/io-markdown/0004/expout b/test/cases/io-markdown/0004/expout
new file mode 100644
index 000000000..b206b3481
--- /dev/null
+++ b/test/cases/io-markdown/0004/expout
@@ -0,0 +1,6 @@
+| a | b | i | x |
+| --- | --- | ---: | --- |
+| pan | pan | 1 | 0.34679000 |
+| eks | wye | 10000 | 0.75868000 |
+| wye | hat | -3 | N/A |
+| hat | zee | 5 | |
diff --git a/test/cases/io-markdown/0004/input b/test/cases/io-markdown/0004/input
new file mode 100644
index 000000000..983929e6c
--- /dev/null
+++ b/test/cases/io-markdown/0004/input
@@ -0,0 +1,5 @@
+a,b,i,x
+pan,pan,1,0.34679
+eks,wye,10000,0.75868
+wye,hat,-3,N/A
+hat,zee,5,
diff --git a/test/cases/io-pprint-right-align-numeric/0001/cmd b/test/cases/io-pprint-right-align-numeric/0001/cmd
new file mode 100644
index 000000000..56d83155b
--- /dev/null
+++ b/test/cases/io-pprint-right-align-numeric/0001/cmd
@@ -0,0 +1 @@
+mlr --icsv --opprint --right-align-numeric cat ${CASEDIR}/input
diff --git a/test/cases/io-pprint-right-align-numeric/0001/experr b/test/cases/io-pprint-right-align-numeric/0001/experr
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/cases/io-pprint-right-align-numeric/0001/expout b/test/cases/io-pprint-right-align-numeric/0001/expout
new file mode 100644
index 000000000..904116eb2
--- /dev/null
+++ b/test/cases/io-pprint-right-align-numeric/0001/expout
@@ -0,0 +1,5 @@
+a b i x
+pan pan 1 0.34679000
+eks wye 10000 0.75868000
+wye hat -3 N/A
+hat zee 5 -
diff --git a/test/cases/io-pprint-right-align-numeric/0001/input b/test/cases/io-pprint-right-align-numeric/0001/input
new file mode 100644
index 000000000..983929e6c
--- /dev/null
+++ b/test/cases/io-pprint-right-align-numeric/0001/input
@@ -0,0 +1,5 @@
+a,b,i,x
+pan,pan,1,0.34679
+eks,wye,10000,0.75868
+wye,hat,-3,N/A
+hat,zee,5,
diff --git a/test/cases/io-pprint-right-align-numeric/0002/cmd b/test/cases/io-pprint-right-align-numeric/0002/cmd
new file mode 100644
index 000000000..ad12c83e8
--- /dev/null
+++ b/test/cases/io-pprint-right-align-numeric/0002/cmd
@@ -0,0 +1 @@
+mlr --icsv --opprint --barred --right-align-numeric cat ${CASEDIR}/input
diff --git a/test/cases/io-pprint-right-align-numeric/0002/experr b/test/cases/io-pprint-right-align-numeric/0002/experr
new file mode 100644
index 000000000..e69de29bb
diff --git a/test/cases/io-pprint-right-align-numeric/0002/expout b/test/cases/io-pprint-right-align-numeric/0002/expout
new file mode 100644
index 000000000..db257f18f
--- /dev/null
+++ b/test/cases/io-pprint-right-align-numeric/0002/expout
@@ -0,0 +1,8 @@
++-----+-----+-------+------------+
+| a | b | i | x |
++-----+-----+-------+------------+
+| pan | pan | 1 | 0.34679000 |
+| eks | wye | 10000 | 0.75868000 |
+| wye | hat | -3 | N/A |
+| hat | zee | 5 | |
++-----+-----+-------+------------+
diff --git a/test/cases/io-pprint-right-align-numeric/0002/input b/test/cases/io-pprint-right-align-numeric/0002/input
new file mode 100644
index 000000000..983929e6c
--- /dev/null
+++ b/test/cases/io-pprint-right-align-numeric/0002/input
@@ -0,0 +1,5 @@
+a,b,i,x
+pan,pan,1,0.34679
+eks,wye,10000,0.75868
+wye,hat,-3,N/A
+hat,zee,5,