summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--META6.json4
-rw-r--r--lib/String/Fold.pm6123
-rw-r--r--t/files/input/indented-block.txt1
-rw-r--r--t/files/input/multiple-long-lines.txt6
-rw-r--r--t/files/input/multiple-short-lines.txt3
-rw-r--r--t/files/input/single-long-line.txt1
-rw-r--r--t/files/input/single-short-line.txt1
-rw-r--r--t/files/input/three-paragraphs.txt5
-rw-r--r--t/files/output/indented-block.txt11
-rw-r--r--t/files/output/multiple-long-lines.txt12
-rw-r--r--t/files/output/multiple-short-lines.txt3
-rw-r--r--t/files/output/single-long-line.txt2
-rw-r--r--t/files/output/single-short-line.txt1
-rw-r--r--t/files/output/three-paragraphs.txt28
-rw-r--r--t/indented-block.t19
-rw-r--r--t/paragraphs.t23
-rw-r--r--t/simple-blocks.t70
18 files changed, 312 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1003abb..618a64d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,5 +5,5 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic
Versioning](http://semver.org/spec/v2.0.0.html).
-## [UNRELEASED]
+## [0.1.0] - 2018-07-08
- Initial release
diff --git a/META6.json b/META6.json
index d4ecdba..4ef74fe 100644
--- a/META6.json
+++ b/META6.json
@@ -11,7 +11,7 @@
"name": "String::Fold",
"perl": "6.c",
"provides": {
-
+ "String::Fold": "lib/String/Fold.pm6"
},
"resources": [
@@ -19,5 +19,5 @@
"tags": [
],
- "version": "0.0.0"
+ "version": "0.1.0"
} \ No newline at end of file
diff --git a/lib/String/Fold.pm6 b/lib/String/Fold.pm6
new file mode 100644
index 0000000..7b47be3
--- /dev/null
+++ b/lib/String/Fold.pm6
@@ -0,0 +1,123 @@
+#! /usr/bin/env false
+
+use v6.c;
+
+unit module String::Fold;
+
+#| Fold a string to contain no lines longer than the given width.
+sub fold (
+ #| The string to fold.
+ Str:D $string,
+
+ #| The maximum width of lines in the text.
+ Int:D :$width where 0 < * = 80,
+
+ #| The number of spaces used to indent the text.
+ Int:D :$indent where -1 < * = 0,
+
+ --> Str
+) is export {
+ my Str @folded-lines = [];
+ my Str @current-words = [];
+
+ for $string.trim.lines -> $line {
+ # Nothing to do if the line is less than the maximum width.
+ if ($line.chars <= $width) {
+ @folded-lines.append($line);
+ next;
+ }
+
+ # Work through each word on the line and fold them to the maximum width.
+ for $line.comb(/\S+/) -> $word {
+ if (new-line-length(@current-words, $word, $indent) <= $width) {
+ @current-words.append($word);
+ next;
+ }
+
+ @folded-lines.append(@current-words.join(" "));
+ @current-words = [$word];
+ }
+
+ # Clean up the current list of words.
+ @folded-lines.append(@current-words.join(" "));
+ @current-words = [];
+ }
+
+ # Add the last line if we have any leftover current words.
+ @folded-lines.push(@current-words.join(" ")) if @current-words;
+
+ return @folded-lines>>.indent($indent).join("\n");
+}
+
+#| Calculate the total line length of a would-be line.
+sub new-line-length (
+ Str:D @words,
+ Str:D $new-word,
+ Int:D $indent-width,
+ --> Int
+) {
+ my Int $chars = 0;
+
+ # Get the number of characters in each word.
+ $chars += [+] @words>>.chars;
+
+ $chars += @words.elems; # Spaces inbetween the words.
+ $chars += $new-word.chars;
+ $chars += $indent-width;
+
+ $chars;
+}
+
+=begin pod
+
+=NAME String::Fold
+=AUTHOR Patrick Spek <p.spek@tyil.work>
+=VERSION 0.1.0
+
+=head1 SYNOPSIS
+
+fold(Str:D $, Int:D :$width, Int:D :$indent);
+
+=head1 DESCRIPTION
+
+Fold a C<Str> to a given width. Accepts a C<:$width>N<Defaults to C<80>> and a
+C<:$indent>N<Defaults to C<0>>.
+
+=head1 EXAMPLES
+
+=head2 Basic usage
+
+=begin input
+use String::Fold;
+
+my Str $folded = fold(slurp("some-text-file"));
+=end input
+
+This will yield a folded string in C<$folded>. The input file will have all its
+lines folded to a maximum width of 80 characters.
+
+=head2 Folding at a custom width
+
+=begin input
+use String::Fold;
+
+my Str $folded = slurp("some-text-file").&fold(:width(40));
+=end input
+
+This will yield a string folded at 40 characters, instead of the default of 80
+characters. Any number higher that C<0> is accepted.
+
+=head2 Indented block
+
+=begin input
+use String::Fold;
+
+my Str $indented = slurp("some-text-file").&fold(:indent(8));
+=end input
+
+This will yield a string folded at 80 characters (the default), and indented by
+8 spaces.
+
+=end pod
+
+# vim: ft=perl6 noet
diff --git a/t/files/input/indented-block.txt b/t/files/input/indented-block.txt
new file mode 100644
index 0000000..c6d096f
--- /dev/null
+++ b/t/files/input/indented-block.txt
@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sit amet diam at ipsum malesuada pulvinar. Cras ut aliquet purus. Pellentesque vehicula urna felis, non facilisis libero volutpat egestas. Aliquam placerat tempor neque nec consectetur. Maecenas lacinia egestas tellus eu lacinia. Aenean tincidunt quam ante, at pharetra enim maximus et. Proin scelerisque metus at neque rutrum commodo at at mi. Vivamus fringilla ullamcorper euismod. Donec finibus non justo at tempus. Suspendisse efficitur felis a consequat scelerisque. Suspendisse consectetur eu nisl nec pellentesque. Sed vitae quam pellentesque, dignissim quam vitae, scelerisque urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
diff --git a/t/files/input/multiple-long-lines.txt b/t/files/input/multiple-long-lines.txt
new file mode 100644
index 0000000..901fd30
--- /dev/null
+++ b/t/files/input/multiple-long-lines.txt
@@ -0,0 +1,6 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur dictum, magnanon semper maximus, est ex
+mattis ipsum, eu sodales lectus est nec nibh. Maecenas porttitor nisi non tortor ultricies, quis vulputate nunc
+convallis. Mauris lacus mi, malesuada vel metus in, tempor malesuada leo. Mauris id neque et sem efficitur ornare.
+Praesent egestas nisi malesuada sagittis tempor. Quisque nunc arcu, ullamcorper et sem et, tristique auctor tortor.
+Nullam sagittis malesuada placerat. Aenean pretium leo et odio molestie porta. Praesent eu arcu sit amet risus
+convallis consectetur vel in quam. Integer id augue mauris. Morbi eget dictum ligula. Nulla facilisi.
diff --git a/t/files/input/multiple-short-lines.txt b/t/files/input/multiple-short-lines.txt
new file mode 100644
index 0000000..886c6e3
--- /dev/null
+++ b/t/files/input/multiple-short-lines.txt
@@ -0,0 +1,3 @@
+This is a short line.
+This is another short line.
+For good measure, let's use a third line.
diff --git a/t/files/input/single-long-line.txt b/t/files/input/single-long-line.txt
new file mode 100644
index 0000000..72ffc3e
--- /dev/null
+++ b/t/files/input/single-long-line.txt
@@ -0,0 +1 @@
+This is a long test line, to test whether it cuts of at the right point. For this, it needs to be at least 80 characters.
diff --git a/t/files/input/single-short-line.txt b/t/files/input/single-short-line.txt
new file mode 100644
index 0000000..f242fad
--- /dev/null
+++ b/t/files/input/single-short-line.txt
@@ -0,0 +1 @@
+This is a test line.
diff --git a/t/files/input/three-paragraphs.txt b/t/files/input/three-paragraphs.txt
new file mode 100644
index 0000000..bd478c5
--- /dev/null
+++ b/t/files/input/three-paragraphs.txt
@@ -0,0 +1,5 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sit amet diam at ipsum malesuada pulvinar. Cras ut aliquet purus. Pellentesque vehicula urna felis, non facilisis libero volutpat egestas. Aliquam placerat tempor neque nec consectetur. Maecenas lacinia egestas tellus eu lacinia. Aenean tincidunt quam ante, at pharetra enim maximus et. Proin scelerisque metus at neque rutrum commodo at at mi. Vivamus fringilla ullamcorper euismod. Donec finibus non justo at tempus. Suspendisse efficitur felis a consequat scelerisque. Suspendisse consectetur eu nisl nec pellentesque. Sed vitae quam pellentesque, dignissim quam vitae, scelerisque urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
+
+Nulla dignissim diam dui, eu maximus dolor tincidunt id. Aenean gravida elementum pellentesque. Ut consectetur ante quis mauris facilisis faucibus. Morbi pharetra ex sodales massa faucibus, a convallis libero consequat. Sed in blandit eros. Maecenas id elit nec lorem tempus bibendum. Duis consequat dui ut tortor auctor, non vestibulum lorem tempus. Praesent imperdiet efficitur metus, at malesuada odio tempus a. Nulla dictum sed tellus et consectetur. Integer ac efficitur est. Proin at euismod urna, ut tincidunt mi.
+
+Proin egestas arcu felis, ut interdum orci suscipit tempor. Vestibulum vitae libero mi. Nunc feugiat non arcu vel faucibus. Duis id tempus turpis. Sed at orci ultricies, volutpat leo id, iaculis velit. Maecenas tempus libero odio, bibendum placerat est placerat vitae. Nulla bibendum iaculis sagittis. Etiam eget arcu ac velit elementum placerat et non massa. Etiam eget imperdiet quam. Cras volutpat turpis eget dapibus convallis. Fusce viverra tempor faucibus. Quisque a felis volutpat, pretium nisi in, iaculis neque. Morbi dignissim lorem mattis dignissim ornare. Etiam fringilla semper aliquam. Integer blandit tempus ipsum, non pellentesque nunc ullamcorper et.
diff --git a/t/files/output/indented-block.txt b/t/files/output/indented-block.txt
new file mode 100644
index 0000000..3930b9f
--- /dev/null
+++ b/t/files/output/indented-block.txt
@@ -0,0 +1,11 @@
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sit
+ amet diam at ipsum malesuada pulvinar. Cras ut aliquet purus.
+ Pellentesque vehicula urna felis, non facilisis libero volutpat egestas.
+ Aliquam placerat tempor neque nec consectetur. Maecenas lacinia egestas
+ tellus eu lacinia. Aenean tincidunt quam ante, at pharetra enim maximus
+ et. Proin scelerisque metus at neque rutrum commodo at at mi. Vivamus
+ fringilla ullamcorper euismod. Donec finibus non justo at tempus.
+ Suspendisse efficitur felis a consequat scelerisque. Suspendisse
+ consectetur eu nisl nec pellentesque. Sed vitae quam pellentesque,
+ dignissim quam vitae, scelerisque urna. Vestibulum ante ipsum primis in
+ faucibus orci luctus et ultrices posuere cubilia Curae;
diff --git a/t/files/output/multiple-long-lines.txt b/t/files/output/multiple-long-lines.txt
new file mode 100644
index 0000000..e2588ba
--- /dev/null
+++ b/t/files/output/multiple-long-lines.txt
@@ -0,0 +1,12 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur dictum,
+magnanon semper maximus, est ex
+mattis ipsum, eu sodales lectus est nec nibh. Maecenas porttitor nisi non tortor
+ultricies, quis vulputate nunc
+convallis. Mauris lacus mi, malesuada vel metus in, tempor malesuada leo. Mauris
+id neque et sem efficitur ornare.
+Praesent egestas nisi malesuada sagittis tempor. Quisque nunc arcu, ullamcorper
+et sem et, tristique auctor tortor.
+Nullam sagittis malesuada placerat. Aenean pretium leo et odio molestie porta.
+Praesent eu arcu sit amet risus
+convallis consectetur vel in quam. Integer id augue mauris. Morbi eget dictum
+ligula. Nulla facilisi.
diff --git a/t/files/output/multiple-short-lines.txt b/t/files/output/multiple-short-lines.txt
new file mode 100644
index 0000000..886c6e3
--- /dev/null
+++ b/t/files/output/multiple-short-lines.txt
@@ -0,0 +1,3 @@
+This is a short line.
+This is another short line.
+For good measure, let's use a third line.
diff --git a/t/files/output/single-long-line.txt b/t/files/output/single-long-line.txt
new file mode 100644
index 0000000..ed6ad21
--- /dev/null
+++ b/t/files/output/single-long-line.txt
@@ -0,0 +1,2 @@
+This is a long test line, to test whether it cuts of at the right point. For
+this, it needs to be at least 80 characters.
diff --git a/t/files/output/single-short-line.txt b/t/files/output/single-short-line.txt
new file mode 100644
index 0000000..f242fad
--- /dev/null
+++ b/t/files/output/single-short-line.txt
@@ -0,0 +1 @@
+This is a test line.
diff --git a/t/files/output/three-paragraphs.txt b/t/files/output/three-paragraphs.txt
new file mode 100644
index 0000000..8f884f4
--- /dev/null
+++ b/t/files/output/three-paragraphs.txt
@@ -0,0 +1,28 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent sit amet diam
+at ipsum malesuada pulvinar. Cras ut aliquet purus. Pellentesque vehicula urna
+felis, non facilisis libero volutpat egestas. Aliquam placerat tempor neque nec
+consectetur. Maecenas lacinia egestas tellus eu lacinia. Aenean tincidunt quam
+ante, at pharetra enim maximus et. Proin scelerisque metus at neque rutrum
+commodo at at mi. Vivamus fringilla ullamcorper euismod. Donec finibus non justo
+at tempus. Suspendisse efficitur felis a consequat scelerisque. Suspendisse
+consectetur eu nisl nec pellentesque. Sed vitae quam pellentesque, dignissim
+quam vitae, scelerisque urna. Vestibulum ante ipsum primis in faucibus orci
+luctus et ultrices posuere cubilia Curae;
+
+Nulla dignissim diam dui, eu maximus dolor tincidunt id. Aenean gravida
+elementum pellentesque. Ut consectetur ante quis mauris facilisis faucibus.
+Morbi pharetra ex sodales massa faucibus, a convallis libero consequat. Sed in
+blandit eros. Maecenas id elit nec lorem tempus bibendum. Duis consequat dui ut
+tortor auctor, non vestibulum lorem tempus. Praesent imperdiet efficitur metus,
+at malesuada odio tempus a. Nulla dictum sed tellus et consectetur. Integer ac
+efficitur est. Proin at euismod urna, ut tincidunt mi.
+
+Proin egestas arcu felis, ut interdum orci suscipit tempor. Vestibulum vitae
+libero mi. Nunc feugiat non arcu vel faucibus. Duis id tempus turpis. Sed at
+orci ultricies, volutpat leo id, iaculis velit. Maecenas tempus libero odio,
+bibendum placerat est placerat vitae. Nulla bibendum iaculis sagittis. Etiam
+eget arcu ac velit elementum placerat et non massa. Etiam eget imperdiet quam.
+Cras volutpat turpis eget dapibus convallis. Fusce viverra tempor faucibus.
+Quisque a felis volutpat, pretium nisi in, iaculis neque. Morbi dignissim lorem
+mattis dignissim ornare. Etiam fringilla semper aliquam. Integer blandit tempus
+ipsum, non pellentesque nunc ullamcorper et.
diff --git a/t/indented-block.t b/t/indented-block.t
new file mode 100644
index 0000000..9acf5e6
--- /dev/null
+++ b/t/indented-block.t
@@ -0,0 +1,19 @@
+#! /usr/bin/env perl6
+
+use v6.c;
+
+use String::Fold;
+use Test;
+
+my @result-lines = fold(slurp("t/files/input/indented-block.txt"), :indent(8)).lines;
+my @expected-lines = slurp("t/files/output/indented-block.txt").trim-trailing.lines;
+
+plan 1 + @expected-lines.elems;
+
+is @result-lines.elems, @expected-lines.elems, "Expected number of lines";
+
+for ^@expected-lines {
+ is @result-lines[$_], @expected-lines[$_], "Line {$_ + 1} is the same";
+}
+
+# vim: ft=perl6 noet
diff --git a/t/paragraphs.t b/t/paragraphs.t
new file mode 100644
index 0000000..99b557f
--- /dev/null
+++ b/t/paragraphs.t
@@ -0,0 +1,23 @@
+#! /usr/bin/env perl6
+
+use v6.c;
+
+use String::Fold;
+use Test;
+
+plan 1;
+
+subtest "Three paragraphs" => {
+ my @result-lines = fold(slurp("t/files/input/three-paragraphs.txt")).lines;
+ my @expected-lines = slurp("t/files/output/three-paragraphs.txt").trim.lines;
+
+ plan 1 + @expected-lines.elems;
+
+ is @result-lines.elems, @expected-lines.elems, "Expected number of lines";
+
+ for ^@expected-lines {
+ is @result-lines[$_], @expected-lines[$_], "Line {$_ + 1} is the same";
+ }
+}
+
+# vim: ft=perl6 noet
diff --git a/t/simple-blocks.t b/t/simple-blocks.t
new file mode 100644
index 0000000..b52e721
--- /dev/null
+++ b/t/simple-blocks.t
@@ -0,0 +1,70 @@
+#! /usr/bin/env perl6
+
+use v6.c;
+
+use String::Fold;
+use Test;
+
+plan 5;
+
+subtest "Empty string" => {
+ plan 1;
+
+ my Str $result = fold("");
+
+ is $result, "", "Empty string returns another empty string";
+}
+
+subtest "Single short line" => {
+ plan 1;
+
+ my $result = slurp("t/files/input/single-short-line.txt").trim.&fold;
+
+ is $result, slurp("t/files/output/single-short-line.txt").trim, "Short line returns the same short line";
+}
+
+subtest "Single long line" => {
+ plan 1;
+
+ my $result = slurp("t/files/input/single-long-line.txt").trim.&fold();
+ my @expected-lines = slurp("t/files/output/single-long-line.txt").trim.lines;
+ my @result-lines = $result.lines;
+
+ plan 1 + @expected-lines.elems;
+
+ is @result-lines.elems, @expected-lines.elems, "Expected {@result-lines.elems} lines";
+
+ for ^@expected-lines {
+ is @result-lines[$_], @expected-lines[$_], "Line {$_ + 1} is correct";
+ }
+}
+
+subtest "Multiple short lines" => {
+ my $result = slurp("t/files/input/multiple-short-lines.txt").trim.&fold();
+ my @expected-lines = slurp("t/files/output/multiple-short-lines.txt").trim.lines;
+ my @result-lines = $result.lines;
+
+ plan 1 + @expected-lines.elems;
+
+ is @result-lines.elems, @expected-lines.elems, "Expected {@result-lines.elems} lines";
+
+ for ^@expected-lines {
+ is @result-lines[$_], @expected-lines[$_], "Line {$_ + 1} is correct";
+ }
+}
+
+subtest "Multiple long lines" => {
+ my $result = slurp("t/files/input/multiple-long-lines.txt").trim.&fold();
+ my @expected-lines = slurp("t/files/output/multiple-long-lines.txt").trim.lines;
+ my @result-lines = $result.lines;
+
+ plan 1 + @expected-lines.elems;
+
+ is @result-lines.elems, @expected-lines.elems, "Expected {@result-lines.elems} lines";
+
+ for ^@expected-lines {
+ is @result-lines[$_], @expected-lines[$_], "Line {$_ + 1} is correct";
+ }
+}
+
+# vim: ft=perl6 noet