Compare commits

..

9 Commits

Author SHA1 Message Date
8cc6b2b263 fix typo, add a tiny bit of doc to the code 2017-01-26 11:30:56 +11:00
c7961ce94c update stylesheet for tables 2017-01-26 11:03:52 +11:00
eae91fa428 add separator for tables' header 2017-01-26 10:57:12 +11:00
6f18e8e4a2 remove .prettify() @ pre_with_pr (bs4);
fix spaces in tables too
2017-01-26 10:43:04 +11:00
48c1800065 use bs4 for pre2br; fix style sheet for tables
Also: load default.css from the actual file if the package is not
zipped.
2017-01-26 10:36:52 +11:00
bad1cb74c6 MDtables base OK. Use bs4. #12 2017-01-26 09:21:49 +11:00
4198504fd1 [docs] add custom css part 2017-01-22 19:41:00 +11:00
1bef00de14 fix bug: support custom css from user 2017-01-22 18:41:36 +11:00
d707cf7a47 enable devListener 2017-01-22 17:51:48 +11:00
10 changed files with 173 additions and 54 deletions

View File

@ -7,6 +7,13 @@
"caption": "MarkdownLivePreview: Clear the cache", "caption": "MarkdownLivePreview: Clear the cache",
"command": "markdown_live_preview_clear_cache" "command": "markdown_live_preview_clear_cache"
}, },
{
"caption": "MarkdownLivePreview: Edit Custom CSS File",
"command": "open_file",
"args": {
"file": "$packages/User/MarkdownLivePreview.css"
}
},
{ {
"caption": "Preferences: MarkdownLivePreview Settings", "caption": "Preferences: MarkdownLivePreview Settings",
"command": "edit_settings", "command": "edit_settings",

View File

@ -7,6 +7,7 @@ import os.path
from html.parser import HTMLParser from html.parser import HTMLParser
from .lib import markdown2 as md2 from .lib import markdown2 as md2
from .lib.pre_tables import pre_tables
from .escape_amp import * from .escape_amp import *
from .functions import * from .functions import *
from .setting_names import * from .setting_names import *
@ -15,15 +16,19 @@ from random import randint as rnd
__folder__ = os.path.dirname(__file__) __folder__ = os.path.dirname(__file__)
STYLE_FILE = os.path.join(os.path.dirname(__folder__), 'User', USER_STYLE_FILE = os.path.join(os.path.dirname(__folder__), 'User', 'MarkdownLivePreview.css')
'MarkdownLivePreview.css')
# used to store the phantom's set # used to store the phantom's set
windows_phantom_set = {} windows_phantom_set = {}
def plugin_loaded(): def plugin_loaded():
global DEFAULT_STYLE_FILE global DEFAULT_STYLE_FILE
DEFAULT_STYLE_FILE = sublime.load_resource('Packages/MarkdownLivePreview/default.css') if os.path.exists(os.path.join(__folder__, 'default.css')):
with open(os.path.join(__folder__, 'default.css')) as fp:
DEFAULT_STYLE_FILE = fp.read()
else:
DEFAULT_STYLE_FILE = sublime.load_resource('Packages/MarkdownLivePreview/default.css')
def get_preview_name(md_view): def get_preview_name(md_view):
file_name = md_view.file_name() file_name = md_view.file_name()
@ -44,37 +49,36 @@ def create_preview(window, file_name):
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)}" if os.path.exists(USER_STYLE_FILE):
with open(USER_STYLE_FILE) as fp:
content += '\n' + fp.read() + '\n'
return content
def show_html(md_view, preview): def markdown2html(md, basepath):
global windows_phantom_set html = ''
html = [] html += '<style>\n{}\n</style>\n'.format(get_style())
html.append('<style>\n{}\n</style>'.format(get_style())) # pre_with_br
html.append(pre_with_br(md2.markdown(get_view_content(md_view), html += pre_with_br(pre_tables(md2.markdown(md, extras=['fenced-code-blocks',
extras=['fenced-code-blocks', 'no-code-highlighting', 'tables'])))
'no-code-highlighting']))) # the option no-code-highlighting does not exists in the official version of markdown2 for now
# the option no-code-highlighting does not exists
# in the official version of markdown2 for now
# I personaly edited the file (markdown2.py:1743) # I personaly edited the file (markdown2.py:1743)
html = '\n'.join(html)
html = html.replace('&nbsp;', '&nbspespace;') # save where are the spaces 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 # exception, again, because <pre> aren't supported by the phantoms
html = html.replace('&nbspespace;', '<i class="space">.</i>') html = html.replace('&nbspespace;', '<i class="space">.</i>')
html = replace_img_src_base64(html, basepath=os.path.dirname( html = replace_img_src_base64(html, basepath=os.path.dirname(basepath))
md_view.file_name())) return html
def show_html(md_view, preview):
global windows_phantom_set
html = markdown2html(get_view_content(md_view), os.path.dirname(md_view.file_name()))
phantom_set = windows_phantom_set.setdefault(preview.window().id(), phantom_set = windows_phantom_set.setdefault(preview.window().id(),
sublime.PhantomSet(preview, sublime.PhantomSet(preview, 'markdown_live_preview'))
'markdown_live_preview'))
phantom_set.update([sublime.Phantom(sublime.Region(0), html, sublime.LAYOUT_BLOCK, phantom_set.update([sublime.Phantom(sublime.Region(0), html, sublime.LAYOUT_BLOCK,
lambda href: sublime.run_command('open_url', lambda href: sublime.run_command('open_url', {'url': href}))])
{'url': href}))])
# lambda href: sublime.run_command('open_url', {'url': href}) # lambda href: sublime.run_command('open_url', {'url': href})
# get the "ratio" of the markdown view's position. # get the "ratio" of the markdown view's position.

View File

@ -1,21 +1,21 @@
Fast: Fast:
☐ sync scroll @needsUpdate(because of images)
☐ cache image in object when used, so that it's faster @needsTest ☐ cache image in object when used, so that it's faster @needsTest
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
☐ fix custom css @bug
Long: Long:
☐ support hanchor (TOC) @big ☐ support anchor (TOC) @big
Unknown: Unknown:
☐ check how many times is the show_html function called
___________________ ___________________
Archive: Archive:
✔ fix custom css @bug @done Sun 22 Jan 2017 at 18:40 @project(Medium)
✘ check how many times is the show_html function called @cancelled Sun 22 Jan 2017 at 18:40 @project(Unknown)
✔ sync scroll @needsUpdate(because of images) @done Sun 22 Jan 2017 at 18:39 @project(Fast)
✔ fix #4 @high @done Mon 09 Jan 2017 at 18:42 @project(Long) ✔ fix #4 @high @done Mon 09 Jan 2017 at 18:42 @project(Long)
✔ use MarkdownLivePreview syntax, so we can use syntax's settings @done Mon 09 Jan 2017 at 18:41 @project(Medium) ✔ use MarkdownLivePreview syntax, so we can use syntax's settings @done Mon 09 Jan 2017 at 18:41 @project(Medium)
✔ add clear cache command @done Mon 09 Jan 2017 at 18:41 @project(Fast) ✔ add clear cache command @done Mon 09 Jan 2017 at 18:41 @project(Fast)

View File

@ -1,19 +1,21 @@
html { html {
--light-bg: color(var(--background) blend(#999 85%)); --light-bg: color(var(--background) blend(#999 85%));
--very-light-bg: color(var(--background) blend(#999 92%));
} }
body { body {
padding:10px; padding:10px;
padding-top: 0px; padding-top: 0px;
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
background-color: var(--background); background-color: var(--background);
font-size: 15px; font-size: 15px;
color: #333;
} }
blockquote { blockquote {
font-style: italic; font-style: italic;
display: block; display: block;
margin-left: 30px; margin-left: 30px;
border: 1px solid red;
} }
code { code {
@ -22,28 +24,36 @@ code {
background-color: var(--light-bg); background-color: var(--light-bg);
margin: 0; margin: 0;
border-radius: 3px; border-radius: 3px;
margin: 5px;
} }
pre { pre {
display: block; display: block;
margin-top: 20px; margin-top: 20px;
line-height: 1.7;
background-color: var(--light-bg); background-color: var(--light-bg);
padding-left: 10px; padding-left: 10px;
padding-top: 5px;
padding-bottom: 5px;
width: 100%; width: 100%;
border-radius: 3px; border-radius: 3px;
} }
pre code { pre code {
padding-left: 0; padding: 0;
}
pre code .space {
color: var(--light-bg);
}
pre.table {
background-color: var(--backgroud);
}
pre.table code {
background-color: var(--backgroud);
padding: 0;
margin: 0;
} }
kbd { kbd {
padding: 0 .29412em; padding: 0 5px;
border-radius: .2rem; background-color: var(--very-light-bg);
background-color: #f5f5f5;
color: #555;
box-shadow: 0 0.1rem 0 #b0b0b0;
word-break: break-word;
font-family: "Roboto Mono","Courier New",Courier,monospace; font-family: "Roboto Mono","Courier New",Courier,monospace;
} }

7
dependencies.json Normal file
View File

@ -0,0 +1,7 @@
{
"*": {
"*": [
"bs4"
]
}
}

View File

@ -7,14 +7,15 @@ 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 # 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
sublime.run_command('reload_plugin', { sublime.run_command('reload_plugin', {
'main': os.path.join(sublime.packages_path(), 'main': os.path.join(sublime.packages_path(), 'MarkdownLivePreview',
'MarkdownLivePreview', 'md_in_popup.py'), 'MarkdownLivePreview.py'),
'scripts': ['image_manager', 'functions', 'MLPApi', 'scripts': ['image_manager', 'functions', 'MLPApi',
'setting_names'], 'setting_names'],
'folders': ['lib'],
'quiet': True 'quiet': True
}) })

View File

@ -59,7 +59,26 @@ As told in the introduction, MarkdownLivePreview is very easy to use:
!!! tip !!! tip
[Markdown Extended][] is supported too! [Markdown Extended][] is supported too!
That's it. That's it. That's all you need to do to preview your markdown!
### Custom CSS
If you want to, you can add custom `CSS` to the MarkdownLivePreview's default stylesheet.
Just search for `MarkdownLivePreview: Edit Custom CSS File` in the command palette
(<kbd>ctrl+shift+p</kbd>). It will open a file in which you can add some CSS that will be *added* to
the normal CSS.
!!! bug
Comments in the CSS is interpreted weirdly by Sublime Text's phantoms. After a few tests, I
think that everything that is bellow a comment is ignored.
If you want to be sure that your CSS works, don't put any comments in it
#### Share your tweaks!
If you think that other users would enjoy your added CSS, then raise an issue, or PR the
[GitHub repo][] to share your tweaks!
### Clearing the cache ### Clearing the cache
@ -115,7 +134,7 @@ Here's what I'd recommend (and use):
} }
``` ```
!!! note !!! tip
On Windows at least, you can press <kbd>alt</kbd> to focus (so show) the menu, even if they're On Windows at least, you can press <kbd>alt</kbd> to focus (so show) the menu, even if they're
originally hidden originally hidden
@ -130,3 +149,4 @@ frameborder="0" scrolling="0" width="160px" height="30px"></iframe>!
[pck-con]: https://packagecontrol.io [pck-con]: https://packagecontrol.io
[install-pck-con]: https://packagecontrol.io/installation [install-pck-con]: https://packagecontrol.io/installation
[tweet]: https://twitter.com/_math2001 [tweet]: https://twitter.com/_math2001
[GitHub repo]: https://github.com/math2001/MarkdownLivePreview/issues

View File

@ -4,6 +4,7 @@ import os.path
import sublime import sublime
import re import re
from .image_manager import ImageManager from .image_manager import ImageManager
from bs4 import BeautifulSoup
def plugin_loaded(): def plugin_loaded():
global error404, loading global error404, loading
@ -89,14 +90,9 @@ def get_settings():
def pre_with_br(html): def pre_with_br(html):
"""Because the phantoms of sublime text does not support <pre> blocks """Because the phantoms of sublime text does not support <pre> blocks
this function replaces every \n with a <br> in a <pre>""" this function replaces every \n with a <br> in a <pre>"""
soup = BeautifulSoup(html)
while True: for pre in soup.find_all('pre'):
obj = re.search(r'<pre>(.*?)</pre>', html, re.DOTALL) code = pre.find('code')
if not obj: code.replaceWith(BeautifulSoup(''.join(str(node) for node in pre.contents) \
break .replace('\n', '<br/>').replace(' ', '<i class="space">.</i>'), 'html.parser'))
html = list(html) return str(soup).replace('<br/>', '<br />')
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

46
lib/pre_tables.py Normal file
View File

@ -0,0 +1,46 @@
# -*- encoding: utf-8 -*-
"""
'pre_tables' transform *html* tables into markdown tables, and put them in some <pre><code> tags
"""
from bs4 import BeautifulSoup
def python_table(s_table):
"""Transform BeautifulSoup table into list of list"""
rows = []
for row in s_table.find_all('tr'):
# rows.append(list(map( lambda td: td.text, row.find_all(['th', 'td']) )))
rows.append(row.find_all(['th', 'td']))
return rows
def pre_table(s_table):
rows = python_table(s_table)
cols_width = [len(cell) for cell in rows[0]]
for j, row in enumerate(rows):
for i, cell in enumerate(row):
if cols_width[i] < len(cell.text):
cols_width[i] = len(cell.text)
text = '<pre class="table"><code>'
for i, row in enumerate(rows):
if i == 1:
for j, cell in enumerate(row):
text += '|' + '-' * (cols_width[j] + 2)
text += '|\n'
for j, cell in enumerate(row):
text += '| ' + ''.join(str(node) for node in cell.contents) \
+ ' ' * (cols_width[j] - len(cell.text) + 1)
text += '|\n'
text += '</pre></code>'
return text
def pre_tables(html):
soup = BeautifulSoup(html, 'html.parser')
for table in soup.find_all('table'):
table.replace_with(BeautifulSoup(pre_table(table), 'html.parser'))
return str(soup)
if __name__ == "__main__":
# CSW: ignore
print(pre_tables(html))

View File

@ -4,8 +4,36 @@ Some `inline code` with *italic* and **bold** text.
```python ```python
import this import this
if you('are', 'curious'): if you is moods.curious:
print('then do it!') print('then do it!')
``` ```
<kbd>ctrl+\`</kbd> or *View → Show Console* and paste `import this`! <kbd>ctrl+\`</kbd> or *View → Show Console* and paste `import this`!
> Perfect programmers do NOT need comments.
- to be efficient
- you need
- todos
| ID | Name |
|-----------|-------|
| 56 | Matt |
| 42 | Colin |
| 23 | Lisa |
| 45 | John |
| `<table>` | `><` |
[Sublime Text Logo](https://upload.wikimedia.org/wikipedia/en/4/4c/Sublime_Text_Logo.png)
Some plugin I just *need*:
- [PackageResourceReviewer](https://packagecontrol.io/packages/PackageResourceViewer)
- [Boxy Theme](https://packagecontrol.io/packages/Boxy%20Theme)
- [Markdown Preview](https://packagecontrol.io/packages/Markdown%20Preview)
- [FileManager](https://packagecontrol.io/packages/FileManager)
- [PlainTasks](https://packagecontrol.io/packages/PlainTasks)
- [JSONComma](https://packagecontrol.io/packages/JSONComma)