summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jirutka <jakub@jirutka.cz>2015-01-11 23:49:43 +0100
committerJakub Jirutka <jakub@jirutka.cz>2015-01-12 14:54:52 +0100
commit2edf642b82ae88ed93ec5f6ed7ae699771c04fc6 (patch)
treee90bf2e685b9b36cb95864f1a58ba96cd6345a2c
parent3c27c089589523203f87f88de9e4955f0073e0d4 (diff)
downloadpsych-2edf642b82ae88ed93ec5f6ed7ae699771c04fc6.tar.gz
Use appropriate style for serialized strings
When psych parses YAML with string in the folded style as: a: > some inline content and serializes it back to YAML, then it renders the string in the literal style instead: a: | some inline content This patch fixes this behaviour. When a string doesn't contain newlines (blank line at the end is ignored) and it's not necessary to be quoted, then it will use plain style or folded style according to its length and the `line_width` option. # line_width = 100 a: some inline content # line_width = 11 a: > some inline content This change was originally proposed by @Iazel.
-rw-r--r--lib/psych/visitors/yaml_tree.rb15
-rw-r--r--test/psych/test_string.rb24
2 files changed, 34 insertions, 5 deletions
diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb
index e24b655..976ea8d 100644
--- a/lib/psych/visitors/yaml_tree.rb
+++ b/lib/psych/visitors/yaml_tree.rb
@@ -309,19 +309,20 @@ module Psych
style = Nodes::Scalar::LITERAL
plain = false
quote = false
- elsif o =~ /\n/
+ elsif o =~ /\n[^\Z]/ # match \n except blank line at the end of string
style = Nodes::Scalar::LITERAL
elsif o == '<<'
style = Nodes::Scalar::SINGLE_QUOTED
tag = 'tag:yaml.org,2002:str'
plain = false
quote = false
+ elsif line_width != 0 && o.length > line_width
+ style = Nodes::Scalar::FOLDED
+ o += "\n" unless o =~ /\n\Z/ # to avoid non-default chomping indicator
elsif o =~ /^[^[:word:]][^"]*$/
style = Nodes::Scalar::DOUBLE_QUOTED
- else
- unless String === @ss.tokenize(o)
- style = Nodes::Scalar::SINGLE_QUOTED
- end
+ elsif not String === @ss.tokenize(o)
+ style = Nodes::Scalar::SINGLE_QUOTED
end
ivars = find_ivars o
@@ -588,6 +589,10 @@ module Psych
accept target.instance_variable_get(iv)
end
end
+
+ def line_width
+ @line_width ||= (@options[:line_width] || 0)
+ end
end
end
end
diff --git a/test/psych/test_string.rb b/test/psych/test_string.rb
index 26a4e20..3188b5c 100644
--- a/test/psych/test_string.rb
+++ b/test/psych/test_string.rb
@@ -34,6 +34,30 @@ module Psych
assert_match(/---\s*"/, yaml)
end
+ def test_plain_when_shorten_than_line_width
+ str = "Lorem ipsum"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*[^>|]+\n/, yaml
+ end
+
+ def test_folded_when_longer_than_line_width_and_no_newlines
+ str = "Lorem ipsum dolor sit amet, consectetur"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*>\n(.*\n){3}\Z/, yaml
+ end
+
+ def test_folded_when_longer_than_line_width_and_trailing_newline
+ str = "Lorem ipsum dolor sit\n"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*>\n(.*\n){2}\Z/, yaml
+ end
+
+ def test_literal_when_inner_newline
+ str = "Lorem ipsum\ndolor\n"
+ yaml = Psych.dump str, line_width: 12
+ assert_match /---\s*|\n(.*\n){2}\Z/, yaml
+ end
+
def test_cycle_x
str = X.new 'abc'
assert_cycle str