Highlight code blocks with pygments #18

This commit is contained in:
Mathieu PATUREL
2017-02-11 08:52:42 +11:00
parent 40a563fb1e
commit 7257cb467e
8 changed files with 55 additions and 25 deletions

View File

@ -8,6 +8,7 @@ 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 .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 *
@ -16,16 +17,11 @@ from random import randint as rnd
__folder__ = os.path.dirname(__file__) __folder__ = os.path.dirname(__file__)
USER_STYLE_FILE = os.path.join(os.path.dirname(__folder__), 'User', '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():
global DEFAULT_STYLE_FILE
DEFAULT_STYLE_FILE = sublime.load_resource('Packages/MarkdownLivePreview/default.css')
def create_preview(window, file_name): def create_preview(window, file_name):
preview = window.new_file() preview = window.new_file()
@ -36,23 +32,16 @@ def create_preview(window, file_name):
return preview return preview
def get_style(): def markdown2html(md, basepath, color_scheme):
content = ''.join([line.strip() + ' ' for line in DEFAULT_STYLE_FILE.splitlines()])
if os.path.exists(USER_STYLE_FILE):
with open(USER_STYLE_FILE) as fp:
content += '\n' + fp.read() + '\n'
return content
def markdown2html(md, basepath):
# removes/format the header. # removes/format the header.
md = manage_header(md, get_settings().get('header_action')) md = manage_header(md, get_settings().get('header_action'))
html = '<style>\n{}\n</style>\n'.format(get_style()) html = '<style>\n{}\n</style>\n'.format(get_style(color_scheme))
# 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 += md2.markdown(md, extras=['fenced-code-blocks', 'no-code-highlighting', 'tables']) html += md2.markdown(md, extras=['fenced-code-blocks', 'tables'])
# tables aren't supported by the Phantoms # tables aren't supported by the Phantoms
# This function transforms them into aligned ASCII tables and displays them in a <pre> block # This function transforms them into aligned ASCII tables and displays them in a <pre> block
@ -79,13 +68,14 @@ def markdown2html(md, basepath):
# BeautifulSoup uses the <br/> but the sublime phantoms do not support them... # BeautifulSoup uses the <br/> but the sublime phantoms do not support them...
html = html.replace('<br/>', '<br />').replace('<hr/>', '<hr />') html = html.replace('<br/>', '<br />').replace('<hr/>', '<hr />')
sublime.set_clipboard(html) # print sublime.set_clipboard(html) # print('hello')
return html return html
def show_html(md_view, preview): def show_html(md_view, preview):
global windows_phantom_set global windows_phantom_set
html = markdown2html(get_view_content(md_view), os.path.dirname(md_view.file_name())) html = markdown2html(get_view_content(md_view), os.path.dirname(md_view.file_name()),
os.path.join(sublime.packages_path(), '..', md_view.settings().get('color_scheme')))
phantom_set = windows_phantom_set.setdefault(preview.window().id(), phantom_set = windows_phantom_set.setdefault(preview.window().id(),
sublime.PhantomSet(preview, 'markdown_live_preview')) sublime.PhantomSet(preview, 'markdown_live_preview'))

View File

@ -25,7 +25,7 @@ code {
border-radius: 3px; border-radius: 3px;
} }
pre { div.codehilite {
display: block; display: block;
margin-top: 20px; margin-top: 20px;
background-color: var(--light-bg); background-color: var(--light-bg);

View File

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

View File

@ -1,6 +1,6 @@
--- ---
title: Demo title: Demo
description: Preview your markdown right in Sublime Text! description: Preview your markdown right in Sublime Text!
hope: You'll enjoy using it! hope: You'll enjoy using it!
--- ---

View File

@ -4,13 +4,18 @@ import os.path
import sublime import sublime
import re import re
from .image_manager import ImageManager from .image_manager import ImageManager
from .lib.pygments_from_theme import pygments_from_theme
from bs4 import BeautifulSoup, Comment as html_comment from bs4 import BeautifulSoup, Comment as html_comment
def plugin_loaded(): def plugin_loaded():
global error404, loading global error404, loading, DEFAULT_STYLE, USER_STYLE_FILE
loading = sublime.load_resource('Packages/MarkdownLivePreview/loading.txt') loading = sublime.load_resource('Packages/MarkdownLivePreview/loading.txt')
error404 = sublime.load_resource('Packages/MarkdownLivePreview/404.txt') error404 = sublime.load_resource('Packages/MarkdownLivePreview/404.txt')
DEFAULT_STYLE = sublime.load_resource('Packages/MarkdownLivePreview/default.css')
USER_STYLE_FILE = os.path.join(sublime.packages_path(), 'User', "MarkdownLivePreview.css")
print(USER_STYLE_FILE)
MATCH_YAML_HEADER = re.compile(r'^([\-\+])\1{2}\n(?P<content>.+)\n\1{3}\n', re.DOTALL) MATCH_YAML_HEADER = re.compile(r'^([\-\+])\1{2}\n(?P<content>.+)\n\1{3}\n', re.DOTALL)
def strip_html_comments(html): def strip_html_comments(html):
@ -102,12 +107,27 @@ 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_spaces(code):
for tag in code.find_all(text=True):
tag.replace_with(BeautifulSoup(str(tag).replace('\t', ' ' * 4).replace(' ', '<i class="space">.</i>').replace('\n', '<br />'), 'html.parser'))
return code
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, 'html.parser') soup = BeautifulSoup(html, 'html.parser')
for pre in soup.find_all('pre'): for pre in soup.find_all('pre'):
code = pre.find('code') code = pre.find('code')
code.replaceWith(BeautifulSoup(''.join(str(node) for node in pre.contents) \ code.replace_with(_pre_with_spaces(code))
.replace('\n', '<br/>').replace(' ', '<i class="space">.</i>'), 'html.parser'))
return str(soup) return str(soup)
def get_style(color_scheme):
css = ''.join([line.strip() + ' ' for line in DEFAULT_STYLE.splitlines()])
if os.path.exists(USER_STYLE_FILE):
with open(USER_STYLE_FILE) as fp:
css += '\n' + fp.read() + '\n'
if color_scheme:
css += pygments_from_theme(color_scheme)
return css

View File

@ -8,7 +8,7 @@ from collections import defaultdict
class Style: class Style:
# .highlight is the wrapper class for highlighting therefore # .highlight is the wrapper class for highlighting therefore
# all css rules are prefixed with .highlight # all css rules are prefixed with .highlight
PREFIX = '.highlight' PREFIX = '.codehilite'
# ----------------------------------------- # -----------------------------------------
# Params # Params
@ -150,7 +150,7 @@ def pygments_from_theme(file):
styles.append(Style('bp', settings['variable.language'], settings['variable'], [settings['text_color']])) styles.append(Style('bp', settings['variable.language'], settings['variable'], [settings['text_color']]))
styles.append(Style('p', [settings['text_color']])) styles.append(Style('p', [settings['text_color']]))
css = '.highlight { background-color: ' + settings['editor_bg'] + '; color: ' + settings['text_color'] + '; }\n' css = '{} {{ background-color: {}; color: {}; }}\n'.format(Style.PREFIX, settings['editor_bg'], settings['text_color'])
for st in styles: for st in styles:
css_style = st.toString() css_style = st.toString()
if css_style: if css_style:

9
sample.md/sample.md Normal file
View File

@ -0,0 +1,9 @@
Hello world
```python
print('Hello world')
if hello:
print('hello')
for i in range(4):
print(i)
```

10
test.md Normal file
View File

@ -0,0 +1,10 @@
```python
import this
if you.are('new'):
print('Welcome!')
if you.are('brand new'):
print("You'll see, python's just awesome")
else:
print('Hello!')
```