--- /dev/null
+#!/usr/bin/env perl
+use 5.014;
+use warnings;
+use utf8;
+use open IO => ':utf8', ':std';
+use Data::Dump 'pp';
+
+our $VERSION = '1.00';
+
+# translation table for deprecated code points
+my %replace = (
+ 0xF015 => '⎇', # alt
+ 0xF016 => '⇧', # shift
+ 0xF017 => '⎈', # control
+);
+
+# expect input data source at command line
+@ARGV or die "Specify input source file or - for STDIN\n";
+
+# convert each character line to perl code
+# (assume no backslashes or curlies, so we can just q{} w/o escaping)
+say "# automatically generated by $0";
+say 'use utf8;';
+say '+{';
+while ($_ = readline) {
+ my ($chrhex, $mnems, $sample, $name) = m{\A([0-9A-F]{4}) (.{11}) (.)\t(.*)}i
+ or warn("syntax error on line $.: $_"), next;
+ my $chrnum = hex $chrhex;
+ my $chr = chr $chrnum;
+ $chr eq $sample
+ or warn("character mismatch on line $.: $_"), next;
+ $chr = $replace{$chrnum} or next if defined $replace{$chrnum};
+ my $chrstr = pp($replace{$chrnum} // $chr);
+ for my $mnem (split / /, $mnems) {
+# next if length $mnem != 2;
+ say "q{$mnem} => $chrstr, # $name";
+ }
+}
+say '}';
+
+__END__
+
+=head1 NAME
+
+mkdigraphs-plan9 - Output digraph data from Plan9 keyboard data
+
+=head1 SYNOPSIS
+
+Extract digraphs from text specifications as a perl hash:
+
+ mkdigraphs-plan9 keyboard >digraphs-plan9.inc.pl
+
+Input can be the literal RFC (or similar) document:
+
+ curl https://9fans.github.io/usr/local/plan9/lib/keyboard | mkdigraphs-plan9 -
+
+Test by printing the character for DO (should be a dollar sign):
+
+ perl -e'$di = do "digraphs-plan9.inc.pl"; print chr $di->{DO}'
+
+=head1 DESCRIPTION
+
+Parses the official RFC-1345 document, searching the
+'character mnemonic table' for all digraph definitions.
+If successful, Perl code is output resulting in a hash
+with Unicode code points keyed by digraph.
+Obsolete values (references to private use area)
+are converted to modern alternatives.
+Any errors and warnings are given at STDERR.
+
+=head1 AUTHOR
+
+Mischa POSLAWSKY <perl@shiar.org>
+
+=head1 LICENSE
+
+Licensed under the GNU Affero General Public License version 3.
+