summaryrefslogtreecommitdiff
path: root/lib/String/Fold.pm6
blob: 0bd22961af5885c96d769f1ee92d74da5becbf86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#! /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 <p.spek@tyil.work>
=VERSION 0.1.0

=head1 SYNOPSIS

fold(Str:D $, Int:D :$width);

=head1 DESCRIPTION

Fold a C<Str> to a given width. Accepts a C<:$width>N<Defaults to C<79>>
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