Created
July 21, 2022 11:56
-
-
Save agoose77/6d35a2066c6e9a95ea9538b0ef673706 to your computer and use it in GitHub Desktop.
Sphinx extension to render emojis in XeLaTeX using emojicdn
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import pathlib | |
import os | |
import re | |
from sphinx.util import logging | |
logger = logging.getLogger(__name__) | |
def emoji_to_identifier(emoji): | |
return ord(emoji) | |
def parse_emoji_whitelist(whitelist): | |
emoji = [] | |
for entry in whitelist: | |
from_, _, to = entry.partition(":") | |
if not to: | |
to = from_ | |
emoji.extend([ | |
chr(c) for c in range(ord(from_), ord(to)+1) | |
]) | |
return emoji | |
def ensure_emoji_cache(cache_path, emoji, style): | |
for symbol in emoji: | |
# Find name of emoji | |
symbol_path = cache_path / f"{emoji_to_identifier(symbol)}.png" | |
if symbol_path.exists(): | |
continue | |
logger.info(f"Could not find emoji: {symbol}, downloading...") | |
# Request from CDN | |
symbol_quote = requests.utils.quote(symbol) | |
response = requests.get( | |
f"https://emojicdn.elk.sh/{symbol_quote}", | |
params={"style": style} | |
) | |
with symbol_path.open("wb") as f: | |
f.write(response.content) | |
def update_latex_preamble(cache_path, emoji, config): | |
include = r""" | |
\usepackage{newunicodechar} | |
""" | |
cache_command = rf""" | |
\providecommand{{\emojicachepath}}[1]{{{cache_path}/#1}} | |
""" | |
emoji_command = r""" | |
\newcommand{\staticemoji}[1]{% | |
\bgroup\raisebox{-0.15em}{% | |
\includegraphics[height=1em]{\emojicachepath{#1}}% | |
}\egroup% | |
} | |
""" | |
# Translate unicode into \includegraphics commands | |
declarations = [ | |
rf"\newunicodechar{{{x}}}{{\staticemoji{{{emoji_to_identifier(x)}}}}}" | |
for x in emoji | |
] | |
preamble = include + cache_command + emoji_command + "\n".join(declarations) | |
config['latex_elements']['preamble'] = config['latex_elements'].get('preamble', '') + preamble | |
def setup_emoji_cache(app, config): | |
cache_path = pathlib.Path(config.emoji_cache).absolute() | |
cache_path.mkdir(exist_ok=True, parents=True) | |
emoji = parse_emoji_whitelist(config.emoji_whitelist) | |
ensure_emoji_cache(cache_path, emoji, config.emoji_style) | |
update_latex_preamble(cache_path, emoji, config) | |
def setup(app): | |
app.add_config_value("emoji_whitelist", [], "html", [list]) | |
app.add_config_value("emoji_cache", ".emoji", "html", [str, bytes, os.PathLike]) | |
app.add_config_value("emoji_style", "google", "html", [str]) | |
app.connect('config-inited', setup_emoji_cache) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Inspired by https://github.com/mreq/xelatex-emoji/
Only supports single-codepoint emoji