Compare commits

...

10 Commits

Author SHA1 Message Date
f48ef63956 update tasks 2017-01-08 15:54:32 +11:00
a4e670de43 clean code/files 2017-01-08 15:40:25 +11:00
d466a29cd4 the stylesheet's back 2017-01-08 15:30:49 +11:00
0f0e53ff34 minor updates 2017-01-08 14:26:25 +11:00
30ac30082f update README 2017-01-08 14:19:09 +11:00
e4e7c44c3c clean unused variables/import 2017-01-08 13:51:50 +11:00
75a8cf53f9 working, needs few improvement 2017-01-08 12:30:20 +11:00
3dcaed0ede small optimisation, working 2017-01-07 16:09:36 +11:00
c605ffb3db added package control messages 2017-01-07 12:36:17 +11:00
aa5fd4faf8 set main callback async (should help #6) 2017-01-07 09:11:30 +11:00
18 changed files with 158 additions and 142 deletions

View File

@ -1,10 +1,7 @@
[ [
{ {
"keys": ["alt+m"], "keys": ["alt+m"],
"command": "toggle_setting", "command": "new_markdown_live_preview",
"args": {
"setting": "markdown_live_preview_enabled"
},
"context": [ "context": [
{ {
"key": "selector", "key": "selector",

View File

@ -1,9 +1,6 @@
[ [
{ {
"caption": "MarkdownLivePreview: Toggle", "caption": "MarkdownLivePreview: Edit Current File",
"command": "toggle_setting", "command": "new_markdown_live_preview"
"args": {
"setting": "markdown_live_preview_enabled"
}
} }
] ]

View File

@ -6,7 +6,7 @@ import sublime_plugin
import os.path import os.path
from html.parser import HTMLParser from html.parser import HTMLParser
from .lib import markdown2 from .lib import markdown2 as md2
from .escape_amp import * from .escape_amp import *
from .functions import * from .functions import *
from .setting_names import * from .setting_names import *
@ -23,91 +23,33 @@ def plugin_loaded():
'default.css') 'default.css')
def get_preview_name(md_view): def get_preview_name(md_view):
file_name = md_view.file_name()
name = md_view.name() \ name = md_view.name() \
or os.path.basename(md_view.file_name()) \ or os.path.basename(file_name) if file_name else None \
or 'Untitled' or 'Untitled'
return name + ' - Preview' return name + ' - Preview'
def find_preview(window): def create_preview(window, file_name):
for view in window.views():
vsettings = view.settings()
if vsettings.get(IS_PREVIEW):
yield view, vsettings
def create_preview(md_view):
window = md_view.window()
md_view_settings = md_view.settings()
md_view_settings.set(JUST_CREATED, True)
preview = window.new_file() preview = window.new_file()
psettings = preview.settings() preview.set_name(get_preview_name(file_name))
psettings.set(IS_PREVIEW, True)
psettings.set(MD_VIEW_ID, md_view.id())
preview.set_name(get_preview_name(md_view))
preview.set_scratch(True) preview.set_scratch(True)
md_view_settings.set(PREVIEW_ID, preview.id())
def move_and_focus_md_view():
window.run_command('new_pane')
sublime.set_timeout_async(lambda: window.focus_view(md_view), 250)
sublime.set_timeout_async(move_and_focus_md_view, 250)
return preview return preview
def hide_preview(view):
window = view.window()
vsettings = view.settings()
if vsettings.get(IS_PREVIEW):
preview = view
psettings = vsettings
md_view_id = vsettings.get(MD_VIEW_ID)
md_view = get_view_from_id(window, md_view_id)
if md_view is None:
raise ValueError('Tried to get md_view from id {} but got None'.format(md_view_id))
mdvsettings = md_view.settings()
elif vsettings.get(PREVIEW_ENABLED):
md_view = view
preview_id = vsettings.get(PREVIEW_ID)
preview = get_view_from_id(window, preview_id)
mdvsettings = vsettings
if preview is None:
raise ValueError('Tried to get preview from id {} but got None'.format(preview_id))
psettings = preview.settings()
else:
raise ValueError('Call hide_preview with a view which is not the preview or the md_view')
psettings.set(IS_HIDDEN, True)
mdvsettings.erase(PREVIEW_ID)
sublime.set_timeout(lambda: preview.close(), 250)
return
window = md_view.window()
if window is None:
return
mdvsettings = md_view.settings()
preview_id = mdvsettings.get(PREVIEW_ID)
if not preview_id:
return
mdvsettings.erase(PREVIEW_ID)
preview = get_view_from_id(window, preview_id)
if preview is None:
raise ValueError('Tried to get view from id {} but got None'.format(preview_id))
psettings = preview.settings()
psettings.set(IS_HIDDEN, True)
sublime.set_timeout(preview.close(), 250)
def get_style(): def get_style():
content = ''.join([line.strip() for line in DEFAULT_STYLE_FILE.splitlines()]) content = ''.join([line.strip() + ' ' for line in DEFAULT_STYLE_FILE.splitlines()])
return content + "pre code .space {color: var(--light-bg)}" return content + "pre code .space {color: var(--light-bg)}"
def show_html(md_view, preview): def show_html(md_view, preview):
html = '<style>{}</style>\n{}'.format(get_style(), html = []
pre_with_br(markdown2.markdown(get_view_content(md_view), html.append('<style>\n{}\n</style>'.format(get_style()))
html.append(pre_with_br(md2.markdown(get_view_content(md_view),
extras=['fenced-code-blocks', extras=['fenced-code-blocks',
'no-code-highlighting']))) 'no-code-highlighting'])))
html = '\n'.join(html)
# the option no-code-highlighting does not exists # the option no-code-highlighting does not exists
# in the official version of markdown2 for now # in the official version of markdown2 for now
# I personaly edited the file (markdown2.py:1743) # I personaly edited the file (markdown2.py:1743)
@ -129,11 +71,8 @@ def show_html(md_view, preview):
lambda href: sublime.run_command('open_url', lambda href: sublime.run_command('open_url',
{'url': href})) {'url': href}))
# set viewport position
# sublime.set_clipboard(html)
return return
# set viewport position
# 0 < y < 1 # 0 < y < 1
y = md_view.text_to_layout(md_view.sel()[0].begin())[1] / md_view.layout_extent()[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]] vector = [0, y * preview.layout_extent()[1]]

View File

@ -1,7 +1,5 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
import sys
import os.path
import sublime import sublime
import sublime_plugin import sublime_plugin
@ -9,43 +7,59 @@ from .MLPApi import *
from .setting_names import * from .setting_names import *
from .functions import * from .functions import *
class NewMarkdownLivePreviewCommand(sublime_plugin.ApplicationCommand):
def run(self):
"""Inspired by the edit_settings command"""
current_view = sublime.active_window().active_view()
file_name = current_view.file_name()
current_view.close()
if file_name is None:
return sublime.error_message('Not supporting unsaved file for now')
sublime.run_command('new_window')
self.window = sublime.active_window()
self.window.settings().set(PREVIEW_WINDOW, True)
self.window.run_command('set_layout', {
'cols': [0.0, 0.5, 1.0],
'rows': [0.0, 1.0],
'cells': [[0, 0, 1, 1], [1, 0, 2, 1]]
})
self.window.focus_group(1)
preview = create_preview(self.window, current_view)
self.window.focus_group(0)
md_view = self.window.open_file(file_name)
mdsettings = md_view.settings()
mdsettings.set(PREVIEW_ENABLED, True)
mdsettings.set(PREVIEW_ID, preview.id())
def is_enabled(self):
return is_markdown_view(sublime.active_window().active_view())
class MarkdownLivePreviewListener(sublime_plugin.EventListener): class MarkdownLivePreviewListener(sublime_plugin.EventListener):
def on_modified(self, view): def on_modified(self, view):
window = view.window() if not is_markdown_view(view): # faster than getting the settings
return
vsettings = view.settings() vsettings = view.settings()
if vsettings.get(PREVIEW_ENABLED): if not vsettings.get(PREVIEW_ENABLED):
return
id = vsettings.get(PREVIEW_ID) id = vsettings.get(PREVIEW_ID)
preview = get_view_from_id(window, id) if id is None:
if id is None or preview is None: raise ValueError('The preview id is None')
preview = create_preview(view) preview = get_view_from_id(view.window(), id)
sublime.set_timeout(lambda: show_html(view, preview), 1000) if preview is None:
else: raise ValueError('The preview is None (id: {})'.format(id))
show_html(view, preview) show_html(view, preview)
return def on_window_command(self, window, command, args):
if command == 'close' and window.settings().get(PREVIEW_WINDOW):
return 'close_window', {}
def on_activated(self, view): def on_load_async(self, view):
# if view is md_view and has no preview self.on_modified(view)
# -> create preview
window = view.window()
vsettings = view.settings()
if vsettings.get(PREVIEW_ENABLED):
id = vsettings.get(PREVIEW_ID)
preview = get_view_from_id(window, id)
if id is None or preview is None:
preview = create_preview(view)
sublime.set_timeout(lambda: show_html(view, preview), 1000)
else:
show_html(view, preview)
return
# if view is preview
# -> do nothing
if vsettings.get(IS_PREVIEW):
return
# if view is not the md_view or the preview
# remove preview if any
for view, settings in find_preview(window):
settings.set(IS_HIDDEN, True)
view.close()

View File

@ -4,12 +4,14 @@ Fast:
☐ cache image in object when used, so that it's faster @needsTest ☐ cache image in object when used, so that it's faster @needsTest
☐ call settings listener on_new too - might be too heavy ☐ call settings listener on_new too - might be too heavy
☐ add clear cache command ☐ add clear cache command
☐ add settings for the preview
Medium: Medium:
☐ auto refresh preview if loading images ☐ auto refresh preview if loading images
☐ use alt attribute for 404 error ☐ use alt attribute for 404 error
☐ use MarkdownLivePreview syntax, so we can use syntax's settings ☐ use MarkdownLivePreview syntax, so we can use syntax's settings
☐ listen for settings to change ☐ listen for settings to change
☐ fix relative source
Long: Long:
☐ fix #4 @high ☐ fix #4 @high

View File

@ -28,7 +28,11 @@ Done!
### Usage ### Usage
Sometimes, you just want to open a markdown file to edit it quickly, you don't care about the preview, and even worse, **you don't want it**. So, if you want to have the preview, press `alt+m`, edit your file, and you'll get a nice preview. You can choose to enable MarkdownLivePreview by pressing <kbd>alt+m</kbd> or selecting in the command palette `MarkdownLivePreview: Edit Current File`. Note that you need to be editing (simply having the focus on) a markdown file. Because [Markdown Extended][markdown-extended] did a good job, it's compatible with this plugin.
It will open a new window, with only your markdown file, with the preview. Once your done, close whichever file and it'll close the entire window.
*Notice that it will close the entire window if you close **whichever** file. It means that if you open a random file in this window, and then close it, it'll close the entire window still*
### In dev ### In dev
@ -45,3 +49,7 @@ It is possible to set your own css. But, be carefull, you have to respect [those
### How to open the [README](http://github.com/math2001/MarkdownLivePreview/README.md) ### How to open the [README](http://github.com/math2001/MarkdownLivePreview/README.md)
Some of the package add a command in the menus, others in the command palette, or other nowhere. None of those options are really good, especially the last one on ST3 because the packages are compressed. But, fortunately, there is plugin that exists and **will solve this problem** for us (and he has a really cute name, don't you think?): [ReadmePlease](https://packagecontrol.io/packages/ReadmePlease). Some of the package add a command in the menus, others in the command palette, or other nowhere. None of those options are really good, especially the last one on ST3 because the packages are compressed. But, fortunately, there is plugin that exists and **will solve this problem** for us (and he has a really cute name, don't you think?): [ReadmePlease](https://packagecontrol.io/packages/ReadmePlease).
[markdown-extended]: https://packagecontrol.io/packages/Markdown

View File

@ -1,9 +1,5 @@
:root, html, body {
height: 100%;
}
html { html {
--light-bg: color(var(--background) blend(#999 85%)) --light-bg: color(var(--background) blend(#999 85%));
height: 100%;
} }
body { body {
padding:10px; padding:10px;

View File

@ -2,9 +2,7 @@
import re import re
__all__ = [ __all__ = ['escape_amp']
'escape_amp'
]
RE_REPLACE_AMPERSAND = re.compile(r'&(\w*)(;)?') RE_REPLACE_AMPERSAND = re.compile(r'&(\w*)(;)?')
@ -27,11 +25,14 @@ def run_tests():
fails = 0 fails = 0
for i, (subject, result) in enumerate(tests): for i, (subject, result) in enumerate(tests):
if RE_REPLACE_AMPERSAND.sub(replace, subject) != result: if RE_REPLACE_AMPERSAND.sub(replace, subject) != result:
# CSW: ignore
print('TEST FAIL ({i}): {subject!r} escaped did not match {result!r}'.format(**locals())) print('TEST FAIL ({i}): {subject!r} escaped did not match {result!r}'.format(**locals()))
fails += 1 fails += 1
if fails == 0: if fails == 0:
# CSW: ignore
print("SUCCESS: every tests ({}) passed successfully!".format(len(tests))) print("SUCCESS: every tests ({}) passed successfully!".format(len(tests)))
else: else:
# CSW: ignore
print("{} test{} failed".format(fails, 's' if fails > 1 else '')) print("{} test{} failed".format(fails, 's' if fails > 1 else ''))
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -75,6 +75,8 @@ def get_view_content(view):
return view.substr(sublime.Region(0, view.size())) return view.substr(sublime.Region(0, view.size()))
def get_view_from_id(window, id): def get_view_from_id(window, id):
if not isinstance(id, int):
return
for view in window.views(): for view in window.views():
if view.id() == id: if view.id() == id:
return view return view

View File

@ -1,11 +1,11 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
import os.path import os.path
import tempfile
import sublime
from threading import Thread from threading import Thread
import urllib.request, urllib.error import urllib.request, urllib.error
import sublime
from .functions import * from .functions import *
import tempfile
CACHE_FILE = os.path.join(tempfile.gettempdir(), CACHE_FILE = os.path.join(tempfile.gettempdir(),
'MarkdownLivePreviewCache.txt') 'MarkdownLivePreviewCache.txt')

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

1
imgs/README.md Normal file
View File

@ -0,0 +1 @@
There is images here, allthough they aren't of any use for the plugin. They're just the image that I used to generate the base64 (404.txt and loading.txt)

View File

Before

Width:  |  Height:  |  Size: 953 B

After

Width:  |  Height:  |  Size: 953 B

4
messages.json Normal file
View File

@ -0,0 +1,4 @@
{
"install": "messages/install.txt",
"1.1.2": "messages/1.1.2.txt"
}

12
messages/1.1.2.txt Normal file
View File

@ -0,0 +1,12 @@
Sorry to interupt you... :(
Small changes occured on MarkdownLivePreview.
Changes:
~~~~~~~~
Main callback is now async (prevent ST from crashing)
Tip of the day: Delete all the content till the end of the line: Ctrl+k, Ctrl+k
You'll use it much more than you think ;)

42
messages/install.txt Normal file
View File

@ -0,0 +1,42 @@
__ __ _ _ _ _ _____ _
| \/ | | | | | | | (_) | __ \ (_)
| \ / | __ _ _ __| | ____| | _____ ___ __ | | ___ _____| |__) | __ _____ ___ _____ __
| |\/| |/ _` | '__| |/ / _` |/ _ \ \ /\ / / '_ \| | | \ \ / / _ \ ___/ '__/ _ \ \ / / |/ _ \ \ /\ / /
| | | | (_| | | | < (_| | (_) \ V V /| | | | |____| |\ V / __/ | | | | __/\ V /| | __/\ V V /
|_| |_|\__,_|_| |_|\_\__,_|\___/ \_/\_/ |_| |_|______|_| \_/ \___|_| |_| \___| \_/ |_|\___| \_/\_/
Thanks for installing MarkdownLivePreview! I hope you'll enjoy using it!
Quick Start:
~~~~~~~~~~~~
To enable MarkdownLivePreview, you need to me on a markdown view (works with
Markdown Extended). Then just press `alt+m`, or search up in the command
palette: 'MarkdownLivePreview: Toggle'. Hit enter and you're done. As soon as
you'll type anything in, it'll show up the preview in a new group.
Say thanks:
~~~~~~~~~~~
Just letting me know you're enjoying this plugin is a great way to say thanks!
You can do so by staring the GitHub repo, or sending a tweet (@_math2001) for
example!
Troubles?
~~~~~~~~~
If you have any kind of trouble with it, just let me now by raising an issue on
the GitHub issue tracker here:
https://github.com/math2001/MarkdownLivePreview/issues
Tip of the day: Right click on a URL and choose 'Open <the url>' to open it in
your default browser.
Credits:
~~~~~~~~
The ASCII MLP has been generated using the ASCII Decorator.
https://github.com/viisual/ASCII-Decorator

View File

@ -1,18 +1,19 @@
# DuckDuckGo - The Search engine you'll fall in love with this is a test. # DuckDuckGo - The Search engine you'll fall in love
This is cool. The stylesheet's back!
This is a test, and this is pretty cool! This is a test, and this is pretty cool!
![image](http://afterishtar.pl/images/100x100.gif)
Hope you'll enjoy using MarkdownLivePreview! Hope you'll enjoy using MarkdownLivePreview!
![image](https://forum.sublimetext.com/uploads/st-forum-wide.png) ![Sublime Text Forum](https://forum.sublimetext.com/uploads/st-forum-wide.png)
![image](http://local.dev/tests/php/img/image-php.php) ```python
print(hello world)
if DEBUG:
print('DEBUG_MODE on')
```
hello world > Only a fool knows everything. A wise man knows how little he knows
This is a test dfsdf hello world, this is pretty cool.
This is a test
The only think I know right now is that Boxy Theme's just awesome.

View File

@ -5,4 +5,4 @@ PREVIEW_ID = 'markdown_live_preview_id'
IS_PREVIEW = 'is_markdown_live_preview' IS_PREVIEW = 'is_markdown_live_preview'
IS_HIDDEN = 'is_hidden_markdown_live_preview' IS_HIDDEN = 'is_hidden_markdown_live_preview'
MD_VIEW_ID = 'markdown_live_preview_md_id' MD_VIEW_ID = 'markdown_live_preview_md_id'
JUST_CREATED = 'markdown_live_preview_just_created' PREVIEW_WINDOW = 'markdown_live_preview_window'