preview markdown working

This commit is contained in:
Mathieu PATUREL
2017-01-04 12:24:05 +11:00
parent ac09c523e7
commit 6ad9e79926
6 changed files with 154 additions and 2 deletions

View File

@ -3,9 +3,20 @@
import sublime import sublime
import sublime_plugin import sublime_plugin
import os.path
from html.parser import HTMLParser
from .lib import markdown2
from .escape_amp import *
from .functions import * from .functions import *
from .setting_names import * from .setting_names import *
__folder__ = os.path.dirname(__file__)
STYLE_FILE = os.path.join(os.path.dirname(__folder__), 'User',
'MarkdownLivePreview.css')
DEFAULT_STYLE_FILE = os.path.join(__folder__, 'default.css')
def get_preview_name(md_view): def get_preview_name(md_view):
name = md_view.name() \ name = md_view.name() \
or os.path.basename(md_view.file_name()) \ or os.path.basename(md_view.file_name()) \
@ -40,3 +51,51 @@ def hide_preview(md_view):
psettings = preview.settings() psettings = preview.settings()
psettings.set(IS_HIDDEN, True) psettings.set(IS_HIDDEN, True)
sublime.set_timeout(preview.close(), 250) sublime.set_timeout(preview.close(), 250)
def get_style():
if os.path.exists(STYLE_FILE):
with open(STYLE_FILE) as fp:
return fp.read()
with open(DEFAULT_STYLE_FILE) as fp:
content = fp.read()
content = ''.join([line.strip() for line in content.splitlines()])
return content + "pre code .space {color: var(--light-bg)}"
def show_html(md_view, preview):
html = '<style>{}</style>\n{}'.format(get_style(),
pre_with_br(markdown2.markdown(get_view_content(md_view),
extras=['fenced-code-blocks',
'no-code-highlighting'])))
# the option no-code-highlighting does not exists
# in the official version of markdown2 for now
# I personaly edited the file (markdown2.py:1743)
html = html.replace('&nbsp;', '&nbspespace;') # save where are the spaces
html = HTMLParser().unescape(html)
html = escape_amp(html)
# exception, again, because <pre> aren't supported by the phantoms
html = html.replace('&nbspespace;', '<i class="space">.</i>')
html = replace_img_src_base64(html)
preview.erase_phantoms('markdown_preview')
preview.add_phantom('markdown_preview',
sublime.Region(-1),
html,
sublime.LAYOUT_BLOCK,
lambda href: sublime.run_command('open_url',
{'url': href}))
# set viewport position
# 0 < y < 1
y = md_view.text_to_layout(md_view.sel()[0].begin())[1] / md_view.layout_extent()[1]
vector = [0, y * preview.layout_extent()[1]]
# remove half of the viewport_extent.y to center it on the screen (verticaly)
vector[1] -= preview.viewport_extent()[1] / 2
vector[1] = mini(vector[1], 0)
vector[1] += preview.line_height()
preview.set_viewport_position(vector, animate=False)

View File

@ -27,12 +27,17 @@ class MarkdownLivePreviewListener(sublime_plugin.EventListener):
md_view_settings = md_view.settings() md_view_settings = md_view.settings()
if md_view_settings.get(PREVIEW_ENABLED) is not True: if md_view_settings.get(PREVIEW_ENABLED) is not True:
return return
id = md_view_settings.get(PREVIEW_ID)
if not md_view_settings.get(PREVIEW_ID): if not id:
MarkdownLivePreviewListener.md_view = md_view MarkdownLivePreviewListener.md_view = md_view
create_preview(md_view) create_preview(md_view)
MarkdownLivePreviewListener.has_preview = True MarkdownLivePreviewListener.has_preview = True
window.focus_view(md_view) window.focus_view(md_view)
else:
preview = get_view_from_id(window, id)
if preview is None:
raise ValueError('Getting preview from id: got None')
show_html(md_view, preview)
def on_pre_close(self, view): def on_pre_close(self, view):
vsettings = view.settings() vsettings = view.settings()

43
default.css Normal file
View File

@ -0,0 +1,43 @@
:root, html, body {
height: 100%;
}
html {
--light-bg: color(var(--background) blend(#999 85%))
height: 100%;
}
body {
padding:10px;
padding-top: 0px;
font-family: "Open Sans", sans-serif;
background-color: var(--background);
font-size: 15px;
}
blockquote {
font-style: italic;
display: block;
margin-left: 30px;
border: 1px solid red;
}
code {
padding-left: 0.2rem;
padding-right: 0.2rem;
background-color: var(--light-bg);
margin: 0;
border-radius: 3px;
margin: 5px;
}
pre {
display: block;
margin-top: 20px;
line-height: 1.7;
background-color: var(--light-bg);
padding-left: 10px;
width: 100%;
border-radius: 3px;
}
pre code {
padding-left: 0;
}

View File

@ -7,6 +7,7 @@ import os.path
class MLPDevListener(sublime_plugin.EventListener): class MLPDevListener(sublime_plugin.EventListener):
def on_post_save(self, view): def on_post_save(self, view):
return
if not (os.path.dirname(__file__) in view.file_name() and if not (os.path.dirname(__file__) in view.file_name() and
view.file_name().endswith('.py')): view.file_name().endswith('.py')):
return return

View File

@ -2,9 +2,36 @@
import base64 import base64
import os.path import os.path
import sublime import sublime
import re
from .image_manager import ImageManager
file404 = os.path.join(os.path.dirname(__file__), '404.png') file404 = os.path.join(os.path.dirname(__file__), '404.png')
def replace_img_src_base64(html):
"""Really messy, but it works (should be updated)"""
index = -1
tag_start = '<img src="'
shtml, html = html, list(html)
while True:
index = shtml.find(tag_start, index + 1)
if index == -1:
break
path, end = get_content_till(html, '"', start=index + len(tag_start))
if ''.join(path).startswith('data:image/'):
continue
if ''.join(path).startswith(tuple(get_settings().get('load_from_internet'
'_when_starts'))):
image = ImageManager.get(''.join(path))
image = image or to_base64('loading.png')
else:
# local image
image = to_base64(''.join(path))
html[index+len(tag_start):end] = image
shtml = ''.join(html)
return ''.join(html)
def is_markdown_view(view): def is_markdown_view(view):
return 'markdown' in view.scope_name(0) return 'markdown' in view.scope_name(0)
@ -51,3 +78,18 @@ def get_view_from_id(window, id):
def get_settings(): def get_settings():
return sublime.load_settings('MarkdownLivePreview.sublime-settings') return sublime.load_settings('MarkdownLivePreview.sublime-settings')
def pre_with_br(html):
"""Because the phantoms of sublime text does not support <pre> blocks
this function replaces every \n with a <br> in a <pre>"""
while True:
obj = re.search(r'<pre>(.*?)</pre>', html, re.DOTALL)
if not obj:
break
html = list(html)
html[obj.start(0):obj.end(0)] = '<pre >' + ''.join(html[obj.start(1):obj.end(1)]) \
.replace('\n', '<br>') \
.replace(' ', '&nbsp;') + '</pre>'
html = ''.join(html)
return html

View File

@ -3,3 +3,5 @@
![image](http://afterishtar.pl/images/100x100.gif) ![image](http://afterishtar.pl/images/100x100.gif)
this is a test this is a test
hello world...