logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

generate_km.py (7581B)


  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import json
  4. import layout
  5. import os
  6. import re
  7. def gen_uc_iter():
  8. length = len(layout.uc_dict)
  9. for key, value in sorted(layout.uc_dict.items()):
  10. length -= 1
  11. if length:
  12. yield (key, value, False)
  13. else:
  14. yield (key, value, True)
  15. def _translate(s):
  16. if re.match("^[0-9]$", s):
  17. return ("KC_{0}".format(s), " {0} ".format(s))
  18. elif re.match("^[a-z]$", s):
  19. return ("KC_{0}".format(s.upper()), " {0} ".format(s))
  20. elif re.match("^[A-Z]$", s):
  21. return ("S(KC_{0})".format(s), " {0} ".format(s))
  22. elif re.match("^F[0-9]{1,2}$", s): # Fn, works from F0 to F99
  23. return ("KC_{0}".format(s), "{0:^7}".format(s))
  24. elif re.match("^DF[0-9]{1,2}$", s): # DFn, works from DF0 to DF99
  25. return ("DF({0})".format(s[2:]), "{0:^7}".format(s))
  26. elif re.match("^MO[0-9]{1,2}$", s): # MOn, works from MO0 to MO99
  27. return ("MO({0})".format(s[2:]), "{0:^7}".format(s))
  28. elif re.match("^OSL[0-9]{1,2}$", s): # OSLn, works from OSL0 to OSL99
  29. return ("OSL({0})".format(s[3:]), "{0:^7}".format(s))
  30. elif re.match("^TG[0-9]{1,2}$", s): # TGn, works from TG0 to TG99
  31. return ("TG({0})".format(s[2:]), "{0:^7}".format(s))
  32. elif re.match("^TO[0-9]{1,2}$", s): # Tn, works from TO0 to TO99
  33. return ("TO({0})".format(s[2:]), "{0:^7}".format(s))
  34. elif re.match("^TT[0-9]{1,2}$", s): # Tn, works from TT0 to TT99
  35. return ("TT({0})".format(s[2:]), "{0:^7}".format(s))
  36. elif s in layout.uc_dict:
  37. return ("UM("+s+")", " {0} ".format(chr(int(layout.uc_dict[s], 0))))
  38. elif s in layout.qmk_dict:
  39. return (layout.qmk_dict[s], "{0:^7}".format(s))
  40. elif s == s.upper() and s.startswith("KC_"):
  41. return (s, "{0:^7}".format(s[2:]))
  42. else:
  43. return ("XXXXXXX", " {0} ".format(chr(128165)))
  44. def toKC(s):
  45. return _translate(s)[0]
  46. def toLgd(s):
  47. return _translate(s)[1]
  48. def quoteC(text):
  49. yield "/*"
  50. for line in text:
  51. yield " * " + line
  52. yield " */\n"
  53. def getKeymapText(id, layer, columns, rows):
  54. keymap = []
  55. keymap.append("Layer %d" % id)
  56. keymap.append("------------------------------------------------- -------------------------------------------------")
  57. keymap.append("|{0}|{1}|{2}|{3}|{4}|{5}| |{6}|{7}|{8}|{9}|{10}|{11}|".format(*map(toLgd, layer[:12])))
  58. keymap.append("------------------------------------------------- -------------------------------------------------")
  59. keymap.append("|{0}|{1}|{2}|{3}|{4}|{5}| |{6}|{7}|{8}|{9}|{10}|{11}|".format(*map(toLgd, layer[12:24])))
  60. keymap.append("------------------------------------------------- -------------------------------------------------")
  61. keymap.append("|{0}|{1}|{2}|{3}|{4}|{5}| |{6}|{7}|{8}|{9}|{10}|{11}|".format(*map(toLgd, layer[24:36])))
  62. keymap.append("-----------------------------------------------------------------------------------------------------------------")
  63. keymap.append(" {0} {1} {2} |{3}|{4}|{5}|{6}|{7}|{8}| {9} {10} {11}".format(*map(toLgd, layer[36:48])).rstrip())
  64. keymap.append(" -------------------------------------------------")
  65. return keymap
  66. def writeKeymap(f_template, f_keymap, layers, columns, rows):
  67. doCopy = False
  68. for line in f_template:
  69. doCopy = True
  70. if line.startswith("//<enum/>"):
  71. doCopy = False
  72. # f_keymap.write(str(layout.uc_dict))
  73. for k, v, isLast in gen_uc_iter():
  74. if isLast:
  75. f_keymap.write(k + "\n")
  76. else:
  77. f_keymap.write(k + ",\n")
  78. elif line.startswith("//<uc_map/>"):
  79. doCopy = False
  80. for k, v, isLast in gen_uc_iter():
  81. if isLast:
  82. f_keymap.write(u"\t[{0}] = {1} // {2}\n".format(k, v, chr(int(v, 0))))
  83. else:
  84. f_keymap.write(u"\t[{0}] = {1}, // {2}\n".format(k, v, chr(int(v, 0))))
  85. elif line.startswith("//<keymaps/>"):
  86. doCopy = False
  87. for layer, L in enumerate(layers):
  88. r_counter = rows
  89. f_keymap.write('\n'.join(quoteC(getKeymapText(layer, L, columns, rows))))
  90. l_code = '\tLAYOUT_ortho_4x12(\n'
  91. for r in range(r_counter):
  92. r_counter -= 1
  93. c_counter = columns
  94. l_code += '\t\t'
  95. for c in range(c_counter):
  96. c_counter -= 1
  97. if c != 0:
  98. l_code += " "
  99. l_code += "%s" % toKC(L[r*columns + columns-c_counter-1])
  100. if r_counter or c_counter:
  101. l_code += ","
  102. l_code += '\n'
  103. if layer + 1 != len(layout.layers):
  104. l_code += "\t),\n\n"
  105. else:
  106. l_code += "\t)\n"
  107. f_keymap.write(l_code)
  108. if doCopy:
  109. f_keymap.write(line)
  110. def getKeymapJSON(keyboard, keymap, layout, layers):
  111. return json.dumps({
  112. 'keyboard': keyboard,
  113. 'keymap': keymap,
  114. 'layout': layout,
  115. 'layers': layers
  116. }, sort_keys=True, indent=4)
  117. def getKeymapAsciidoc(title, layers, columns, rows):
  118. yield '= ' + title
  119. yield ''
  120. for id, layer in enumerate(layers):
  121. keymap = getKeymapText(id, layer, columns, rows)
  122. if len(keymap):
  123. yield '.' + keymap[0]
  124. yield '--------------------------'
  125. for line in keymap[1:]:
  126. yield ' ' + line
  127. yield '--------------------------'
  128. yield ''
  129. def layersToKC(layers):
  130. return [list(map(toKC, layer)) for layer in layers]
  131. def pathToKeymap(path):
  132. head, keymap = os.path.split(path)
  133. _, keymapsdir = os.path.split(head)
  134. if keymapsdir == 'keymaps':
  135. return keymap
  136. def pathToKeyboard(path):
  137. head, keymap = os.path.split(path)
  138. head, keymapsdir = os.path.split(head)
  139. if keymapsdir == 'keymaps':
  140. head, dir = os.path.split(head)
  141. while dir not in ('/', 'keyboards'):
  142. yield dir
  143. head, dir = os.path.split(head)
  144. if __name__ == "__main__":
  145. with open("km_template.txt", mode="r") as f_template:
  146. with open("keymap.c", mode="w", encoding='utf-8') as f_keymap:
  147. writeKeymap(f_template, f_keymap, layout.layers, columns=12, rows=4)
  148. abspath = os.path.dirname(os.path.abspath(__file__))
  149. keyboard = list(reversed(list(pathToKeyboard(abspath))))
  150. keymap = pathToKeymap(abspath)
  151. keyboard_layout = 'LAYOUT_ortho_4x12'
  152. with open("%s_%s.json" % ('_'.join(keyboard), keymap), mode="w") as f_keymapjson:
  153. f_keymapjson.write(
  154. getKeymapJSON(
  155. '/'.join(keyboard),
  156. keymap,
  157. keyboard_layout,
  158. layersToKC(layout.layers))
  159. )
  160. with open("keymap.adoc", mode="w") as f_keymapasciidoc:
  161. f_keymapasciidoc.write('\n'.join(getKeymapAsciidoc('Signum 3.0 %s_%s' % ('_'.join(keyboard), keymap), layout.layers, columns=12, rows=4)))
  162. print("Run the following command to generate a PDF from the keymap")
  163. print("a2x -f pdf --xsltproc-opts '--stringparam page.orientation landscape --stringparam body.font.master 12' --fop -v keymap.adoc")