Skip to content

Commit a859de1

Browse files
committed
feat(cli): add option --yaml-style-newline
1 parent bf8e468 commit a859de1

12 files changed

+104
-9
lines changed

completions/remarshal.bash

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ _remarshal() {
99
input_formats=$formats
1010
output_formats="$formats python"
1111

12-
opts='--help --version --from --if --input-format --input --indent --stringify --max-values --multiline --output --sort-keys --to --of --output-format --unwrap --verbose --width --wrap --yaml-style'
12+
opts='--help --version --from --if --input-format --input --indent --stringify --max-values --multiline --output --sort-keys --to --of --output-format --unwrap --verbose --width --wrap --yaml-style --yaml-style-newline'
1313

1414
case "${prev}" in
1515
--from | --if | --input-format | -f)
@@ -20,7 +20,7 @@ _remarshal() {
2020
COMPREPLY=($(compgen -W "${output_formats}" -- ${cur}))
2121
return 0
2222
;;
23-
--yaml-style)
23+
--yaml-style | --yaml-style-newline)
2424
COMPREPLY=($(compgen -W '\" '"\\' '|' '>'" -- ${cur}))
2525
return 0
2626
;;

completions/remarshal.fish

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
set --local yaml_styles '"\'" "\\"" "|" ">"'
2+
13
complete -c remarshal -s h -l help -d "Show help message and exit"
24
complete -c remarshal -s v -l version -d "Show program's version number and exit"
35

@@ -14,4 +16,5 @@ complete -c remarshal -l unwrap -x -d "Only output data under given key"
1416
complete -c remarshal -l verbose -d "Print debug information on error"
1517
complete -c remarshal -l width -x -d "Python and YAML line width"
1618
complete -c remarshal -l wrap -x -d "Wrap data in a map with given key"
17-
complete -c remarshal -l yaml-style -x -a '"\'" "\\"" "|" ">"' -d "YAML formatting style"
19+
complete -c remarshal -l yaml-style -x -a $yaml_styles -d "YAML formatting style"
20+
complete -c remarshal -l yaml-style-newline -x -a $yaml_styles -d "YAML formatting style override for strings that contain a newline"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
44

55
[project]
66
name = "remarshal"
7-
version = "1.0.1"
7+
version = "1.1.0"
88
description = "Convert between CBOR, JSON, MessagePack, TOML, and YAML"
99
authors = [{ name = "D. Bohdan", email = "dbohdan@dbohdan.com" }]
1010
license = { text = "MIT" }

src/remarshal/main.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import ruamel.yaml
4242
import ruamel.yaml.parser
4343
import ruamel.yaml.representer
44+
import ruamel.yaml.scalarstring
4445
import ruamel.yaml.scanner
4546
import umsgpack
4647

@@ -109,6 +110,7 @@ class TOMLOptions(FormatOptions):
109110
class YAMLOptions(FormatOptions):
110111
indent: int = Defaults.YAML_INDENT
111112
style: YAMLStyle = Defaults.YAML_STYLE
113+
style_newline: YAMLStyle | None = None
112114
width: int = Defaults.WIDTH
113115

114116

@@ -392,6 +394,13 @@ def output_width(value: str) -> int:
392394
help="YAML formatting style",
393395
)
394396

397+
parser.add_argument(
398+
"--yaml-style-newline",
399+
choices=["", "'", '"', "|", ">"],
400+
default=YAMLOptions().style_newline,
401+
help="YAML formatting style override for strings that contain a newline",
402+
)
403+
395404
parser.add_argument(
396405
"--yaml-width",
397406
dest="width",
@@ -761,15 +770,12 @@ def multilinify(item: tomlkit.items.Item) -> None:
761770
raise ValueError(msg)
762771

763772

764-
def _yaml_represent_none(self, data):
765-
return self.represent_scalar("tag:yaml.org,2002:null", "null")
766-
767-
768773
def _encode_yaml(
769774
data: Document,
770775
*,
771776
indent: int | None,
772777
style: YAMLStyle,
778+
style_newline: YAMLStyle | None,
773779
width: int,
774780
) -> str:
775781
yaml = ruamel.yaml.YAML(pure=True)
@@ -779,7 +785,15 @@ def _encode_yaml(
779785
yaml.indent = indent
780786
yaml.width = width
781787

782-
yaml.representer.add_representer(type(None), _yaml_represent_none)
788+
def represent_none(self, data):
789+
return self.represent_scalar("tag:yaml.org,2002:null", "null")
790+
791+
def represent_str(self, data):
792+
str_style = style_newline if "\n" in data else style
793+
return self.represent_scalar("tag:yaml.org,2002:str", data, style=str_style)
794+
795+
yaml.representer.add_representer(type(None), represent_none)
796+
yaml.representer.add_representer(str, represent_str)
783797

784798
try:
785799
out = StringIO()
@@ -804,6 +818,7 @@ def format_options(
804818
stringify: bool = False,
805819
width: int = Defaults.WIDTH,
806820
yaml_style: YAMLStyle = Defaults.YAML_STYLE,
821+
yaml_style_newline: YAMLStyle | None = None,
807822
) -> FormatOptions:
808823
match output_format:
809824
case "cbor":
@@ -837,6 +852,7 @@ def format_options(
837852
return YAMLOptions(
838853
indent=Defaults.YAML_INDENT if indent is None else indent,
839854
style=yaml_style,
855+
style_newline=yaml_style_newline,
840856
width=width,
841857
)
842858

@@ -918,6 +934,7 @@ def encode(
918934
data,
919935
indent=options.indent,
920936
style=options.style,
937+
style_newline=options.style_newline,
921938
width=options.width,
922939
).encode(UTF_8)
923940

@@ -1004,6 +1021,7 @@ def main() -> None:
10041021
stringify=args.stringify,
10051022
width=args.width,
10061023
yaml_style=args.yaml_style,
1024+
yaml_style_newline=args.yaml_style_newline,
10071025
)
10081026

10091027
remarshal(

tests/newline-default.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'single': 'this'
2+
'multiline': 'is
3+
4+
an
5+
6+
example'

tests/newline-double-quote.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
'single': 'this'
2+
'multiline': "is\nan\nexample"

tests/newline-empty.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
'single': 'this'
2+
'multiline': "is\nan\nexample"

tests/newline-gt.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'single': 'this'
2+
'multiline': >-
3+
is
4+
5+
an
6+
7+
example

tests/newline-pipe.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'single': 'this'
2+
'multiline': |-
3+
is
4+
an
5+
example

tests/newline-single-quote.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'single': 'this'
2+
'multiline': 'is
3+
4+
an
5+
6+
example'

0 commit comments

Comments
 (0)