generate-emoji-picker.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #!/usr/bin/env python3
  2. import json
  3. GROUPS_JSON = '../../../twemoji-picker/generated/groups.json'
  4. # Load and group emoji data
  5. with open(GROUPS_JSON, 'r') as f:
  6. groups = json.loads(f.read())
  7. # Define category order
  8. category_order = [
  9. {'id': 'people', 'name': 'Smileys & People'},
  10. {'id': 'nature', 'name': 'Animals & Nature'},
  11. {'id': 'food', 'name': 'Food & Drink'},
  12. {'id': 'activity', 'name': 'Activity'},
  13. {'id': 'travel', 'name': 'Travel & Places'},
  14. {'id': 'objects', 'name': 'Objects'},
  15. {'id': 'symbols', 'name': 'Symbols'},
  16. {'id': 'flags', 'name': 'Flags'},
  17. ]
  18. # Helper functions
  19. def make_hexchar(codepoint):
  20. return '&#x%s;' % codepoint.replace('-', ';&#x')
  21. # Data extracted from http://xahlee.info/comp/text_vs_emoji.html
  22. text_default_codepoints = [
  23. '1f004', '1f170', '1f171', '1f17e', '1f17f', '1f202', '1f237', '1f321',
  24. '1f324', '1f325', '1f326', '1f327', '1f328', '1f329', '1f32a', '1f32b',
  25. '1f32c', '1f336', '1f37d', '1f396', '1f397', '1f399', '1f39a', '1f39b',
  26. '1f39e', '1f39f', '1f3cb', '1f3cc', '1f3cd', '1f3ce', '1f3d4', '1f3d5',
  27. '1f3d6', '1f3d7', '1f3d8', '1f3d9', '1f3da', '1f3db', '1f3dc', '1f3dd',
  28. '1f3de', '1f3df', '1f3f3', '1f3f5', '1f3f7', '1f43f', '1f441', '1f4fd',
  29. '1f549', '1f54a', '1f56f', '1f570', '1f573', '1f574', '1f575', '1f576',
  30. '1f577', '1f578', '1f579', '1f587', '1f58a', '1f58b', '1f58c', '1f58d',
  31. '1f590', '1f5a5', '1f5a8', '1f5b1', '1f5b2', '1f5bc', '1f5c2', '1f5c3',
  32. '1f5c4', '1f5d1', '1f5d2', '1f5d3', '1f5dc', '1f5dd', '1f5de', '1f5e1',
  33. '1f5e3', '1f5e8', '1f5ef', '1f5f3', '1f5fa', '1f6cb', '1f6cd', '1f6ce',
  34. '1f6cf', '1f6e0', '1f6e1', '1f6e2', '1f6e3', '1f6e4', '1f6e5', '1f6e9',
  35. '1f6f0', '1f6f3', '203c', '2049', '2122', '2139', '2196', '2197', '2198',
  36. '2199', '21a9', '21aa', '2328', '23cf', '23ed', '23ee', '23ef', '23f1',
  37. '23f2', '23f8', '23f9', '23fa', '24c2', '25ab', '25fb', '25fc', '2600',
  38. '2602', '2603', '2604', '2618', '2620', '2622', '2623', '2626', '262e',
  39. '2640', '2642', '265f', '2668', '267b', '267e', '2692', '2694', '2695',
  40. '2696', '2697', '2699', '269b', '269c', '26a0', '26b0', '26b1', '26c8',
  41. '26cf', '26d1', '26d3', '26e9', '26f0', '26f1', '26f4', '26f7', '26f8',
  42. '26f9', '2934', '2935', '2b05', '2b06', '2b07', '2b50', '3030', '303d',
  43. '3297', '3299', 'a9', 'ae',
  44. ]
  45. def is_text_default(codepoint):
  46. """
  47. Temporary hack, see https://github.com/milesj/emojibase/issues/37.
  48. """
  49. return codepoint in text_default_codepoints
  50. # Generate HTML
  51. print('<div class="twemoji-picker" data-skintone="0">')
  52. for i, category in enumerate(category_order):
  53. print(' <div class="tab">')
  54. print(' <input type="radio" id="tab-%d" name="tabs"%s>' % (i, ' checked' if i == 0 else ''))
  55. print(' <label for="tab-{0}" title="{1}" aria-label="{1} Emoji">'.format(i, category['name']))
  56. print(' <img src="emoji/{0}.svg" class="em-{0}" height="24" width="24" role="button" tabindex="0"></span>'.format(category['id']))
  57. print(' </label>')
  58. print(' <div class="content" role="listbox">')
  59. def print_emoji(emoji):
  60. if emoji['representation'] == 'text-default' or is_text_default(emoji['codepoint']):
  61. hex_codepoint = emoji['codepoint'].lower() + '-fe0f'
  62. else:
  63. hex_codepoint = emoji['codepoint'].lower()
  64. print(' ', end='')
  65. print('<span class="em em-{}-{}"'.format(category['id'], emoji['codepoint'].lower()), end='')
  66. print(' role="option" tabindex="0"', end='')
  67. print(' data-c="{}"'.format(emoji['codepoint'].lower()), end='')
  68. print(' data-s="{}"'.format(emoji['shortname']), end='')
  69. if 'skins' in emoji:
  70. print(' data-t="0"', end='')
  71. if 'skintone' in emoji:
  72. print(' data-t="{}"'.format(emoji['skintone']), end='')
  73. print(' title="{}"'.format(emoji['name']), end='')
  74. print('>{}</span>'.format(make_hexchar(hex_codepoint)))
  75. for emoji in groups[category['id']]:
  76. if 'gender' in emoji and emoji['gender'] is None:
  77. # Skip gender-neutral emoji if gendered versions are available
  78. continue
  79. print_emoji(emoji)
  80. print(' </div>')
  81. print(' </div>')
  82. print(' <div class="skins">')
  83. print(' <img src="emoji/tone0.svg" width="24" height="24" data-tone="0" title="No Skin Tone" role="option" tabindex="0">')
  84. print(' <img src="emoji/tone1.svg" width="24" height="24" data-tone="1" title="Light Skin Tone" role="option" tabindex="0">')
  85. print(' <img src="emoji/tone2.svg" width="24" height="24" data-tone="2" title="Medium-Light Skin Tone" role="option" tabindex="0">')
  86. print(' <img src="emoji/tone3.svg" width="24" height="24" data-tone="3" title="Medium Skin Tone" role="option" tabindex="0">')
  87. print(' <img src="emoji/tone4.svg" width="24" height="24" data-tone="4" title="Medium-Dark Skin Tone" role="option" tabindex="0">')
  88. print(' <img src="emoji/tone5.svg" width="24" height="24" data-tone="5" title="Dark Skin Tone" role="option" tabindex="0">')
  89. print(' </div>')
  90. print('</div>')