digraphs: prepare target characters as strings
[sheet.git] / tools / mkdigraphs-rfc
1 #!/usr/bin/env perl
2 use 5.010;
3 use strict;
4 use warnings;
5 use utf8;
6 use open OUT => ':utf8', ':std';
7 use Data::Dump 'pp';
8
9 our $VERSION = '1.01';
10
11 # translation table for deprecated code points
12 my %replace = (
13         0xE001 => 0,  # join lines: not accepted
14         0xE004 => 0,  # umlaut is no different from diaeresis 0x0308
15         0xE005 => "\x{0344}", # discouraged
16         0xE006 => "\x{0300}",
17         0xE007 => "\x{0301}",
18         0xE008 => "\x{0302}",
19         0xE009 => "\x{0303}",
20         0xE00A => "\x{0304}",
21         0xE00B => "\x{0306}",
22         0xE00C => "\x{0307}",
23         0xE00D => "\x{0308}",
24         0xE00E => "\x{030A}",
25         0xE00F => "\x{030B}",
26         0xE010 => "\x{030C}",
27         0xE011 => "\x{0327}",
28         0xE012 => "\x{0328}",
29         0xE013 => "\x{0332}",
30         0xE014 => "\x{0333}",
31         0xE015 => "\x{0338}",
32         0xE016 => "\x{0345}",
33         0xE017 => "\x{0314}",
34         0xE018 => "\x{0313}",
35         0xE019 => "\x{1FFE}",
36         0xE01A => "\x{1FBF}",
37         0xE01B => "\x{03D0}",  # middle beta = curled beta?
38         0xE01C => "\x{25CB}",
39         0xE01D => "\x{0192}",
40         0xE01E => "\x{0292}",
41         0xE01F => "\x{33C2}",  # am, compatibility char
42         0xE020 => "\x{33D8}",  # pm, compatibility char
43         0xE021 => "\x{2121}",
44         0xE022 => "\x{FE8E}",
45         0xE023 => 0,  # dutch guilder 0192 is already encoded, and not very useful anyway
46         0xE024 => "\x{0393}",
47         0xE025 => "\x{20D7}",  # also 20D1; non-spacing
48         0xE026 => "\x{1FEF}",
49         0xE027 => "\x{1FC0}",
50         0xE028 => "\x{01F0}", #but uppercase
51 );
52
53 # expect input data source at command line
54 @ARGV or die "Specify input source file or - for STDIN\n";
55
56 # skip everything until a character indented by 1 space (table start)
57 do {
58         $_ = readline;
59         defined or die "Premature input end";
60 } until s/^\s(?=\S)//;
61
62 chomp;
63 my @line = $_;  # add first line (already read, assume it's ok)
64
65 # read the rest of the character table
66 while ($_ = readline) {
67         # check for table end (chapter 4)
68         last if /^\d/;
69
70         # parse table lines (ignore (unindented) page break)
71         next unless s/^ //;
72         chomp;
73
74         # append line contents
75         if (s/^ {15}/ /) {
76                 # continuation line (add to last entry)
77                 $line[-1] .= $_;
78         }
79         else {
80                 # add a new entry
81                 push @line, $_;
82         }
83 }
84
85 # output perl code of hash
86 # (assume no backslashes or curlies, so we can just q{} w/o escaping)
87 say "# automatically generated by $0";
88 say 'use utf8;';
89 say '+{';
90 for (@line) {
91         my ($mnem, $chrhex, $name) = split / +/, $_, 3;
92         next if length $mnem != 2;
93         my $chrnum = hex $chrhex;
94         my $chr = $replace{$chrnum} // chr $chrnum or next;
95         my $chrstr = pp $chr;
96         say "q{$mnem} => $chrstr, # $name";
97 }
98 say '}';
99
100 __END__
101
102 =head1 NAME
103
104 mkdigraphs-rfc - Output digraph data from RFC-1345
105
106 =head1 SYNOPSIS
107
108 Extract digraphs from text specifications as a perl hash:
109
110     mkdigraphs-rfc rfc1345.txt >digraphs-rfc.inc.pl
111
112 Input can be the literal RFC (or similar) document:
113
114     curl http://www.ietf.org/rfc/rfc1345.txt | mkdigraphlist -
115
116 Test by printing the character for DO (should be a dollar sign):
117
118     perl -e'$di = do "digraphs-rfc.inc.pl"; print chr $di->{DO}'
119
120 =head1 DESCRIPTION
121
122 Parses the official RFC-1345 document, searching the
123 'character mnemonic table' for all digraph definitions.
124 If successful, Perl code is output resulting in a hash
125 with Unicode code points keyed by digraph.
126 Obsolete values (references to private use area)
127 are converted to modern alternatives.
128 Any errors and warnings are given at STDERR.
129
130 =head1 AUTHOR
131
132 Mischa POSLAWSKY <perl@shiar.org>
133
134 =head1 LICENSE
135
136 Licensed under the GNU Affero General Public License version 3.
137