File: sort-ops.raku

package info (click to toggle)
nqp 2020.12%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 8,880 kB
  • sloc: java: 26,979; perl: 3,386; ansic: 450; makefile: 203; javascript: 68; sh: 1
file content (70 lines) | stat: -rw-r--r-- 2,033 bytes parent folder | download | duplicates (3)
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
# Script to be run whenever a section or an op is added or removed
# from ops.markdown.  Or just before every commit.  It makes sure
# that all sections and all entries are alphabetically sorted for
# easier lookup, while the Miscellaneous section is always last.

my @in = "ops.markdown".IO.slurp.lines(:!chomp);
my $line;
my @out;

my %sections;

class Section {
    has $.name;
    has $.label;
    has %.ops;

    method toc() {
        my $ops := %!ops.keys.sort.map( {
            my $name := .words.head;
            my $label := .subst(/ \s* '`' (\w+) '`' /, { "-$0" }, :g );
            "[$name](#$label)"
        } ).join(" |\n");
        "## [$!name](#$!label)\n\n$ops\n\n"
    }

    method doc() {
        my $doc := %!ops.sort(*.key).map( -> (:key($name), :value($text)) {
            "## $name\n$text"
        } ).join;
        "# <a id=\"$!label\"></a> $!name\n\n$doc"
    }
}

# until we get to the table of contents
@out.push($line)
  until ($line := @in.shift).starts-with('## [');

# skip the table of contents
Nil until ($line := @in.shift).starts-with('# <a id="');

# until the end of the file
while @in {
    my $label   := ~$line.match(/ '"' <( .* )> '"' /);
    my $name    := $line.match(/ 'a>' \s* <( .*/).chomp;
    my $section := %sections{$label} //= Section.new(:$label,:$name);
    
    # skip empty lines until first op
    Nil until ($line := @in.shift).starts-with('## ');

    # handle ops until end of file or next section
    repeat {
        my $op := $line.substr(3).chomp;
        my @lines;
        @lines.push($line)
          until !@in
            || ($line := @in.shift).starts-with('## ')
            || $line.starts-with('# <a id="');
        $section.ops{$op} = @lines.join;

    } until !@in || $line.starts-with('# <a id="');
}

# Make sure <misc> comes last
my @labels  = %sections.keys.sort: { $_ eq 'misc' ?? 'zzz' !! $_ };

# push labels and then sections
@out.push(%sections{$_}.toc) for @labels;
@out.push(%sections{$_}.doc) for @labels;

"ops.markdown".IO.spurt(@out.join);