diff --git a/MarkdownLivePreview.py b/MarkdownLivePreview.py index 5bc40fb..5f99e63 100644 --- a/MarkdownLivePreview.py +++ b/MarkdownLivePreview.py @@ -6,6 +6,7 @@ from functools import partial from .markdown2html import markdown2html from .utils import * +from .resources import resources def plugin_loaded(): pass @@ -52,7 +53,6 @@ class OpenMarkdownPreviewCommand(sublime_plugin.TextCommand): # FIXME: save the document to a temporary file, so that if we crash, # the user doesn't lose what he wrote - sublime.run_command('new_window') preview_window = sublime.active_window() @@ -183,8 +183,12 @@ class MarkdownLivePreviewListener(sublime_plugin.EventListener): markdown = markdown_view.substr(total_region) basepath = os.path.dirname(markdown_view.file_name()) - html = markdown2html(markdown, basepath, partial(self._update_preview, - markdown_view)) + html = markdown2html( + markdown, + basepath, + partial(self._update_preview, markdown_view), + resources + ) self.phantom_sets[markdown_view.id()].update([ sublime.Phantom(sublime.Region(0), html, sublime.LAYOUT_BLOCK, diff --git a/live-testing/images.md b/live-testing/images.md index 268e112..734f94e 100644 --- a/live-testing/images.md +++ b/live-testing/images.md @@ -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 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! diff --git a/markdown2html.py b/markdown2html.py index 3d4792c..04430ca 100644 --- a/markdown2html.py +++ b/markdown2html.py @@ -16,16 +16,12 @@ markdowner = Markdown(extras=['fenced-code-blocks']) # does it stupidly throw them out? (we could implement something of our own) 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 = {} class LoadingError(Exception): 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 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 @@ -55,10 +51,9 @@ def markdown2html(markdown, basepath, re_render): try: base64 = get_base64_image(path, re_render) except FileNotFoundError as e: - base64 = BASE64_404_IMAGE + base64 = resources['base64_404_image'] except LoadingError: - # the image is loading - base64 = BASE64_LOADING_IMAGE + base64 = resources['base64_loading_image'] img_element['src'] = base64 @@ -72,7 +67,7 @@ def markdown2html(markdown, basepath, re_render): # FIXME: include a stylesheet - return str(soup) + return "\n\n{}".format(resources['stylesheet'], soup) 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)) 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: return 'data:image/png;base64,' + base64.b64encode(fp.read()).decode('utf-8') diff --git a/resources.py b/resources.py new file mode 100644 index 0000000..cecc707 --- /dev/null +++ b/resources.py @@ -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') diff --git a/resources/404.base64 b/resources/404.base64 new file mode 100644 index 0000000..d82c610 --- /dev/null +++ b/resources/404.base64 @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/resources/404.png b/resources/404.png new file mode 100644 index 0000000..af1ef6a Binary files /dev/null and b/resources/404.png differ diff --git a/resources/convertresources.py b/resources/convertresources.py new file mode 100644 index 0000000..eb78792 --- /dev/null +++ b/resources/convertresources.py @@ -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())) diff --git a/resources/loading.base64 b/resources/loading.base64 new file mode 100644 index 0000000..3fcbe3d --- /dev/null +++ b/resources/loading.base64 @@ -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= \ No newline at end of file diff --git a/resources/loading.png b/resources/loading.png new file mode 100644 index 0000000..183ae2d Binary files /dev/null and b/resources/loading.png differ diff --git a/resources/stylesheet.css b/resources/stylesheet.css new file mode 100644 index 0000000..12780e3 --- /dev/null +++ b/resources/stylesheet.css @@ -0,0 +1,3 @@ +body { + font-family: "Open Sans", sans-serif, serif; +} \ No newline at end of file