-
Notifications
You must be signed in to change notification settings - Fork 1
/
Paragraphs.rakumod
35 lines (31 loc) · 1.95 KB
/
Paragraphs.rakumod
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
unit module Text::Paragraphs;
my token bullet { [@(<- + *>) | [ \d\d? '.' ]] \s* }
my token non-bullet { <-[- + *] - [\d]> }
my token bullet-prefix { ^^ $<ws>=(\h*) <bullet> }
my token indent-prefix { ^^ \h* }
my token blank-line { ^^ \h* [\n | $ ] }
my token rest-of-line { \N* [\n | $ ] }
my token continuation-line($indent) {
\h ** {$indent} [\S & <non-bullet>] <rest-of-line> }
our proto paragraphs(|) is export {*}
multi paragraphs(Str $_, :$chomp=True, :$limit is copy =∞, :(:$pos is copy = 0) --> Seq()) {
gather until $pos ≥ .chars or $limit-- ≤ 0 {
if m:p($pos)• <bullet-prefix> • { my $indent = .<ws>.chars..$_.chars with $<bullet-prefix>;
m:p($pos)• <bullet-prefix> <rest-of-line>
<continuation-line($indent)>* • }
elsif m:p($pos)• <indent-prefix> • { my $indent = $<indent-prefix>.chars;
m:p($pos)• <indent-prefix> <( <rest-of-line>
<continuation-line(0..^$indent)>*
<blank-line>* )> • }
$chomp ?? take(~$/.trim-trailing) !! take(~$/) andthen $pos = $/.to }
}
multi paragraphs(Cool $c, :$chomp=True, :$limit=∞) { $c.Str.¶graphs: :$chomp:$limit }
multi paragraphs(IO::Path $p, :$chomp=True, :$limit=∞, :$enc = 'utf8', :$nl-in = ["\x0A", "\r\n"]) {
my $handle = $p.open(:$enc:$nl-in) andthen LEAVE try .close;
eager $handle.¶graphs: :$chomp:$limit }
multi paragraphs(IO::Handle $h, :$chomp=True, :$limit is copy =∞, :$close) {
# A limited bit of laziness (closser to &split's laziness than &lines)
flat gather for $h.comb(/.*? [\n <blank-line> | $]/, :$close) {
for .¶graphs: :$chomp:$limit { $limit--; .take }
last if $limit ≤ 0}
}