Source of shell.plp

<(common.inc.plp)><:
use List::Util qw(sum max first);

Html({
	title => 'Shell compatibility cheat sheet',
	version => '1.0',
	stylesheet => [qw'circus dark mono red light'],
	data => ['shell.inc.pl'],
});

say "<h1>Shell compatibility</h1>\n";

my $data = Data('shell');
my @agents = keys %{ $data->{agents} };

print '<table class="mapped">';
print '<col>';  # should match first thead row
printf '<colgroup span="%d">', 1 for @agents;
say '</colgroup><col>';

my $header = join('',
	'<tr>',
	'<th>feature',
	(map {
		sprintf('<th%s>%s',
			(map {
				sprintf ' title="%s"', Entity($_)
			} $data->{agents}->{$_}->{name} // ()),
			$_
		)
	} @agents),
);
print '<thead>', $header;
say '</thead>';
say '<tfoot>', $header;

sub saytitlecol {
	my ($row) = @_;
	print '<td>', Entity($row->{title});
}

my %TSTATS = (
	l5 => '✔',
	l4 => '✔',
	l3 => '±',
	l2 => '*',
	l1 => '✘',
);

sub saysupportcols {
	my ($row, $agent) = @_;
	my $support = $row->{support}->{$agent};
	my $level = (
		!defined $support ? 'l1' :
		ref $support ne 'HASH' ? 'l0' :
		$support->{alt} ? 'l2' :
		$support->{partial} ? 'l3' :
		$support->{optional} ? 'l4' :
		'l5'
	);
	my $title = join(' ',
		defined $support ? 'supported' : 'unsupported',
		'in', $data->{agents}->{$agent}->{abbr} // $agent,
	);
	$title .= " ($_)"
		for ref $support && ($support->{note} // $support->{optional}) || ();
	my $header = defined $support ? '✔' : '✘';
	printf('<td class="%s" title="%s">%s',
		join(' ', X => $level),
		$title,
		$TSTATS{$level} // (ref $support ? '?' : $support),
	);
}

say '<tbody>';
for my $row (sort {
	$a->{title} cmp $b->{title}
} @{ $data->{feature} }) {
	(my $id = lc $row->{title}) =~ s/\W+/-/g;
	printf '<tr id="%s">', $id;
	saytitlecol($row);
	saysupportcols($row, $_) for @agents;
	say '</tr>';
}
say '</tbody>';
say '</table>';