use a resource system to load images and stylesheet

This commit is contained in:
Mathieu PATUREL
2019-11-15 07:21:41 +11:00
parent 8c1012eb8c
commit 5f2cac54e8
10 changed files with 48 additions and 13 deletions

View File

@ -6,6 +6,7 @@ from functools import partial
from .markdown2html import markdown2html from .markdown2html import markdown2html
from .utils import * from .utils import *
from .resources import resources
def plugin_loaded(): def plugin_loaded():
pass pass
@ -52,7 +53,6 @@ class OpenMarkdownPreviewCommand(sublime_plugin.TextCommand):
# FIXME: save the document to a temporary file, so that if we crash, # FIXME: save the document to a temporary file, so that if we crash,
# the user doesn't lose what he wrote # the user doesn't lose what he wrote
sublime.run_command('new_window') sublime.run_command('new_window')
preview_window = sublime.active_window() preview_window = sublime.active_window()
@ -183,8 +183,12 @@ class MarkdownLivePreviewListener(sublime_plugin.EventListener):
markdown = markdown_view.substr(total_region) markdown = markdown_view.substr(total_region)
basepath = os.path.dirname(markdown_view.file_name()) basepath = os.path.dirname(markdown_view.file_name())
html = markdown2html(markdown, basepath, partial(self._update_preview, html = markdown2html(
markdown_view)) markdown,
basepath,
partial(self._update_preview, markdown_view),
resources
)
self.phantom_sets[markdown_view.id()].update([ self.phantom_sets[markdown_view.id()].update([
sublime.Phantom(sublime.Region(0), html, sublime.LAYOUT_BLOCK, sublime.Phantom(sublime.Region(0), html, sublime.LAYOUT_BLOCK,

View File

@ -3,7 +3,7 @@ I'm not sure that it **actually** going to work, but it seems nicer than the [pr
This is the first image from the local file system (absolute path, sorry, it's not going This is the first image from the local file system (absolute path, sorry, it's not going
to work on your system unless your username is math2001): to work on your system unless your username is math2001):
![The sublime text logo!](file:///home/math2001/.config/sublime-text-3/Packages/MarkdownLivePreview2/live-testing/sublime_text.png) ![The sublime text logo!](file:///home/math2001/.config/sublime-text-3/Packages/MarkdownLivePreview/live-testing/sublime_text.png)
This is the first image from the local file system, *relative* path! This is the first image from the local file system, *relative* path!

View File

@ -16,16 +16,12 @@ markdowner = Markdown(extras=['fenced-code-blocks'])
# does it stupidly throw them out? (we could implement something of our own) # does it stupidly throw them out? (we could implement something of our own)
executor = concurrent.futures.ThreadPoolExecutor(max_workers=5) executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)
# FIXME: put a nice picture please :^)
BASE64_LOADING_IMAGE = 'loading image!'
BASE64_404_IMAGE = '404 not found :-('
images_cache = {} images_cache = {}
class LoadingError(Exception): class LoadingError(Exception):
pass pass
def markdown2html(markdown, basepath, re_render): def markdown2html(markdown, basepath, re_render, resources):
""" converts the markdown to html, loads the images and puts in base64 for sublime """ 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 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 images from the internet. Hence, we take in re_render, which is just a function we
@ -55,10 +51,9 @@ def markdown2html(markdown, basepath, re_render):
try: try:
base64 = get_base64_image(path, re_render) base64 = get_base64_image(path, re_render)
except FileNotFoundError as e: except FileNotFoundError as e:
base64 = BASE64_404_IMAGE base64 = resources['base64_404_image']
except LoadingError: except LoadingError:
# the image is loading base64 = resources['base64_loading_image']
base64 = BASE64_LOADING_IMAGE
img_element['src'] = base64 img_element['src'] = base64
@ -72,7 +67,7 @@ def markdown2html(markdown, basepath, re_render):
# FIXME: include a stylesheet # FIXME: include a stylesheet
return str(soup) return "<style>\n{}\n</style>\n\n{}".format(resources['stylesheet'], soup)
def get_base64_image(path, re_render): def get_base64_image(path, re_render):
@ -93,6 +88,8 @@ def get_base64_image(path, re_render):
executor.submit(load_image, path).add_done_callback(partial(callback, path)) executor.submit(load_image, path).add_done_callback(partial(callback, path))
raise LoadingError() raise LoadingError()
# FIXME: use some kind of cache for this as well, because it decodes on every
# keystroke here...
with open(path, 'rb') as fp: with open(path, 'rb') as fp:
return 'data:image/png;base64,' + base64.b64encode(fp.read()).decode('utf-8') return 'data:image/png;base64,' + base64.b64encode(fp.read()).decode('utf-8')

17
resources.py Normal file
View File

@ -0,0 +1,17 @@
import os.path
import sublime
def get_resource(resource):
path = 'Packages/MarkdownLivePreview/resources/' + resource
abs_path = os.path.join(sublime.packages_path(), '..', path)
if os.path.isfile(abs_path):
with open(abs_path, 'r') as fp:
return fp.read()
return sublime.load_resource(path)
resources = {}
def plugin_loaded():
resources["base64_loading_image"] = get_resource('loading.base64')
resources["base64_404_image"] = get_resource('404.base64')
resources["stylesheet"] = get_resource('stylesheet.css')

1
resources/404.base64 Normal file

File diff suppressed because one or more lines are too long

BIN
resources/404.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,12 @@
""" A small script to convert the images into base64 data """
# FIXME: ignore this script and the original images in .gitignore so that it pushes to
# the GitHub repository but not package control
from base64 import b64encode
with open('404.png', 'rb') as png, open('404.base64', 'wb') as base64:
base64.write(b64encode(png.read()))
with open('loading.png', 'rb') as png, open('loading.base64', 'wb') as base64:
base64.write(b64encode(png.read()))

1
resources/loading.base64 Normal file
View File

@ -0,0 +1 @@
R0lGODlhZABkAPU+AAAAAAwNDRweHyYpKzg8Pzo+QUBFSERJTEdMT05UV1NYXFVbX1hfY1lfZGFobWJpbmhvdGxzeHF5fnJ6gHV9g3Z+hHqDiXuEin+IjoCIjoKLkYKMkoSNk4eQl4iSmIqTmouUm42XnY+ZoJKco5OdpJOepZSeppahqJeiqZmjqpumrZ6psJ+qsqOutqSvt6SwuKezu6i0vKm1vay4wK66wq+7w6+8xLK+xrK/x7TAybXCy7bDy7jEzbjFzrzJ0gAAACH5BAUAAD4AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAZABkAAAG/kCfcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsHhMLpvP6LR6zW673/C4fE6v2+/4vH7P7/v/gIGCg4SFhoeIiW8IAAAUilUpjQABkEsmMUchkwBIOTOQBQICGUabk0ctFhYdiSajAgOZRKeNRjkYqxaghyuwAgxFtZ1FJBe6NokHvya0nEUzuhYgijG/B86oRCDSOZAPv6VCw0SquiiWNwOwAzfjz0I8uasYPIMvDQ0kRhm/Ee/afKiQ1sIIDBAgkuUxQKDhA29ERMHK9GJSJR85pLUiwkOELgx6Goo0sG/IK1gVhCig9MjHimOreAmBMU+XngciRTrAMSQB/qxmR6KtEjGko7Shey7kbGgA6A0GBz4oOUjCno8YNXWp6NOCwVICD6UYPQqiBiANDHNOkILiqIYVg2Y0yPlAikddICASQtuwJJQY9OAimqFCZpRPei0pPnKjg4fHkB936JBYyg4VmDNrVlH5zYMFoEOLZgDBSoejqDfQEc1atBXUsOl8bi26bpUNsKWpnlPjg+PIj32brZJjs/HOi5PjiMFzCo4ZyAWpqCBhwgspMFa9NZRjg4TvEjZCEQFzWvQ9KiiA/+73SVtpGAT7mcFh/XcPVqH0uCsNhDs+J9gnAQXX+cADCSDMggRVVtGE2lZ6fCAgfkPcdYFhRAhlAVHxxfCnC4d42EdghtII1hYGLgjxki6GOSiNHtR990F+QpymizcZ0SNEjquI1+FHetDHQYFEuCANhBpaMMRAuqRYxEEJDSLPR1YlWVRN9Vjy3ioFCWHlEC6Uh44iOcB0gQck2kSEB90o4sEFx1yY5irQ9JdIDdIANcSXRBiDzGAfVcbnELiwmEgHx3Q5p5JGmOPjIdAF9eIRnyRnhA1AWvqEn4pq6umnoIYq6qiklmrqqaimquqqrLbq6quwxirrrLTWauuttwYBADs=

BIN
resources/loading.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

3
resources/stylesheet.css Normal file
View File

@ -0,0 +1,3 @@
body {
font-family: "Open Sans", sans-serif, serif;
}