Automatically build _Xmodmap and unicode_sampler for posts/Xmodmap.
authorW. Trevor King <wking@drexel.edu>
Wed, 6 Oct 2010 18:05:25 +0000 (14:05 -0400)
committerW. Trevor King <wking@drexel.edu>
Wed, 6 Oct 2010 18:05:25 +0000 (14:05 -0400)
Makefile
index.mdwn
posts/Xmodmap.mdwn
posts/Xmodmap/Makefile [new file with mode: 0644]
posts/Xmodmap/gen_sampler.py [new file with mode: 0755]

index d79c957a917e183311c283c318686fa9869ebc93..60744bb4218cda0fe825e2a455fab6c9fec5bdf7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Build everything necessary to compile the wiki.
 
-SUBDIRS = posts/yacc2dot posts/XSLT/chapter posts/XSLT/code
+SUBDIRS = posts/yacc2dot posts/Xmodmap posts/XSLT/chapter posts/XSLT/code
 TARGETS = all clean
 
 all :
index 4199c42004e9fc9d0580c66e2bffacf67a9fe6d6..1e3ff13a92a243e29759abeb35dd97d975e7f1aa 100644 (file)
@@ -1,4 +1,5 @@
-[[!inline pages="./posts/*" show="10" actions=yes rootpage="posts"]]
+[[!inline pages="./posts/* and !./posts/*/*"
+  show="10" actions=yes rootpage="posts"]]
 
 ----
 
index 448ff00a0627f39541f009b98a8005925574ec85..ad51b096cddccd2682de31444fc5feb93d9a2d60 100644 (file)
@@ -1,10 +1,10 @@
 Remap your keyboard in X!  Ok, so not really a tool, but one of those
 things you wish someone had told you about earlier.  Excellent for
 getting easy access to all those neat [unicode][unicode]
-[[symbols|unicode_sampler]].
+[[symbols|unicode_sampler]] (generated with [[gen_sampler.py]]).
 
-You're welcome to my `~/.Xmodmap` file, which I version with
-[[dotfiles]] so it stays up to date across several computers.
+You're welcome to my [[~/.Xmodmap|_Xmodmap]] file, which I version
+with [[dotfiles]] so it stays up to date across several computers.
 
 [gucharmap][] is a nice tool for finding Unicode encodings for
 whichever character you're looking for.
diff --git a/posts/Xmodmap/Makefile b/posts/Xmodmap/Makefile
new file mode 100644 (file)
index 0000000..b04431d
--- /dev/null
@@ -0,0 +1,21 @@
+REPO = http://www.physics.drexel.edu/~wking/code/git/dotfiles.git/
+PACKAGE = dotfiles
+
+.PHONY : all checkout clean
+
+all : unicode_sampler _Xmodmap
+
+clean :
+       rm -rf $(PACKAGE) unicode_sampler _Xmodmap
+
+$(PACKAGE) : 
+       git clone $(REPO) $@
+
+checkout : $(PACKAGE)
+       git --git-dir $(<:%=%/.git) --work-tree ../ pull
+
+_Xmodmap : checkout
+       cp $(PACKAGE:%=%/$@) $@
+
+unicode_sampler : _Xmodmap gen_sampler.py
+       ./gen_sampler.py $< > $@
diff --git a/posts/Xmodmap/gen_sampler.py b/posts/Xmodmap/gen_sampler.py
new file mode 100755 (executable)
index 0000000..f65b7d3
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# Generate a unicode sampler from an Xmodmap file
+
+ENCODING = 'utf-8'
+XKEYSIMDEF_H = "/usr/include/X11/keysymdef.h"
+
+
+def sample(lines, keysyms):
+    """Conver lines from an Xmodmap file to sampler lines."""
+    for line in lines:
+        # parse line
+        line = line.strip()
+        if not line.startswith('keycode '):
+            continue
+        fields = line.split()
+        # keycode  10 = 1 exclam U2081 onehalf
+        fields = fields + [None] * (7-len(fields))
+        k,keycode,eq,a,b,c,d = fields
+        assert k == 'keycode', k
+        assert eq == '=', eq
+        keycode = int(keycode)
+        if keycode > 100:
+            continue  # control code, not very interesting
+
+        # convert keys to unicode
+        keys = [a,b,c,d]
+        for i,key in enumerate(keys):
+            if key == None:
+                continue
+            if key in keysyms:
+                keys[i] = keysyms[key]
+                continue
+            assert key.startswith('U'), key
+            key = r'\u'+key[len('U'):]
+            keys[i] = unicode(key, 'unicode escape')
+
+        line = (' '.join([key or ' ' for key in keys])).rstrip()
+        if len(line) > 0:
+            yield line
+
+def read_keysyms(file=None):
+    """Read keysymdef.h and extract keysym -> unicode mappings."""
+    if file == None:
+        file = XKEYSIMDEF_H
+    keysyms = {}
+    for line in open(file, 'r').readlines():
+        if not line.startswith('#define XK_'):
+            continue
+        # #define XK_space                         0x0020  /* U+0020 SPACE */
+        fields = line.split()
+        assert len(fields) >= 3, fields
+        keysym = fields[1]
+        code = fields[2]
+        assert keysym.startswith('XK_'), keysym
+        assert code.startswith('0x'), code
+        keysym = keysym[len('XK_'):]
+        if len(fields) >= 5:
+            codepoint = fields[4]
+            if not codepoint.startswith('U+'):
+                codepoint = None
+            else:
+                codepoint = r'\u'+codepoint[len('U+'):]
+                codepoint = unicode(codepoint, 'unicode escape')
+        else:
+            codepoint = None  # keysym to unicode mapping not well defined
+        keysyms[keysym] = codepoint
+    return keysyms
+
+
+if __name__ == '__main__':
+    import sys
+    import time
+
+    xmodmap_filename = sys.argv[1]
+
+    keysyms = read_keysyms()
+    lines = open(xmodmap_filename, 'r').readlines()
+    #lines = sample(lines, keysyms)
+    lines = sorted(sample(lines, keysyms))
+    print 'These characters are bound in my current .Xmodmap'
+    print '(%s)' % time.asctime()
+    print ''
+    for line in lines:
+        print line.encode(ENCODING)