#!/usr/bin/perl -w # # Updates the
that surround the headings # in reference.md, for the ids' x:* (expansions) and c:* (conditions). # # Also updates the keyword index. # # With --check, checks that they are all up to date. use strict; use JSON qw(from_json); our $install; if (@ARGV==0) { $install = 1; } elsif (@ARGV==1 && $ARGV[0] eq '--check') { $install = 0; } else { die "bad usage\n"; } our $input = "doc/reference.md"; our $output = "doc/reference.md.new"; our $handled = qr{^[xc]:}; our $div_id = qr{^\
\s*$}; our %targets; # $targets{$lno} = [ $id, ... ] #---------- Read reference.md ---------- open F, $input or die $!; our @f = ; F->error and die $!; close F; unshift @f, ""; #---------- read the JSON telling us where the ref headings are ---------- open J, "maint/check-keywords-documented --json |" or die $!; our $json; { local ($/) = undef; $json = ; } J->error and die $!; $json = from_json($json) or die $!; foreach my $id (sort keys %{ $json->{ref_lines} }) { next unless $id =~ m{$handled}; my %lno = map { $_, 1 } @{ $json->{ref_lines}{$id} }; keys(%lno) == 1 or die "multiple for $id"; my ($i) = keys %lno; push @{ $targets{$i} }, $id; } #---------- decide what divs need to go where, strip out old ones ---------- our @instructions; foreach my $i (sort { $a <=> $b } keys %targets) { eval { die 'missing blank line before' if $f[$i-1] =~ m/\S/; die 'missing blank line after' if $f[$i+1] =~ m/\S/; my $delta = 2; for ( $delta = 2; $f[$i+$delta] =~ m{^\\s*$}; $delta++ ) { $f[$i-$delta] =~ m{$div_id} or die "invalid pre-div \@+$delta \`$_`"; my $target = $1; if ($target =~ m{$handled}) { $f[$i-$delta] = ""; $f[$i+$delta] = ""; } } if ($delta > 2) { die 'missing blank line before divs' if $f[$i-$delta] =~ m/\S/; die 'missing blank line after divs' if $f[$i+$delta] =~ m/\S/; } push @instructions, [ $i, $delta ]; } or die "$input:$i: error: $@"; } #---------- check for misplaced divs (not deleted above) ---------- foreach my $i (1..$#f) { next unless $f[$i] =~ m{$div_id}; my $id = $1; next unless $id =~ m{$handled}; die "$input:$i: misplaced div for id=\"$id\"\n"; } #---------- (re)insert the keyword divs ---------- foreach my $insn (@instructions) { my ($i, $delta) = @$insn; my $append_before = ""; my $insert_after = ""; if ($delta == 2) { $append_before = "\n\n"; $insert_after = "\n\n"; } foreach my $target (sort @{ $targets{$i} }) { $append_before .= "
\n"; $insert_after = "
\n" . $insert_after; } $f[$i-$delta] .= $append_before; $f[$i+$delta] = $insert_after . $f[$i+$delta]; 1; } #---------- make the indexes ---------- sub mkindex ($$) { my ($kind, $kformat) = @_; my $i = 0; for (;;) { die "missing meta for index $kind" if $i > @f; last if $f[$i] =~ m{^\<\!--\#\# index $kind \#\#--\>.*$}; $i++; } for (my $j = $i+1; $j < @f && $f[$j] =~ m{^\s}; $j++) { $f[$j] = ""; } my $l = \ $f[$i]; $$l .= "\n"; my $ref_lines = $json->{ref_lines}; foreach my $az ('a'..'z') { my @ids = grep { m{^$kind:$az} } sort keys %$ref_lines; next unless @ids; $$l .= " * **".(sprintf $kformat, $az)."**: ". (join ', ', map { s/^$kind://; "[`$_`](#$kind:$_)" } @ids). "\n"; } $$l .= "\n"; } mkindex('x', '$%s…'); mkindex('c', '%s…'); #---------- write and handle output ---------- die unless shift(@f) eq ''; open O, "> $output" or die "$output: $!"; print O @f or die $!; close O or die $!; if ($install) { rename "$output", "$input" or die $!; } else { $?=$!=0; system qw(diff -u), "$input", "$output"; if ($? == 0) { } elsif ($? == 256) { print STDERR <