[OpenBIOS] r816 - cpu/x86/pc/olpc

svn at openbios.org svn at openbios.org
Wed Feb 27 05:40:24 CET 2008


Author: wmb
Date: 2008-02-27 05:40:24 +0100 (Wed, 27 Feb 2008)
New Revision: 816

Added:
   cpu/x86/pc/olpc/parsekbd0.py
Log:
New file parsekbd0.py makes KA tags from old-style tables in Libya and Thailand keyboard wiki pages.


Added: cpu/x86/pc/olpc/parsekbd0.py
===================================================================
--- cpu/x86/pc/olpc/parsekbd0.py	                        (rev 0)
+++ cpu/x86/pc/olpc/parsekbd0.py	2008-02-27 04:40:24 UTC (rev 816)
@@ -0,0 +1,262 @@
+#!/usr/bin/python
+# parsekbd.py
+# Usage:  python parsekbd.py OLPC_Nigeria_Keyboard
+#
+# Gets the wiki page (e.g.) http://wiki.laptop.org/go/OLPC_Nigeria_Keyboard
+# Parses the keyboard table contained therein and converts it to a KA
+# tag per http://wiki.laptop.org/go/Manufacturing_Data#Keyboard_ASCII_Map.
+#
+# The output is stored in a file named (e.g.) OLPC_Nigeria_Keyboard.ka
+#
+# Warnings on standard output tell you if duplicate entries are discarded
+# or if some ASCII characters are not present.
+#
+# In a few cases, this program substitutes dead_{grave,circumflex,tilde}
+# for {grave,asciicircumflex,asciitilde} because the ascii versions are
+# in inaccessible locations (the firmware has only shift, unshift, AltGr
+# maps, so a Shift-AltGr symbol is inaccessible).
+
+from sys import *
+from urllib import *
+from HTMLParser import HTMLParser
+
+lastdata = ""
+indent = 0
+tableseen = False
+keys = 128*[0]
+modifiers = 128*[0]
+column = 0
+keyid = 0
+
+# Convert from textual names of punctuation characters to the ASCII character
+punctuation = {
+  'exclam':ord('!'),
+  'at':ord('@'),
+  'numbersign':ord('#'),
+  'dollar':ord('$'),
+  'percent':ord('%'),
+  'asciicircum':ord('^'),
+  'dead_circumflex':ord('^'),
+  'ampersand':ord('&'),
+  'asterisk':ord('*'),
+  'parenleft':ord('('),
+  'parenright':ord(')'),
+  'underscore':ord('_'),
+  'plus':ord('+'),
+  'minus':ord('-'),
+  'equal':ord('='),
+  'semicolon':ord(';'),
+  'colon':ord(':'),
+  'apostrophe':ord('\''),
+  'grave':ord('`'),
+  'dead_grave':ord('`'),
+  'quotedbl':ord('"'),
+  'dblquote':ord('"'),
+  'bar':ord('|'),
+  'less':ord('<'),
+  'greater':ord('>'),
+  'period':ord('.'),
+  'slash':ord('/'),
+  'backslash':ord('\\'),
+  'question':ord('?'),
+  'comma':ord(','),
+  'bracketleft':ord('['),
+  'bracketright':ord(']'),
+  'braceleft':ord('{'),
+  'braceright':ord('}'),
+  'asciitilde':ord('~') ,
+  'dead_tilde':ord('~') ,
+  'backspace':8,
+  'space':32,
+  'tab':9,
+  'linefeed':10,
+  'enter':13,
+  'esc':27,
+  'escape':27,
+  'del':127,
+  'delete':127,
+  '&amp;':ord('&'),
+  '&lt;':ord('<'),
+  '&gt;':ord('>'),
+}
+
+def string_to_ascii(s):
+        if len(s) == 0:
+                return -1
+        if len(s) == 1:
+                return ord(s)
+        try:
+                i = punctuation[s]
+                return i
+        except:
+                pass
+        if (len(s) == 3) & (s[:2] == 'C-'):
+                return ord(s[2]) & 0x1f
+        return -1
+
+def handle_key(modifier, s):
+        global keyid
+        ascii = string_to_ascii(s)
+        if ascii == -1:
+                return
+        if keys[ascii] != 0:
+                if (ascii >= 0x20) & (((modifier & 1) == 0) & (keys[ascii] != keyid)):
+                        if modifier < modifiers[ascii]:
+                                print "Replacing", chr(ascii), "at keyid", keys[ascii], "modifier", modifiers[ascii], "with keyid", keyid, "modifier", modifier
+                        else:
+                                print "Discarding", chr(ascii), "at keyid", keyid, "modifier", modifier, "because keyid", keys[ascii], "modifier", modifiers[ascii], "is better"
+                        return
+        if ascii < 0x20:
+                if (modifier & 2) != 0:   # ctrl
+                        if keys[ascii + 0x60] == keyid:
+                                return
+                        if keys[ascii + 0x40] == keyid:
+                                return
+        keys[ascii] = keyid
+        modifiers[ascii] = modifier
+
+def do_key():
+        global column, keyid, lastdata
+        s = lastdata.strip()
+        if column == 1:    # row
+                pass
+        elif column == 2:  # Key
+                if s.isdigit():
+                        keyid = int(s)
+        elif column == 3:  # Unmodified
+                handle_key(0,s)
+        elif column == 4:  # Shift
+                handle_key(1,s)
+        elif column == 5:  # AltGR
+                handle_key(4,s)
+        elif column == 6:  # Shift AltGr
+                # handle_key(5,s)
+                pass
+        elif column == 7:  # Ctrl
+                handle_key(2,s)
+        elif column == 8:  # Ctrl Shift
+                handle_key(6,s)
+        elif column == 9:  # Fn
+                handle_key(8,s)
+        elif column == 10:  # comment
+                pass
+        elif column == 11:  # another comment
+                pass
+
+class MyHTMLParser(HTMLParser):
+    def handle_starttag(self, tag, attrs):
+        global column, keyid, indent, lastdata
+        #for i in range(indent):
+        #        print "",
+        #print "<", tag
+        #indent = indent+2
+        if tag == 'tr':
+                column = 0
+                keyid = 0
+        elif tag == 'td':
+                lastdata = ""
+                column = column + 1;
+    
+    def handle_endtag(self, tag):
+        global tableseen, column, keyid, indent
+        #for i in range(indent):
+        #        print "",
+        #print tag,">" 
+        #indent = indent - 2
+        #if indent < 0:
+        #        indent = 0
+
+        if tag == 'table':
+                tableseen = True
+        elif (tag == 'td') & tableseen:
+                do_key()
+    
+    def handle_data(self, data):
+        global lastdata, indent
+        #for i in range(indent):
+        #        print "",
+        #print "{", data, "}"
+        lastdata = lastdata + data.strip()
+        if lastdata.startswith("There is currently no text"):
+                print "No such Wiki page"
+                raise
+
+    def handle_entityref(self, data):
+        global lastdata, indent
+        #for i in range(indent):
+        #        print "",
+        #print "{", data, "}"
+        # print "Entity", data.strip()
+        lastdata = lastdata + "&" + data.strip() + ";"
+
+# This table converts from the IBM physical keystation number to
+# the corresponding scancode value in scan set 1.
+
+#   0     1     3     3     4     5     6     7     8     9
+scan1_map = [
+ 0x00, 0x29, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,    # 0x
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x0e, 0x0f, 0x10, 0x11, 0x12,    # 1x
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x2b,    # 2x
+ 0x3a, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,    # 3x
+ 0x27, 0x28, 0x2b, 0x1c, 0x2a, 0x56, 0x2c, 0x2d, 0x2e, 0x2f,    # 4x
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x73, 0x36, 0x1d, 0x00,    # 5x
+ 0x38, 0x39, 0x38, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00,    # 6x
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    # 7x
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    # 8x
+ 0x45, 0x47, 0x4B, 0x4F, 0x00, 0x00, 0x48, 0x4C, 0x50, 0x52,    # 9x
+ 0x37, 0x49, 0x4D, 0x51, 0x53, 0x4A, 0x4E, 0x00, 0x1c, 0x00,    # 10x 
+ 0x01, 0x00, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42,    # 11x
+ 0x43, 0x44, 0x57, 0x58, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00,    # 12x
+ 0x79, 0x01, 0x00, 0x5c, 0x73, 0x6e, 0x00, 0x00, 0x00, 0x00,    # 13x (analog intermediates)
+ 0x00, 0x00, 0x00, 0x00, 0x00,                                  # 14x
+]
+
+def put_ka_format(outfile):
+        global keys, modifiers
+        # a-z - output scancode only; unshifted map is implied
+        # and shifted map is derived automatically
+        for i in range(ord('a'),ord('a')+26):
+                if (keys[i] == 0):
+                        print "Missing",chr(i)
+                if modifiers[i] != 0:
+                        print chr(i),"is modified"
+                outfile.write(chr(scan1_map[keys[i]]))
+        
+        # Numbers and punctuation - output scancode and keymap number
+        for i in '0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~':
+                ascii = ord(i)
+                if (keys[ascii] == 0):
+                        print "Missing",i
+                if (modifiers[ascii] & 0xa) != 0:
+                        print i,"is Ctrl or Fn"
+                outfile.write(chr(scan1_map[keys[ascii]]))
+                
+                if (modifiers[ascii] & 0x4) != 0:
+                        # modifier & 4 implies AltGr map
+                        outfile.write(chr(2))
+                else:
+                        # otherwise it's either the shift (1) or unshift (0) map
+                        outfile.write(chr(modifiers[ascii] & 1))
+        
+        outfile.write(chr(0))   # Null terminator
+        
+        outfile.write(chr(111 ^ 0xff))
+        outfile.write(chr(111))
+        outfile.write('KA')
+
+if len(argv) != 2:
+        print "Usage: python parsekbd.py PageName"
+else:
+        try:
+                print "Getting",'http://wiki.laptop.org/go/' + argv[1]
+                infile = urlopen('http://wiki.laptop.org/go/' + argv[1])
+                myparser=MyHTMLParser()
+                myparser.feed(infile.read())
+                myparser.close()
+                infile.close()
+                outfile = open(argv[1] + '.ka', 'w')
+                put_ka_format(outfile)
+                outfile.close()
+                print "Output at",argv[1] + '.ka'
+        except:
+                print "Failed"




More information about the OpenBIOS mailing list