summaryrefslogtreecommitdiff
path: root/lib/String/Fold.pm6
diff options
context:
space:
mode:
authorPatrick Spek <p.spek@tyil.nl>2019-08-05 15:33:49 +0200
committerPatrick Spek <p.spek@tyil.nl>2019-08-05 15:33:49 +0200
commit6debedec5f308607c38273cdb5d7a43de531c55f (patch)
treedf1b3764ad1b5ae3fa468611fe485eb99e717d04 /lib/String/Fold.pm6
parent8edebb9d3c912349d28255bbdbe73c2660d34346 (diff)
parent883ea2f95c3dcc749b0117ca7c121d8bdef4a1bc (diff)
Merge branch 'master' into merge
Diffstat (limited to 'lib/String/Fold.pm6')
-rw-r--r--lib/String/Fold.pm697
1 files changed, 38 insertions, 59 deletions
diff --git a/lib/String/Fold.pm6 b/lib/String/Fold.pm6
index 127b913..0bd2296 100644
--- a/lib/String/Fold.pm6
+++ b/lib/String/Fold.pm6
@@ -7,81 +7,71 @@ 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,
+ Str() $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,
+ Int() :$width where 0 < * = 79,
--> 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;
- }
+ my @paragraphs;
- # Work through each word on the line and fold them to the maximum width.
- for $line.words -> $word {
- if (new-line-length(@current-words, $word, $indent) <= $width) {
- @current-words.append($word);
- next;
+ for $string.split("\n\n") -> $paragraph {
+ my @lines;
+ my $current-line = 0;
+
+ for $paragraph.lines.join(" ").words -> $word {
+ # If this word would make the line too long, go to the next line.
+ if (@lines[$current-line].&line-length + $word.chars > $width) {
+ $current-line++;
}
- @folded-lines.append(@current-words.join(" "));
- @current-words = [$word];
+ # Append the current word to the line.
+ @lines[$current-line].append($word);
}
- # Clean up the current list of words.
- @folded-lines.append(@current-words.join(" "));
- @current-words = [];
+ @paragraphs.append(@lines.join("\n"));
}
- # 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");
+ @paragraphs.join("\n\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,
+#| Get the length of a line array. If the array does not exist yet, it is
+#| clearly empty, and this sub returns 0.
+multi sub line-length (
+ Any,
+
--> Int
) {
- my Int $chars = 0;
-
- # Get the number of characters in each word.
- $chars += [+] @words>>.chars;
+ 0
+}
- $chars += @words.elems; # Spaces inbetween the words.
- $chars += $new-word.chars;
- $chars += $indent-width;
+#| Get the length of a line array. This counts the characters of all words in
+#| the array, and adds up the number of spaces required for it to be a human
+#| representable line.
+multi sub line-length (
+ #| The line array, containing any number of words.
+ @line,
- $chars;
+ --> Int
+) {
+ @line.map(*.chars).sum + @line.elems
}
=begin pod
=NAME String::Fold
=AUTHOR Patrick Spek <p.spek@tyil.work>
-=VERSION 0.1.2
+=VERSION 0.1.0
=head1 SYNOPSIS
-fold(Str:D $, Int:D :$width, Int:D :$indent);
+fold(Str:D $, Int:D :$width);
=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>>.
+Fold a C<Str> to a given width. Accepts a C<:$width>N<Defaults to C<79>>
+argument.
=head1 EXAMPLES
@@ -94,7 +84,7 @@ 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.
+lines folded to a maximum width of 79 characters.
=head2 Folding at a custom width
@@ -104,19 +94,8 @@ 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.
+This will yield a string folded at 40 characters, instead of the default of 79
+characters. Any number higher than C<0> is accepted.
=end pod