From 1b2b4494703226d4fd71ef20ef2dee25a62df437 Mon Sep 17 00:00:00 2001 From: facelessuser Date: Fri, 4 Jul 2014 23:00:47 -0600 Subject: [PATCH 1/3] Add github extension and bug fixes - add github extension which includes extra and all extensions that provide a github feel - b64 should return full tag - headeranchor should use unique ids - toc should always occur before headeranchor (usability) --- MarkdownPreview.py | 2 +- markdown/extensions/github.py | 24 ++++++++++++++++++++++++ markdown/extensions/headeranchor.py | 12 +++++++++--- markdown/extensions/toc.py | 6 +++++- 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 markdown/extensions/github.py diff --git a/MarkdownPreview.py b/MarkdownPreview.py index fc706865..998fd225 100644 --- a/MarkdownPreview.py +++ b/MarkdownPreview.py @@ -373,7 +373,7 @@ def postprocessor_base64(self, html): def b64(m): import base64 src = m.group('src') - data = src + data = m.group('tag') filename = self.view.file_name() base_path = "" if filename and os.path.exists(filename): diff --git a/markdown/extensions/github.py b/markdown/extensions/github.py new file mode 100644 index 00000000..898e48ae --- /dev/null +++ b/markdown/extensions/github.py @@ -0,0 +1,24 @@ +from __future__ import unicode_literals +from ..extensions import Extension + +extensions = [ + 'extra', + 'delete', + 'githubemoji', + 'magiclink', + 'tasklist', + 'headeranchor', + 'nl2br' +] + + +class GithubExtension(Extension): + """Add various extensions to Markdown class""" + + def extendMarkdown(self, md, md_globals): + """Register extension instances""" + md.registerExtensions(extensions, self.config) + + +def makeExtension(configs={}): + return GithubExtension(configs=dict(configs)) diff --git a/markdown/extensions/headeranchor.py b/markdown/extensions/headeranchor.py index 315eec84..a9ac9f8c 100644 --- a/markdown/extensions/headeranchor.py +++ b/markdown/extensions/headeranchor.py @@ -17,7 +17,7 @@ from __future__ import absolute_import from ..extensions import Extension from ..treeprocessors import Treeprocessor -from .headerid import slugify, stashedHTML2text, itertext +from .headerid import slugify, stashedHTML2text, itertext, unique LINK = '' @@ -26,13 +26,19 @@ class HeaderAnchorTreeprocessor(Treeprocessor): def run(self, root): """ Add header anchors """ + # Get a list of id attributes + used_ids = set() + for tag in root.getiterator(): + if "id" in tag.attrib: + used_ids.add(tag.attrib["id"]) + for tag in root.getiterator(): if tag.tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'): if "id" in tag.attrib: id = tag.get('id') else: id = stashedHTML2text(''.join(itertext(tag)), self.md) - id = slugify(id, self.config.get('sep')) + id = unique(slugify(id, self.config.get('sep')), used_ids) tag.set('id', id) tag.text = self.markdown.htmlStash.store( LINK % {"id": id}, @@ -59,7 +65,7 @@ def extendMarkdown(self, md, md_globals): if 'toc' in md.treeprocessors.keys(): insertion = ">toc" else: - insertion = ">_end" + insertion = "_end" md.treeprocessors.add("headeranchor", self.processor, insertion) md.registerExtension(self) diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index 89468d60..74c0a131 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -233,7 +233,11 @@ def extendMarkdown(self, md, md_globals): # by the header id extension) if both are used. Same goes for # attr_list extension. This must come last because we don't want # to redefine ids after toc is created. But we do want toc prettified. - md.treeprocessors.add("toc", tocext, "_end") + if 'headeranchor' in md.treeprocessors.keys(): + insertion = " Date: Fri, 4 Jul 2014 23:24:49 -0600 Subject: [PATCH 2/3] Keep extra separate --- markdown/extensions/github.py | 1 - 1 file changed, 1 deletion(-) diff --git a/markdown/extensions/github.py b/markdown/extensions/github.py index 898e48ae..bf8f245c 100644 --- a/markdown/extensions/github.py +++ b/markdown/extensions/github.py @@ -2,7 +2,6 @@ from ..extensions import Extension extensions = [ - 'extra', 'delete', 'githubemoji', 'magiclink', From 48a005db4e454979916b2491717e0a2977a2109b Mon Sep 17 00:00:00 2001 From: facelessuser Date: Sat, 5 Jul 2014 08:37:18 -0600 Subject: [PATCH 3/3] One command to rule the all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add MarkdownPreviewSelectCommand - Quick panel option is now only MarkdownPreviewSelectCommand When multiple parsers are enabled in “enabled_parsers” the user will be prompted for which parser to use. If only one is defined in the list, that parser will automatically be run. --- Default.sublime-commands | 50 +++++------------------ MarkdownPreview.py | 68 ++++++++++++++++++++++++++------ MarkdownPreview.sublime-settings | 10 +++++ 3 files changed, 75 insertions(+), 53 deletions(-) diff --git a/Default.sublime-commands b/Default.sublime-commands index 534cbff0..76aa0442 100644 --- a/Default.sublime-commands +++ b/Default.sublime-commands @@ -1,61 +1,29 @@ [ { - "caption": "Markdown Preview: Python Markdown: Preview in Browser", - "command": "markdown_preview", + "caption": "Markdown Preview: Preview in Browser", + "command": "markdown_preview_select", "args": { - "target": "browser", - "parser": "markdown" + "target": "browser" } }, { - "caption": "Markdown Preview: Python Markdown: Export HTML in Sublime Text", - "command": "markdown_preview", + "caption": "Markdown Preview: Export HTML in Sublime Text", + "command": "markdown_preview_select", "args": { - "target": "sublime", - "parser": "markdown" + "target": "sublime" } }, { - "caption": "Markdown Preview: Python Markdown: Copy to Clipboard", - "command": "markdown_preview", + "caption": "Markdown Preview: Copy to Clipboard", + "command": "markdown_preview_select", "args": { - "target": "clipboard", - "parser": "markdown" + "target": "clipboard" } }, - - { - "caption": "Markdown Preview: Github Flavored Markdown: Preview in Browser", - "command": "markdown_preview", - "args": { - "target": "browser", - "parser": "github" - } - }, - { - "caption": "Markdown Preview: Github Flavored Markdown: Export HTML in Sublime Text", - "command": "markdown_preview", - "args": { - "target": "sublime", - "parser": "github" - } - }, - { - "caption": "Markdown Preview: Github Flavored Markdown: Copy to Clipboard", - "command": "markdown_preview", - "args": { - "target": "clipboard", - "parser": "github" - } - }, { "caption": "Markdown Preview: Open Markdown Cheat sheet", "command": "markdown_cheatsheet", "args": {} } - - - - ] diff --git a/MarkdownPreview.py b/MarkdownPreview.py index 998fd225..bee83c22 100644 --- a/MarkdownPreview.py +++ b/MarkdownPreview.py @@ -219,7 +219,7 @@ def isurl(self, css_name): return True return False - def get_default_css(self, parser): + def get_default_css(self): ''' locate the correct CSS with the 'css' setting ''' css_name = self.settings.get('css', 'default') @@ -231,7 +231,7 @@ def get_default_css(self, parser): return u"" % load_utf8(os.path.expanduser(css_name)) elif css_name == 'default': # use parser CSS file - return u"" % load_resource('github.css' if parser == 'github' else 'markdown.css') + return u"" % load_resource('github.css' if self.parser == 'github' else 'markdown.css') return '' @@ -250,9 +250,9 @@ def get_override_css(self): return u"" % load_utf8(css_filename) return '' - def get_stylesheet(self, parser): + def get_stylesheet(self): ''' return the correct CSS file based on parser and settings ''' - return self.get_default_css(parser) + self.get_override_css() + return self.get_default_css() + self.get_override_css() def get_javascript(self): js_files = self.settings.get('js') @@ -283,7 +283,7 @@ def get_highlight(self): ''' return the Highlight.js and css if enabled ''' highlight = '' - if self.settings.get('enable_highlight') is True and self.settings.get('parser') == 'default': + if self.settings.get('enable_highlight') is True and self.parser == 'default': highlight += "" % load_resource('highlight.css') highlight += "" % load_resource('highlight.js') if self.settings.get("highlight_js_guess", True): @@ -419,7 +419,7 @@ def process_extensions(self, extensions): if filename and os.path.exists(filename): base_path = os.path.dirname(filename) - if self.settings.get("get_highlight") and self.settings.get("parser") == "default": + if self.settings.get("get_highlight") and self.parser == "default": found = False for e in extensions: if e.startswith("codehilite"): @@ -470,11 +470,11 @@ def curl_convert(self, data): sublime.error_message('cannot use github API to convert markdown. SSL is not included in your Python installation. And using curl didn\'t work either') return None - def convert_markdown(self, markdown_text, parser): + def convert_markdown(self, markdown_text): ''' convert input markdown to HTML, with github or builtin parser ''' markdown_html = _CANNOT_CONVERT - if parser == 'github': + if self.parser == 'github': github_oauth_token = self.settings.get('github_oauth_token') # use the github API @@ -514,7 +514,7 @@ def convert_markdown(self, markdown_text, parser): else: sublime.status_message('converted markdown with github API successfully') - elif parser == 'markdown2': + elif self.parser == 'markdown2': # convert the markdown enabled_extras = set(self.get_config_extensions(['footnotes', 'toc', 'fenced-code-blocks', 'cuddled-lists'])) if self.settings.get("enable_mathjax") is True or self.settings.get("enable_highlight") is True: @@ -553,10 +553,11 @@ def run(self, view, parser, wholefile=False): ''' return full html and body html for view. ''' self.settings = sublime.load_settings('MarkdownPreview.sublime-settings') self.view = view + self.parser = parser contents = self.get_contents(wholefile) - body = self.convert_markdown(contents, parser) + body = self.convert_markdown(contents) html_template = self.settings.get('html_template') @@ -564,7 +565,7 @@ def run(self, view, parser, wholefile=False): if html_template and os.path.exists(html_template): head = u'' if not self.settings.get('skip_default_stylesheet'): - head += self.get_stylesheet(parser) + head += self.get_stylesheet() head += self.get_javascript() head += self.get_highlight() head += self.get_mathjax() @@ -576,7 +577,7 @@ def run(self, view, parser, wholefile=False): else: html = u'' html += '' - html += self.get_stylesheet(parser) + html += self.get_stylesheet() html += self.get_javascript() html += self.get_highlight() html += self.get_mathjax() @@ -592,6 +593,49 @@ def run(self, view, parser, wholefile=False): compiler = MarkdownCompiler() +class MarkdownPreviewSelectCommand(sublime_plugin.TextCommand): + def run(self, edit, target='browser'): + parsers = [ + "markdown", + "markdown2", + "github" + ] + + self.target = target + + settings = sublime.load_settings("MarkdownPreview.sublime-settings") + enabled_parsers = set() + for p in settings.get("enabled_parsers", ["markdown", "github"]): + if p in parsers: + enabled_parsers.add(p) + + self.user_parsers = list(enabled_parsers) + + window = self.view.window() + length = len(self.user_parsers) + if window is not None and length: + if length == 1: + self.view.run_command( + "markdown_preview", + { + "parser": self.user_parsers[0], + "target": self.target + } + ) + else: + window.show_quick_panel(self.user_parsers, self.run_command) + + def run_command(self, value): + if value > -1: + self.view.run_command( + "markdown_preview", + { + "parser": self.user_parsers[value], + "target": self.target + } + ) + + class MarkdownPreviewCommand(sublime_plugin.TextCommand): def run(self, edit, parser='markdown', target='browser'): settings = sublime.load_settings('MarkdownPreview.sublime-settings') diff --git a/MarkdownPreview.sublime-settings b/MarkdownPreview.sublime-settings index 7b281ad9..aafcd98d 100644 --- a/MarkdownPreview.sublime-settings +++ b/MarkdownPreview.sublime-settings @@ -55,6 +55,16 @@ */ "enabled_extensions": "default", + /* + Enabled parsers for the parser "select parser" command + Available parsers: markdown, markdown2, github + + When there are more than one parser in the list, Sublime will prompt + via the quick panel for which one to use. If there is only one, it + will automatically run that parser. + */ + "enabed_parsers": ["markdown", "github"], + /* Default mode for the github Markdown parser : markdown (documents) or gfm (comments) see http://developer.github.com/v3/markdown/#render-an-arbitrary-markdown-document