ahem-generate-table.py (2893B)
1 import itertools 2 import unicodedata 3 4 from fontTools.ttLib import TTFont 5 6 try: 7 chr(0x100) 8 except ValueError: 9 chr = unichr 10 11 def grouper(n, iterable): 12 """ 13 >>> list(grouper(3, 'ABCDEFG')) 14 [['A', 'B', 'C'], ['D', 'E', 'F'], ['G']] 15 """ 16 iterable = iter(iterable) 17 return iter(lambda: list(itertools.islice(iterable, n)), []) 18 19 ttf = TTFont("../../../fonts/Ahem.ttf") 20 21 chars = {char for table in ttf['cmap'].tables for char in table.cmap.keys()} 22 23 # exclude chars that can't be represented as HTML numeric character refs 24 chars = chars - (set(range(0x80, 0x9F+1)) | {0x00}) 25 26 chars_sorted = sorted(chars) 27 28 per_row = 17 29 30 31 doctype = "<!doctype html>" 32 title = "<title>Ahem checker</title>" 33 style_open = """ 34 <style> 35 * { 36 padding: 0; 37 margin: 0; 38 border: none; 39 } 40 td { 41 width: 34px; 42 }""".strip() 43 style_close = "</style>" 44 style_font_face = """ 45 @font-face { 46 font-family: Ahem; 47 src: url("../../fonts/Ahem.ttf"); 48 }""".strip() 49 style_table_font_specified = """ 50 table { 51 font: 15px/1 Ahem; 52 border-collapse: separate; 53 border-spacing: 1px; 54 table-layout: fixed; 55 }""".strip() 56 style_table_font_unspecified = """ 57 table { 58 font-size: 15px; 59 line-height: 1; 60 border-collapse: separate; 61 border-spacing: 1px; 62 table-layout: fixed; 63 }""".strip() 64 65 66 def build_header(is_test, rel, href): 67 rv = [doctype, title] 68 69 if rel != None and href != None: 70 rv.append('<link rel="%s" href="%s">' % (rel, href)) 71 72 rv.append(style_open) 73 74 if not is_test: 75 if rel == None and href == None: 76 # ahem-notref.html 77 rv.append(style_table_font_unspecified) 78 else: 79 # ahem-ref.html 80 rv.append(style_font_face) 81 rv.append(style_table_font_specified) 82 else: 83 # ahem.html 84 rv.append(style_table_font_specified) 85 86 rv.append(style_close) 87 88 return "\n".join(rv) 89 90 91 def build_table(): 92 rv = ["\n"] 93 94 rv.append("<table>\n") 95 for row in grouper(per_row, chars_sorted): 96 rv.append(" " * 4 + "<tr>\n") 97 for codepoint in row: 98 assert codepoint <= 0xFFFF 99 try: 100 name = unicodedata.name(chr(codepoint)) 101 except ValueError: 102 rv.append(" " * 8 + "<td>&#x%04X;x <!-- U+%04X -->\n" % (codepoint, codepoint)) 103 else: 104 rv.append(" " * 8 + "<td>&#x%04X;x <!-- U+%04X: %s -->\n" % (codepoint, codepoint, name)) 105 rv.append("</table>\n") 106 107 return "".join(rv) 108 109 110 cases = [ 111 # file, is_test, rel 112 ("../ahem.html", True, "mismatch"), 113 ("../ahem-notref.html", False, None), 114 ] 115 116 table = build_table() 117 118 for index, case in enumerate(cases): 119 next_index = index + 1 120 file, is_test, rel = case 121 href = cases[next_index][0][3:] if next_index < len(cases) else None 122 header = build_header(is_test, rel, href) 123 124 with open(file, "w") as file: 125 file.write("%s%s" % (header, table))