Format everything with black
Follow the readme's instruction haha
This commit is contained in:
@ -9,9 +9,9 @@ from functools import lru_cache, partial
|
||||
|
||||
from .lib.markdown2 import Markdown
|
||||
|
||||
__all__ = ('markdown2html', )
|
||||
__all__ = ("markdown2html",)
|
||||
|
||||
markdowner = Markdown(extras=['fenced-code-blocks'])
|
||||
markdowner = Markdown(extras=["fenced-code-blocks"])
|
||||
|
||||
# FIXME: how do I choose how many workers I want? Does thread pool reuse threads or
|
||||
# does it stupidly throw them out? (we could implement something of our own)
|
||||
@ -19,9 +19,11 @@ executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)
|
||||
|
||||
images_cache = {}
|
||||
|
||||
|
||||
class LoadingError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def markdown2html(markdown, basepath, re_render, resources):
|
||||
""" converts the markdown to html, loads the images and puts in base64 for sublime
|
||||
to understand them correctly. That means that we are responsible for loading the
|
||||
@ -31,19 +33,19 @@ def markdown2html(markdown, basepath, re_render, resources):
|
||||
html = markdowner.convert(markdown)
|
||||
|
||||
soup = bs4.BeautifulSoup(html, "html.parser")
|
||||
for img_element in soup.find_all('img'):
|
||||
src = img_element['src']
|
||||
for img_element in soup.find_all("img"):
|
||||
src = img_element["src"]
|
||||
|
||||
# already in base64, or something of the like
|
||||
# FIXME: what other types are possible? Are they handled by ST? If not, could we
|
||||
# convert it into base64? is it worth the effort?
|
||||
if src.startswith('data:image/'):
|
||||
if src.startswith("data:image/"):
|
||||
continue
|
||||
|
||||
if src.startswith('http://') or src.startswith('https://'):
|
||||
if src.startswith("http://") or src.startswith("https://"):
|
||||
path = src
|
||||
elif src.startswith('file://'):
|
||||
path = src[len('file://'):]
|
||||
elif src.startswith("file://"):
|
||||
path = src[len("file://") :]
|
||||
else:
|
||||
# expanduser: ~ -> /home/math2001
|
||||
# realpath: simplify that paths so that we don't have duplicated caches
|
||||
@ -52,39 +54,45 @@ def markdown2html(markdown, basepath, re_render, resources):
|
||||
try:
|
||||
base64 = get_base64_image(path, re_render)
|
||||
except FileNotFoundError as e:
|
||||
base64 = resources['base64_404_image']
|
||||
base64 = resources["base64_404_image"]
|
||||
except LoadingError:
|
||||
base64 = resources['base64_loading_image']
|
||||
base64 = resources["base64_loading_image"]
|
||||
|
||||
img_element['src'] = base64
|
||||
img_element["src"] = base64
|
||||
|
||||
# remove comments, because they pollute the console with error messages
|
||||
for comment_element in soup.find_all(text=lambda text: isinstance(text, bs4.Comment)):
|
||||
for comment_element in soup.find_all(
|
||||
text=lambda text: isinstance(text, bs4.Comment)
|
||||
):
|
||||
comment_element.extract()
|
||||
|
||||
# FIXME: how do tables look? should we use ascii tables?
|
||||
|
||||
# pre aren't handled by ST3. The require manual adjustment
|
||||
for pre_element in soup.find_all('pre'):
|
||||
for pre_element in soup.find_all("pre"):
|
||||
# select the first child, <code>
|
||||
code_element = next(pre_element.children)
|
||||
|
||||
# FIXME: this method sucks, but can we do better?
|
||||
fixed_pre = str(code_element) \
|
||||
.replace(' ', '<i class="space">.</i>') \
|
||||
.replace('\n', '<br />')
|
||||
fixed_pre = (
|
||||
str(code_element)
|
||||
.replace(" ", '<i class="space">.</i>')
|
||||
.replace("\n", "<br />")
|
||||
)
|
||||
|
||||
code_element.replace_with(bs4.BeautifulSoup(fixed_pre, "html.parser"))
|
||||
|
||||
# FIXME: highlight the code using Sublime's syntax
|
||||
|
||||
# FIXME: report that ST doesn't support <br/> but does work with <br />... WTF?
|
||||
return "<style>\n{}\n</style>\n\n{}".format(resources['stylesheet'], soup).replace('<br/>', '<br />')
|
||||
return "<style>\n{}\n</style>\n\n{}".format(resources["stylesheet"], soup).replace(
|
||||
"<br/>", "<br />"
|
||||
)
|
||||
|
||||
|
||||
def get_base64_image(path, re_render):
|
||||
|
||||
def callback(url, future):
|
||||
# this is "safe" to do because callback is called in the same thread as
|
||||
# this is "safe" to do because callback is called in the same thread as
|
||||
# add_done_callback:
|
||||
# > Added callables are called in the order that they were added and are always
|
||||
# > called in a thread belonging to the process that added them
|
||||
@ -94,7 +102,7 @@ def get_base64_image(path, re_render):
|
||||
# will read from the cache
|
||||
re_render()
|
||||
|
||||
if path.startswith('http://') or path.startswith('https://'):
|
||||
if path.startswith("http://") or path.startswith("https://"):
|
||||
if path in images_cache:
|
||||
return images_cache[path]
|
||||
executor.submit(load_image, path).add_done_callback(partial(callback, path))
|
||||
@ -102,8 +110,9 @@ def get_base64_image(path, re_render):
|
||||
|
||||
# FIXME: use some kind of cache for this as well, because it decodes on every
|
||||
# keystroke here...
|
||||
with open(path, 'rb') as fp:
|
||||
return 'data:image/png;base64,' + base64.b64encode(fp.read()).decode('utf-8')
|
||||
with open(path, "rb") as fp:
|
||||
return "data:image/png;base64," + base64.b64encode(fp.read()).decode("utf-8")
|
||||
|
||||
|
||||
# FIXME: wait what the hell? Why do I have two caches? (lru and images_cache)
|
||||
# FIXME: This is an in memory cache. 20 seems like a fair bit of images... Should it be
|
||||
@ -114,6 +123,10 @@ def get_base64_image(path, re_render):
|
||||
def load_image(url):
|
||||
with urllib.request.urlopen(url, timeout=60) as conn:
|
||||
content_type = conn.info().get_content_type()
|
||||
if 'image' not in content_type:
|
||||
raise ValueError("{!r} doesn't point to an image, but to a {!r}".format(url, content_type))
|
||||
return 'data:image/png;base64,' + base64.b64encode(conn.read()).decode('utf-8')
|
||||
if "image" not in content_type:
|
||||
raise ValueError(
|
||||
"{!r} doesn't point to an image, but to a {!r}".format(
|
||||
url, content_type
|
||||
)
|
||||
)
|
||||
return "data:image/png;base64," + base64.b64encode(conn.read()).decode("utf-8")
|
||||
|
||||
Reference in New Issue
Block a user