Format everything with black

Follow the readme's instruction haha
This commit is contained in:
Mathieu PATUREL
2019-11-16 09:54:07 +11:00
parent e13842ede4
commit 2785df74ce
5 changed files with 875 additions and 551 deletions

View File

@ -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")