Viewing images works for local files
We have to make sure that everything is converted to base64 (and replaced in the src attribute) because otherwise ST3 messes up the height of the images
This commit is contained in:
69
markdown2html.py
Normal file
69
markdown2html.py
Normal file
@ -0,0 +1,69 @@
|
||||
import base64
|
||||
import os.path
|
||||
from functools import lru_cache
|
||||
from .lib.markdown2 import Markdown
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
__all__ = ('markdown2html', )
|
||||
|
||||
markdowner = Markdown()
|
||||
|
||||
# FIXME: put a nice picture please :^)
|
||||
BASE64_LOADING_IMAGE = 'loading image!'
|
||||
BASE64_404_IMAGE = '404 not found :-('
|
||||
|
||||
class LoadingError(Exception):
|
||||
pass
|
||||
|
||||
def markdown2html(markdown, basepath, re_render):
|
||||
""" 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
|
||||
images from the internet. Hence, we take in re_render, which is just a function we
|
||||
call when an image has finished loading to retrigger a render (see #90)
|
||||
"""
|
||||
html = markdowner.convert(markdown)
|
||||
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
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/'):
|
||||
continue
|
||||
|
||||
if src.startswith('http://') or src.startswith('https://'):
|
||||
path = src
|
||||
elif src.startswith('file://'):
|
||||
path = src[len('file://'):]
|
||||
else:
|
||||
# expanduser: ~ -> /home/math2001
|
||||
# realpath: simplify that paths so that we don't have duplicated caches
|
||||
path = os.path.realpath(os.path.expanduser(os.path.join(basepath, src)))
|
||||
|
||||
try:
|
||||
base64 = get_base64_image(path)
|
||||
except FileNotFoundError as e:
|
||||
print("{!r} not found {!r}".format(path, e))
|
||||
base64 = BASE64_404_IMAGE
|
||||
except LoadingError:
|
||||
# the image is loading
|
||||
base64 = BASE64_LOADING_IMAGE
|
||||
|
||||
img_element['src'] = base64
|
||||
|
||||
# FIXME: how do tables look? should we use ascii tables?
|
||||
|
||||
return str(soup)
|
||||
|
||||
# FIXME: This is an in memory cache. 20 seems like a fair bit of images... Should it be
|
||||
# bigger? Should the user be allowed to chose? There definitely should be a limit
|
||||
# because we don't wanna use to much memory, we're a simple markdown preview plugin
|
||||
@lru_cache(maxsize=20)
|
||||
def get_base64_image(path):
|
||||
if path.startswith('http://') or path.startswith('https://'):
|
||||
return 'loading of the internet!'
|
||||
|
||||
with open(path, 'rb') as fp:
|
||||
return 'data:image/png;base64,' + base64.b64encode(fp.read()).decode('utf-8')
|
||||
|
||||
Reference in New Issue
Block a user