#!/usr/bin/env perl use 5.014; use warnings; use utf8; use re '/msx'; use open IO => ':encoding(utf-8)', ':std'; use charnames (); use JSON (); use Data::Dump 'pp'; our $VERSION = '1.02'; my $symname = eval { open my $keysymh, '<', 'data/keysymdef.json' or die $!; local $/; return JSON->new->decode(readline $keysymh); } or die "Could not read keysym definitions: $@\n"; my $geochar = do './keyspos.inc.pl' or die "Could not read keyboard position names: $@\n"; my %res; while (readline) { my ($pos, $def) = m/^\h* key \h+ <(\w+)> \h+ \{ (.+?) \};/ or next; my @mode = map { [split /,\h*/] } $def =~ m/\[ \h* (.*?) \h* \]/g; for my $shift (0, 1) { defined(my $chr = $mode[0]->[$shift + 2]) or warn "missing $pos +$shift\n"; if ($chr =~ m/^U ([A-F0-9]+) $/) { $chr = chr hex $1; } elsif (defined $symname->{$chr}) { $chr = $symname->{$chr}; } elsif ($chr eq 'NoSymbol') { next; } else { warn "unknown symbol $chr at $pos\n"; } $res{$geochar->{$pos}->[$shift] // $pos} = $chr; #$res{$pos}[$shift] = $symname->{$chr} // $chr; # geochar } } say ppp(\%res); sub ppp { local $_ = pp(@_); s/(?<=") \\x \{? ([0-9A-F]{2,6}) \}?/chr hex $1/eg; # unescape glyphs s/(\p{Mn})/sprintf '\N{%s}', charnames::viacode(ord $1)/eg; # named accents return $_; } __END__ =head1 NAME mkkeyboard-xkb-symbols - Character map of an xkb symbols file =head1 SYNOPSIS cat /usr/share/X11/xkb/symbols/us | perl -ne 'print if /^xkb_symbols "intl"/../^\};/' | mkkeyboard-xkb-symbols >map-us-intl.inc.pl =head1 DESCRIPTION Parses C declarations inside an C section and returns a perl hash of normalised qwerty input to unicode output of 3rd and 4th levels (altgr and shift+altgr modes) to be manually cleaned and integrated in a keyboard page include. =head1 AUTHOR Mischa POSLAWSKY =head1 LICENSE Licensed under the GNU Affero General Public License version 3.