#! /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() $string, #| The maximum width of lines in the text. Int() :$width where 0 < * = 79, --> Str ) is export { my @paragraphs; 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++; } # Append the current word to the line. @lines[$current-line].append($word); } @paragraphs.append(@lines.join("\n")); } @paragraphs.join("\n\n"); } #| 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 ) { 0 } #| 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, --> Int ) { @line.map(*.chars).sum + @line.elems } =begin pod =NAME String::Fold =AUTHOR Patrick Spek =VERSION 0.2.0 =head1 SYNOPSIS fold(Str:D $, Int:D :$width); =head1 DESCRIPTION Fold a C to a given width. Accepts a C<:$width>N> argument. =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 79 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 79 characters. Any number higher than C<0> is accepted. =end pod # vim: ft=perl6 noet