/
Form.pm
66 lines (54 loc) · 1.55 KB
/
Form.pm
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
unit module Form;
use Form::TextFormatting;
use Form::Grammar;
use Form::Actions;
use Form::Field;
sub form(*@args --> Str) is export {
my @lines;
my $result = '';
my $actions = Form::Actions.new;
while @args.elems {
my $format = @args.shift;
my $f = Form::Grammar.parse($format, :actions($actions));
$f or die "form: error: argument '$format' is not a valid format string";
my $nonliteral-field-count = $f.ast.grep( { $_ ~~ Form::Field::Field } ).elems;
if @args.elems < $nonliteral-field-count {
die "Insufficient number of data arguments ({@args.elems}) provided for format template '$format' which requires $nonliteral-field-count";
}
my @data;
for ^$nonliteral-field-count {
@data.push(@args.shift);
}
my @formatted;
for @($f.ast) {
when Str {
@formatted.push([$_]);
}
when Form::Field::Field {
@formatted.push([.format(@data.shift)]);
}
}
my $most-lines = ([max] @formatted.map: *.elems);
# RAKUDO: used to use $flines is rw and just overwrite in place that way
# But it doesn't seem to work at the moment
for (@($f.ast) Z (0..*)) -> ($field, $index) {
if @formatted[$index].elems < $most-lines {
if $field ~~ Form::Field::Field {
@formatted[$index] = $field.align(@formatted[$index], $most-lines);
}
elsif $field ~~ Str {
@formatted[$index] = $field xx $most-lines;
}
}
}
for ^$most-lines -> $line-number {
my $line;
for @formatted {
$line ~= $_[$line-number];
}
$result ~= $line ~ "\n";
}
}
return $result;
}
# vim: ft=perl6 sw=4 ts=4 noexpandtab