Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 4e735a4604
Fetching contributors…

Cannot retrieve contributors at this time

file 113 lines (101 sloc) 3.121 kb
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 103 104 105 106 107 108 109 110 111 112 113
use 5.010;
use strict;
use warnings;
use autodie;
use JSON;
use POSIX;
$ENV{TZ}='Z';

binmode(STDOUT, ":encoding(UTF-8)");

# read from 'features.json'
my $features = 'features.json';
my $mtime = (stat $features)[9];

# read in the json data
my $data;
{
    local $/;
    open my $f, '<:encoding(UTF-8)', $features;
    my $raw = <$f>;
    $data = decode_json($raw);
}


# place the column numbers for each compiler into %comp_index
my %comp_index;
my $comp_count = 0;
for my $c (@{$data->{'COMPILERS'}}) {
    $comp_index{$c->{'abbr'}} = $comp_count++;
}

# walk through all of the items, filling in @ratings for each item
# and populating footnotes
my %footnotes;
my $foot_count;
my %rating_class = (
    '+' => 'implemented',
    '-' => 'missing',
    '+-' => 'partial',
    '?' => 'unknown',
);
my %rating_text = ( '+-' => "\N{U+00B1}", '-' => "\N{U+2212}" );
for my $sec (@{$data->{'sections'}}) {
    for my $item (@{$sec->{'items'}}) {
        my $status = $item->{'status'};
        my @ratings;
        while ($status =~ m/(\w+)([+-]+)\s*(?:\(([^()]+)\))?/g) {
            my ($abbr, $rating, $comment) = ($1, $2, $3);
            die "Unknown abbreviation '$abbr'"
                unless exists $comp_index{$abbr};
            my $r = {
                status => $rating_text{$rating} // $rating,
                class => $rating_class{$rating},
            };
            if ($comment) {
                $footnotes{$comment} //= ++$foot_count;
                $r->{footnote} = $footnotes{$comment};
                $r->{foottext} = $comment;
            }
            $ratings[$comp_index{$abbr}] = $r;
        }
        for (0..($comp_count-1)) {
            $ratings[$_] //= { status => '?', class => 'unknown' }
        }
        $item->{'ratings'} = \@ratings;
        $item->{'code'} = arrayify($item->{'code'}, 'code');
        $item->{'spec'} = arrayify($item->{'spec'}, 'spec');
    }
}

# use Data::Dumper;
# print Dumper $data;
write_html();

sub arrayify {
    my ($r, $key) = @_;
    if (defined $r && ref($r) eq 'ARRAY') {
        return [ map { { $key => $_ } } @{$r} ];
    }
    if ($r) {
        return [ { $key => $r } ];
    }
    [ ];
}


sub write_html {
    require HTML::Template::Compiled;
    my $t = HTML::Template::Compiled->new(
        filename => 'template.html',
        open_mode => ':encoding(UTF-8)',
        default_escape => 'HTML',
        global_vars => 1,
    );
    $t->param(compilers => $data->{'COMPILERS'});
    $t->param(sections => $data->{'sections'});
    $t->param(when => POSIX::ctime($mtime) . " " . (POSIX::tzname())[0] );
    $t->param(now => POSIX::ctime(time) . " " . (POSIX::tzname())[0] );

    my @footkeys = sort { $footnotes{$a} <=> $footnotes{$b} }
                        keys %footnotes;
    my @footnotes = map { { id => $footnotes{$_}, text => $_, } } @footkeys;
    $t->param(footnotes => \@footnotes);

    if (@ARGV) {
        my $filename = shift @ARGV;
        open my $out, '>:encoding(UTF-8)', $filename;
        print { $out } $t->output;
        close $out;
    } else {
        print $t->output;
    }
}
Something went wrong with that request. Please try again.