--- keymapper-0.5.3.orig/gen_keymap.1 +++ keymapper-0.5.3/gen_keymap.1 @@ -0,0 +1,62 @@ +.Dd September 5, 2006 +.Os Ubuntu +.ds volume-operating-system Ubuntu +.Dt GEN_KEYMAP 1 +.Sh NAME +.Nm gen_keymap +.Nd generate a keyboard map decision tree +.Sh SYNOPSIS +.Nm +.Ar list ... +.Sh DESCRIPTION +.Nm +generates a decision tree from a set of keyboard maps which can be used to +help a user decide which keyboard map to use. +The program using the decision tree typically asks the user to press some +keys; at each step, it examines the returned keycode and uses it to prune +the list of possible keyboard maps until there is only one left. +.Sh OPTIONS +.Bl -tag -width 4n +.It Fl Fl version +Show program's version number and exit. +.It Fl ? , Fl Fl help +Show help text. +.It Fl v , Fl Fl verbose +Be more verbose. +.It Fl m Ns Ar MINLEN , Fl Fl minlen Ns = Ns Ar MINLEN +Too-short keymaps are skipped (default: 30 entries). +.It Fl g , Fl Fl graph +Generate a hopefully-nice-looking .dot file. +.It Fl Fl maps +Print the to-be-processed keymaps +.It Fl i , Fl Fl installer +Input files are in d-i map form. +.It Fl I Ns Ar DIRS , Fl Fl inc Ns = Ns Ar DIRS , Fl Fl include Ns = Ns Ar DIRS +Add a directory to the search path. +.It Fl o Ns Ar FILENAME , Fl Fl output Ns = Ns Ar FILENAME +Set output file (default: stdout). +.It Fl f Ns Ar FILTER , Fl Fl filter Ns = Ns Ar FILTER +Include only the branches leading to these keymaps. +.It Fl u Ns Ar USEONLY , Fl Fl useonly Ns = Ns Ar USEONLY +Start generating the tree based only on these keymaps. +(The difference between +.Fl Fl filter +and +.Fl Fl useonly +is that the former generates the whole tree and then prunes it, while the +latter only generates a reduced tree to begin with. +This may have implications for performance on large trees.) +.It Fl s Ns Ar SKIP , Fl Fl skip Ns = Ns Ar SKIP +Keymaps to skip. +.It Fl t , Fl Fl test +Test the generated maps. +.It Fl Fl interactive +Ask user to choose among indistinguishable keymaps. +.El +.Sh AUTHORS +.An -nosplit +.Nm +was written by +.An "Matthias Urlichs" Aq smurf@debian.org . +This manual page was written by +.An "Colin Watson" Aq cjwatson@ubuntu.com . --- keymapper-0.5.3.orig/Makefile +++ keymapper-0.5.3/Makefile @@ -3,3 +3,7 @@ compile: # python setup.py $(MAKE) -C keymapper/parse + +clean: + # python setup.py clean --all + $(MAKE) -C keymapper/parse clean --- keymapper-0.5.3.orig/changelog +++ keymapper-0.5.3/changelog @@ -1,4 +1,743 @@ ChangeSet + 1.69 05/04/01 13:35:59 smurf@smurf.noris.de +2 -0 + fixed heuristics + + keymapper/tree.py + 1.17 05/04/01 13:35:59 smurf@smurf.noris.de +12 -10 + fixed heuristics + + keymapper/keymap.py + 1.14 05/04/01 13:35:59 smurf@smurf.noris.de +1 -1 + comment added + +ChangeSet + 1.68 05/04/01 12:26:19 smurf@smurf.noris.de +5 -0 + Ignore control, spacing, and unassigned characters. + + keymapper/tree.py + 1.16 05/04/01 12:26:19 smurf@smurf.noris.de +3 -3 + Ignore control, spacing, and unassigned characters. + + keymapper/keymap.py + 1.13 05/04/01 12:26:19 smurf@smurf.noris.de +6 -2 + Ignore control, spacing, and unassigned characters. + + keymapper/equiv.py + 1.5 05/04/01 12:26:19 smurf@smurf.noris.de +12 -1 + Ignore control, spacing, and unassigned characters. + + debian/changelog + 1.27 05/04/01 12:26:19 smurf@smurf.noris.de +7 -0 + Ignore control, spacing, and unassigned characters. + +ChangeSet + 1.67 05/04/01 12:25:48 smurf@smurf.noris.de +1 -0 + broken bar == solid bar + unified angle brackets + + data/equivs + 1.10 05/04/01 12:25:47 smurf@smurf.noris.de +3 -5 + broken bar == solid bar + unified angle brackets + + BitKeeper/deleted/.del-maps.py~ce085e4573381ab2 + 1.9 05/03/30 22:13:12 smurf@smurf.noris.de +0 -0 + Delete: keymapper/parse/maps.py + +ChangeSet + 1.66 05/03/30 18:43:06 smurf@smurf.noris.de +2 -0 + Added shortcuts to break excessively-broad recursion + + keymapper/tree.py + 1.15 05/03/30 18:43:06 smurf@smurf.noris.de +61 -10 + Added shortcuts to break excessively-broad recursion + + debian/changelog + 1.26 05/03/30 18:43:06 smurf@smurf.noris.de +2 -1 + Added shortcuts to break excessively-broad recursion + +ChangeSet + 1.65 05/03/30 18:41:19 smurf@smurf.noris.de +2 -0 + Increased the penalty for ALT-key combinations + + keymapper/keymap.py + 1.12 05/03/30 18:41:19 smurf@smurf.noris.de +1 -1 + Increased the penalty for ALT-key combinations + + debian/changelog + 1.25 05/03/30 18:41:19 smurf@smurf.noris.de +2 -1 + Increased the penalty for ALT-key combinations + +ChangeSet + 1.64 05/03/30 18:28:03 smurf@smurf.noris.de +2 -0 + more character stuff + + debian/changelog + 1.24 05/03/30 18:28:03 smurf@smurf.noris.de +3 -1 + more character stuff + + data/equivs + 1.9 05/03/30 18:28:03 smurf@smurf.noris.de +3 -3 + more stuff + +ChangeSet + 1.63 05/03/30 10:53:24 smurf@smurf.noris.de +2 -0 + Adjust heuristics + + keymapper/tree.py + 1.14 05/03/30 10:53:24 smurf@smurf.noris.de +2 -2 + Adjust heuristics + + debian/changelog + 1.23 05/03/30 10:53:24 smurf@smurf.noris.de +2 -1 + Adjust heuristics + +ChangeSet + 1.62 05/03/30 10:30:39 smurf@smurf.noris.de +4 -0 + Fix a crash generating sparse mapping trees + + keymapper/tree.py + 1.13 05/03/30 10:30:38 smurf@smurf.noris.de +5 -3 + Fix a crash generating sparse mapping trees + + keymapper/graph.py + 1.11 05/03/30 10:30:38 smurf@smurf.noris.de +6 -4 + Fix a crash generating sparse mapping trees + + keymapper/file.py + 1.9 05/03/30 10:30:38 smurf@smurf.noris.de +4 -2 + Fix a crash generating sparse mapping trees + + debian/changelog + 1.22 05/03/30 10:30:38 smurf@smurf.noris.de +1 -0 + Fix a crash generating sparse mapping trees + +ChangeSet + 1.61 05/03/30 10:30:09 smurf@smurf.noris.de +2 -0 + Another round of lookalike characters + + debian/changelog + 1.21 05/03/30 10:30:08 smurf@smurf.noris.de +6 -0 + Another round of lookalike characters + + data/equivs + 1.8 05/03/30 10:30:08 smurf@smurf.noris.de +4 -5 + Another round of lookalike characters + +ChangeSet + 1.60 05/03/25 01:08:37 smurf@smurf.noris.de +1 -0 + more debugging + + keymapper/script.py + 1.9 05/03/25 01:08:37 smurf@smurf.noris.de +6 -0 + more debugging + +ChangeSet + 1.59 05/03/25 01:06:53 smurf@smurf.noris.de +2 -0 + Aliased cedilla and comma + + debian/changelog + 1.20 05/03/25 01:06:53 smurf@smurf.noris.de +1 -0 + Aliased cedilla and comma + + data/equivs + 1.7 05/03/25 01:06:53 smurf@smurf.noris.de +2 -2 + Aliased cedilla and comma + +ChangeSet + 1.58 05/03/25 01:01:34 smurf@smurf.noris.de +3 -0 + add filter option + + keymapper/tree.py + 1.12 05/03/25 01:01:34 smurf@smurf.noris.de +29 -1 + add filter option + + gen_keymap + 1.17 05/03/25 01:01:34 smurf@smurf.noris.de +6 -1 + add filter option + + debian/changelog + 1.19 05/03/25 01:01:34 smurf@smurf.noris.de +7 -0 + add filter option + +ChangeSet + 1.57 05/02/27 20:36:24 smurf@smurf.noris.de +1 -0 + ignore more test stuff + + BitKeeper/etc/ignore + 1.14 05/02/27 17:41:32 smurf@smurf.noris.de +2 -0 + added map_equiv.py seektester + +ChangeSet + 1.56 05/02/27 17:40:58 smurf@smurf.noris.de +2 -0 + Install scripts + + debian/rules + 1.5 05/02/27 17:40:58 smurf@smurf.noris.de +2 -0 + Install scripts + + debian/changelog + 1.18 05/02/27 17:40:58 smurf@smurf.noris.de +2 -1 + Added script + +ChangeSet + 1.55 05/02/27 17:37:59 smurf@smurf.noris.de +1 -0 + Map comparison for X + + x2console_keymap + 1.4 05/02/27 17:37:59 smurf@smurf.noris.de +38 -45 + Map comparison for X + +ChangeSet + 1.54 05/02/27 17:37:31 smurf@smurf.noris.de +4 -0 + Query parser refactoring + + test_x11.py + 1.2 05/02/27 17:37:31 smurf@smurf.noris.de +2 -2 + Query parser refactoring + + test_gen_map.py + 1.10 05/02/27 17:37:31 smurf@smurf.noris.de +2 -2 + Query parser refactoring + + keymapper/script.py + 1.8 05/02/27 17:37:31 smurf@smurf.noris.de +23 -10 + Query parser refactoring + + keymapper/fakequery.py + 1.10 05/02/27 17:37:31 smurf@smurf.noris.de +17 -7 + Query parser refactoring + +ChangeSet + 1.53 05/02/27 17:37:08 smurf@smurf.noris.de +1 -0 + Ignore Hyper_* symbols + + keymapper/parse/linuxsyms.py + 1.6 05/02/27 17:37:08 smurf@smurf.noris.de +2 -1 + Ignore Hyper_ too + +ChangeSet + 1.52 05/02/27 17:36:14 smurf@smurf.noris.de +2 -0 + X11 parser extensions + + keymapper/parse/x11.g + 1.2 05/02/27 17:36:14 smurf@smurf.noris.de +30 -15 + X11 parser extensions, bugfix for subdirectories + + data/symbols + 1.3 05/02/27 17:36:14 smurf@smurf.noris.de +173 -32 + More symbols, some of them typos, for X11. + +ChangeSet + 1.51 05/02/27 17:34:50 smurf@smurf.noris.de +2 -0 + More equivalents. + + debian/changelog + 1.17 05/02/27 17:34:50 smurf@smurf.noris.de +2 -1 + Various small bugfixes. + + data/equivs + 1.6 05/02/27 17:34:50 smurf@smurf.noris.de +2 -1 + More equivalent characters. + + x2console_keymap + 1.3 05/02/27 13:16:26 smurf@smurf.noris.de +0 -0 + Rename: x2c_keymap -> x2console_keymap + + x2c_keymap + 1.2 05/02/27 13:16:11 smurf@smurf.noris.de +0 -0 + bk cp test_x11.py x2c_keymap + +ChangeSet + 1.50 05/02/27 13:14:44 smurf@smurf.noris.de +1 -0 + reverse keymap output for the tester + + keymapper/keymap.py + 1.11 05/02/27 13:14:44 smurf@smurf.noris.de +30 -6 + reverse keymap output for the tester + +ChangeSet + 1.49 05/02/27 13:13:22 smurf@smurf.noris.de +1 -0 + Skip meta and alt tags + + keymapper/parse/linuxsyms.py + 1.5 05/02/27 13:13:22 smurf@smurf.noris.de +2 -3 + Skip meta and alt tags + +ChangeSet + 1.48 05/02/27 13:12:54 smurf@smurf.noris.de +2 -0 + Speed up keymap filtering when keymaps have subsets. + + keymapper/tree.py + 1.11 05/02/27 13:12:54 smurf@smurf.noris.de +13 -5 + Speed up keymap filtering when keymaps have subsets. + + debian/changelog + 1.16 05/02/27 13:12:54 smurf@smurf.noris.de +2 -1 + Speed up keymap filtering when keymaps have subsets. + +ChangeSet + 1.47 05/02/27 13:11:43 smurf@smurf.noris.de +2 -0 + Fix color/style assignment in graph output. + + keymapper/graph.py + 1.10 05/02/27 13:11:43 smurf@smurf.noris.de +5 -2 + Fix color/style assignment in graph output. + + debian/changelog + 1.15 05/02/27 13:11:43 smurf@smurf.noris.de +2 -1 + Fix color/style assignment in graph output. + + x2c_keymap + 1.1 05/02/27 13:10:39 smurf@smurf.noris.de +74 -0 + + test_x11.py + 1.1 05/02/27 13:10:39 smurf@smurf.noris.de +74 -0 + + keymapper/parse/x11.g + 1.1 05/02/27 13:10:39 smurf@smurf.noris.de +247 -0 + + data/xkeys + 1.1 05/02/27 13:10:39 smurf@smurf.noris.de +58 -0 + +ChangeSet + 1.46 05/02/27 13:10:39 smurf@smurf.noris.de +8 -0 + Added an analyzer for X11 keymaps. + + x2c_keymap + 1.0 05/02/27 13:10:39 smurf@smurf.noris.de +0 -0 + BitKeeper file /daten/src/debian/keymapper/test_x11.py + + test_x11.py + 1.0 05/02/27 13:10:39 smurf@smurf.noris.de +0 -0 + BitKeeper file /daten/src/debian/keymapper/test_x11.py + + keymapper/parse/x11.g + 1.0 05/02/27 13:10:39 smurf@smurf.noris.de +0 -0 + BitKeeper file /daten/src/debian/keymapper/keymapper/parse/x11.g + + debian/rules + 1.4 05/02/27 13:10:39 smurf@smurf.noris.de +1 -0 + Install keycode table for X => console. + + debian/control + 1.7 05/02/27 13:10:39 smurf@smurf.noris.de +1 -1 + depend on X keymaps. + + debian/changelog + 1.14 05/02/27 13:10:39 smurf@smurf.noris.de +1 -0 + Added an analyzer for X11 keymaps. + + data/xkeys + 1.0 05/02/27 13:10:39 smurf@smurf.noris.de +0 -0 + BitKeeper file /daten/src/debian/keymapper/data/xkeys + + data/symbols + 1.2 05/02/27 13:10:39 smurf@smurf.noris.de +945 -338 + Lots of new stuff for X. + + BitKeeper/etc/ignore + 1.13 05/02/27 13:10:39 smurf@smurf.noris.de +1 -0 + added keymapper/parse/x11.py + +ChangeSet + 1.45 05/02/27 13:07:11 smurf@smurf.noris.de +1 -0 + utf-8-ize sys.stdout + + test_gen_map.py + 1.9 05/02/27 13:07:11 smurf@smurf.noris.de +2 -0 + utf-8-ize sys.stdout + +ChangeSet + 1.44 05/02/27 13:06:05 smurf@smurf.noris.de +2 -0 + Added lots of new lookalike Unicode characters, + from Unicode's NamesList.txt. + + debian/changelog + 1.13 05/02/27 13:06:05 smurf@smurf.noris.de +2 -0 + Added lots of new lookalike Unicode characters, + from Unicode's NamesList.txt. + + data/equivs + 1.5 05/02/27 13:06:05 smurf@smurf.noris.de +142 -28 + Added lots of new lookalike Unicode characters, + from Unicode's NamesList.txt. + +ChangeSet + 1.43 05/02/27 13:01:17 smurf@smurf.noris.de +3 -0 + Reworked the step file interpreter to process multiple possible choices in parallel + + keymapper/script.py + 1.7 05/02/27 13:01:17 smurf@smurf.noris.de +37 -31 + Reworked the step file interpreter to process multiple possible choices in parallel + + keymapper/fakequery.py + 1.9 05/02/27 13:01:17 smurf@smurf.noris.de +9 -5 + Reworked the step file interpreter to process multiple possible choices in parallel + + debian/changelog + 1.12 05/02/27 13:01:17 smurf@smurf.noris.de +7 -0 + Reworked the step file interpreter to process multiple possible choices in parallel + +ChangeSet + 1.42 05/02/15 20:27:44 smurf@smurf.noris.de +3 -0 + Version 0.4.3-1 + change search path logic to allow arbitrary paths + + keymapper/parse/linux.g + 1.3 05/02/15 20:27:43 smurf@smurf.noris.de +8 -15 + change search path logic to allow arbitrary paths + + gen_keymap + 1.16 05/02/15 20:27:43 smurf@smurf.noris.de +6 -5 + change search path logic to allow arbitrary paths + + debian/changelog + 1.11 05/02/15 20:27:43 smurf@smurf.noris.de +3 -2 + Version 0.4.3-1 + change search path logic to allow arbitrary paths + +ChangeSet + 1.41 05/02/14 22:52:07 smurf@smurf.noris.de +2 -0 + Fix dependency on python-dev. + + debian/control + 1.6 05/02/14 22:51:57 smurf@smurf.noris.de +1 -1 + Fix dependency on python-dev. + + debian/changelog + 1.10 05/02/14 22:51:57 smurf@smurf.noris.de +6 -0 + Fix dependency on python-dev. + +ChangeSet + 1.40 05/02/14 18:53:31 smurf@smurf.noris.de +1 -0 + ignore unicode files + + BitKeeper/etc/ignore + 1.12 05/02/14 18:53:20 smurf@smurf.noris.de +2 -0 + added NamesList.txt UnicodeData.txt + +ChangeSet + 1.39 05/02/14 18:52:52 smurf@smurf.noris.de +1 -0 + depend on current Python 2.4 + + debian/control + 1.5 05/02/14 18:52:52 smurf@smurf.noris.de +1 -1 + depend on current Python 2.4 + +ChangeSet + 1.38 05/02/14 18:49:16 smurf@smurf.noris.de +1 -0 + unstable => hoary + + debian/changelog + 1.9 05/02/14 18:49:15 smurf@smurf.noris.de +6 -6 + unstable => hoary + +ChangeSet + 1.37 05/02/04 23:45:32 smurf@smurf.noris.de +1 -0 + colorize the graph + + keymapper/graph.py + 1.9 05/02/04 23:45:28 smurf@smurf.noris.de +20 -13 + colorize + +ChangeSet + 1.36 05/02/04 23:45:10 smurf@smurf.noris.de +2 -0 + Small test fixes + + test_gen_map.py + 1.8 05/02/04 23:45:08 smurf@smurf.noris.de +1 -1 + Use utf-8 in map reader + + gen_keymap + 1.15 05/02/04 23:45:07 smurf@smurf.noris.de +27 -0 + Add test option to run the generated maps + +ChangeSet + 1.35 05/02/04 23:44:27 smurf@smurf.noris.de +7 -0 + Fix a couple of annoying bugs + + keymapper/tree.py + 1.10 05/02/04 23:44:20 smurf@smurf.noris.de +30 -4 + Use SymSet from keymapper.keymap + Check char type to prioritize better + Complain when a symbol doesn't print + + keymapper/script.py + 1.6 05/02/04 23:44:19 smurf@smurf.noris.de +31 -5 + fix multi-char "ask" + evaluate printed spacing symbols and control chars + + keymapper/keymap.py + 1.10 05/02/04 23:44:19 smurf@smurf.noris.de +11 -4 + Use NFC internally + add Set type to enfoce that + + keymapper/file.py + 1.8 05/02/04 23:44:18 smurf@smurf.noris.de +21 -2 + Print spacing symbols and some control chars + + keymapper/fakequery.py + 1.8 05/02/04 23:44:17 smurf@smurf.noris.de +9 -8 + Fix multi-char "ask" + + keymapper/fakemaps.py + 1.7 05/02/04 23:44:17 smurf@smurf.noris.de +1 -1 + Fix coding: header + + keymapper/equiv.py + 1.4 05/02/04 23:44:15 smurf@smurf.noris.de +9 -3 + Switch to NFC encoding internally + +ChangeSet + 1.34 05/02/03 13:57:10 smurf@smurf.noris.de +1 -0 + fix priorities + + keymapper/tree.py + 1.9 05/02/03 13:57:09 smurf@smurf.noris.de +38 -25 + priority adjust + +ChangeSet + 1.33 05/02/03 11:39:16 smurf@smurf.noris.de +5 -0 + Cleanup: The main programs are responsible for equipping the streams + passed into keymapper.* with appropriate codecs. + + test_gen_map.py + 1.7 05/02/03 11:39:13 smurf@smurf.noris.de +4 -3 + codec-ize the file streams here + + keymapper/file.py + 1.7 05/02/03 11:39:13 smurf@smurf.noris.de +2 -2 + don't encode, that's supposed to be done in the file + + keymapper/fakequery.py + 1.7 05/02/03 11:39:13 smurf@smurf.noris.de +1 -1 + don't utf8-decode here, input is supposed to be Unicode already + + keymapper/fakemaps.py + 1.6 05/02/03 11:39:13 smurf@smurf.noris.de +2 -2 + add a nice utf-8 character to the test to make it mroe interesting + + debian/changelog + 1.8 05/02/03 11:39:13 smurf@smurf.noris.de +3 -1 + Cleanup: The main programs are responsible for equipping the streams + passed into keymapper.* with appropriate codecs. + +ChangeSet + 1.32 05/02/03 11:31:42 smurf@smurf.noris.de +1 -0 + cleanup, now works with Python 2.3 + + gen_keymap + 1.14 05/02/03 11:31:41 smurf@smurf.noris.de +3 -3 + drop the subprocess import + syntax niceties + +ChangeSet + 1.31 05/02/03 11:31:16 smurf@smurf.noris.de +2 -0 + added more interesting letters + + debian/changelog + 1.7 05/02/03 11:31:15 smurf@smurf.noris.de +6 -0 + added more interesting letters + + data/equivs + 1.4 05/02/03 11:31:15 smurf@smurf.noris.de +22 -21 + more interesting letters + +ChangeSet + 1.30 05/02/02 19:30:45 smurf@smurf.noris.de +2 -0 + Add one and zero. + Conflate L and I. + + debian/changelog + 1.6 05/02/02 19:30:44 smurf@smurf.noris.de +7 -0 + Add one and zero. + Conflate L and I. + + data/equivs + 1.3 05/02/02 19:30:44 smurf@smurf.noris.de +2 -3 + Add one and zero. + Conflate L and I. + +ChangeSet + 1.29 05/02/02 19:28:52 smurf@smurf.noris.de +7 -0 + Extension: We print only those characters under consideration in the present step. + + keymapper/tree.py + 1.8 05/02/02 19:28:52 smurf@smurf.noris.de +30 -11 + core code to display only those characters that actually appear on the keys + + keymapper/keymap.py + 1.9 05/02/02 19:28:52 smurf@smurf.noris.de +4 -1 + add list of symbols actually present + + keymapper/graph.py + 1.8 05/02/02 19:28:52 smurf@smurf.noris.de +4 -3 + fix output code to deal with symbol stuff + + keymapper/file.py + 1.6 05/02/02 19:28:52 smurf@smurf.noris.de +5 -4 + There may be more than one symbol -- print correctly + + keymapper/fakequery.py + 1.6 05/02/02 19:28:52 smurf@smurf.noris.de +3 -3 + fixed processing for symbols that aren't present + + keymapper/equiv.py + 1.3 05/02/02 19:28:52 smurf@smurf.noris.de +5 -2 + add lowercase and uppercase versions + + debian/changelog + 1.5 05/02/02 19:28:52 smurf@smurf.noris.de +7 -0 + print only those characters under consideration at this step. + +ChangeSet + 1.28 05/02/02 17:08:40 smurf@smurf.noris.de +1 -0 + add more lookalike characters + + data/equivs + 1.2 05/02/02 17:08:40 smurf@smurf.noris.de +33 -22 + even more lookalike characters + +ChangeSet + 1.27 05/02/02 16:17:08 smurf@smurf.noris.de +1 -0 + bad file name in keymapper/equiv.py + + keymapper/equiv.py + 1.2 05/02/02 16:17:08 smurf@smurf.noris.de +2 -2 + bad file name + + keymapper/equiv.py + 1.1 05/02/02 16:14:49 smurf@smurf.noris.de +79 -0 + + data/equivs + 1.1 05/02/02 16:14:49 smurf@smurf.noris.de +30 -0 + +ChangeSet + 1.26 05/02/02 16:14:49 smurf@smurf.noris.de +13 -0 + Add character equivalence table. + + test_gen_map.py + 1.6 05/02/02 16:14:49 smurf@smurf.noris.de +4 -0 + Add character equivalence table. + + keymapper/tree.py + 1.7 05/02/02 16:14:49 smurf@smurf.noris.de +19 -8 + Add character equivalence table. + + keymapper/script.py + 1.5 05/02/02 16:14:49 smurf@smurf.noris.de +2 -2 + Add character equivalence table. + + keymapper/parse/linuxsyms.py + 1.4 05/02/02 16:14:49 smurf@smurf.noris.de +5 -0 + Add character equivalence table. + + keymapper/keymap.py + 1.8 05/02/02 16:14:49 smurf@smurf.noris.de +3 -1 + Add character equivalence table. + + keymapper/graph.py + 1.7 05/02/02 16:14:49 smurf@smurf.noris.de +9 -2 + Add character equivalence table. + + keymapper/file.py + 1.5 05/02/02 16:14:49 smurf@smurf.noris.de +4 -2 + Add character equivalence table. + + keymapper/fakequery.py + 1.5 05/02/02 16:14:49 smurf@smurf.noris.de +13 -6 + Add character equivalence table. + + keymapper/fakemaps.py + 1.5 05/02/02 16:14:49 smurf@smurf.noris.de +2 -2 + Add character equivalence table. + + keymapper/equiv.py + 1.0 05/02/02 16:14:49 smurf@smurf.noris.de +0 -0 + BitKeeper file /daten/src/debian/keymapper/keymapper/equiv.py + + debian/rules + 1.3 05/02/02 16:14:49 smurf@smurf.noris.de +1 -0 + Install character equivalence table. + + debian/changelog + 1.4 05/02/02 16:14:49 smurf@smurf.noris.de +6 -0 + Add character equivalence table. + + data/equivs + 1.0 05/02/02 16:14:49 smurf@smurf.noris.de +0 -0 + BitKeeper file /daten/src/debian/keymapper/data/equivs + +ChangeSet + 1.25 05/02/02 16:14:28 smurf@smurf.noris.de +1 -0 + Add option to skip tables (if they're identical to other tables) + + gen_keymap + 1.13 05/02/02 16:14:28 smurf@smurf.noris.de +8 -0 + Add option to skip tables (if they're identical to other tables) + +ChangeSet + 1.24 05/02/02 09:50:40 smurf@smurf.noris.de +1 -0 + ignore changelog + + BitKeeper/etc/ignore + 1.11 05/02/02 09:50:30 smurf@smurf.noris.de +1 -0 + added changelog + +ChangeSet + 1.23 05/02/02 09:50:27 smurf@smurf.noris.de +3 -0 + more build and installation stuff + + keymapper/parse/linuxsyms.py + 1.3 05/02/02 09:50:27 smurf@smurf.noris.de +1 -1 + read the symfile from somewhere sane + + gen_keymap + 1.12 05/02/02 09:50:27 smurf@smurf.noris.de +11 -8 + input file format option + + debian/rules + 1.2 05/02/02 09:50:27 smurf@smurf.noris.de +6 -1 + build the parser + install the symbol map + +ChangeSet + 1.22 05/02/02 09:29:22 smurf@smurf.noris.de +3 -0 + Added option to set the file system root. + + keymapper/parse/linux.g + 1.2 05/02/02 09:29:22 smurf@smurf.noris.de +5 -1 + Added option to set the file system root. + + gen_keymap + 1.11 05/02/02 09:29:22 smurf@smurf.noris.de +6 -1 + Added option to set the file system root. + + debian/changelog + 1.3 05/02/02 09:29:22 smurf@smurf.noris.de +1 -0 + Added option to set the file system root. + +ChangeSet + 1.21 05/02/02 08:58:42 smurf@smurf.noris.de +1 -0 + fixed the dependencies + + debian/control + 1.4 05/02/02 08:58:42 smurf@smurf.noris.de +1 -1 + dependency + + debian/exporter + 1.1 05/02/02 08:56:54 smurf@smurf.noris.de +10 -0 + +ChangeSet + 1.20 05/02/02 08:56:54 smurf@smurf.noris.de +1 -0 + added exporter for changelog + + debian/exporter + 1.0 05/02/02 08:56:54 smurf@smurf.noris.de +0 -0 + BitKeeper file /daten/src/debian/keymapper/debian/exporter + +ChangeSet 1.19 05/02/02 08:54:14 smurf@smurf.noris.de +1 -0 ignore stuff --- keymapper-0.5.3.orig/gen_keymap +++ keymapper-0.5.3/gen_keymap @@ -22,12 +22,13 @@ from keymapper.script import Script from keymapper.fakequery import FakeQuery from keymapper.parse.linux import parse_file as parse_linux -from keymapper.parse.linux import FileProblem +from keymapper.parse.linux import FileProblem, add_dir +from keymapper.fakequery import FakeQuery import sys import codecs from optparse import OptionParser, OptParseError -from subprocess import Popen,PIPE +#from subprocess import Popen,PIPE try: from cStringIO import StringIO except ImportError: @@ -39,42 +40,78 @@ parser.add_option("-?","--help", action="help", help="show this help text") parser.add_option("-v","--verbose", action="count", dest="verbose", help="be more verbose") parser.add_option("-m","--minlen", action="store", dest="minlen", type="int", default=30, help="Too-short Keymaps are skipped (default: 30 entries)") -parser.add_option("-g","--graph", action="store_const", dest="format", const="graphviz", - help="generate a hopefully-nice-looking .dot file") -parser.add_option("--maps", action="store_const", dest="format", const="mapdump", - help="print the to-be-processed keymaps") +parser.add_option("-g","--graph", action="store_const", dest="format", + const="graphviz", help="generate a hopefully-nice-looking .dot file") +parser.add_option("--maps", action="store_const", dest="format", + const="mapdump", help="print the to-be-processed keymaps") +parser.add_option("-i","--installer", action="store_const", dest="iformat", + const="d-i", help="Input files are in d-i map form") +parser.add_option("-I","--inc","--include", action="append", dest="dirs", + help="add a directory to the search path") parser.add_option("-o","--output", action="store", dest="filename", help="output file (default: stdout)") +parser.add_option("-f","--filter", action="store", dest="filter", + help="Include only the branches leading to these keymaps") +parser.add_option("-u","--useonly", action="store", dest="useonly", + help="Start generating the tree based only on these keymaps") +parser.add_option("-s","--skip", action="store", dest="skip", + help="keymaps to skip") +parser.add_option("-t","--test", action="store_true", dest="test", + help="Test the generated maps") +parser.add_option("--interactive", action="store_true", dest="interactive", + help="Ask user to choose among indistinguishable keymaps") +parser.add_option("--no-altgr", action="store_false", dest="altgr", + help="Do not consider AltGr keys", default=True) (opts, args) = parser.parse_args() if not args: parser.error("no arguments supplied") sys.exit(1) +if opts.test and opts.format: + parser.error("You can only test scripts") + sys.exit(1) +if opts.test and not opts.filename: + parser.error("You can only test scripts if you write them to a file") + sys.exit(1) t = Tree() keymapper.tree.trace = opts.verbose +keymapper.tree.interactive = opts.interactive + +if opts.dirs: + for d in opts.dirs: + add_dir(d) if opts.filename: - out=open(opts.filename,"w") + out = open(opts.filename,"w") else: - out=sys.stdout + out = sys.stdout if opts.format == "graphviz": out = codecs.getwriter("latin1")(out,"replace") else: out = codecs.getwriter("utf-8")(out) +known={} for f in args: for l in open(f): comment = l.find('#') if comment > -1: l = l[:comment] l = l.strip() if l == "": continue - if " " in l or "\t" in l: - (name,code) = l.split() + name = l.split() + if opts.iformat == "d-i": + name = name[1] else: - name = l - code = "utf-8" + name = name[0] + if opts.useonly and name not in opts.useonly.split(","): + continue + if opts.skip and name in opts.skip.split(","): + continue + if name in known: + continue + known[name]=1 + # code = codecs.getreader(code) # pipe = Popen(("loadkeys","-q","-M",name), stdout=PIPE).stdout # pipe = code(pipe) @@ -83,8 +120,8 @@ try: if opts.verbose: print "Parsing:",name -# map = parse_map(name,pipe) - map = parse_linux(name) +# map = parse_map(name,pipe,opts.altgr) + map = parse_linux(name,opts.altgr) except EmptyMapError: print >>sys.stderr,"Map '%s' skipped: empty" % name except MapInputError,exc: @@ -107,11 +144,32 @@ if opts.format == "mapdump": sys.exit(0) -t.gen_tree() +l=() +if opts.filter: + l = opts.filter.split(",") +t.gen_tree(*l) if opts.format == "graphviz": gen_report(t,GraphReporter(out)) else: gen_report(t,FileReporter(out)) +if opts.test: + buf=codecs.getreader("utf-8")(open(opts.filename)) + err=0 + for i in range(0,3): + for k in t: + buf.seek(0,0) + print "Testing keymap %s" % (k.dump(),) + s = Script(buf,FakeQuery(k)) + name = s.run() + if name != k.name: + print "SCRIPT ERROR: %s != %s" % (name,k.name) + err += 1 + else: + print "... OK." + print + if err: + print >>sys.stderr,"There are problems!" + sys.exit(1) # done! --- keymapper-0.5.3.orig/README +++ keymapper-0.5.3/README @@ -162,7 +162,13 @@ This is a question of last resort; it's asked only if keymaps cannot be distinguished otherwise. -This command will be accompanied by one YES and one GOTO command. +This command will be accompanied by one YES and one NO command. + +FINDP char +++++++++++ + +Equivalent to FIND, except that the user is asked to consider only the +primary symbols (i.e. Plain and Shift). YES ## ++++++ --- keymapper-0.5.3.orig/test_gen_map.py +++ keymapper-0.5.3/test_gen_map.py @@ -22,6 +22,12 @@ from keymapper.fakequery import FakeQuery import sys +import codecs + +sys.stdout = codecs.getwriter("utf-8")(sys.stdout) + +import keymapper.tree +keymapper.tree.trace = 1 try: from cStringIO import StringIO @@ -32,13 +38,14 @@ t = Tree() for k in maps(): t.add(k) + print k.dump() keymaps.append(k) t.gen_tree() buf = StringIO() -gen_report(t,FileReporter(buf)) +gen_report(t,FileReporter(codecs.getwriter("utf-8")(buf))) -g = open("test.dot","w") +g = codecs.getwriter("latin1")(open("test.dot","w"),"replace") gen_report(t,GraphReporter(g)) # 'buf' now contains our script. @@ -50,8 +57,8 @@ for k in keymaps: buf.seek(0,0) print "Testing keymap %s" % (k.dump(),) - s = Script(buf,FakeQuery(k)) - name = s.run() + s = Script(codecs.getreader("utf-8")(buf)) + name = s.run(FakeQuery(k)) if name != k.name: print "SCRIPT ERROR: %s != %s" % (name,k.name) err += 1 --- keymapper-0.5.3.orig/x2console_keymap +++ keymapper-0.5.3/x2console_keymap @@ -0,0 +1,67 @@ +#!/usr/bin/python + +# Copyright (c) 2005 by Matthias Urlichs +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of Version 2 of the GNU General Public License as +# published by the Free Software Foundation. See the file COPYING.txt +# or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. + +"""\ +This script analyzes an X11 keymap and prints the equivalent console +keymap name, based on a decision tree. +""" + +from keymapper.parse.x11 import parse_file as parse_x11 +from keymapper.fakequery import FakeQuery +from keymapper.script import Script,DupMap,NoMap +from optparse import OptionParser, OptParseError +from sets import Set + +import sys +import codecs + +sys.stdout = codecs.getwriter("utf-8")(sys.stdout) + +import keymapper.tree +keymapper.tree.trace = 1 + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +parser = OptionParser(usage="%prog tree_file x11name...", version="%prog 0.1") +parser.remove_option("-h") +#parser.remove_option("--help") +parser.add_option("-?","--help", action="help", help="show this help text") +parser.add_option("-v","--verbose", action="count", dest="verbose", + help="be more verbose") +parser.add_option("-g","--graph", action="store_const", dest="format", + const="graphviz", help="generate a hopefully-nice-looking .dot file") +(opts, args) = parser.parse_args() + +script = Script(codecs.getreader("utf-8")(open(args[0])), verbose=opts.verbose) +rev = {} +def rev_add(b,a): + if a not in rev: + rev[a] = Set() + rev[a].add(b) + +for x11map in args[1:]: + km = parse_x11(x11map) + if km is None: continue + try: + consolemap = script.run(FakeQuery(km, verbose=opts.verbose)) + except DupMap,err: + for m in err.args[0]: + rev_add(km.name,m) + except NoMap: + print "# %s could not be mapped." % (km.name,) + else: + rev_add(km.name,consolemap) + +for a,b in rev.iteritems(): + print a," ".join(b) + + --- keymapper-0.5.3.orig/test_x11.py +++ keymapper-0.5.3/test_x11.py @@ -0,0 +1,74 @@ +#!/usr/bin/python + +# Copyright (c) 2005 by Matthias Urlichs +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of Version 2 of the GNU General Public License as +# published by the Free Software Foundation. See the file COPYING.txt +# or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. + +"""\ +This test script grabs a number of interesting key maps from +keymapper.fakemaps, generates a decision tree, saves that in an +in-memory file, and then runs each key map against the file's +interpreter to see if the correct map is returned. +""" + +from keymapper.parse.x11 import parse_file as parse_x11 +from keymapper.tree import Tree, gen_report +from keymapper.file import FileReporter +from keymapper.graph import GraphReporter +from keymapper.script import Script +from keymapper.fakequery import FakeQuery + +import sys +import codecs + +import keymapper.tree +keymapper.tree.trace = 1 + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +keymaps = [] +t = Tree() +for k in sys.argv[1:]: + k = parse_x11(k) + t.add(k) + print k.rdump() + keymaps.append(k) +t.gen_tree() + +buf = StringIO() +gen_report(t,FileReporter(codecs.getwriter("utf-8")(buf))) + +g = codecs.getwriter("latin1")(open("test.dot","w"),"replace") +gen_report(t,GraphReporter(g)) + +# 'buf' now contains our script. + +buf.seek(0,0) +print buf.read(), + +err = 0 +for k in keymaps: + buf.seek(0,0) + print "Testing keymap %s" % (k.rdump(),) + s = Script(codecs.getreader("utf-8")(buf)) + name = s.run(FakeQuery(k)) + if name != k.name: + print "SCRIPT ERROR: %s != %s" % (name,k.name) + err += 1 + else: + print "... OK." + print + +if err: + print "%d errors found!" % err + sys.exit(1) +else: + print "Everything works." + sys.exit(0) + --- keymapper-0.5.3.orig/keymapper/equiv.py +++ keymapper-0.5.3/keymapper/equiv.py @@ -0,0 +1,101 @@ + +# equiv.py +# find equivalent glyphs + +# Copyright (c) 2005 by Matthias Urlichs +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of Version 2 of the GNU General Public License as +# published by the Free Software Foundation. See the file COPYING.txt +# or (on Debian systems) /usr/share/common-licenses/GPL-2 for details. + +"""\ +This module exports a 'looks_like()' function. it accepts a Unicode +symbol and returns a list of symbols which look the same, in either +upper or lower case. + +It also exports a chartype() function which returns the first letter +of the Unicode category (e.g., 'C' for control characters, or 'Z' for +spacing). + +""" + +from os.path import exists +import codecs +from unicodedata import normalize,category + +equivfile = "/usr/share/misc/keysym.equiv"; +if exists("data/equivs") and exists("gen_keymap"): + equivfile = "data/equivs"; + +map = {} +cache = {} +syms = [] + +charhash={} +def chartype(c): + if c in charhash: + return charhash[c] + charhash[c] = h = category(c)[0] + return h + +def read_map(): + for l in codecs.getreader("utf-8")(open(equivfile,"r")): + r = [] + for c in l.strip(): + cc = normalize("NFC",c.lower()) + if cc not in r: r.append(cc) + cc = normalize("NFC",c.upper()) + if cc not in r: r.append(cc) + found=1 + while found: + found=0 + for c in r: + if c in map: + for cc in map[c]: + if cc not in r: + found=1 + r.append(cc) + r.sort() + r = tuple(r) + for c in r: + map[c] = r + cache[c] = len(syms) + syms.append(r) + +def looks_like(sym): + """Return a symbol number for something looking like sym""" + + if not map: + read_map() + + if sym in cache: + return cache[sym] + + s = normalize("NFC",sym.lower()) + if s in cache: + s = cache[s] + cache[sym] = s + return s + + if s in map: + res = map[s] + else: + res = [s] + for c in res: + if c in cache: + res = cache[c] + cache[sym] = res + return res + + syms.append(res) + res = len(syms)-1 + cache[sym] = res + if sym != s: + cache[s] = res + return res + +def get_sym(pos): + """Return the symbols at that position""" + return syms[pos] + --- keymapper-0.5.3.orig/keymapper/fakequery.py +++ keymapper-0.5.3/keymapper/fakequery.py @@ -14,31 +14,53 @@ """ from keymapper.query import Query +from keymapper.equiv import looks_like,get_sym from random import uniform class FakeQuery(Query): """A fake keyboard inquiry which actually looks at a keymap. Used for testing.""" - def __init__(self, map): + def __init__(self, map, verbose=1): Query.__init__(self) self.map = map + self.verbose = verbose def press(self,syms): - print "* Press one of '"+"' '".join(syms)+"' !" - syms = [ sym for sym in syms if sym in self.map.sym2code ] - print "I have '"+"' '".join(syms)+"'." - sym = syms[int(uniform(0,len(syms)))] - code = self.map.sym2code[sym] - code = code[int(uniform(0,len(code)))][0] - print "I choose %s => %d" % (sym,code) - return code - - def ask(self,sym): - print "* Do I see '"+sym+"' ?" - if sym in self.map.sym2code: - print "Yes" - else: + if self.verbose: + print "* Press one of '"+"' '".join(syms)+"' !" + like=[] + for s in syms: + s = looks_like(s) + for ss in get_sym(s): + if ss not in like and ss in self.map.seen: + like.append(ss) + if self.verbose: + print "I have '"+"' '".join(like)+"'." + codes = [] + for sym in like: + code = self.map.sym2code[looks_like(sym)] + for code in code: + code = code[0] + if self.verbose: + print "I can press %s => %d" % (sym,code) + if code not in codes: + codes.append(code) + return codes + + def ask(self,syms): + if self.verbose: + print "* Do I see '"+"' or '".join(syms)+"' ?" + for sym in syms: + if looks_like(unicode(sym)) in self.map.sym2code \ + and sym in self.map.seen: + if self.verbose: + print "Yes" + return True + if self.verbose: print "No" - return sym in self.map.sym2code + return False + def message(self,msg): + if self.verbose: + print msg --- keymapper-0.5.3.orig/keymapper/keymap.py +++ keymapper-0.5.3/keymapper/keymap.py @@ -14,7 +14,9 @@ keyboard mapping. """ -from sets import ImmutableSet +from sets import Set,ImmutableSet +from keymapper.equiv import looks_like,get_sym,chartype +from unicodedata import normalize # This code implements a bitmask and associated bit values. modlist=("shift","altgr","control","alt","shiftl","shiftr","controll","controlr","capsshift") @@ -50,7 +52,7 @@ pri=0 mods=self.mods - for mod,val in (("altgr",500),("alt",1000),("control",1500)): + for mod,val in (("altgr",800),("alt",1000),("control",1500)): if mod in self.mods: pri -= val mods = mods-ImmutableSet(mod) @@ -111,15 +113,26 @@ # """Trying to add a code+modifier entry to a keymap that's already known""" # pass +class SymSet(Set): + """Add and compare with NFC""" + def __contains__(self,sym): + return Set.__contains__(self,normalize("NFC",sym.lower())) + def add(self,sym): + return Set.add(self,normalize("NFC",sym.lower())) + class Keymap(object): """encapsulates a named symbol <=> keycode+modifiers mapping""" - def __init__(self,name): + def __init__(self,name, with_alt=True): self.name = name self.sym2code = {} # sym => (code,modifier) list self.sym2cod = {} # sym => code list -# self.code2sym = {} # <= + self.sym2cod_no_alt = {} # sym => code list + self.code2sym = {} # <= self.submap_cache = {} + self.seen = SymSet() # symbols actually seen + self.stdseen = SymSet() # symbols reachable without modifier keys + self.with_alt = with_alt def __str__(self): return "Map<%s>" % (self.name,) @@ -129,39 +142,86 @@ def add(self,sym,code,mod=STD): """add a single key mapping to this keymap""" - if sym == "": + if sym == "" or sym is None: return + if len(sym) == 1: + cat = chartype(sym) + if cat == "Z" or cat == "C" or cat == "U": + return # zero-width, control, unassigned + if not self.with_alt: + if mod != STD and mod != SHIFT: + return + self.seen.add(sym) + if mod == STD: + self.stdseen.add(sym) + sym = looks_like(sym) if sym in self.sym2cod: if code not in self.sym2cod[sym]: self.sym2cod[sym].append(code) else: self.sym2cod[sym] = [code] + if mod in (STD,SHIFT): + if sym in self.sym2cod_no_alt: + if code not in self.sym2cod_no_alt[sym]: + self.sym2cod_no_alt[sym].append(code) + else: + self.sym2cod_no_alt[sym] = [code] + + if mod == STD: + if code not in self.code2sym: + self.code2sym[code] = [] + self.code2sym[code].append(sym) + code = (code,mod) if sym in self.sym2code: if code not in self.sym2code[sym]: self.sym2code[sym].append(code) return -# if code in self.code2sym: -# raise CodeKnown(self.name,code) self.sym2code[sym] = [code] -# self.code2sym[code] = sym def symbols(self): """Return a list of known symbols""" return self.sym2code.iterkeys() + def symbols_no_alt(self): + """Return a list of known symbols on non-alt keys""" + #for k,(c,m) in self.sym2code.iteritems(): + for s in self.sym2code.iteritems(): + (k,l) = s + for c,m in l: + if m == STD or m == SHIFT: + yield k + break + def priority(self,sym): """Return how likely it is that this symbol is actually shown on the physical keyboard""" if not self.sym2code[sym]: pass - return reduce(max, [ k[1].pri for k in self.sym2code[sym] ]) - + # Disambiguate. The 500 is here to make the values non-negative. + return 500-sym + reduce(max, [ k[1].pri for k in self.sym2code[sym] ]) def dump(self): - """Show my mapping""" - return self.name+": "+",".join([ "%s:%s" % (self.vis(s), "+".join([str(x) for x in c])) for s,c in self.sym2cod.items()]) + """Show my mapping (sym => code)""" + return self.name+": "+",".join([ "%s:%s" % ("".join([self.vis(sy) for sy in get_sym(s) if sy in self.seen]), "+".join([str(x) for x in c])) for s,c in self.sym2cod.items()]) + + def rdump1(self,syms): + """Helper for rdump""" + seen={} + res=[] + for sym in syms: + if sym in seen: continue + seen[sym]=1 + for s in get_sym(sym): + if s not in self.stdseen: continue + res.append(self.vis(s)) + return res + + + def rdump(self): + """Show my reverse mapping (code => sym)""" + return self.name+": "+" ".join([ "%s:%s" % (c,",".join(self.rdump1(s))) for c,s in self.code2sym.items()]) def vis(self,s): if len(s) == 1 and ord(s) < 128: @@ -171,6 +231,8 @@ def is_submap(self,m): """Check if self is a submap of m.""" + if self is m: + return False try: return self.submap_cache[m] except KeyError: --- keymapper-0.5.3.orig/keymapper/tree.py +++ keymapper-0.5.3/keymapper/tree.py @@ -35,12 +35,28 @@ """ from sets import Set,ImmutableSet +from keymapper.equiv import get_sym,chartype +from keymapper.keymap import SymSet +from unicodedata import category # follow what's happening? trace=False last_trace=0 from time import time +interactive=False + +charhash={} +def chartype(c): + if c in charhash: + return charhash[c] + charhash[c] = h = category(c)[0] + return h + +class NoShownSyms(Exception): + """A step doesn't actually display anything""" + pass + class DupKeycode(Exception): """A key code has been added to a Choice node twice""" pass @@ -73,6 +89,9 @@ def ask(self,sym,no,yes): """Ask whether that symbol is visible""" raise NotImplementedError + def ask_no_alt(self,sym,no,yes): + """Ask whether that symbol is visible on primary keys""" + raise NotImplementedError def finish(self): """Conclude this step""" pass @@ -86,8 +105,9 @@ class Node(object): """a generic node in the keymap decision tree""" - def __init__(self): + def __init__(self,maps): self.delay = 0 + self.maps = maps def __eq__(self,other): """Compare this node to another""" @@ -102,6 +122,7 @@ def simplify(self,cache): """Check whether this node is redundant""" self = self._simplify(cache) + if self is None: return None key = self.key() if key in cache: return cache[key] cache[key] = self @@ -143,7 +164,8 @@ self.step = nr nr += 1 for c in self: # iterates the children - nr = c.seq1(nr) + if c is not None: + nr = c.seq1(nr) self.maxstep = nr return nr @@ -158,15 +180,35 @@ return yield self for c in self: # iterates over child nodes - for n in c.seq2(): - yield n + if c is not None: + for n in c.seq2(): + yield n + + def visible_syms(self, keys): + """List symbols which actually correspond to keycodes""" + num=0 + for sym,codes in keys: + seen = SymSet() + for s in get_sym(sym): + for m in self.maps: + if s not in m.seen: continue + if s in seen: continue + seen.add(s) + break + for s in seen: + num += 1 + yield s,codes + if not num: + raise NoShownSyms + + class Choice(Node): """a node in the keymap decision tree which asks for one of a number of symbols and selects by the keycode that's returned""" - def __init__(self, sym2codes, code2map): - Node.__init__(self) + def __init__(self, maps, sym2codes, code2map): + Node.__init__(self, maps) self.sym2codes = sym2codes # list of symbols to display => key codes self.children = code2map # key code => node or keymap @@ -195,7 +237,7 @@ def key(self): syms = [ sym for sym in self.sym2codes ] syms.sort() - ret = "Q:"+":".join(self.sym2codes.keys())+":" + ret = "Q:"+":".join(["".join(get_sym(s)) for s in self.sym2codes.keys()])+":" codes = self.children.keys() codes.sort() for code in codes: @@ -221,9 +263,23 @@ return self return uniq + def filter(self,maps): + """Drop branches not in map list""" + for code,node in self.children.items(): + if node: + node = node.filter(maps) + if not node: + del self.children[code] + + # Throw this node away if it doesn't decide anything any more + if not self.children: + return None + return self + def report(self,gen): gen.step(self.step) - gen.symbols(self.sym2codes) + + gen.symbols(self.visible_syms(self.sym2codes.iteritems())) for code,node in self.children.items(): gen.choice(code,node) gen.finish() @@ -231,8 +287,8 @@ class Ask(Node): """a node in the keymap decision tree which asks whether a given keyboard symbol exists""" - def __init__(self, sym,no,yes): - Node.__init__(self) + def __init__(self, maps, sym,no,yes): + Node.__init__(self,maps) self.sym = sym self.no = no self.yes = yes @@ -265,16 +321,32 @@ if self.no: return self.no return self.yes + def filter(self,maps): + if self.yes: + self.yes = self.yes.filter(maps) + if self.no: + self.no = self.no.filter(maps) + if not self.yes and not self.no: return None + return self + + def report(self,gen): + gen.step(self.step) + gen.ask([s for s,c in self.visible_syms([(self.sym,None)])], self.no, self.yes) + gen.finish() + +class AskNoAlt(Ask): + """same as Ask, not without Alt* keys""" def report(self,gen): gen.step(self.step) - gen.ask(self.sym, self.no, self.yes) + gen.ask_no_alt([s for s,c in self.visible_syms([(self.sym,None)])], self.no, self.yes) gen.finish() class Found(Node): """A node which resolves to a single keymap""" def __init__(self, node): - Node.__init__(self) + Node.__init__(self,[node]) self.node = node + self.maps = [node] def __iter__(self): return ().__iter__() @@ -290,6 +362,11 @@ if self.node is None: return None return self + def filter(self,maps): + print "%s %s" % (self.node,maps) + if self.node.name not in maps: return None + return self + def report(self,gen): gen.step(self.step) gen.keymap(self.node) @@ -306,6 +383,9 @@ class SingleMapping(Exception): pass +class SingleMappingNoAlt(Exception): + pass + # The main code starts here. @@ -316,23 +396,32 @@ self.maps=Set() # list of keyboards self.symbols={} # symbol => [nummaps,sumpriority] self._id = 0 + self.interactively_skipped = Set() def add(self,map): """add a keymap to the list""" self.maps.add(map) - def gen_tree(self): + def __iter__(self): + return iter(self.maps) + + def gen_tree(self, *filter): """generate a decision tree""" cache={} self.tree = self._gen_tree(self.maps) self.tree = self.tree.simplify(cache) + if self.tree and filter: + self.tree.filter(filter) def report(self,gen): """Emit the generated nodes by passing them to a generator.""" self.tree.seq1(0) for n in self.tree.seq2(): n.report(gen) + if interactive and self.interactively_skipped: + print >>sys.stderr, "Skipped these keymaps interactively:", + print >>sys.stderr, ' '.join(self.interactively_skipped) def _gen_tree(self, maps, xsyms=None): """One step of the selection algorithm.""" @@ -354,11 +443,14 @@ syms = ImmutableSet() # selected symbols codes = {} # keycode => number of selected keymaps for alt in range(2): # Try to get one alternate mapping + steps=0 # for reporting + bt_steps=0 # for limiting backtracks + bt_level=None if trace>1: if alt: - print "*** Alternate:",syms + print "*** Alternate:"," ".join(["".join(get_sym(s)) for s in syms]).encode("utf-8") else: - print "*** Start:",_id,len(maps),"maps:",",".join([m.name for m in maps]) + print "*** Start:",_id,len(maps),"maps:",",".join([m.name for m in maps]).encode("utf-8") try: open_map = ImmutableSet(maps) track = [] @@ -369,12 +461,17 @@ chooser=None while open_map: + # Check if we overdid it + steps += 1 + if alt and steps>1000: + break + if not chooser: global last_trace if trace>2 or trace and time()-last_trace > 3 and len(open_map)>2: - print "choose from",",".join([m.name for m in open_map]) + print "Step %d %d: choose from %s" % (steps, len(track), ",".join([m.name for m in open_map])) last_trace=time() - chooser = choose_sym(open_map, syms.union(xsyms), xcode=codes, all_maps=maps, alt=alt) + chooser = choose_sym(open_map, syms.union(xsyms), xcode=codes, all_maps=maps, alt=alt, depth=len(track)) while True: # Loop invariant: @@ -392,9 +489,27 @@ # This chooser is unable to return a # suitable choice, so backtrack. if trace>1: print "exhausted",",".join([m.name for m in open_map]) - if not track: raise AlgorithmProblem(syms,maps,open_map) + + # Check if we need to backtrack more aggressively. + # Otherwise we run for *ages*. + bt_steps += 1 + if bt_steps > 100000: + bt_steps=0 + if bt_level is None or bt_level > len(track): + bt_level = len(track) + if trace>1: print "Backtrack stepup",bt_level + else: + track = track[0:bt_level] + # Drop off if we stepped way back + # one and two levels + if bt_level <= 1: + bt_level = None + else: + bt_level = bt_level-1 + if trace>1: print "Backtrack stepdown",bt_level + chooser,syms,codes,open_map = track.pop() if trace>1: print "... back to",",".join([m.name for m in open_map]) @@ -402,7 +517,7 @@ raise AlgorithmProblem(syms,maps,open_map) else: - if trace>2: print "got",sym.encode("utf-8"), + if trace>2: print "got",str(sym).encode("utf-8"), # We have a possible candidate. try: # Get the list of keymaps chosen by it @@ -417,13 +532,23 @@ if trace>2: print "no mapping" continue - except SingleMapping,exc: + except (SingleMapping,SingleMappingNoAlt),exc: # This is a possible yes/no question. # If that's the best we can do, OK. map_yes,map_no = exc.args - if trace>2: print "single mapping: yes",len(map_yes),"no",len(map_no) + if trace>2: + if exc == SingleMapping: + print "single mapping:", + else: + print "single mapping no alt:", + print "yes",len(map_yes),"no",len(map_no),"open",len(open_map),"track",len(track) if not track: - return Ask(sym, + if exc == SingleMapping: + return Ask(maps, sym, + yes=self._gen_tree(map_yes), + no=self._gen_tree(map_no)) + else: + return AskNoAlt(maps, sym, yes=self._gen_tree(map_yes), no=self._gen_tree(map_no)) @@ -477,6 +602,24 @@ if trace: for m in open_map: print >>sys.stderr, m.dump().encode("utf-8") + if interactive: + print >>sys.stderr, "Enter a preferred keymap (or nothing to quit):" + while True: + line = sys.stdin.readline().strip() + if line: + for m in open_map: + if m.name == line: + for other in open_map: + if other.name != line: + self.interactively_skipped.add(other.name) + return Found(m) + else: + print >>sys.stderr, "%s not found." % line + else: + print >>sys.stderr, "OK, giving up." + print >>sys.stderr, "Skipped these keymaps interactively:", + print >>sys.stderr, ' '.join(self.interactively_skipped) + break sys.exit(1) # Now build a Choice node from what we have found. @@ -500,39 +643,59 @@ for code,map in codes.items(): print code,map print "*** end ***",_id,len(maps),"***", \ - " ".join(["%s:%s" % (s,",".join([str(cc) for cc in c])) for s,c in sym2codes.items()]).encode("utf-8") + " ".join(["%s:%s" % (s,",".join(["".join(get_sym(cc)) for cc in c])) for s,c in sym2codes.items()]).encode("utf-8") print for code,map in codes.items(): codes[code] = self._gen_tree(map) - ch = Choice(sym2codes, codes) + ch = Choice(maps, sym2codes, codes) return ch -def choose_sym(maps, xsym=(), xcode=(), all_maps=(), alt=0): +def choose_sym(maps, xsym=(), xcode=(), all_maps=(), alt=0, depth=None): """Find the 'best' symbol in a set of keymaps""" symdata={} # symbol => [ preference, number of keymaps with that symbol, # mapping keycode => number of keyboards with that mapping + symdata_no_alt={} # same, but without "alt" keys + + supermaps = Set() + do_log=0 + if depth is not None: + if depth >= 2: + depth = None # 10*depth + elif depth == 1: + do_log=2 + depth = 30 + else: # 0 + do_log=1 + depth = 10 # If any of these maps is a subset of one of all_maps, drop out. # Reason: We can't put up a "do you have this key" question now. for m in maps: for am in all_maps: - if am not in maps and m.is_submap(am): - return + if m.is_submap(am): + if am not in maps: + return + supermaps.add(am) + + # Otherwise, filter supermaps + if len(maps)-len(supermaps) <= 1: + supermaps = () for map in maps: + if map in supermaps: continue for sym in map.symbols(): if sym in xsym: continue if sym not in symdata: symdata[sym] = [ 0, 0, {} ] data = symdata[sym] + pri = 0 # Heuristic: We try to block keys on ALT mappings, which # have values smaller than zero, by never raising the value # if it ever goes below zero - pri = map.priority(sym) # if data[0] >= 0: # if pri is None: # pass @@ -543,27 +706,39 @@ # if pri < 0: # data[0] += pri - if ord(sym) > 0x40 and ord(sym) <= 0x5a: - if alt: - pri += 300 - else: - pri += 5000 - elif ord(sym) > 0x60 and ord(sym) <= 0x7a: - if alt: - pri += 300 - else: - pri += 5000 - elif ord(sym) > 128: - pri += 800 - elif ord(sym) < 32 or ord(sym) == 127: - pri += -300 - else: - if alt: - pri += 600 + for s in get_sym(sym): + + if len(s) != 1: + pri += 100 + elif ord(s) > 0x40 and ord(s) <= 0x5a: + if alt: + pri += 300 + else: + pri += 2000 + elif ord(s) > 0x60 and ord(s) <= 0x7a: + if alt: + pri += 300 + else: + pri += 2000 + elif ord(s) <= 32 or ord(s) == 127: + pri += -100000 # ... likewise ... else: - pri += 1000 + cat = chartype(s)[0] + if cat == "L": + if alt: + pri += 600 + else: + pri += 1500 + elif cat == "Z" or cat == "C" or cat == "U": + pri -= 100000 # shouldn't happen, but ... + elif cat == "M": + pri -= 10000 # non-spacing modifiers + elif cat == "S": + pri += 100 # includes spacing modifiers + else: + pri += 200 # whatever's left - data[0] += pri + data[0] += pri/len(get_sym(sym)) + map.priority(sym) for code in map.sym2cod[sym]: # This check must not be done here. @@ -579,8 +754,72 @@ data[1] += 1 data[2][code] += 1 + # Duplicate of the same, for the non-alt case + for sym in map.symbols_no_alt(): + if sym in xsym: continue + if sym not in symdata_no_alt: + symdata_no_alt[sym] = [ 0, 0, {} ] + data_no_alt = symdata_no_alt[sym] + pri = 0 + + # Heuristic: We try to block keys on ALT mappings, which + # have values smaller than zero, by never raising the value + # if it ever goes below zero +# if data_no_alt[0] >= 0: +# if pri is None: +# pass +# data_no_alt[0] += pri +# if pri >= 0 and data_no_alt[0] < 0: +# data_no_alt[0] = 0 +# else: +# if pri < 0: +# data_no_alt[0] += pri + + for s in get_sym(sym): + + if len(s) != 1: + pri += 100 + elif ord(s) > 0x40 and ord(s) <= 0x5a: + if alt: + pri += 300 + else: + pri += 2000 + elif ord(s) > 0x60 and ord(s) <= 0x7a: + if alt: + pri += 300 + else: + pri += 2000 + elif ord(s) <= 32 or ord(s) == 127: + pri += -100000 # ... likewise ... + else: + cat = chartype(s)[0] + if cat == "L": + if alt: + pri += 600 + else: + pri += 1500 + elif cat == "Z" or cat == "C" or cat == "U": + pri -= 100000 # shouldn't happen, but ... + elif cat == "M": + pri -= 10000 # non-spacing modifiers + elif cat == "S": + pri += 100 # includes spacing modifiers + else: + pri += 200 # whatever's left + + data_no_alt[0] += pri/len(get_sym(sym)) + map.priority(sym) + + for code in map.sym2cod_no_alt[sym]: + if code not in data_no_alt[2]: + data_no_alt[2][code] = 0 + + data_no_alt[1] += 1 + data_no_alt[2][code] += 1 + syms=[] + syms_no_alt=[] xxsyms=Set() + for sym,(pri,sum,codes) in symdata.iteritems(): if not codes.values(): continue @@ -596,26 +835,68 @@ maxcodes = reduce(max,[ num for num in codes.values() ]) nfull=0 for map in all_maps: - if sym in map.sym2code: + if sym in map.sym2cod: nfull += 1 - # more heuristics: - # Prefer symbols that appear in all maps. + # Count the number of symbols which actually appear + nsym=0 + for c in get_sym(sym): + for m in all_maps: + if c in m.seen: + nsym += 1 + break + # adjust for capital letters + if nsym == 2: + nsym = 1 + + # heuristics: + # Prefer symbols that appear in all maps (slightly). # Prefer symbols that don't appear in maps we already selected. # Prefer symbols that appear in many keyboards. # Prefer symbols which result in many small subtrees, # i.e. the number of maps having that symbol on the same # keycode is small. - #pri -= 100*(len(maps)-sum) + # Prefer non-ambiguous symbols. + pri -= 50*(len(maps)-sum) pri -= 500*(nfull-sum) pri += 100*len(codes) - pri -= 500*maxcodes + pri -= 1000*maxcodes + pri -= 500*nsym syms.append((-pri,sym)) - if len(maps) > 1 and not syms: - raise AlgorithmProblem + # Duplicate of the same, for the non-alt case + for sym,(pri,sum,codes) in symdata_no_alt.iteritems(): + if not codes.values(): + continue + for c in codes: + if c in xcode: + xxsyms.add(sym) + break + + maxcodes = reduce(max,[ num for num in codes.values() ]) + nfull=0 + for map in all_maps: + if sym in map.sym2cod_no_alt: + nfull += 1 + + nsym=0 + for c in get_sym(sym): + for m in all_maps: + if c in m.seen: + nsym += 1 + break + if nsym == 2: + nsym = 1 + + pri -= 50*(len(maps)-sum) + pri -= 500*(nfull-sum) + pri += 100*len(codes) + pri -= 1000*maxcodes + pri -= 500*nsym + syms_no_alt.append((-pri,sym)) syms.sort() + syms_no_alt.sort() # print # print syms # for m in maps: @@ -623,23 +904,49 @@ # print # First, generate normal "press a key" choices. + nret=0 for pri,sym in syms: if sym not in xxsyms: - if trace>2: print "check",sym.encode("utf-8"), - yield sym,False + if trace>2: print "check",str(sym).encode("utf-8"), + if do_log and trace>1: + print "Return1",do_log,"".join(get_sym(sym)).encode("utf-8") + yield sym,None + if depth: + nret += 1 + if nret > depth: + break # If that didn't work, use excluded keycodes if not alt: + nret=0 for pri,sym in syms: if sym in xxsyms: - if trace>2: print "check",sym.encode("utf-8"), - yield sym,False + if trace>2: print "check",str(sym).encode("utf-8"), + if do_log and trace>1: + print "Return2",do_log,"".join(get_sym(sym)).encode("utf-8") + yield sym,None + if depth: + nret += 1 + if nret > depth: + break + + # If that didn't work, generate yes/no questions for non-ALT keys. + for pri,sym in syms_no_alt: + if symdata_no_alt[sym][1] < len(maps)-len(supermaps): + # ... but only if there are keyboards for which the answer is 'no'. + if do_log and trace>1: + print "Return3",do_log,"".join(get_sym(sym)).encode("utf-8") + yield sym,SingleMappingNoAlt # If that didn't work, generate yes/no questions. for pri,sym in syms: - if symdata[sym][1] < len(maps): + if symdata[sym][1] < len(maps)-len(supermaps): # ... but only if there are keyboards for which the answer is 'no'. - yield sym,True + if do_log and trace>1: + print "Return4",do_log,"".join(get_sym(sym)).encode("utf-8") + yield sym,SingleMapping + + if do_log and trace>1: print "ReturnEnd",do_log def drop_sym(maps, xsym): """Find those symbol in a set of keymaps""" @@ -649,12 +956,16 @@ """Returns a list keycode => maps with the symbol on that key""" codes = Set() xmaps = Set() + xmaps_no_alt = Set() altmaps = Set() for map in maps: - if not sym in map.sym2code: + if not sym in map.sym2cod: xmaps.add(map) + xmaps_no_alt.add(map) continue + if not sym in map.sym2cod_no_alt: + xmaps_no_alt.add(map) for code,pri in map.sym2code[sym]: codes.add(code) if pri < 0: @@ -662,12 +973,22 @@ # If there's less than two choices, return via an exception. if len(codes) == 0: + if trace>3: print "unknown,", raise NoMapping(sym) - if len(codes) == 1: - if not xmaps: + if choose or len(codes) == 1: + if not xmaps or (choose == SingleMappingNoAlt and not xmaps_no_alt): + if trace>3: + if len(codes) == 1: + print "same,", + else: + print "choice,", raise NoMapping(sym) if choose: - raise SingleMapping(maps-xmaps, xmaps) + if trace>3: print "single,", + if choose == SingleMappingNoAlt: + raise choose(maps-xmaps_no_alt, xmaps_no_alt) + else: + raise choose(maps-xmaps, xmaps) # If the symbol occurs with normal AND AltGr mappings, # ignore the AltGr stuff -- the symbol may not actually be --- keymapper-0.5.3.orig/keymapper/file.py +++ keymapper-0.5.3/keymapper/file.py @@ -14,8 +14,29 @@ """ from keymapper.tree import Reporter +from keymapper.equiv import get_sym +from unicodedata import normalize import sys +def nsym(s): + if len(s) != 1: + return s + elif ord(s) == 127: + return "" + elif ord(s) == 32: + return "" + elif ord(s) == 10: + return "" + elif ord(s) == 13: + return "" + elif ord(s) == 8: + return "" + elif ord(s) == 9: + return "" + else: + return s + + class FileReporter(Reporter): """Report the result as a list of steps to a file""" def __init__(self,file=sys.stdout): @@ -31,8 +52,8 @@ def symbols(self,symbols): """Start a choice: display these symbols""" - for sym in symbols: - print >>self.file,"PRESS %s" % sym + for sym,c in symbols: + print >>self.file,"PRESS %s" % nsym(normalize("NFC",sym)) def choice(self,code,nextstep): """Choice: This keycode leads to that step""" @@ -40,11 +61,22 @@ def ask(self,sym,no,yes): """Ask whether that symbol is visible""" - print >>self.file,"FIND %s" % sym - print >>self.file,"YES %s" % yes.step - print >>self.file,"NO %s" % no.step + print >>self.file,"FIND %s" % " ".join([nsym(normalize("NFC",s)) for s in sym]) + if yes: + print >>self.file,"YES %s" % yes.step + if no: + print >>self.file,"NO %s" % no.step + + def ask_no_alt(self,sym,no,yes): + """Ask whether that symbol is visible on primary keys""" + print >>self.file,"FINDP %s" % " ".join([nsym(normalize("NFC",s)) for s in sym]) + if yes: + print >>self.file,"YES %s" % yes.step + if no: + print >>self.file,"NO %s" % no.step def finish(self): """Conclude this step""" pass + --- keymapper-0.5.3.orig/keymapper/fakemaps.py +++ keymapper-0.5.3/keymapper/fakemaps.py @@ -1,4 +1,4 @@ - +# -*- coding: utf-8 -*- # fakemaps.py # invent fake keyboard maps for testing @@ -28,7 +28,7 @@ """synthesize a Keymap""" map=Keymap(name) for sym,code,mod in keys: - map.add(sym,code,mod) + map.add(unicode(sym),code,mod) return map def maps(): @@ -42,7 +42,7 @@ # Remove a key yield gen_map("removed", - ("A",1,STD),("B",2,STD),("C",3,STD),("D",4,STD)) + (u"α",1,STD),("B",2,STD),("C",3,STD),("D",4,STD)) # Duplicate a key yield gen_map("duped", @@ -62,7 +62,7 @@ # Totally different keys yield gen_map("diff_keys", - ("a",1,STD),("b",2,STD),("c",3,STD),("d",4,STD),("e",5,STD)) + ("aa",1,STD),("bb",2,STD),("cc",3,STD),("dd",4,STD),("ee",5,STD)) # Totally different codes yield gen_map("diff_codes", --- keymapper-0.5.3.orig/keymapper/graph.py +++ keymapper-0.5.3/keymapper/graph.py @@ -16,15 +16,26 @@ from keymapper.tree import Reporter import sys import unicodedata +from keymapper.equiv import get_sym, looks_like +from random import uniform + +colors = ("red","green","blue","magenta","black","grey","yellowgreen","purple","plum") +styles = ("solid","dotted","dashed") def uname(sym): try: + sym=unicodedata.normalize("NFC",sym) return unicodedata.name(unicode(sym)).lower() except ValueError: return "U+%4x" % ord(sym) + except TypeError: + return sym + +#def uname(sym): +# return ", ".join([_uname(s) for s in sym]) def symnums(syms): - return ".".join([str(ord(s)) for s in syms]) + return ".".join([str(looks_like(s)) for s in syms]) class GraphReporter(Reporter): """Report the result as a graphviz .dot file""" @@ -43,32 +54,54 @@ def keymap(self,map): """This steps selects a unique keymap""" - print >>self.file, '"Step %d" [label="Map: %s"]' % (self.nr,map.name) + print >>self.file, '"Step %d" [label="Map: %s", shape="box"]' % (self.nr,map.name) def symbols(self,symbols): """Start a choice: display these symbols""" - self.syms = symbols + self.syms = [ (s,c) for s,c in symbols ] + self.color=colors[int(uniform(0,len(colors)))] + self.style=styles[int(uniform(0,len(styles)))] + # copy, for we need it more than once def choice(self,code,nextstep): """Choice: This keycode leads to that step""" syms=[] - for s,c in self.syms.items(): + for s,c in self.syms: if code in c: syms.append(s) - print >>self.file, '"Step %d" -> "S_%d_%s_%d"' % (self.nr,self.nr, symnums(syms), code) - print >>self.file, '"S_%d_%s_%d" -> "Step %d"' % (self.nr,symnums(syms), code, nextstep.step) - print >>self.file, '"S_%d_%s_%d" [ label="%s -> %d" ]' % (self.nr, symnums(syms), code, "\\n".join([uname(s) for s in syms]), code) + print >>self.file, '"Step %d" [ color="%s", shape="box" ] ' % (self.nr, self.color) + print >>self.file, '"Step %d" -> "S_%d_%s_%d" [ color="%s", style="%s", weight=2 ] ' % (self.nr,self.nr, symnums(syms), code, self.color,self.style) + print >>self.file, '"S_%d_%s_%d" -> "Step %d" [ color="%s", style="%s" ] ' % (self.nr,symnums(syms), code, nextstep.step, self.color,self.style) + print >>self.file, '"S_%d_%s_%d" [ label="%s -> %d", color="%s" ]' % (self.nr, symnums(syms), code, "\\n".join([uname(s) for s in syms]), code, self.color) def ask(self,sym,no,yes): """Ask whether that symbol is visible""" - print >>self.file, '"Step %d" [ label="Step %d\\nCheck for %s" ]' % (self.nr,self.nr,uname(sym)) - print >>self.file, '"Step %d" -> "AY-%d" -> "Step %d"' % (self.nr,self.nr,yes.step) - print >>self.file, '"AY-%d" [ label="Yes" ]' % (self.nr,) - print >>self.file, '"Step %d" -> "AN-%d" -> "Step %d"' % (self.nr,self.nr,no.step) - print >>self.file, '"AN-%d" [ label="No" ]' % (self.nr,) + self.color=colors[int(uniform(0,len(colors)))] + self.style=styles[int(uniform(0,len(styles)))] + + print >>self.file, '"Step %d" [ shape="box", label="Step %d\\nCheck for %s", color="%s" ]' % (self.nr,self.nr,"\\nor ".join([uname(s) for s in sym]), self.color) + if yes: + print >>self.file, '"Step %d" -> "AY-%d" -> "Step %d" [ color="%s", style="%s", weight=2 ]' % (self.nr,self.nr,yes.step, self.color,self.style) + print >>self.file, '"AY-%d" [ label="Yes", color="%s" ]' % (self.nr,self.color) + if no: + print >>self.file, '"Step %d" -> "AN-%d" -> "Step %d" [ color="%s", style="%s", weight=2 ]' % (self.nr,self.nr,no.step, self.color,self.style) + print >>self.file, '"AN-%d" [ label="No", color="%s" ]' % (self.nr,self.color) + + def ask_no_alt(self,sym,no,yes): + """Ask whether that symbol is visible on primary keys""" + self.color=colors[int(uniform(0,len(colors)))] + self.style=styles[int(uniform(0,len(styles)))] + + print >>self.file, '"Step %d" [ shape="box", label="Step %d\\nCheck for %s\\n(no Alt*)", color="%s" ]' % (self.nr,self.nr,"\\nor ".join([uname(s) for s in sym]), self.color) + if yes: + print >>self.file, '"Step %d" -> "AY-%d" -> "Step %d" [ color="%s", style="%s", weight=2 ]' % (self.nr,self.nr,yes.step, self.color,self.style) + print >>self.file, '"AY-%d" [ label="Yes", color="%s" ]' % (self.nr,self.color) + if no: + print >>self.file, '"Step %d" -> "AN-%d" -> "Step %d" [ color="%s", style="%s", weight=2 ]' % (self.nr,self.nr,no.step, self.color,self.style) + print >>self.file, '"AN-%d" [ label="No", color="%s" ]' % (self.nr,self.color) def finish(self): """Conclude this step""" --- keymapper-0.5.3.orig/keymapper/script.py +++ keymapper-0.5.3/keymapper/script.py @@ -17,46 +17,81 @@ exception will be raised. """ +from sets import Set + +def osym(s): + if s == "": + return u"\x7F" + elif s == "": + return u" " + elif s == "": + return u"\x0A" + elif s == "": + return u"\x0D" + elif s == "": + return u"\x08" + elif s == "": + return u"\x09" + else: + return s -class FoundMap(Exception): - """Pseudo-exception, raised when the script terminates with a unique keyboard map""" - pass class UnknownLine(Exception): """The script file contains a line that's not parseable""" pass class BadFile(Exception): """The script file isn't well-formed""" pass +class NoMap(Exception): + """No result!""" + pass +class DupMap(Exception): + """Inconclusive result!""" + pass class Script(object): """Run this script with that query. Return the result.""" - def __init__(self,file,query): + def __init__(self,file, verbose=1): self.file = file self.in_step = -1 - self.query = query + self.verbose = verbose - def get_step(self,nr): + def get_step(self,nrs): """Return the data for step NR.""" + reported=False + if self.verbose > 1: + print "want",nrs,", have",self.in_step for f in self.file: f = f.strip() if f == "" or f.startswith("#"): continue if f.startswith("STEP"): + if self.verbose > 1: + print f f = f[4:] f = int(f.strip()) - if self.in_step == nr: # done + if self.in_step in nrs: + nrs.remove(self.in_step) # done with this one self.in_step = f return self.in_step = f - elif self.in_step == nr: + elif self.in_step in nrs: + if self.verbose: + if not reported: + print "Step",self.in_step + reported=True + if self.verbose > 1: + print "have",f yield f + elif self.verbose > 1: + print "skip",f # ran off the end of the file? - if nr != self.in_step: - raise BadFile + if self.in_step not in nrs: + raise BadFile,nrs + nrs.remove(self.in_step) # done, at EOF - def run_step(self,step): + def run_step(self,query,step,res): """Run a singe step. Returns the next step's number, or raise an exception.""" what = None @@ -67,47 +102,63 @@ for line in self.get_step(step): if line.startswith("PRESS") and what in (None,"press"): what="press" - syms.append(line[5:].strip()) + syms.append(osym(line[5:].strip())) elif line.startswith("CODE") and what in (None,"press"): what="press" - code,goal = line[4:].strip().split() + try: + code,goal = line[4:].strip().split() + except ValueError: + print "BAD LINE <"+line.strip()+">" + continue keys[int(code)] = int(goal) elif line.startswith("MAP") and what in (None,): - raise FoundMap(line[3:].strip()) + res.add(line[3:].strip()) elif line.startswith("FIND") and what in (None,): what="find1" - find = line[4:].strip() + find = line[4:].strip().split() elif line.startswith("YES") and what in ("find1",): what="find2" - dest_yes = int(line[3:].strip()) + dest_yes = int(line[4:].strip()) elif line.startswith("NO") and what in ("find2",): what="find3" - dest_no = int(line[4:].strip()) + dest_no = int(line[3:].strip()) else: raise UnknownLine(line.strip()) # Second, decide what to do if what == "press" and syms and keys: - while True: - code = self.query.press(syms) + codes = query.press(syms) + for code in codes: if code in keys: - return keys[code] - self.query.message("Unexpected key code: <%d>" % code) + step.add(keys[code]) + if self.verbose: + print "Goto step step",keys[code] + else: + query.message("Unexpected key code: <%d>" % code) elif what == "find3": - if self.query.ask(find): - return dest_yes + if query.ask([osym(f) for f in find]): + step.add(dest_yes) + if self.verbose: + print "Goto step step",dest_yes else: - return dest_no - - else: - raise BadFile + step.add(dest_no) + if self.verbose: + print "Goto step step",dest_no - def run(self): + def run(self,query): """Run this script, starting with step 0.""" - step=0 - while True: - try: - step = self.run_step(step) - except FoundMap,exc: - return exc.args[0] - + self.file.seek(0,1) ## Python 2.4 regression workaround: + self.file.read() ## flush codec's input buffers + self.file.seek(0,0) + self.in_step = -1 + step=Set((0,)) + maps = Set() + while step: + self.run_step(query,step,maps) + if not maps: + raise NoMap + if len(maps) != 1: + raise DupMap(list(maps)) + return list(maps)[0] + + --- keymapper-0.5.3.orig/keymapper/parse/Makefile +++ keymapper-0.5.3/keymapper/parse/Makefile @@ -1,8 +1,12 @@ # Makefile for keymapper stuff # -all: ${addsuffix .py, ${basename ${wildcard *.g}, .g}} +GENPY := ${addsuffix .py, ${basename ${wildcard *.g}, .g}} + +all: $(GENPY) %.py: %.g yapps $< +clean: + rm -f $(GENPY) --- keymapper-0.5.3.orig/keymapper/parse/linux.g +++ keymapper-0.5.3/keymapper/parse/linux.g @@ -3,22 +3,16 @@ """ from keymapper.parse.linuxsyms import lookup_symbol,SymbolNotFound -from os.path import exists,join +from os.path import exists,join,curdir from gzip import GzipFile from keymapper.keymap import Keymap,Modifier import os dirs = [ -# ".", - "/usr/share/keymaps/i386/azerty", - "/usr/share/keymaps/i386/dvorak", - "/usr/share/keymaps/i386/fgGIod", - "/usr/share/keymaps/i386/qwerty", - "/usr/share/keymaps/i386/qwertz", - - "/usr/share/keymaps/i386/include", - "/usr/share/keymaps/include" ] +def add_dir(d): + """Helper to add a directory to the search path""" + dirs.append(d) class NoFileFound(Exception): pass @@ -29,6 +23,9 @@ def get_file(name): """Find a keymap file""" + global dirs + if not dirs: + dirs=(curdir,) for end in ("",".kmap",".kmap.gz",".inc",".inc.gz", ".gz"): for dir in dirs: n = os.path.join(dir,name+end) @@ -73,9 +70,9 @@ self.add(rvalue, code, keys) -def parse_file(name): +def parse_file(name, with_alt=True): f = get_file(name) - keymap = ConsoleKeymap(name) + keymap = ConsoleKeymap(name, with_alt=with_alt) parser = linuxmap(linuxmapScanner("",file=f,filename=name)) try: --- keymapper-0.5.3.orig/keymapper/parse/maps.py +++ keymapper-0.5.3/keymapper/parse/maps.py @@ -36,9 +36,9 @@ names={"plain":STD, "shift":SHIFT, "altgr":ALT, "shift_altgr":ALTSHIFT, "shift_alt":ALTSHIFT,"altgr_alt":ALT,"alt":ALT,"shift_altgr_alt":ALTSHIFT} -def parse_map(name,f): +def parse_map(name,f,with_alt=True): """read a Keymap""" - map=Keymap(name) + map=Keymap(name,with_alt) l = f.read() if not l: raise EmptyMapError(name) --- keymapper-0.5.3.orig/keymapper/parse/linuxsyms.py +++ keymapper-0.5.3/keymapper/parse/linuxsyms.py @@ -13,7 +13,12 @@ translate symbols to unicode (and back). """ -symfile = "data/symbols" +from os.path import exists + +symfile = "/usr/share/misc/keymap.syms"; +if exists("data/symbols") and exists("gen_keymap"): + symfile = "data/symbols"; + map = {} alias = {} @@ -57,9 +62,9 @@ read_table() # print name, - # XXX TODO: return that stuff somehow? - if name.startswith("Meta_"): - name = name[5:] + if name.startswith("Meta_") or name.startswith("Alt_") \ + or name.startswith("Hyper_"): + return None while name in alias: name = alias[name] --- keymapper-0.5.3.orig/keymapper/parse/x11.g +++ keymapper-0.5.3/keymapper/parse/x11.g @@ -0,0 +1,262 @@ +""" +This code implements a parser for Linux keyboard maps. +""" + +from keymapper.parse.linuxsyms import lookup_symbol,SymbolNotFound +from os.path import exists,join,curdir +from gzip import GzipFile +from keymapper.keymap import Keymap,Modifier, STD,SHIFT,ALT,ALTSHIFT +import os, re + +symfile = "/usr/share/misc/keymap.xkeys"; +if exists("data/xkeys") and exists("gen_keymap"): + symfile = "data/xkeys"; + +xsyms = {} +def read_map(): + f = open(symfile) + for l in f: + l = l.strip() + comment = l.find('#') + if comment > -1: l = l[:comment] + l = l.strip() + if l == "": continue + s,d = l.split() + xsyms[s] = eval("0x"+d, {},{}) +read_map() +del read_map + +defmap="us" +defkey="pc101" + +dirs = [ +] +def add_dir(d): + """Helper to add a directory to the search path""" + dirs.append(d) + +class BadStep(Exception): + pass +class NoFileFound(Exception): + pass +class FileProblem(Exception): + pass +class TooManySyms(Exception): + pass + +class Restart: # Marker + pass +class UseOld: + pass +class UseNew: + pass + +def get_file(name): + """Find a keymap file""" + global dirs + if not dirs: + dirs=("/usr/lib/X11/xkb/symbols",) + for end in ("",".gz"): + for dir in dirs: + n = os.path.join(dir,name+end) + if exists(n): + if n.endswith(".gz"): + f = GzipFile(n,"rb") + else: + f = open(n,"r") + return f + + raise NoFileFound(name) + +m_incl2 = re.compile("^(.+)\\((.+)\\)$") +next_mod = {STD:SHIFT, SHIFT:ALT, ALT:ALTSHIFT, ALTSHIFT:ALT} + +class X11Keymap(Keymap): + """submap with interesting features for generating X11 maps""" + def __init__(self,name,sub=None): + Keymap.__init__(self,name+"("+sub+")") + self.map_vector = [] + self.steps = [] + self.build_done = False + + def append(self,what): + self.steps.append(what) + + def build_map(self,to_map=None,keymap=None): + if to_map is None: + if self.build_done: + return + to_map = self + + if keymap is None: + keymap={} + for s in self.steps: + if isinstance(s,list) or isinstance(s,tuple): + rep = s[0] + code = s[1] + try: + code = xsyms[code] + except KeyError: + continue + s = s[2:] + if rep == UseOld and code in keymap: + continue + keymap[code] = s + + elif isinstance(s,basestring): + # include file. Can be "name(sub)". + m = m_incl2.match(s) + if m: + s = (m.group(1),m.group(2)) + if not known.has_key(s): + parse_file(s[0],s[1]) + else: + if not known.has_key(s): + parse_file(s) + + known[s].build_map(to_map,keymap) + else: + raise BadStep + + if to_map == self and not self.build_done: + self.build_done = True + s = (defmap,defkey) + if not known.has_key(s): + parse_file(defmap,defkey) + known[s].build_map(to_map,keymap) + + for code,keys in keymap.iteritems(): + mod=STD + for k in keys: + if k == Restart: + # mod=STD # heuristic + continue + to_map.add(k,code,mod) + mod=next_mod[mod] + +known = {} + +def parse_file(name, sub=None): + if sub: + k = (name,sub) + else: + m = m_incl2.match(name) + if m: + (name,sub) = (m.group(1),m.group(2)) + k = (name,sub) + else: + k = name + + if not known.has_key(k): + f = get_file(name) + parser = x11map(x11mapScanner("",file=f,filename=name)) + + try: + parser.map(name) + except SymbolNotFound,e: + print >>sys.stderr, "Keysym '%s' not found" % e.args + print >>sys.stderr, parser._scanner + raise FileProblem(name) + except runtime.SyntaxError, e: + runtime.print_error(e, parser._scanner, max_ctx=1) + raise FileProblem(name) + except runtime.NoMoreTokens: + print >>sys.stderr, 'Could not complete parsing; stopped around here:' + print >>sys.stderr, parser._scanner + raise FileProblem(name) + + try: + map = known[k] + except KeyError: + return None + map.build_map() + return map + +%% + +parser x11map: + ignore: "[ \n\r\t]+" + ignore: "(#|!).*" + ignore: "\/\/.*" + + token EOF: "$" + token INCLUDE: "include" + token SETMODWHAT: "SetMods\\.[a-zA-Z0-9_]+" + token KEYWHAT: "key\\.[a-zA-Z0-9_]+" + token HEX: "0x[a-zA-Z0-9]+" + token UNI: "U[0-9A-Fa-f]{4}" + token UNI3: "U[0-9A-Fa-f]{3}" + token SYM: "[a-zA-Z0-9_]+" + token NUM: "[-+]?[0-9_]+" + #token _CHAR1: "'([0-7]){1,3}'" + #token _CHAR2: "'\\\\.'" + #token _CHAR3: "'.'" + #token PLUS: "\\+" + token _STRLITERAL: '\'([^\\n\'\\\\]|\\\\.)*\'|"([^\\n"\\\\]|\\\\.)*"' + token _KEYLITERAL: '<[A-Za-z0-9]+>' + + rule STRLITERAL: _STRLITERAL {{ return eval(_STRLITERAL,{},{}) }} + rule KEYLITERAL: _KEYLITERAL {{ return _KEYLITERAL[1:-1] }} + + rule map<>: one_map<>* EOF + + rule one_map<>: {{ default = False }} {{ hidden = False }} + ( "partial" + | "default" {{ default=True }} + | "hidden" {{ hidden=True }} + )* + mods* + "xkb_symbols" STRLITERAL {{ sub=STRLITERAL }} + {{ data = X11Keymap(name,sub) }} + "{" + ( incl<> | entry<> + | setmod | vmod | naming | modmap | keyset ) * + "}" + {{ known[(name,sub)] = data }} + {{ if default: known[name] = data }} + ";" + + rule naming: "[Nn]ame" "\\[" SYM "\\]" "=" STRLITERAL ";" + + rule modmap: "modifier_map" SYM "{" symkey ( "," ? symkey ) * "}" ";" + #rule modmap: "modifier_map" SYM "{" SYM ( "," SYM ) * "}" ";" + rule symkey: SYM | _KEYLITERAL + rule vmod: "virtual_modifiers" SYM ";" + rule setmod: SETMODWHAT "=" SYM ";" + + + rule keyset: KEYWHAT ( "\\[" SYM "\\]" ) ? "=" STRLITERAL ";" + + + rule mods: "keypad_keys" | "function_keys" + | "alphanumeric_keys" | "modifier_keys" | "alternate_group" + rule incl<>: "include" STRLITERAL {{ data.append(STRLITERAL) }} + + rule entry<>: {{ rep=UseOld }} + ( ( "replace" | "override" ) {{ rep=UseNew }} ) ? + "key" KEYLITERAL {{ k=[rep,KEYLITERAL] }} + "{" stuffgroup<> + ( "," {{ k.append(Restart) }} stuffgroup<> ) * + "}" ";" {{ data.append(k) }} + + rule stuffgroup<>: stuff | group<> + rule stuff: stuffsym | stuffvirt | stufftype | stuffover + rule stuffsym: "symbols" "\\[" SYM "\\]" "=" + "\\[" ( SYM ( "," SYM ) * ) ? "\\]" + rule stuffvirt: "virtualMods" "=" SYM + rule stufftype: "type" ( "\\[" SYM "\\]" ) ? "=" STRLITERAL + rule stuffover: "overlay[12]" "=" KEYLITERAL + + rule group<>: "\\[" ( sym {{ if sym: k.append(sym) }} + ( "," ? sym {{ if sym: k.append(sym) }} ) * ) ? + "\\]" + + rule sym: "NoSymbol" {{ return None }} + | "SetMods" "\\(" SYM "=" SYM "\\)" {{ return None }} + | "LockGroup" "\\(" SYM "=" NUM "\\)" {{ return None }} + | UNI {{ return eval('u"\\u%s"' % (UNI[1:]),{},{}) }} + | UNI3 {{ return eval('u"\\u0%s"' % (UNI3[1:]),{},{}) }} + | HEX {{ return eval('u"\\U%08x"' % (eval(HEX)-0x1000000,),{},{}) }} + | SYM {{ return lookup_symbol(SYM) }} + +%% --- keymapper-0.5.3.orig/debian/changelog +++ keymapper-0.5.3/debian/changelog @@ -1,12 +1,188 @@ -keymapper (0.2-1) unstable; urgency=low +keymapper (0.5.3-10.1build1) precise; urgency=low + + * Rebuild to drop python2.6 dependencies. + + -- Matthias Klose Sat, 31 Dec 2011 02:04:25 +0000 + +keymapper (0.5.3-10.1) unstable; urgency=low + + * Non-maintainer upload. + * Rebuild to add Python 2.7 support + + -- Piotr Ożarowski Sun, 08 May 2011 16:45:56 +0200 + +keymapper (0.5.3-10) unstable; urgency=low + + * Convert to dh_python2. + * Build-depend on python-all, not python-all-dev. + + -- Colin Watson Fri, 15 Oct 2010 22:17:14 +0100 + +keymapper (0.5.3-9) unstable; urgency=low + + * Use 'dh $@ --options' rather than 'dh --options $@', for + forward-compatibility with debhelper v8. + * Set XS-Python-Version control field. + + -- Colin Watson Tue, 13 Jul 2010 10:49:37 +0100 + +keymapper (0.5.3-8) unstable; urgency=low + + * Upgrade to debhelper v7. + + -- Colin Watson Tue, 06 Oct 2009 11:07:57 +0100 + +keymapper (0.5.3-7) unstable; urgency=low + + [ Matthias Urlichs ] + * Add a --no-altgr option to skip symbols that are not reachable via + either a plain key or SHIFT. + * Add a step asking users whether they have a key that's reachable + directly or via SHIFT. + + [ Colin Watson ] + * Further fixes to no-alt step generation. The UK keymap can now be + detected even if you don't know that æ is on AltGr-a, which was my main + motivation. :-) + + -- Colin Watson Thu, 12 Oct 2006 02:12:35 +0100 + +keymapper (0.5.3-6) unstable; urgency=low + + * Upload to Debian, so that we can consider integrating this into mainline + d-i. + * Set myself as maintainer and Matthias as uploader. + * Convert to Architecture: all. + * Policy version 3.7.2. + + -- Colin Watson Mon, 11 Sep 2006 14:13:52 +0100 + +keymapper (0.5.3-5) edgy; urgency=low + + * Add gen_keymap --interactive mode that prompts for help when + indistinguishable keymaps are found. + * Add gen_keymap --useonly option to generate the tree based only on + certain keymaps (the opposite of --skip, and possibly faster than + --filter). + * Use dh_python to restore our dependency on python. + * Improve clean targets. + + -- Colin Watson Wed, 6 Sep 2006 16:50:03 +0100 + +keymapper (0.5.3-4) edgy; urgency=low + + * Fix Python exception when trying to use higher debugging levels. + * Add man page for gen_keymap. + * Don't install x2console_keymap for now, as we don't install the + keymapper.parse.x11 module so that script is currently untested and + probably won't work. + * Convert to new Python policy, using python-support. + * Remove .pyc and .pyo files in source package on clean. + * Update xkeyboard-config dependency to xkb-data | xkeyboard-config. + + -- Colin Watson Wed, 6 Sep 2006 00:16:46 +0100 + +keymapper (0.5.3-3) dapper; urgency=low + + * data/symbols: Rename Thai_* to thai_*, in accordance with console-tools + 1:0.2.3dbs-60ubuntu3. Add thai_yamakkan, thai_fongman, thai_angkhankhu, + and thai_khomut keysyms. + + -- Colin Watson Wed, 12 Apr 2006 23:11:58 +0100 + +keymapper (0.5.3-2) dapper; urgency=low + + * Depend on xkeyboard-config rather than on the removed xlibs. + * Remove duplicate Build-Depends line. + + -- Colin Watson Wed, 25 Jan 2006 09:17:10 +0000 + +keymapper (0.5.3-1) hoary; urgency=low + + * Ignore control, spacing, and unassigned characters. + * Map double-angle quotes and much-less/greater to simple less/greater. + + -- Matthias Urlichs Fri, 1 Apr 2005 10:43:39 +0200 + +keymapper (0.5.2-1) hoary; urgency=low + + * Added ו (Hebrew vav) to the list of stuff looking like ell/one + * Added ¤ (Currency sign) as an alias to * (asterisk), and + ¢ to c (available on the US keymap but not commonly printed on keycaps) + * Added shortcuts to break excessively-broad recursion + * Fix a crash generating sparse mapping trees + * Adjust heuristics + * Increased the penalty for ALT-key combinations + + -- Matthias Urlichs Wed, 30 Mar 2005 18:42:15 +0200 + +keymapper (0.5.1-1) hoary; urgency=low + + * Add a filter option to visualize decision path differences between + a small number of keymaps more clearly. + * Aliased cedilla and comma. + + -- Matthias Urlichs Fri, 25 Mar 2005 01:00:04 +0100 + +keymapper (0.5-1) hoary; urgency=low + + * Added an analyzer for X11 keymaps. + - Added a script to print possible console=>X11 mappings. + * Speed up keymap filtering when keymaps have subsets. + * Changed the script file interpreter to process multiple + possible choices in parallel. + * Added lots of new lookalike Unicode characters, + from Unicode's NamesList.txt. + * Fix color/style assignment in graph output. + * Various small bugfixes. + + -- Matthias Urlichs Sun, 27 Feb 2005 17:38:05 +0100 + +keymapper (0.4.3-1) hoary; urgency=low + + * change search path logic to allow arbitrary paths. + * Fix dependency on python-dev. + + -- Matthias Urlichs Tue, 15 Feb 2005 18:10:02 +0100 + +keymapper (0.4.2-1) hoary; urgency=low + + * Added more interesting letters to the equivs table. + * Fix codec handling: The main program is responsible for equipping + the file objects passed into keymapper.* with appropriate codecs. + + -- Matthias Urlichs Thu, 3 Feb 2005 11:38:04 +0100 + +keymapper (0.4.1-1) hoary; urgency=low + + * Add one and zero. + * Conflate l and I. + + -- Matthias Urlichs Wed, 2 Feb 2005 19:29:45 +0100 + +keymapper (0.4-1) hoary; urgency=low + + * Fix output code to print only those characters which actually appear + on the keyboards which are under consideration at this step. + + -- Matthias Urlichs Wed, 2 Feb 2005 19:27:34 +0100 + +keymapper (0.3-1) hoary; urgency=low + + * Add character equivalence table. + + -- Matthias Urlichs Wed, 2 Feb 2005 16:11:32 +0100 + +keymapper (0.2-1) hoary; urgency=low * Works, for now. * Optionally generates graphviz output. * Added installation and copyright stuff. + * Added option to set the file system root. -- Matthias Urlichs Wed, 2 Feb 2005 08:34:28 +0100 -keymapper (0.1-1) unstable; urgency=low +keymapper (0.1-1) hoary; urgency=low * Initial Release. (Doesn't do anything useful yet...) --- keymapper-0.5.3.orig/debian/install +++ keymapper-0.5.3/debian/install @@ -0,0 +1 @@ +gen_keymap usr/bin --- keymapper-0.5.3.orig/debian/rules +++ keymapper-0.5.3/debian/rules @@ -1,79 +1,17 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# GNU copyright 1997 to 1999 by Joey Hess. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - - -CFLAGS = -Wall -g - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif -ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) - INSTALL_PROGRAM += -s -endif - -configure: configure-stamp -configure-stamp: - dh_testdir - # Add here commands to configure the package. - - touch configure-stamp - - -build: build-stamp - -build-stamp: configure-stamp - dh_testdir - - # Add here commands to compile the package. - python setup.py build - - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp configure-stamp - - test -f changelog || bk changes > changelog - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - python setup.py install --root=$(shell pwd)/debian/keymapper --no-compile --install-purelib=/usr/lib/site-python - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - find debian/*/usr/share -name SCCS -print0 | xargs -0r rm -rf - dh_compress - dh_fixperms -# dh_perl - dh_python -# dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure +#! /usr/bin/make -f +%: + dh $@ --buildsystem=python_distutils --with python2 + +override_dh_auto_build: + dh_auto_build + $(MAKE) -C keymapper/parse + +override_dh_auto_clean: + dh_auto_clean + $(MAKE) -C keymapper/parse clean + +override_dh_install: + dh_install + install -m 644 data/symbols debian/keymapper/usr/share/misc/keymap.syms + install -m 644 data/xkeys debian/keymapper/usr/share/misc/keymap.xkeys + install -m 644 data/equivs debian/keymapper/usr/share/misc/keysym.equiv --- keymapper-0.5.3.orig/debian/exporter +++ keymapper-0.5.3/debian/exporter @@ -0,0 +1,10 @@ +#!/bin/sh + +set -e + +test -n "$1" +test -z "$3" +if test -z "$2" ; then T="+"; else T="$2"; fi +D="$1" + +bk changes -v -r1.0..$T > "$D"/changelog --- keymapper-0.5.3.orig/debian/manpages +++ keymapper-0.5.3/debian/manpages @@ -0,0 +1 @@ +gen_keymap.1 --- keymapper-0.5.3.orig/debian/control +++ keymapper-0.5.3/debian/control @@ -1,14 +1,15 @@ Source: keymapper Section: utils Priority: optional -Maintainer: Matthias Urlichs -Build-Depends: debhelper (>= 4.1) -Standards-Version: 3.6.1 -Build-Depends: yapps2, python (>= 2.4) +Maintainer: Colin Watson +Uploaders: Matthias Urlichs +Standards-Version: 3.7.2 +Build-Depends: yapps2, python-all (>= 2.6.5-2), debhelper (>= 7.0.50) +XS-Python-Version: all Package: keymapper -Architecture: any -Depends: ${misc:Depends}, ${python:Depends}, yapps2-runtime (>= 2.1.1-17) +Architecture: all +Depends: ${misc:Depends}, ${python:Depends}, xkb-data | xkeyboard-config, yapps2-runtime (>= 2.1.1-17) Suggests: graphviz Description: Keyboard map decision tree builder and interpreter This package implements an alternate way to let a user decide which --- keymapper-0.5.3.orig/debian/compat +++ keymapper-0.5.3/debian/compat @@ -1 +1 @@ -4 +7 --- keymapper-0.5.3.orig/debian/dirs +++ keymapper-0.5.3/debian/dirs @@ -1 +1,2 @@ usr/bin +usr/share/misc --- keymapper-0.5.3.orig/data/equivs +++ keymapper-0.5.3/data/equivs @@ -0,0 +1,153 @@ +£₤ +aаAαАΑаαɑą +bвBΒ♭ьƅВЬвьℬʙ +чƨᠽᠴ +cℂCСсʗ∁¢ +dD +eE∈ℰεЕℇеєƐΕ℮Ɛɛeɛ∊∈∊ƹع +fFϜϝℱ +gGɡɢℊցɡ +hнHНнһℋℍℌℎΗʜʰհ +jJℐјℑϳʲ +kкKКкҚқҠҡΚκKK +l∟ΙL1iӀІİIℓℒ¡ІіΙιɪʟⅠˡւԼℭıi讠⻈ɩι℩Ɩɩɪ℩⍳וןוּיּיاﭐﺃﺄﺍﺎ +mМℳMмΜмᠮ +nNΝɴറℕոⁿה +oOѺoѻОоΟο0ഠܘՕօ०∅⌀Ø +pPРрΡℙρϱр +qQℚ +rRʀʳℛℝℜ +sSѕЅˢടՏ +șş +tтTТтΤττէ⊤ʈƮ +uUυՍսՄԱ +wWωΩѠѡʷΩΩ +xхXχΧХхˣﬡאאּ +yУYүУуҮүΥγʸɣγƔvVѴѵν +zZΖℤℨƶ +äÄ +ÏïϊÏïİı +öÖ +üÜϋŰű +´`' +ßβϐ阝ƀ +θϑ +ϕφΦՓ +ѰѱΨψ +Ϟϟ +Ϡϡ +зэ∃∋∍ӡʒȝ∍϶ +Ϛϛςσ +гΓГгΓ୮ +пЛПΠπлᴫᠯ ᠳдΠ∏ +∂ĐƉÐđðђδɖ +əӘǝәƏ +ӨƟөθѳɵ +υ℧ʋʊƲ +1¹ +2Չշ²२Ձ +3Յ३³ӠȜƷ +5ƽ +8ȣ +-‒–—―─━﹣-⁻₋−᠆−­-‑‐–‒ー— ++⁺₊∔﹢ +.·˙ׁׂ̇ׄ۰۔ܼ݀݁․⋅⠁⠂⠄⠈⠐⠠⡀⢀〮៙๏ +Ɓɓ +⁠      +⋀⌃̂˄∧ˆ⊍ʌ⨃⟑⩀‸Λ⍝^ +ǀ∣⧸⁄ʇ׀/∕❘̸|¦ +։ː׃:∶ +₠€ +́΄҆̍̓̒̕’‘❛ء'′´ʹʻʼʾˈˊ՛՚❜٬ʹ +!ǃ❢יִ +؟ˁ҅‽ʕ̔?ˀʔՙ +‛ʽʿ +;؛; +٪% +͇ˍ̱̳̲‗_ +בℶ +∼̃⌇⫭˜〰⫬~⦚〜~ +ǁ∥⃦ʖ‖⫽ +☀⨀☉◉⊙ʘ☼⦿ +⋃∪ +⦁•⋅‧·⁰̊․●❌ˑ°·◘∙∘・˚◦ +ɪƗ +ɔƆ +〈〈<⟨‹≺⧼«≪⋘《⟪⋘⫷ +╳✕× +★⋆✨*٭⁎✱∗¤ +℡℻ +ϛς +⊚◎ +◆♦ +。۔. +Ɗɗ +〚⟦ +␣⌴ +▪◾ +ଓବ@ +±∓ +△⃤⧍Δ∆ +※྿ +ᠣо +见⻅ +隸隷 +ىيی +ℸד +〃"❝̋”̎〞〝″‶ʺ˝“❞ +♥❤ +♢⋄◇◊⃟ +⌋⟓」⏌⨼ +ɲƝ +◺◿⊿ +、‚،,¸ +■❎◼█ +民⺠ +ÅÅ +疋⺪ +❡⁋¶ +µμ +⁁⋌ +∩⋂⩍ +љlj +⟩〉❭❯⊱〉≻›⧽>»≫≫》⟫⋙ +□☐◻⟤⃞ +œɶ +ӕæ +∐⨿ +Ƞƞ + ̄‾ +łƚ +⊲◅ +՝`ˋ‵̀ +⧹⧵⃥\∖ +≠ǂ +○⃝〇◯ +☓✗ +țţ +⊠☒ +✩☆ +ʃ∫ +ƩΣ∑ +ɸϕφ +⊥┴⟘ +刂 +ᚹƿ +ֿﬞ +ğǧ +⋁∨˅ +Ћћℏħ +✓√ +©℗ +☙❧ +Ɯɯ +גℷ +͵ˏ +ˉ̅̄¯ +Бƃб +肉⺼ +ɠƓ +Ÿÿ +Ѳϴ +þᚦ +Ṫṫ --- keymapper-0.5.3.orig/data/xkeys +++ keymapper-0.5.3/data/xkeys @@ -0,0 +1,58 @@ +# Map: X11 key name => Linux keycode (hex) +AB01 2c +AB02 2d +AB03 2e +AB04 2f +AB05 30 +AB06 31 +AB07 32 +AB08 33 +AB09 34 +AC01 1e +AC02 1f +AC03 20 +AC04 21 +AC05 22 +AC06 23 +AC07 24 +AC08 25 +AC09 26 +AC10 27 +AC11 28 +AD01 10 +AD02 11 +AD03 12 +AD04 13 +AD05 14 +AD06 15 +AD07 16 +AD08 17 +AD09 18 +AD10 19 +AD11 1a +AD12 1b +AE02 03 +AE03 04 +AE04 05 +AE05 06 +AE06 07 +AE07 08 +AE08 09 +AE09 0a +AE10 0b +AE11 0c +AE12 0d +BKSL 2b +BKSP 0e +CAPS 3a +ESC 01 +LALT 38 +LCTL 1d +LFSH 2a +LSGT 56 +RALT 64 +RCTL 61 +RTRN 1c +RTSH 36 +TAB 0f +TLDE 29 --- keymapper-0.5.3.orig/data/symbols +++ keymapper-0.5.3/data/symbols @@ -31,14 +31,14 @@ 001e Control_asciicircum 001f Control_underscore 0020 space -0021 exclam +0021 exclam excalem 0022 quotedbl 0023 numbersign 0024 dollar 0025 percent 0026 ampersand 0027 apostrophe -0028 parenleft +0028 parenleft parenlef 0029 parenright 002a asterisk 002b plus @@ -46,21 +46,23 @@ 002d minus 002e period 002f slash -0030 zero -0031 one -0032 two -0033 three -0034 four -0035 five -0036 six -0037 seven -0038 eight -0039 nine +0030 0 zero +0031 1 one +0032 2 two +0033 3 three +0034 4 four +0035 5 five +0036 6 six +0037 7 seven +0038 8 eight +0039 9 nine 003a colon 003b semicolon +003c leftcaret 003c less 003d equal 003e greater +003e rightcaret 003f question 0040 at 0041 A @@ -92,9 +94,10 @@ 005b bracketleft 005c backslash 005d bracketright -005e asciicircum dead_circumflex +005e asciicircum dead_circumflex SunFA_Circum +005f underbar 005f underscore -0060 grave dead_grave +0060 grave dead_grave SunFA_Grave 0061 a 0062 b 0063 c @@ -124,7 +127,7 @@ 007b braceleft 007c bar 007d braceright -007e asciitilde dead_tilde +007e asciitilde dead_tilde SunFA_Tilde 007f Delete 00a0 nobreakspace 00a0 no-break_space @@ -136,7 +139,7 @@ 00a6 brokenbar 00a7 paragraph_sign 00a7 section -00a8 diaeresis dead_diaeresis +00a8 diaeresis dead_diaeresis SunFA_Diaeresis 00a9 copyright 00aa ordfeminine 00ab guillemotleft @@ -144,16 +147,17 @@ 00ad hyphen 00ad soft_hyphen 00ae registered -00af macron +00af macron dead_macron +00af overbar 00b0 degree 00b1 plusminus 00b2 twosuperior 00b3 threesuperior -00b4 acute dead_acute +00b4 acute dead_acute SunFA_Acute 00b5 mu 00b6 paragraph 00b7 periodcentered -00b8 cedilla dead_cedilla +00b8 cedilla dead_cedilla SunFA_Cedilla 00b9 onesuperior 00ba masculine 00bb guillemotright @@ -178,7 +182,7 @@ 00cd Iacute 00ce Icircumflex 00cf Idiaeresis -00d0 ETH +00d0 ETH Eth 00d1 Ntilde 00d2 Ograve 00d3 Oacute @@ -193,7 +197,7 @@ 00db Ucircumflex 00dc Udiaeresis 00dd Yacute -00de THORN +00de THORN Thorn 00df ssharp 00e0 agrave 00e1 aacute @@ -314,8 +318,8 @@ 015f scedilla 0160 Scaron 0161 scaron -0162 Tcedilla -0163 tcedilla +0162 Tcedilla Tcediila +0163 tcedilla tcediila 0164 Tcaron 0165 tcaron 0166 Tslash @@ -339,306 +343,852 @@ 017c zabovedot 017d Zcaron 017e zcaron -02bc rightquote -02bd leftquote +0192 function +01e6 Gcaron +01e7 gcaron +01a0 Ohorn +01a1 ohorn +01af Uhorn +01b0 uhorn +02bc rightquote quoteright +02bd leftquote quoteleft 02c7 caron 02d8 breve -02d9 abovedot +02d9 abovedot dead_abovedot +02da abovering dead_abovering 02db ogonek 02dd doubleacute +0309 dead_hook +031b dead_horn +0323 dead_belowdot 0384 accent -0385 diaeresisaccent -0386 Alphaaccent -0388 Epsilonaccent -0389 Etaaccent -038a Iotaaccent -038c Omicronaccent -038e Upsilonaccent -038f Omegaaccent +0385 Greek_accentdieresis diaeresisaccent +0386 Greek_ALPHAaccent Alphaaccent +0388 Greek_EPSILONaccent Epsilonaccent +0389 Greek_ETAaccent Etaaccent +038a Greek_IOTAaccent Iotaaccent +038c Greek_OMICRONaccent Omicronaccent +038e Greek_UPSILONaccent Upsilonaccent +038f Greek_OMEGAaccent Omegaaccent +0390 Greek_iotaaccentdieresis 0390 iotadiaeresisaccent -0391 Alpha -0392 Beta -0393 Gamma -0394 Delta -0395 Epsilon -0396 Zeta -0397 Eta -0398 Theta -0399 Iota -039a Kappa -039b Lamda -039c Mu -039d Nu -039e Ksi -039f Omicron -03a0 Pi -03a1 Rho -03a3 Sigma -03a4 Tau -03a5 Upsilon -03a6 Phi -03a7 Khi -03a8 Psi -03a9 Omega -03aa Iotadiaeresis -03ab Upsilondiaeresis -03ac alphaaccent -03ad epsilonaccent -03ae etaaccent -03af iotaaccent -03b0 upsilondiaeresisaccent -03b1 alpha -03b2 beta -03b3 gamma -03b4 delta -03b5 epsilon -03b6 zeta -03b7 eta -03b8 theta -03b9 iota -03ba kappa -03bb lamda -03bc mu -03bd nu -03be ksi -03bf omicron -03c0 pi -03c1 rho -03c2 terminalsigma -03c3 sigma -03c4 tau -03c5 upsilon -03c6 phi -03c7 khi -03c8 psi -03c9 omega -03ca iotadiaeresis -03cb upsilondiaeresis -03cc omicronaccent -03cd upsilonaccent -03ce omegaaccent -0401 cyrillic_capital_letter_io -0402 serbocroatian_cyrillic_capital_letter_dje -0403 macedonian_cyrillic_capital_letter_gje -0404 ukrainian_cyrillic_capital_letter_ie -0405 macedonian_cyrillic_capital_letter_dze -0406 ukrainian_cyrillic_capital_letter_i -0407 ukrainian_cyrillic_capital_letter_yi -0408 cyrillic_capital_letter_je -0409 cyrillic_capital_letter_lje -040a cyrillic_capital_letter_nje -040b serbocroatian_cyrillic_capital_letter_chje -040c macedonian_cyrillic_capital_letter_kje -040e bielorussian_cyrillic_capital_letter_short_u -040f cyrillic_capital_letter_dze -0410 cyrillic_capital_letter_a -0411 cyrillic_capital_letter_be -0412 cyrillic_capital_letter_ve -0413 cyrillic_capital_letter_ghe -0414 cyrillic_capital_letter_de -0415 cyrillic_capital_letter_ie -0416 cyrillic_capital_letter_zhe -0417 cyrillic_capital_letter_ze -0418 cyrillic_capital_letter_i -0419 cyrillic_capital_letter_short_i -041a cyrillic_capital_letter_ka -041b cyrillic_capital_letter_el -041c cyrillic_capital_letter_em -041d cyrillic_capital_letter_en -041e cyrillic_capital_letter_o -041f cyrillic_capital_letter_pe -0420 cyrillic_capital_letter_er -0421 cyrillic_capital_letter_es -0422 cyrillic_capital_letter_te -0423 cyrillic_capital_letter_u -0424 cyrillic_capital_letter_ef -0425 cyrillic_capital_letter_ha -0426 cyrillic_capital_letter_tse -0427 cyrillic_capital_letter_che -0428 cyrillic_capital_letter_sha -0429 cyrillic_capital_letter_shcha -042a cyrillic_capital_hard_sign -042b cyrillic_capital_letter_yeru -042c cyrillic_capital_soft_sign -042d cyrillic_capital_letter_e -042e cyrillic_capital_letter_yu -042f cyrillic_capital_letter_ya -0430 cyrillic_small_letter_a -0431 cyrillic_small_letter_be -0432 cyrillic_small_letter_ve -0433 cyrillic_small_letter_ghe -0434 cyrillic_small_letter_de -0435 cyrillic_small_letter_ie -0436 cyrillic_small_letter_zhe -0437 cyrillic_small_letter_ze -0438 cyrillic_small_letter_i -0439 cyrillic_small_letter_short_i -043a cyrillic_small_letter_ka -043b cyrillic_small_letter_el -043c cyrillic_small_letter_em -043d cyrillic_small_letter_en -043e cyrillic_small_letter_o -043f cyrillic_small_letter_pe -0440 cyrillic_small_letter_er -0441 cyrillic_small_letter_es -0442 cyrillic_small_letter_te -0443 cyrillic_small_letter_u -0444 cyrillic_small_letter_ef -0445 cyrillic_small_letter_ha -0446 cyrillic_small_letter_tse -0447 cyrillic_small_letter_che -0448 cyrillic_small_letter_sha -0449 cyrillic_small_letter_shcha -044a cyrillic_small_hard_sign -044b cyrillic_small_letter_yeru -044c cyrillic_small_soft_sign -044d cyrillic_small_letter_e -044e cyrillic_small_letter_yu -044f cyrillic_small_letter_ya -0451 cyrillic_small_letter_io -0452 serbocroatian_cyrillic_small_letter_dje -0453 macedonian_cyrillic_small_letter_gje -0454 ukrainian_cyrillic_small_letter_ie -0455 macedonian_cyrillic_small_letter_dze -0456 ukrainian_cyrillic_small_letter_i -0457 ukrainian_cyrillic_small_letter_yi -0458 cyrillic_small_letter_je -0459 cyrillic_small_letter_lje -045a cyrillic_small_letter_nje -045b serbocroatian_cyrillic_small_letter_chje -045c macedonian_cyrillic_small_letter_kje -045e bielorussian_cyrillic_small_letter_short_u -045f cyrillic_small_letter_dze -05d0 alef -05d1 bet -05d2 gimel -05d3 dalet -05d4 he -05d5 vav -05d6 zayin -05d7 het -05d8 tet -05d9 yod -05da finalkaf -05db kaf -05dc lamed -05dd finalmem -05de mem -05df finalnun -05e0 nun -05e1 samekh -05e2 ayin -05e3 finalpe -05e4 pe -05e5 finaltsadi -05e6 tsadi -05e7 qof -05e8 resh -05e9 shin -05ea tav -2017 doubleunderscore -201e quotedblbase -203e overscore -20ac euro -2116 number_acronym -- F1 F2 F3 F4 F5 -- F6 F7 F8 F9 F10 -- F11 F12 F13 F14 F15 -- F16 F17 F18 F19 F20 -- Find -- Insert -- Remove -- Select -- Prior -- Next -- Macro -- Help -- Do -- Pause -- F21 F22 F23 F24 F25 -- F26 F27 F28 F29 F30 -- F31 F32 F33 F34 F35 -- F36 F37 F38 F39 F40 -- F41 F42 F43 F44 F45 -- F46 F47 F48 F49 F50 -- F51 F52 F53 F54 F55 -- F56 F57 F58 F59 F60 -- F61 F62 F63 F64 F65 -- F66 F67 F68 F69 F70 -- F71 F72 F73 F74 F75 -- F76 F77 F78 F79 F80 -- F81 F82 F83 F84 F85 -- F86 F87 F88 F89 F90 -- F91 F92 F93 F94 F95 -- F96 F97 F98 F99 F100 -- F101 F102 F103 F104 F105 -- F106 F107 F108 F109 F110 -- F111 F112 F113 F114 F115 -- F116 F117 F118 F119 F120 -- F121 F122 F123 F124 F125 -- F126 F127 F128 F129 F130 -- F131 F132 F133 F134 F135 -- F136 F137 F138 F139 F140 -- F141 F142 F143 F144 F145 -- F146 F147 F148 F149 F150 -- F151 F152 F153 F154 F155 -- F156 F157 F158 F159 F160 -- F161 F162 F163 F164 F165 -- F166 F167 F168 F169 F170 -- F171 F172 F173 F174 F175 -- F176 F177 F178 F179 F180 -- F181 F182 F183 F184 F185 -- F186 F187 F188 F189 F190 -- F191 F192 F193 F194 F195 -- F196 F197 F198 F199 F200 -- F201 F202 F203 F204 F205 -- F206 F207 F208 F209 F210 -- F211 F212 F213 F214 F215 -- F216 F217 F218 F219 F220 -- F221 F222 F223 F224 F225 -- F226 F227 F228 F229 F230 -- F231 F232 F233 F234 F235 -- F236 F237 F238 F239 F240 -- F241 F242 F243 F244 F245 -- F246 -- VoidSymbol -- Return -- Show_Registers -- Show_Memory -- Show_State +0391 Greek_ALPHA Alpha +0392 Greek_BETA Beta +0393 Greek_GAMMA Gamma +0394 Greek_DELTA Delta +0395 Greek_EPSILON Epsilon +0396 Greek_ZETA Zeta +0397 Greek_ETA Eta +0398 Greek_THETA Theta +0399 Greek_IOTA Iota +039a Greek_KAPPA Kappa +039b Greek_LAMBDA Lamda Greek_LAMDA +039c Greek_MU Mu +039d Greek_NU Nu +039e Greek_XI Ksi +039f Greek_OMICRON Omicron +03a0 Greek_PI Pi +03a1 Greek_RHO Rho +03a3 Greek_SIGMA Sigma +03a4 Greek_TAU Tau +03a5 Greek_UPSILON Upsilon +03a6 Greek_PHI Phi +03a7 Greek_CHI Khi +03a8 Greek_PSI Psi +03a9 Greek_OMEGA Omega +03aa Greek_IOTAdiaeresis Iotadiaeresis +03ab Greek_UPSILONdieresis Upsilondiaeresis +03ac Greek_alphaaccent alphaaccent +03ad Greek_epsilonaccent epsilonaccent +03ae Greek_etaaccent etaaccent +03af Greek_iotaaccent iotaaccent +03b0 Greek_upsilonaccentdieresis upsilondiaeresisaccent +03b1 Greek_alpha alpha +03b2 Greek_beta beta +03b3 Greek_gamma gamma +03b4 Greek_delta delta +03b5 Greek_epsilon epsilon +03b6 Greek_zeta zeta +03b7 Greek_eta eta +03b8 Greek_theta theta +03b9 Greek_iota iota dead_iota +# What the hell is a dead iota supposed to accomplish ?? +03ba Greek_kappa kappa +03bb Greek_lambda lamda Greek_lamda +03bc Greek_mu mu +03bd Greek_nu nu +03be Greek_xi ksi +03bf Greek_omicron omicron +03c0 Greek_pi pi +03c1 Greek_rho rho +03c2 Greek_finalsmallsigma terminalsigma +03c3 Greek_sigma sigma +03c4 Greek_tau tau +03c5 Greek_upsilon upsilon +03c6 Greek_phi phi +03c7 Greek_chi khi +03c8 Greek_psi psi +03c9 Greek_omega omega +03ca Greek_iotadieresis iotadiaeresis +03cb Greek_upsilondieresis upsilondiaeresis +03cc Greek_omicronaccent omicronaccent +03cd Greek_upsilonaccent upsilonaccent +03ce Greek_omegaaccent omegaaccent +0401 cyrillic_capital_letter_io Cyrillic_IO +0402 Serbian_DJE serbocroatian_cyrillic_capital_letter_dje +0403 Macedonia_GJE macedonian_cyrillic_capital_letter_gje +0404 Ukrainian_IE ukrainian_cyrillic_capital_letter_ie +0405 Macedonia_DSE macedonian_cyrillic_capital_letter_dze +0406 ukrainian_cyrillic_capital_letter_i Ukrainian_I +0407 ukrainian_cyrillic_capital_letter_yi Ukrainian_YI +0408 cyrillic_capital_letter_je Cyrillic_JE +0409 cyrillic_capital_letter_lje Cyrillic_LJE +040a cyrillic_capital_letter_nje Cyrillic_NJE +040b Serbian_TSHE serbocroatian_cyrillic_capital_letter_chje +040c Macedonia_KJE macedonian_cyrillic_capital_letter_kje +040e bielorussian_cyrillic_capital_letter_short_u Byelorussian_SHORTU +040f cyrillic_capital_letter_dze Cyrillic_DZHE +0410 Cyrillic_A cyrillic_capital_letter_a +0411 Cyrillic_BE cyrillic_capital_letter_be +0412 cyrillic_capital_letter_ve Cyrillic_VE +0413 cyrillic_capital_letter_ghe Cyrillic_GHE +0414 cyrillic_capital_letter_de Cyrillic_DE +0415 cyrillic_capital_letter_ie Cyrillic_IE +0416 cyrillic_capital_letter_zhe Cyrillic_ZHE +0417 cyrillic_capital_letter_ze Cyrillic_ZE +0418 cyrillic_capital_letter_i Cyrillic_I +0419 cyrillic_capital_letter_short_i Cyrillic_SHORTI +041a cyrillic_capital_letter_ka Cyrillic_KA +041b cyrillic_capital_letter_el Cyrillic_EL +041c cyrillic_capital_letter_em Cyrillic_EM +041d cyrillic_capital_letter_en Cyrillic_EN +041e cyrillic_capital_letter_o Cyrillic_O +041f cyrillic_capital_letter_pe Cyrillic_PE +0420 cyrillic_capital_letter_er Cyrillic_ER +0421 cyrillic_capital_letter_es Cyrillic_ES +0422 cyrillic_capital_letter_te Cyrillic_TE +0423 cyrillic_capital_letter_u Cyrillic_U +0424 cyrillic_capital_letter_ef Cyrillic_EF +0425 cyrillic_capital_letter_ha Cyrillic_HA +0426 cyrillic_capital_letter_tse Cyrillic_TSE +0427 cyrillic_capital_letter_che Cyrillic_CHE +0428 cyrillic_capital_letter_sha Cyrillic_SHA +0429 cyrillic_capital_letter_shcha Cyrillic_SHCHA +042a cyrillic_capital_hard_sign Cyrillic_HARDSIGN +042b cyrillic_capital_letter_yeru Cyrillic_YERU +042c cyrillic_capital_soft_sign Cyrillic_SOFTSIGN +042d cyrillic_capital_letter_e Cyrillic_E +042e cyrillic_capital_letter_yu Cyrillic_YU +042f cyrillic_capital_letter_ya Cyrillic_YA +0430 Cyrillic_a cyrillic_small_letter_a +0431 Cyrillic_be cyrillic_small_letter_be +0432 cyrillic_small_letter_ve Cyrillic_ve +0433 Cyrillic_ghe cyrillic_small_letter_ghe +0434 Cyrillic_de cyrillic_small_letter_de +0435 Cyrillic_ie cyrillic_small_letter_ie +0436 cyrillic_small_letter_zhe Cyrillic_zhe +0437 cyrillic_small_letter_ze Cyrillic_ze +0438 Cyrillic_i cyrillic_small_letter_i +0439 Cyrillic_shorti cyrillic_small_letter_short_i +043a Cyrillic_ka cyrillic_small_letter_ka +043b Cyrillic_el cyrillic_small_letter_el +043c Cyrillic_em cyrillic_small_letter_em +043d Cyrillic_en cyrillic_small_letter_en +043e Cyrillic_o cyrillic_small_letter_o +043f Cyrillic_pe cyrillic_small_letter_pe +0440 Cyrillic_er cyrillic_small_letter_er +0441 Cyrillic_es cyrillic_small_letter_es +0442 cyrillic_small_letter_te Cyrillic_te +0443 cyrillic_small_letter_u Cyrillic_u +0444 Cyrillic_ef cyrillic_small_letter_ef +0445 Cyrillic_ha cyrillic_small_letter_ha +0446 cyrillic_small_letter_tse Cyrillic_tse +0447 Cyrillic_che cyrillic_small_letter_che +0448 Cyrillic_sha cyrillic_small_letter_sha +0449 Cyrillic_shcha cyrillic_small_letter_shcha +044a Cyrillic_hardsign cyrillic_small_hard_sign +044b cyrillic_small_letter_yeru Cyrillic_yeru +044c cyrillic_small_soft_sign Cyrillic_softsign +044d Cyrillic_e cyrillic_small_letter_e +044e cyrillic_small_letter_yu Cyrillic_yu +044f cyrillic_small_letter_ya Cyrillic_ya +0451 Cyrillic_io cyrillic_small_letter_io +0452 Serbian_dje serbocroatian_cyrillic_small_letter_dje +0453 Macedonia_gje macedonian_cyrillic_small_letter_gje +0454 ukrainian_cyrillic_small_letter_ie Ukrainian_ie +0455 Macedonia_dse macedonian_cyrillic_small_letter_dze +0456 ukrainian_cyrillic_small_letter_i Ukrainian_i +0457 ukrainian_cyrillic_small_letter_yi Ukrainian_yi +0458 Cyrillic_je cyrillic_small_letter_je +0459 Cyrillic_lje cyrillic_small_letter_lje +045a Cyrillic_nje cyrillic_small_letter_nje +045b Serbian_tshe serbocroatian_cyrillic_small_letter_chje +045c Macedonia_kje macedonian_cyrillic_small_letter_kje +045e bielorussian_cyrillic_small_letter_short_u Byelorussian_shortu +045f Cyrillic_dzhe cyrillic_small_letter_dze +0490 Ukrainian_GHE_WITH_UPTURN +0491 Ukrainian_ghe_with_upturn +04ae Cyrillic_U_straight +04af Cyrillic_u_straight +04e8 Cyrillic_O_bar +04e9 Cyrillic_o_bar +05d0 alef hebrew_aleph +05d1 bet hebrew_bet +05d2 gimel hebrew_gimel +05d3 dalet hebrew_dalet +05d4 he hebrew_he +05d5 hebrew_waw vav +05d6 hebrew_zain zayin +05d7 hebrew_chet het +05d8 hebrew_tet tet +05d9 hebrew_yod yod +05da finalkaf hebrew_finalkaph +05db hebrew_kaph kaf +05dc hebrew_lamed lamed +05dd finalmem hebrew_finalmem +05de hebrew_mem mem +05df finalnun hebrew_finalnun +05e0 hebrew_nun nun +05e1 hebrew_samech samekh +05e2 ayin hebrew_ayin +05e3 finalpe hebrew_finalpe +05e4 hebrew_pe pe +05e5 finaltsadi hebrew_finalzade +05e6 hebrew_zade tsadi +05e7 hebrew_qoph qof +05e8 hebrew_resh resh +05e9 hebrew_shin shin +05ea hebrew_taw tav +060c Arabic_comma +061b Arabic_semicolon +061f Arabic_question_mark +0621 Arabic_hamza +0622 Arabic_maddaonalef +0623 Arabic_hamzaonalef +0624 Arabic_hamzaonwaw +0625 Arabic_hamzaunderalef +0626 Arabic_hamzaonyeh +0627 Arabic_alef +0628 Arabic_beh +0629 Arabic_tehmarbuta +062a Arabic_teh +062b Arabic_theh +062c Arabic_jeem +062d Arabic_hah +062e Arabic_khah +062f Arabic_dal +0630 Arabic_thal +0631 Arabic_ra +0632 Arabic_zain +0633 Arabic_seen +0634 Arabic_sheen +0635 Arabic_sad +0636 Arabic_dad +0637 Arabic_tah +0638 Arabic_zah +0639 Arabic_ain +063a Arabic_ghain +0640 Arabic_tatweel +0641 Arabic_feh +0642 Arabic_qaf +0643 Arabic_kaf +0644 Arabic_lam +0645 Arabic_meem +0646 Arabic_noon +0647 Arabic_ha Arabic_heh +0648 Arabic_waw +0649 Arabic_alefmaksura +064a Arabic_yeh +064b Arabic_fathatan +064c Arabic_dammatan +064d Arabic_kasratan +064e Arabic_fatha +064f Arabic_damma +0650 Arabic_kasra +0651 Arabic_shadda +0652 Arabic_sukun +0653 Arabic_madda_above +0654 Arabic_hamza_above +0655 Arabic_hamza_below +0670 Arabic_superscript_alef +- gur_v_r gur_v_r_s +0A02 gur_bindi +0A03 gur_visarga +0A05 gur_a +0A06 gur_aa +0A07 gur_i +0A08 gur_ii +0A09 gur_u +0A0A gur_uu +0A0F gur_ee +0A10 gur_ai +0A13 gur_oo +0A14 gur_au +0A15 gur_ka +0A16 gur_kha +0A17 gur_ga +0A18 gur_gha +0A19 gur_nga +0A1A gur_ca +0A1B gur_cha +0A1C gur_ja +0A1D gur_jha +0A1E gur_nya +0A1F gur_tta +0A20 gur_ttha +0A21 gur_dda +0A22 gur_ddha +0A23 gur_nna +0A24 gur_ta +0A25 gur_tha +0A26 gur_da +0A27 gur_dha +0A28 gur_na +0A2A gur_pa +0A2B gur_pha +0A2C gur_ba +0A2D gur_bha +0A2E gur_ma +0A2F gur_ya +0A30 gur_ra +0A32 gur_la +0A35 gur_va +0A36 gur_sha +0A38 gur_sa +0A39 gur_ha +0A3C gur_nukta +0A3E gur_aamatra +0A3F gur_imatra +0A40 gur_iimatra +0A41 gur_umatra +0A42 gur_uumatra +0A47 gur_eematra +0A48 gur_aimatra +0A4B gur_oomatra +0A4C gur_aumatra +0A4D gur_halant +0A59 gur_khha +0A5A gur_ghha +0A5B gur_za +0A5C gur_rra +0A5E gur_fa +0A66 gur_zero +0A67 gur_one +0A68 gur_two +0A69 gur_three +0A6A gur_four +0A6B gur_five +0A6C gur_six +0A6D gur_seven +0A6E gur_eight +0A6F gur_nine +0A70 gur_tippi +0A71 gur_addak +0A72 gur_iri +0A73 gur_ura +0A74 gur_ekonkar +0A81 guj_candrabindu +0A82 guj_anusvara +0A83 guj_visarga +0A85 guj_a +0A86 guj_aa +0A87 guj_i +0A88 guj_ii +0A89 guj_u +0A8A guj_uu +0A8B guj_rvocalic +0A8D guj_ecandra +0A8F guj_e +0A90 guj_ai +0A91 guj_ocandra +0A93 guj_o +0A94 guj_au +0A95 guj_ka +0A96 guj_kha +0A97 guj_ga +0A98 guj_gha +0A99 guj_nga +0A9A guj_ca +0A9B guj_cha +0A9C guj_ja +0A9D guj_jha +0A9E guj_nya +0A9F guj_tta +0AA0 guj_ttha +0AA1 guj_dda +0AA2 guj_ddha +0AA3 guj_nna +0AA4 guj_nnna +0AA4 guj_ta +0AA5 guj_tha +0AA6 guj_da +0AA7 guj_dha +0AA8 guj_na +0AAA guj_pa +0AAB guj_pha +0AAC guj_ba +0AAD guj_bha +0AAE guj_ma +0AAF guj_ya +0AB0 guj_ra +0AB1 guj_rra +0AB2 guj_la +0AB3 guj_lla +0AB4 guj_llla +0AB5 guj_va +0AB6 guj_sha +0AB7 guj_ssa +0AB8 guj_sa +0AB9 guj_ha +0ABC guj_nukta +0ABE guj_aavowelsign +0ABF guj_ivowelsign +0AC0 guj_iivowelsign +0AC1 guj_uvowelsign +0AC2 guj_uuvowelsign +0AC3 guj_rvocalicvowelsign +0AC4 guj_rrvocalicvowelsign +0AC5 guj_ecandravowelsign +0AC7 guj_evowelsign +0AC8 guj_aivowelsign +0AC9 guj_ocandravowelsign +0ACB guj_ovowelsign +0ACC guj_auvowelsign +0ACD guj_virama +0AD0 guj_om +0AE0 guj_rrvocalic +0AE6 guj_zero +0AE7 guj_one +0AE8 guj_two +0AE9 guj_three +0AEA guj_four +0AEB guj_five +0AEC guj_six +0AED guj_seven +0AEE guj_eight +0AEF guj_nine +0e01 thai_kokai +0e02 thai_khokhai +0e03 thai_khokhuat +0e04 thai_khokhwai +0e05 thai_khokhon +0e06 thai_khorakhang +0e07 thai_ngongu +0e08 thai_chochan +0e09 thai_choching +0e0a thai_chochang +0e0b thai_soso +0e0c thai_chochoe +0e0d thai_yoying +0e0e thai_dochada +0e0f thai_topatak +0e10 thai_thothan +0e11 thai_thonangmontho +0e12 thai_thophuthao +0e13 thai_nonen +0e14 thai_dodek +0e15 thai_totao +0e16 thai_thothung +0e17 thai_thothahan +0e18 thai_thothong +0e19 thai_nonu +0e1a thai_bobaimai +0e1b thai_popla +0e1c thai_phophung +0e1d thai_fofa +0e1e thai_phophan +0e1f thai_fofan +0e20 thai_phosamphao +0e21 thai_moma +0e22 thai_yoyak +0e23 thai_rorua +0e24 thai_ru +0e25 thai_loling +0e26 thai_lu +0e27 thai_wowaen +0e28 thai_sosala +0e29 thai_sorusi +0e2a thai_sosua +0e2b thai_hohip +0e2c thai_lochula +0e2d thai_oang +0e2e thai_honokhuk +0e2f thai_paiyannoi +0e30 thai_saraa +0e31 thai_maihanakat +0e32 thai_saraaa +0e33 thai_saraam +0e34 thai_sarai +0e35 thai_saraii +0e36 thai_saraue +0e37 thai_sarauee +0e38 thai_sarau +0e39 thai_sarauu +0e3a thai_phinthu +0e3f thai_baht +0e40 thai_sarae +0e41 thai_saraae +0e42 thai_sarao +0e43 thai_saraaimaimuan +0e44 thai_saraaimaimalai +0e45 thai_lakkhangyao +0e46 thai_maiyamok +0e47 thai_maitaikhu +0e48 thai_maiek +0e49 thai_maitho +0e4a thai_maitri +0e4b thai_maichattawa +0e4c thai_thanthakhat +0e4d thai_nikhahit +0e4e thai_yamakkan +0e4f thai_fongman +0e50 thai_leksun +0e51 thai_leknung +0e52 thai_leksong +0e53 thai_leksam +0e54 thai_leksi +0e55 thai_lekha +0e56 thai_lekhok +0e57 thai_lekchet +0e58 thai_lekpaet +0e59 thai_lekkao +0e5a thai_angkhankhu +0e5b thai_khomut +11a8 Hangul_J_Kiyeog +11a9 Hangul_J_SsangKiyeog +11aa Hangul_J_KiyeogSios +11ab Hangul_J_Nieun +11ac Hangul_J_NieunJieuj +11ad Hangul_J_NieunHieuh +11ae Hangul_J_Dikeud +11af Hangul_J_Rieul +11b0 Hangul_J_RieulKiyeog +11b1 Hangul_J_RieulMieum +11b2 Hangul_J_RieulPieub +11b3 Hangul_J_RieulSios +11b4 Hangul_J_RieulTieut +11b5 Hangul_J_RieulPhieuf +11b6 Hangul_J_RieulHieuh +11b7 Hangul_J_Mieum +11b8 Hangul_J_Pieub +11b9 Hangul_J_PieubSios +11ba Hangul_J_Sios +11bb Hangul_J_SsangSios +11bc Hangul_J_Ieung +11bd Hangul_J_Jieuj +11be Hangul_J_Cieuc +11bf Hangul_J_Khieuq +11c0 Hangul_J_Tieut +11c1 Hangul_J_Phieuf +11c2 Hangul_J_Hieuh +11eb Hangul_J_PanSios +11f0 Hangul_J_KkogjiDalrinIeung +11f9 Hangul_J_YeorinHieuh +1e02 Babovedot +1e03 babovedot +1e0a Dabovedot +1e0b dabovedot +1e1e Fabovedot +1e1f fabovedot +1e40 Mabovedot +1e41 mabovedot +1e56 Pabovedot +1e57 pabovedot +1e60 Sabovedot +1e61 sabovedot +1e6a Tabovedot +1e6b tabovedot +2002 enspace +2003 emspace +2004 em3space +2005 em4space +2007 digitspace +2008 punctspace +2009 thinspace +200a hairspace +2012 figdash +2013 endash +2014 emdash +2015 Greek_horizbar +2017 doubleunderscore hebrew_doublelowline +2018 leftsinglequotemark +2019 rightsinglequotemark +201a singlelowquotemark +201c leftdoublequotemark +201d rightdoublequotemark +201e doublelowquotemark quotedblbase +2020 dagger +2021 doubledagger +2022 enfilledcircbullet +2025 doubbaselinedot +2026 ellipsis +2032 minutes +2033 seconds +2038 caret +203e overline overscore +20a9 Korean_Won +20ab DongSign +20ac euro Euro EuroSign +2105 careof +2116 number_acronym numerosign +2117 phonographcopyright +211e prescription +2122 trademark +2153 onethird +2154 twothirds +2155 onefifth +2156 twofifths +2157 threefifths +2158 fourfifths +2159 onesixth +215a fivesixths +215b oneeighth +215c threeeighths +215d fiveeighths +215e seveneighths +2190 leftarrow +2191 uparrow +2192 rightarrow +2193 downarrow +21d2 implies +21d4 ifonlyif +2202 partialderivative +2207 nabla +2218 jot +221a radical +221d variation +221e infinity +2227 logicaland +2227 upcaret +2228 downcaret logicalor +2229 intersection upshoe +222a downshoe union +222b integral +2234 therefore +223c approximate +2243 similarequal +2260 notequal +2261 identical +2264 lessthanequal +2265 greaterthanequal +2282 includedin leftshoe +2283 includes rightshoe +22a2 lefttack +22a3 righttack +22a4 uptack +22a5 downtack +2308 upstile +230a downstile +2315 telephonerecorder +2320 topintegral +2321 botintegral +2329 leftanglebracket +232a rightanglebracket +2395 quad +239b topleftparens +239d botleftparens +239e toprightparens +23a0 botrightparens +23a1 topleftsqbracket +23a3 botleftsqbracket +23a4 toprightsqbracket +23a6 botrightsqbracket +23a8 leftmiddlecurlybrace +23ac rightmiddlecurlybrace +23b7 leftradical +23ba horizlinescan1 +23bb horizlinescan3 +23bc horizlinescan7 +23bd horizlinescan9 +2409 ht +240a lf +240b vt +240c ff +240d cr +2424 nl +2500 horizconnector horizlinescan5 +2502 vertbar vertconnector +250c topleftradical upleftcorner +2510 uprightcorner +2514 lowleftcorner +2518 lowrightcorner +251c leftt +2524 rightt +252c topt +2534 bott +253c crossinglines +2592 checkerboard +25aa enfilledsqbullet +25ab enopensquarebullet +25ac filledrectbullet +25ad openrectbullet +25ae emfilledrect +25af emopenrectangle +25b2 filledtribulletup +25b3 opentribulletup +25b6 filledrighttribullet +25b7 rightopentriangle +25bc filledtribulletdown +25bd opentribulletdown +25c0 filledlefttribullet +25c1 leftopentriangle +25c6 soliddiamond +25cb circle +25cb emopencircle +25cf emfilledcircle +25e6 enopencircbullet +2606 openstar +260e telephone +2613 signaturemark +261c leftpointer +261e rightpointer +2640 femalesymbol +2642 malesymbol +2663 club +2665 heart +2666 diamond +266d musicalflat +266f musicalsharp +2713 checkmark +2717 ballotcross +271d latincross +2720 maltesecross +3001 kana_comma +3002 kana_fullstop +300c kana_openingbracket +300d kana_closingbracket +309b voicedsound +309c semivoicedsound +30a1 kana_a +30a2 kana_A +30a3 kana_i +30a4 kana_I +30a5 kana_u +30a6 kana_U +30a7 kana_e +30a8 kana_E +30a9 kana_o +30aa kana_O +30ab kana_KA +30ad kana_KI +30af kana_KU +30b1 kana_KE +30b3 kana_KO +30b5 kana_SA +30b7 kana_SHI +30b9 kana_SU +30bb kana_SE +30bd kana_SO +30bf kana_TA +30c1 kana_CHI +30c3 kana_tsu +30c4 kana_TSU +30c6 kana_TE +30c8 kana_TO +30ca kana_NA +30cb kana_NI +30cc kana_NU +30cd kana_NE +30ce kana_NO +30cf kana_HA +30d2 kana_HI +30d5 kana_FU +30d8 kana_HE +30db kana_HO +30de kana_MA +30df kana_MI +30e0 kana_MU +30e1 kana_ME +30e2 kana_MO +30e3 kana_ya +30e4 kana_YA +30e5 kana_yu +30e6 kana_YU +30e7 kana_yo +30e8 kana_YO +30e9 kana_RA +30ea kana_RI +30eb kana_RU +30ec kana_RE +30ed kana_RO +30ef kana_WA +30f2 kana_WO +30f3 kana_N +30fb kana_conjunctive kana_middledot +30fc prolongedsound +- Muhenkan +3131 Hangul_Kiyeog +3132 Hangul_SsangKiyeog +3133 Hangul_KiyeogSios +3134 Hangul_Nieun +3135 Hangul_NieunJieuj +3136 Hangul_NieunHieuh +3137 Hangul_Dikeud +3138 Hangul_SsangDikeud +3139 Hangul_Rieul +313a Hangul_RieulKiyeog +313b Hangul_RieulMieum +313c Hangul_RieulPieub +313d Hangul_RieulSios +313e Hangul_RieulTieut +313f Hangul_RieulPhieuf +3140 Hangul_RieulHieuh +3141 Hangul_Mieum +3142 Hangul_Pieub +3143 Hangul_SsangPieub +3144 Hangul_PieubSios +3145 Hangul_Sios +3146 Hangul_SsangSios +3147 Hangul_Ieung +3148 Hangul_Jieuj +3149 Hangul_SsangJieuj +314a Hangul_Cieuc +314b Hangul_Khieuq +314c Hangul_Tieut +314d Hangul_Phieuf +314e Hangul_Hieuh +314f Hangul_A +3150 Hangul_AE +3151 Hangul_YA +3152 Hangul_YAE +3153 Hangul_EO +3154 Hangul_E +3155 Hangul_YEO +3156 Hangul_YE +3157 Hangul_O +3158 Hangul_WA +3159 Hangul_WAE +315a Hangul_OE +315b Hangul_YO +315c Hangul_U +315d Hangul_WEO +315e Hangul_WE +315f Hangul_WI +3160 Hangul_YU +3161 Hangul_EU +3162 Hangul_YI +3163 Hangul_I +316d Hangul_RieulYeorinHieuh +3171 Hangul_SunkyeongeumMieum +3178 Hangul_SunkyeongeumPieub +317f Hangul_PanSios +3181 Hangul_KkogjiDalrinIeung +3184 Hangul_SunkyeongeumPhieuf +3186 Hangul_YeorinHieuh +318d Hangul_AraeA +318e Hangul_AraeAE +- Alt Alt_Lock +- AltGr AltGr_Lock +- Ascii_0 Ascii_1 Ascii_2 Ascii_3 Ascii_4 +- Ascii_5 Ascii_6 Ascii_7 Ascii_8 Ascii_9 +- Bare_Num_Lock +- Boot - Break -- Last_Console - Caps_Lock -- Num_Lock -- Scroll_Lock -- Scroll_Forward -- Scroll_Backward -- Boot - Caps_On +- CapsShift +- Clear - Compose -- SAK -- Decr_Console -- Incr_Console -- KeyboardSignal -- Bare_Num_Lock -- KP_0 -- KP_1 -- KP_2 -- KP_3 -- KP_4 -- KP_5 -- KP_6 -- KP_7 -- KP_8 -- KP_9 -- KP_Add -- KP_Subtract -- KP_Multiply -- KP_Divide -- KP_Enter -- KP_Comma -- KP_Period -- KP_MinPlus - Console_1 - Console_2 - Console_3 @@ -702,61 +1252,263 @@ - Console_61 - Console_62 - Console_63 +- Control +- Control_Lock +- CtrlL +- CtrlL_Lock +- CtrlR +- CtrlR_Lock +- Decr_Console +- Do - Down +- Eisu_toggle +- Execute +- F1 F2 F3 F4 F5 +- F6 F7 F8 F9 F10 +- F11 F12 F13 F14 F15 +- F16 F17 F18 F19 F20 +- F21 F22 F23 F24 F25 +- F26 F27 F28 F29 F30 +- F31 F32 F33 F34 F35 +- F36 F37 F38 F39 F40 +- F41 F42 F43 F44 F45 +- F46 F47 F48 F49 F50 +- F51 F52 F53 F54 F55 +- F56 F57 F58 F59 F60 +- F61 F62 F63 F64 F65 +- F66 F67 F68 F69 F70 +- F71 F72 F73 F74 F75 +- F76 F77 F78 F79 F80 +- F81 F82 F83 F84 F85 +- F86 F87 F88 F89 F90 +- F91 F92 F93 F94 F95 +- F96 F97 F98 F99 F100 +- F101 F102 F103 F104 F105 +- F106 F107 F108 F109 F110 +- F111 F112 F113 F114 F115 +- F116 F117 F118 F119 F120 +- F121 F122 F123 F124 F125 +- F126 F127 F128 F129 F130 +- F131 F132 F133 F134 F135 +- F136 F137 F138 F139 F140 +- F141 F142 F143 F144 F145 +- F146 F147 F148 F149 F150 +- F151 F152 F153 F154 F155 +- F156 F157 F158 F159 F160 +- F161 F162 F163 F164 F165 +- F166 F167 F168 F169 F170 +- F171 F172 F173 F174 F175 +- F176 F177 F178 F179 F180 +- F181 F182 F183 F184 F185 +- F186 F187 F188 F189 F190 +- F191 F192 F193 F194 F195 +- F196 F197 F198 F199 F200 +- F201 F202 F203 F204 F205 +- F206 F207 F208 F209 F210 +- F211 F212 F213 F214 F215 +- F216 F217 F218 F219 F220 +- F221 F222 F223 F224 F225 +- F226 F227 F228 F229 F230 +- F231 F232 F233 F234 F235 +- F236 F237 F238 F239 F240 +- F241 F242 F243 F244 F245 +- F246 +- Find +- Help +- Hex_0 Hex_1 Hex_2 Hex_3 Hex_4 Hex_5 Hex_6 Hex_7 +- Hex_8 Hex_9 Hex_A Hex_B Hex_C Hex_D Hex_E Hex_F +- Incr_Console +- Insert +- ISO_First_Group +- ISO_Last_Group +- ISO_Left_Tab +- ISO_Level3_Lock +- ISO_Level3_Shift +- ISO_Lock +- ISO_Next_Group +- ISO_Prev_Group +- KeyboardSignal +- KP_0 KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 +- KP_Add +- KP_Begin +- KP_Comma +- KP_Decimal +- KP_Delete +- KP_Divide +- KP_Down +- KP_End +- KP_Enter +- KP_Equal +- KP_Home +- KP_Insert +- KP_Left +- KP_MinPlus +- KP_Multiply +- KP_Next +- KP_Period +- KP_Prior +- KP_Right +- KP_Separator +- KP_Seprator +- KP_Subtract +- KP_Up +- Last_Console - Left +- Macro +- Menu +- Mode_switch +- Multi_key +- Next +- Nosymbol +- Num_Lock +- Pause +- Pointer_EnableKeys +- Print +- Prior +- Redo +- Remove +- Return - Right -- Up +- SAK +- SAlt +- SAltGr +- SControl +- Scroll_Backward +- Scroll_Forward +- Scroll_Lock +- SCtrlL +- SCtrlR +- Select - Shift -- AltGr -- Control -- Alt - ShiftL -- ShiftR -- CtrlL -- CtrlR -- CapsShift -- Ascii_0 -- Ascii_1 -- Ascii_2 -- Ascii_3 -- Ascii_4 -- Ascii_5 -- Ascii_6 -- Ascii_7 -- Ascii_8 -- Ascii_9 -- Hex_0 -- Hex_1 -- Hex_2 -- Hex_3 -- Hex_4 -- Hex_5 -- Hex_6 -- Hex_7 -- Hex_8 -- Hex_9 -- Hex_A -- Hex_B -- Hex_C -- Hex_D -- Hex_E -- Hex_F -- Shift_Lock -- AltGr_Lock -- Control_Lock -- Alt_Lock - ShiftL_Lock +- Shift_Lock +- ShiftR - ShiftR_Lock -- CtrlL_Lock -- CtrlR_Lock +- Show_Memory +- Show_Registers +- Show_State - SShift -- SAltGr -- SControl -- SAlt - SShiftL - SShiftR -- SCtrlL -- SCtrlR +- Super_L +- Super_R +- Sys_Req +- Undo +- Up +- VoidSymbol +- XF86AddFavorite +- XF86ApplicationLeft +- XF86ApplicationRight +- XF86AudioLowerVolume +- XF86AudioMedia +- XF86AudioMute +- XF86AudioNext +- XF86AudioPause +- XF86AudioPlay +- XF86AudioPrev +- XF86AudioRaiseVolume +- XF86AudioRecord +- XF86AudioRewind +- XF86AudioStop +- XF86Away +- XF86Back +- XF86BackForward +- XF86Book +- XF86BrightnessAdjust +- XF86Calculator +- XF86Calendar +- XF86CD +- XF86Clear +- XF86Close +- XF86Community +- XF86ContrastAdjust +- XF86Copy +- XF86Cut +- XF86Display +- XF86Documents +- XF86DOS +- XF86Eject +- XF86Excel +- XF86Explorer +- XF86Favorites +- XF86Finance +- XF86Forward +- XF86Game +- XF86Go +- XF86History +- XF86HomePage +- XF86HotLinks +- XF86Launch0 +- XF86Launch1 +- XF86Launch2 +- XF86Launch3 +- XF86Launch4 +- XF86Launch5 +- XF86LaunchA +- XF86LaunchB +- XF86LaunchC +- XF86LightBulb +- XF86LogOff +- XF86Mail +- XF86MailForward +- XF86Market +- XF86Meeting +- XF86MenuKB +- XF86MenuPB +- XF86Messenger +- XF86Music +- XF86MyComputer +- XF86MySites +- XF86New +- XF86News +- XF86OfficeHome +- XF86Open +- XF86OpenURL +- XF86Option +- XF86Paste +- XF86Phone +- XF86Pictures +- XF86PowerOff +- XF86Q +- XF86Refresh +- XF86Reload +- XF86Reply +- XF86RotateWindows +- XF86RotationKB +- XF86RotationPB +- XF86Save +- XF86ScreenSaver +- XF86ScrollClick +- XF86ScrollDown +- XF86ScrollUp +- XF86Search +- XF86Send +- XF86Shop +- XF86Sleep +- XF86Spell +- XF86SplitScreen +- XF86Standby +- XF86Start +- XF86Stop +- XF86Support +- XF86TaskPane +- XF86Terminal +- XF86Tools +- XF86Travel +- XF86User1KB +- XF86User2KB +- XF86UserPB +- XF86VendorHome +- XF86Video +- XF86WakeUp +- XF86WebCam +- XF86Word +- XF86WWW +- XF86Xfer +- XF86ZoomIn +- XF86ZoomOut +- any = Control_h BackSpace = Control_i Tab = Control_j Linefeed