#! /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.words -> $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