From 7257cb467e9bd393d9c171ae5fec23fed88be4a1 Mon Sep 17 00:00:00 2001 From: Mathieu PATUREL Date: Sat, 11 Feb 2017 08:52:42 +1100 Subject: [PATCH] Highlight code blocks with pygments #18 --- MLPApi.py | 24 +++++++----------------- default.css | 2 +- dependencies.json | 3 ++- sample.md => example.md | 2 +- functions.py | 26 +++++++++++++++++++++++--- lib/pygments_from_theme.py | 4 ++-- sample.md/sample.md | 9 +++++++++ test.md | 10 ++++++++++ 8 files changed, 55 insertions(+), 25 deletions(-) rename sample.md => example.md (94%) create mode 100644 sample.md/sample.md create mode 100644 test.md diff --git a/MLPApi.py b/MLPApi.py index d69dd55..22ca211 100644 --- a/MLPApi.py +++ b/MLPApi.py @@ -8,6 +8,7 @@ from html.parser import HTMLParser from .lib import markdown2 as md2 from .lib.pre_tables import pre_tables + from .escape_amp import * from .functions import * from .setting_names import * @@ -16,16 +17,11 @@ from random import randint as rnd __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 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): preview = window.new_file() @@ -36,23 +32,16 @@ def create_preview(window, file_name): return preview -def get_style(): - 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): +def markdown2html(md, basepath, color_scheme): # removes/format the header. md = manage_header(md, get_settings().get('header_action')) - html = '\n'.format(get_style()) + html = '\n'.format(get_style(color_scheme)) # 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 += 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 # This function transforms them into aligned ASCII tables and displays them in a
 block
@@ -79,13 +68,14 @@ def markdown2html(md, basepath):
     # BeautifulSoup uses the 
but the sublime phantoms do not support them... html = html.replace('
', '
').replace('
', '
') - sublime.set_clipboard(html) # print + sublime.set_clipboard(html) # print('hello') 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())) + 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(), sublime.PhantomSet(preview, 'markdown_live_preview')) diff --git a/default.css b/default.css index 46ed5b1..64bde6f 100644 --- a/default.css +++ b/default.css @@ -25,7 +25,7 @@ code { border-radius: 3px; } -pre { +div.codehilite { display: block; margin-top: 20px; background-color: var(--light-bg); diff --git a/dependencies.json b/dependencies.json index d0b3031..e7e714a 100644 --- a/dependencies.json +++ b/dependencies.json @@ -1,7 +1,8 @@ { "*": { "*": [ - "bs4" + "bs4", + "pygments" ] } } diff --git a/sample.md b/example.md similarity index 94% rename from sample.md rename to example.md index 8564d3a..d6fb04d 100644 --- a/sample.md +++ b/example.md @@ -1,6 +1,6 @@ --- title: Demo -description: Preview your markdown right in Sublime Text! +description: Preview your markdown right in Sublime Text! hope: You'll enjoy using it! --- diff --git a/functions.py b/functions.py index dff7281..2945f19 100644 --- a/functions.py +++ b/functions.py @@ -4,13 +4,18 @@ import os.path import sublime import re from .image_manager import ImageManager +from .lib.pygments_from_theme import pygments_from_theme from bs4 import BeautifulSoup, Comment as html_comment def plugin_loaded(): - global error404, loading + global error404, loading, DEFAULT_STYLE, USER_STYLE_FILE loading = sublime.load_resource('Packages/MarkdownLivePreview/loading.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.+)\n\1{3}\n', re.DOTALL) def strip_html_comments(html): @@ -102,12 +107,27 @@ def get_view_from_id(window, id): def get_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(' ', '.').replace('\n', '
'), 'html.parser')) + return code + def pre_with_br(html): """Because the phantoms of sublime text does not support
 blocks
     this function replaces every \n with a 
in a
"""
     soup = BeautifulSoup(html, 'html.parser')
     for pre in soup.find_all('pre'):
         code = pre.find('code')
-        code.replaceWith(BeautifulSoup(''.join(str(node) for node in pre.contents) \
-                  .replace('\n', '
').replace(' ', '.'), 'html.parser')) + code.replace_with(_pre_with_spaces(code)) 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 diff --git a/lib/pygments_from_theme.py b/lib/pygments_from_theme.py index 88e5ec6..8c0332e 100644 --- a/lib/pygments_from_theme.py +++ b/lib/pygments_from_theme.py @@ -8,7 +8,7 @@ from collections import defaultdict class Style: # .highlight is the wrapper class for highlighting therefore # all css rules are prefixed with .highlight - PREFIX = '.highlight' + PREFIX = '.codehilite' # ----------------------------------------- # 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('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: css_style = st.toString() if css_style: diff --git a/sample.md/sample.md b/sample.md/sample.md new file mode 100644 index 0000000..5f2a85f --- /dev/null +++ b/sample.md/sample.md @@ -0,0 +1,9 @@ +Hello world + +```python +print('Hello world') +if hello: + print('hello') +for i in range(4): + print(i) +``` diff --git a/test.md b/test.md new file mode 100644 index 0000000..3ada6c8 --- /dev/null +++ b/test.md @@ -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!') +```