emoji.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """
  2. Emoji extras for Material.
  3. Override the indexes with an extended version that includes short names for Material icons, FontAwesome, etc.
  4. """
  5. import os
  6. import glob
  7. import copy
  8. import codecs
  9. import inspect
  10. import material
  11. import pymdownx
  12. from pymdownx.emoji import TWEMOJI_SVG_CDN, add_attriubtes
  13. import xml.etree.ElementTree as etree # noqa: N813
  14. OPTION_SUPPORT = pymdownx.__version_info__ >= (7, 1, 0)
  15. RESOURCES = os.path.dirname(inspect.getfile(material))
  16. def _patch_index(options):
  17. """Patch the given index."""
  18. import pymdownx.twemoji_db as twemoji_db
  19. # Copy the Twemoji index
  20. index = {
  21. "name": 'twemoji',
  22. "emoji": copy.deepcopy(twemoji_db.emoji) if not OPTION_SUPPORT else twemoji_db.emoji,
  23. "aliases": copy.deepcopy(twemoji_db.aliases) if not OPTION_SUPPORT else twemoji_db.aliases
  24. }
  25. icon_locations = options.get('custom_icons', [])
  26. icon_locations.append(os.path.join(RESOURCES, '.icons'))
  27. # Find our icons
  28. for icon_path in icon_locations:
  29. norm_base = icon_path.replace('\\', '/') + '/'
  30. for result in glob.glob(icon_path.replace('\\', '/') + '/**/*.svg', recursive=True):
  31. name = ':{}:'.format(result.replace('\\', '/').replace(norm_base, '', 1).replace('/', '-').lstrip('.')[:-4])
  32. if name not in index['emoji'] and name not in index['aliases']:
  33. # Easiest to just store the path and pull it out from the index
  34. index["emoji"][name] = {'name': name, 'path': result}
  35. return index
  36. if OPTION_SUPPORT: # pragma: no cover
  37. def twemoji(options, md):
  38. """Provide a copied Twemoji index with additional codes for Material included icons."""
  39. return _patch_index(options)
  40. else: # pragma: no cover
  41. def twemoji():
  42. """Provide a copied Twemoji index with additional codes for Material included icons."""
  43. return _patch_index({})
  44. def to_svg(index, shortname, alias, uc, alt, title, category, options, md):
  45. """Return SVG element."""
  46. is_unicode = uc is not None
  47. if is_unicode:
  48. # Handle Twemoji emoji.
  49. svg_path = TWEMOJI_SVG_CDN
  50. attributes = {
  51. "class": options.get('classes', index),
  52. "alt": alt,
  53. "src": "%s%s.svg" % (
  54. options.get('image_path', svg_path),
  55. uc
  56. )
  57. }
  58. if title:
  59. attributes['title'] = title
  60. add_attriubtes(options, attributes)
  61. return etree.Element("img", attributes)
  62. else:
  63. # Handle Material SVG assets.
  64. el = etree.Element('span', {"class": options.get('classes', index)})
  65. svg_path = md.inlinePatterns['emoji'].emoji_index['emoji'][shortname]['path']
  66. with codecs.open(svg_path, 'r', encoding='utf-8') as f:
  67. el.text = md.htmlStash.store(f.read())
  68. return el