From 9c64ea09049a8e199048a8a5ac479e79e18cae36 Mon Sep 17 00:00:00 2001 From: Felix Hao Date: Tue, 11 Jul 2017 12:48:01 +0800 Subject: [PATCH 01/18] init 2.2.4 --- messages.json | 3 ++- messages/2.2.4.md | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 messages/2.2.4.md diff --git a/messages.json b/messages.json index f45e2820..4fdab49f 100644 --- a/messages.json +++ b/messages.json @@ -23,5 +23,6 @@ "2.2.0": "messages/2.2.0.md", "2.2.1": "messages/2.2.1.md", "2.2.2": "messages/2.2.2.md", - "2.2.3": "messages/2.2.3.md" + "2.2.3": "messages/2.2.3.md", + "2.2.4": "messages/2.2.4.md" } diff --git a/messages/2.2.4.md b/messages/2.2.4.md new file mode 100644 index 00000000..e46a33d8 --- /dev/null +++ b/messages/2.2.4.md @@ -0,0 +1,12 @@ +# MarkdownEditing 2.2.4 Changelog + +Your _MarkdownEditing_ plugin is updated. Enjoy new version. For any type of +feedback you can use [GitHub issues][issues]. + +## Bug Fixes + +## New Features + +## Changes + +[issues]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues From 2d27f8991d5995c2f2f4e5911d50ae69e6371e05 Mon Sep 17 00:00:00 2001 From: Arjen Zonneveld Date: Tue, 11 Jul 2017 12:00:19 +0200 Subject: [PATCH 02/18] Fix spelling: Broswer -> Browser --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f8b1b1d..920559f3 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ Install them if you haven't. Then 1. LiveReload: Enable/Disable Plugins 1. Enable Simple Reload. -Now open palette and choose "Preview in Broswer" and you will get a WYSIWYG editor. +Now open palette and choose "Preview in Browser" and you will get a WYSIWYG editor. ## Related Plugins From 6f26237e43edd99c29662940413ad5b7aa9658c8 Mon Sep 17 00:00:00 2001 From: Felix Hao Date: Fri, 21 Jul 2017 09:57:25 +0800 Subject: [PATCH 03/18] bug fix new reference command fix #451 --- messages/2.2.4.md | 2 ++ references.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/messages/2.2.4.md b/messages/2.2.4.md index e46a33d8..8bb0981e 100644 --- a/messages/2.2.4.md +++ b/messages/2.2.4.md @@ -5,6 +5,8 @@ feedback you can use [GitHub issues][issues]. ## Bug Fixes +* Fix an issue that occationally prevents creating link references with command + ## New Features ## Changes diff --git a/references.py b/references.py index 11e2ec85..eb686762 100644 --- a/references.py +++ b/references.py @@ -245,7 +245,7 @@ def check_for_link(view, link): refs = getReferences(view) link = link.strip() for name in refs: - link_begin = findScopeFrom(view, refs[name][0].begin(), ref_link_scope_name) + link_begin = findScopeFrom(view, refs[name].regions[0].begin(), ref_link_scope_name) reg = getCurrentScopeRegion(view, link_begin) found_link = view.substr(reg).strip() if found_link == link: @@ -317,7 +317,7 @@ def run(self, edit): def get_next_footnote_marker(view): refs = getReferences(view) - footnotes = [int(ref[1:]) for ref in refs if view.substr(refs[ref][0])[0] == "^"] + footnotes = [int(ref[1:]) for ref in refs if view.substr(refs[ref].regions[0])[0] == "^"] def target_loc(num): return (num - 1) % len(footnotes) From b9a6d77b922fd5b7027884ab6b8431527b875e77 Mon Sep 17 00:00:00 2001 From: Kristinita Date: Fri, 21 Jul 2017 08:13:10 +0300 Subject: [PATCH 04/18] [Add] SublimeLinter and PersistentRegexHighlight support --- MarkdownEditor.tmTheme | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/MarkdownEditor.tmTheme b/MarkdownEditor.tmTheme index d65842f4..3f007da0 100644 --- a/MarkdownEditor.tmTheme +++ b/MarkdownEditor.tmTheme @@ -897,6 +897,72 @@ #565656 + + + + name + Highlight Color Warm Blue + scope + highlight.color.ADD8E6 + settings + + foreground + #ADD8E6 + + + + + name + Highlight Color MistyRose + scope + highlight.color.FFE4E1 + settings + + foreground + #FFE4E1 + + + + + name + Highlight Color Green Tea + scope + highlight.color.D0F0C0 + settings + + foreground + #D0F0C0 + + + + + + name + SublimeLinter: Warning + scope + sublimelinter.mark.warning + settings + + foreground + #DDB700 + + + + + name + SublimeLinter: Error + scope + sublimelinter.mark.error + settings + + foreground + #D02000 + + uuid BF4E1964-0DB9-4E88-8142-E8F52D7EDEEC From 9365e98a74da3653d98fba1d7b7800076f4146d7 Mon Sep 17 00:00:00 2001 From: Felix Hao Date: Wed, 26 Jul 2017 17:33:38 +0800 Subject: [PATCH 05/18] auto-converted sublime-syntax --- Markdown.sublime-syntax | 916 ++++++++++++++++ Markdown.tmLanguage | 2277 --------------------------------------- 2 files changed, 916 insertions(+), 2277 deletions(-) create mode 100644 Markdown.sublime-syntax delete mode 100644 Markdown.tmLanguage diff --git a/Markdown.sublime-syntax b/Markdown.sublime-syntax new file mode 100644 index 00000000..6635aff7 --- /dev/null +++ b/Markdown.sublime-syntax @@ -0,0 +1,916 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Markdown GFM +file_extensions: + - md + - mdown + - markdown + - markdn +scope: text.html.markdown.gfm +contexts: + main: + - match: |- + (?x)^ + (?= [ ]{,3}> + | ([ ]{4}|\t)(?!$) + | [#]{1,6}\s*+ + | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ + ) + comment: | + We could also use an empty end match and set + applyEndPatternLast, but then we must be sure that the begin + pattern will only match stuff matched by the sub-patterns. + push: + - meta_scope: meta.block-level.markdown + - match: |- + (?x)^ + (?! [ ]{,3}> + | ([ ]{4}|\t) + | [#]{1,6}\s*+ + | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ + ) + pop: true + - include: block_quote + - include: block_raw + - include: heading + - include: separator + - match: '^[ ]{0,3}([*+-])(?=\s)' + captures: + 1: punctuation.definition.list_item.markdown + push: + - meta_scope: markup.list.unnumbered.markdown + - match: ^(?=\S) + captures: + 1: punctuation.definition.list_item.markdown + pop: true + - include: fenced-code-blocks + - include: list-paragraph + - match: '^[ ]{0,3}([0-9]+\.)(?=\s)' + captures: + 1: punctuation.definition.list_item.markdown + push: + - meta_scope: markup.list.numbered.markdown + - match: ^(?=\S) + captures: + 1: punctuation.definition.list_item.markdown + pop: true + - include: fenced-code-blocks + - include: list-paragraph + - include: fenced-code-blocks + - match: '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|noscript|form|fieldset|iframe|math|ins|del)\b[^>]*>)(?!.*?)' + comment: Markdown formatting is disabled inside block-level tags. + push: + - meta_scope: meta.disable-markdown + - match: (?<=^$\n) + pop: true + - include: tag-kbd + - include: scope:text.html.basic + - match: '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|noscript|form|fieldset|iframe|math|ins|del)\b[^>]*>)' + comment: Same rule but for one line disables. + push: + - meta_scope: meta.disable-markdown + - match: $\n? + pop: true + - include: tag-kbd + - include: scope:text.html.basic + - match: |- + (?x: + \s* # Leading whitespace + (\[)(\^\d+?)(\])(:) # Reference name + [ \t]* # Optional whitespace + (.+?) # The footnote + [ \t]* # Optional whitespace + $ + ) + scope: meta.link.reference.footnote.markdown + captures: + 1: punctuation.definition.constant.begin.markdown + 2: constant.other.reference.link.markdown + 3: punctuation.definition.constant.end.markdown + 4: punctuation.separator.key-value.markdown + 5: meta.paragraph.markdown + - match: |- + (?x: + \s* # Leading whitespace + (\[)(.+?)(\])(:) # Reference name + [ \t]* # Optional whitespace + (?) # The url + [ \t]* # Optional whitespace + (?: + ((\().+?(\))) # Match title in quotes… + | ((").+?(")) # or in parens. + )? # Title is optional + [ \t]* # Optional whitespace + $ + ) + scope: meta.link.reference.def.markdown + captures: + 1: punctuation.definition.constant.begin.markdown + 2: constant.other.reference.link.markdown + 3: punctuation.definition.constant.end.markdown + 4: punctuation.separator.key-value.markdown + 5: punctuation.definition.link.markdown + 6: markup.underline.link.markdown + 7: punctuation.definition.link.markdown + 8: string.other.link.description.title.markdown + 9: punctuation.definition.string.begin.markdown + 10: punctuation.definition.string.end.markdown + 11: string.other.link.description.title.markdown + 12: punctuation.definition.string.begin.markdown + 13: punctuation.definition.string.end.markdown + - match: '^(?=\S)(?![=-]{3,}(?=$))' + push: + - meta_scope: meta.paragraph.markdown + - match: '^(?:\s*$|(?=[ ]{,3}>)|(?=```|~~~))|(?=[ \t]*\n)(?<=^===|^====|=====|^---|^----|-----)[ \t]*\n|(?=^#)' + pop: true + - include: inline + - include: scope:text.html.basic + - match: '^(={3,})(?=[ \t]*$)' + scope: markup.heading.1.markdown + captures: + 1: punctuation.definition.heading.markdown + - match: '^(-{3,})(?=[ \t]*$)' + scope: markup.heading.2.markdown + captures: + 1: punctuation.definition.heading.markdown + ampersand: + - match: "&(?!([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+);)" + comment: | + Markdown will convert this for us. We match it so that the + HTML grammar will not mark it up as invalid. + scope: meta.other.valid-ampersand.markdown + block_quote: + - match: '\G[ ]{,3}(>)[ ]?' + comment: | + We terminate the block quote when seeing an empty line, a + separator or a line with leading > characters. The latter is + to “reset” the quote level for quoted lines. + captures: + 1: punctuation.definition.blockquote.markdown + push: + - meta_scope: markup.quote.markdown + - match: |- + (?x)^ + (?= \s*$ + | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ + | [ ]{,3}> + ) + pop: true + - match: |- + (?x)\G + (?= [ ]{,3}> + ) + push: + - match: ^ + pop: true + - include: block_quote + - match: |- + (?x)\G + (?= ([ ]{4}|\t) + | [#]{1,6}\s*+ + | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ + ) + push: + - include: block_raw + - include: heading + - include: separator + - match: ^ + pop: true + - match: |- + (?x)\G + (?! $ + | [ ]{,3}> + | ([ ]{4}|\t) + | [#]{1,6}\s*+ + | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ + ) + push: + - match: $|(?<=\n) + pop: true + - include: inline + - include: scope:text.html.basic + block_raw: + - match: '\G([ ]{4}|\t).*$\n?' + scope: markup.raw.block.markdown + bold: + - match: |- + (?x) + (?]*+> # HTML tags + | (?`+)([^`]|(?!(?(?!`))`)*+\k + # Raw + | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes + | \[ + ( + (? # Named group + [^\[\]\\] # Match most chars + | \\. # Escaped chars + | \[ \g*+ \] # Nested brackets + )*+ + \] + ( + ( # Reference Link + [ ]? # Optional space + \[[^\]]*+\] # Ref name + ) + | ( # Inline Link + \( # Opening paren + [ \t]*+ # Optional whtiespace + ? # URL + [ \t]*+ # Optional whtiespace + ( # Optional Title + (?['"]) + (.*?) + \k<title> + )? + \) + ) + ) + ) + | (?!(?<=\S)\1). # Everything besides + # style closer + )++ + (?<=\S)\1 # Close + ) + captures: + 1: punctuation.definition.bold.markdown + push: + - meta_scope: markup.bold.markdown + - match: (?<=\S)(\1) + captures: + 1: punctuation.definition.bold.markdown + pop: true + - match: "(?=<[^>]*?>)" + push: + - include: tag-kbd + - include: scope:text.html.basic + - match: (?<=>) + pop: true + - include: escape + - include: ampersand + - include: bracket + - include: raw + - include: bold_italic + - include: italic + - include: strikethrough + - include: image-inline + - include: link-inline + - include: link-inet + - include: link-email + - include: image-ref + - include: link-ref + - include: link-ref-literal + - include: link-footnote + bold_italic: + - match: |- + (?x) + (?<!\w)(\*|_)(?=\1\1)(\1\1)(?=\S) # Open + (?= + ( + <[^>]*+> # HTML tags + | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> + # Raw + | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes + | \[ + ( + (?<square> # Named group + [^\[\]\\] # Match most chars + | \\. # Escaped chars + | \[ \g<square>*+ \] # Nested brackets + )*+ + \] + ( + ( # Reference Link + [ ]? # Optional space + \[[^\]]*+\] # Ref name + ) + | ( # Inline Link + \( # Opening paren + [ \t]*+ # Optional whtiespace + <?(.*?)>? # URL + [ \t]*+ # Optional whtiespace + ( # Optional Title + (?<title>['"]) + (.*?) + \k<title> + )? + \) + ) + ) + ) + | (?!(?<=\S)\1{3}(?!\1)). # Everything besides + # style closer + )++ + (?<=\S)\1{3}(?!\1) # Close + ) + captures: + 1: punctuation.definition.bold.markdown + 2: punctuation.definition.bold.markdown + push: + - meta_scope: markup.bold_italic.markdown + - match: '(?<=\S)(\1{3})(?!\1)' + captures: + 1: punctuation.definition.bold.markdown + 2: punctuation.definition.bold.markdown + pop: true + - match: "(?=<[^>]*?>)" + push: + - include: tag-kbd + - include: scope:text.html.basic + - match: (?<=>) + pop: true + - include: escape + - include: ampersand + - include: bracket + - include: raw + - include: italic + - include: strikethrough + - include: image-inline + - include: link-inline + - include: link-inet + - include: link-email + - include: image-ref + - include: link-ref + - include: link-ref-literal + - include: link-footnote + bracket: + - match: '<(?![a-z/?\$!])' + comment: | + Markdown will convert this for us. We match it so that the + HTML grammar will not mark it up as invalid. + scope: meta.other.valid-bracket.markdown + escape: + - match: '\\[-`*_#+.!(){}\[\]\\>]' + scope: constant.character.escape.markdown + fenced-c: + - match: '^(\s*[`~]{3,})\s*(c)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.c + fenced-csharp: + - match: '^(\s*[`~]{3,})\s*(c(?:s|sharp|#))\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.cs + fenced-c++: + - match: '^(\s*[`~]{3,})\s*(c\+\+|cpp)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.c++ + fenced-clojure: + - match: '^(\s*[`~]{3,})\s*(clojure)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.clojure + fenced-code-blocks: + - include: fenced-html + - include: fenced-xml + - include: fenced-diff + - include: fenced-perl + - include: fenced-php + - include: fenced-css + - include: fenced-less + - include: fenced-java + - include: fenced-c + - include: fenced-c++ + - include: fenced-csharp + - include: fenced-yaml + - include: fenced-sql + - include: fenced-shell + - include: fenced-sass + - include: fenced-scss + - include: fenced-scala + - include: fenced-obj-c + - include: fenced-coffee + - include: fenced-js + - include: fenced-ts + - include: fenced-tsx + - include: fenced-ruby + - include: fenced-python + - include: fenced-lisp + - include: fenced-lua + - include: fenced-scheme + - include: fenced-swift + - include: fenced-clojure + - include: fenced-undefined + fenced-coffee: + - match: '^(\s*[`~]{3,})\s*(coffee|cjsx)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.coffee + fenced-css: + - match: '^(\s*[`~]{3,})\s*(css)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.css + fenced-diff: + - match: '^(\s*[`~]{3,})\s*(diff|patch)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.diff + fenced-html: + - match: '^(\s*[`~]{3,})\s*(html|html5)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:text.html.basic + fenced-java: + - match: '^(\s*[`~]{3,})\s*(java)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.java + fenced-js: + - match: '^(\s*[`~]{3,})\s*(js|jsx|json|javascript)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.js + fenced-less: + - match: '^(\s*[`~]{3,})\s*(less)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.less + fenced-lisp: + - match: '^(\s*[`~]{3,})\s*(lisp)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.lisp + fenced-lua: + - match: '^(\s*[`~]{3,})\s*(lua)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.lua + fenced-obj-c: + - match: '^(\s*[`~]{3,})\s*(obj(ective-)?c)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.objc + fenced-perl: + - match: '^(\s*[`~]{3,})\s*(perl)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.perl + fenced-php: + - match: '^(\s*[`~]{3,})\s*(php)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.php + fenced-python: + - match: '^(\s*[`~]{3,})\s*(py|python)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.python + fenced-ruby: + - match: '^(\s*[`~]{3,})\s*(ruby)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.ruby + fenced-sass: + - match: '^(\s*[`~]{3,})\s*(sass)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.sass + fenced-scala: + - match: '^(\s*[`~]{3,})\s*(scala)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.scala + fenced-scheme: + - match: '^(\s*[`~]{3,})\s*(scheme)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.scheme + fenced-scss: + - match: '^(\s*[`~]{3,})\s*(scss)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.scss + fenced-shell: + - match: '^(\s*[`~]{3,})\s*(sh|shell|bash)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.shell + fenced-sql: + - match: '^(\s*[`~]{3,})\s*(sql)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.sql + fenced-swift: + - match: '^(\s*[`~]{3,})\s*(swift)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.swift + fenced-ts: + - match: '^(\s*[`~]{3,})\s*(ts|typescript)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.ts + fenced-tsx: + - match: '^(\s*[`~]{3,})\s*(tsx)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.tsx + fenced-undefined: + - match: '^(\s*[`~]{3,}).*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + fenced-xml: + - match: '^(\s*[`~]{3,})\s*(xml)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:text.xml + fenced-yaml: + - match: '^(\s*[`~]{3,})\s*(yaml)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.yaml + heading: + - match: '\G(#{1,6})(?!#)\s*(?=\S)' + captures: + 1: punctuation.definition.heading.markdown + push: + - meta_scope: markup.heading.markdown + - meta_content_scope: entity.name.section.markdown + - match: '[ \t]*(#*)$' + captures: + 1: punctuation.definition.heading.markdown + pop: true + - include: inline + image-inline: + - match: |- + (?x: + \! # Images start with ! + (\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\]) + # Match the link text. + ([ ])? # Space not allowed + (\() # Opening paren for url + (<?)(\S+?)(>?) # The url + [ \t]* # Optional whitespace + (?: + ((\().+?(\))) # Match title in parens… + | ((").+?(")) # or in quotes. + )? # Title is optional + \s* # Optional whitespace + (\)) + ) + scope: meta.image.inline.markdown + captures: + 1: punctuation.definition.string.begin.markdown + 2: string.other.link.description.markdown + 4: punctuation.definition.string.end.markdown + 5: invalid.illegal.whitespace.markdown + 6: punctuation.definition.metadata.markdown + 7: punctuation.definition.link.markdown + 8: markup.underline.link.image.markdown + 9: punctuation.definition.link.markdown + 10: string.other.link.description.title.markdown + 11: punctuation.definition.string.markdown + 12: punctuation.definition.string.markdown + 13: string.other.link.description.title.markdown + 14: punctuation.definition.string.markdown + 15: punctuation.definition.string.markdown + 16: punctuation.definition.metadata.markdown + image-ref: + - match: '\!(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(\[)(.*?)(\])' + scope: meta.image.reference.markdown + captures: + 1: punctuation.definition.string.begin.markdown + 2: string.other.link.description.markdown + 4: punctuation.definition.string.end.markdown + 5: punctuation.definition.constant.begin.markdown + 6: constant.other.reference.link.markdown + 7: punctuation.definition.constant.end.markdown + inline: + - include: escape + - include: ampersand + - include: bracket + - include: raw + - include: bold_italic + - include: bold + - include: italic + - include: strikethrough + - include: line-break + - include: image-inline + - include: link-inline + - include: link-inet + - include: link-email + - include: image-ref + - include: link-ref + - include: link-ref-literal + - include: link-footnote + - include: tag-kbd + - include: scope:text.html.basic + italic: + - match: |- + (?x) + (?<!\w)(\*|_)(?=\S) # Open + (?= + ( + <[^>]*+> # HTML tags + | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> + # Raw + | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes + | \[ + ( + (?<square> # Named group + [^\[\]\\] # Match most chars + | \\. # Escaped chars + | \[ \g<square>*+ \] # Nested brackets + )*+ + \] + ( + ( # Reference Link + [ ]? # Optional space + \[[^\]]*+\] # Ref name + ) + | ( # Inline Link + \( # Opening paren + [ \t]*+ # Optional whtiespace + <?(.*?)>? # URL + [ \t]*+ # Optional whtiespace + ( # Optional Title + (?<title>['"]) + (.*?) + \k<title> + )? + \) + ) + ) + ) + | \1\1 # Must be bold closer + | (?!(?<=\S)\1). # Everything besides + # style closer + )++ + (?<=\S)\1 # Close + ) + captures: + 1: punctuation.definition.italic.markdown + push: + - meta_scope: markup.italic.markdown + - match: (?<=\S)(\1)((?!\1)|(?=\1\1)) + captures: + 1: punctuation.definition.italic.markdown + pop: true + - match: "(?=<[^>]*?>)" + push: + - include: tag-kbd + - include: scope:text.html.basic + - match: (?<=>) + pop: true + - include: escape + - include: ampersand + - include: bracket + - include: raw + - include: bold_italic + - include: bold + - include: strikethrough + - include: image-inline + - include: link-inline + - include: link-inet + - include: link-email + - include: image-ref + - include: link-ref + - include: link-ref-literal + - include: link-footnote + line-break: + - match: " {2,}$" + scope: meta.dummy.line-break + link-email: + - match: '(<)?((?:mailto:)?[-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(>)?' + scope: meta.link.email.lt-gt.markdown + captures: + 1: punctuation.definition.link.markdown + 2: markup.underline.link.markdown + 4: punctuation.definition.link.markdown + link-footnote: + - match: '(\[)(\^[^\]]*+)(\])' + scope: meta.link.reference.markdown + captures: + 1: punctuation.definition.constant.begin.markdown + 2: constant.other.reference.link.markdown + 3: punctuation.definition.constant.end.markdown + link-inet: + - match: '(<)?(\b(?:https?|ftp|file|git):///?[^\s()<>\[\]]+)(>)?' + scope: meta.link.inet.markdown + captures: + 1: punctuation.definition.link.markdown + 2: markup.underline.link.markdown + 3: punctuation.definition.link.markdown + link-inline: + - match: |- + (?x: + (\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\]) + # Match the link text. + ([ ])? # Space not allowed + (\() # Opening paren for url + (<?)(.*?)(>?) # The url + [ \t]* # Optional whitespace + (?: + ((\().+?(\))) # Match title in parens… + | ((").+?(")) # or in quotes. + )? # Title is optional + \s* # Optional whitespace + (\)) + ) + scope: meta.link.inline.markdown + captures: + 1: punctuation.definition.string.begin.markdown + 2: string.other.link.title.markdown + 4: punctuation.definition.string.end.markdown + 5: invalid.illegal.whitespace.markdown + 6: punctuation.definition.metadata.markdown + 7: punctuation.definition.link.markdown + 8: markup.underline.link.markdown + 9: punctuation.definition.link.markdown + 10: string.other.link.description.title.markdown + 11: punctuation.definition.string.begin.markdown + 12: punctuation.definition.string.end.markdown + 13: string.other.link.description.title.markdown + 14: punctuation.definition.string.begin.markdown + 15: punctuation.definition.string.end.markdown + 16: punctuation.definition.metadata.markdown + link-ref: + - match: '(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(\[)([^\]]*+)(\])' + scope: meta.link.reference.markdown + captures: + 1: punctuation.definition.string.begin.markdown + 2: string.other.link.title.markdown + 4: punctuation.definition.string.end.markdown + 5: punctuation.definition.constant.begin.markdown + 6: constant.other.reference.link.markdown + 7: punctuation.definition.constant.end.markdown + link-ref-literal: + - match: '(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(?:(\[)(\]))?' + scope: meta.link.reference.literal.markdown + captures: + 1: punctuation.definition.string.begin.markdown + 2: string.other.link.title.markdown + 4: punctuation.definition.string.end.markdown + 5: punctuation.definition.constant.begin.markdown + 6: punctuation.definition.constant.end.markdown + list-paragraph: + - match: \G\s+(?=\S) + push: + - meta_scope: meta.paragraph.list.markdown + - match: ^\s*$ + pop: true + - include: inline + - match: '\G\s*([*\-+]|[0-9]+\.)\s+' + captures: + 1: punctuation.definition.list_item.markdown + - include: scope:text.html.basic + - include: fenced-code-blocks + raw: + - match: '(`+)((?:[^`]|(?!(?<!`)\1(?!`))`)*+)(\1)' + scope: markup.raw.inline.markdown + captures: + 1: punctuation.definition.raw.markdown + 2: markup.raw.inline.content.markdown + 3: punctuation.definition.raw.markdown + separator: + - match: '\G[ ]{,3}([-*_])([ ]{,2}\1){2,}[ \t]*$\n?' + scope: meta.separator.markdown + strikethrough: + - match: |- + (?x) + (?<!\w)(~~)(?=[^\s~]) # Open + (?= + ( + <[^>]*+> # HTML tags + | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> + # Raw + | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes + | \[ + ( + (?<square> # Named group + [^\[\]\\] # Match most chars + | \\. # Escaped chars + | \[ \g<square>*+ \] # Nested brackets + )*+ + \] + ( + ( # Reference Link + [ ]? # Optional space + \[[^\]]*+\] # Ref name + ) + | ( # Inline Link + \( # Opening paren + [ \t]*+ # Optional whtiespace + <?(.*?)>? # URL + [ \t]*+ # Optional whtiespace + ( # Optional Title + (?<title>['"]) + (.*?) + \k<title> + )? + \) + ) + ) + ) + | (?!(?<=\S)\1). # Everything besides + # style closer + )++ + ) + captures: + 1: punctuation.definition.strikethrough.markdown + push: + - meta_scope: markup.strikethrough.markdown + - match: (?<=\S)(\1)(?!\w) + captures: + 1: punctuation.definition.strikethrough.markdown + pop: true + - match: "(?=<[^>]*?>)" + push: + - include: tag-kbd + - include: scope:text.html.basic + - match: (?<=>) + pop: true + - include: escape + - include: ampersand + - include: bracket + - include: raw + - include: bold_italic + - include: bold + - include: italic + - include: image-inline + - include: link-inline + - include: link-inet + - include: link-email + - include: image-ref + - include: link-ref + - include: link-ref-literal + - include: link-footnote + tag-kbd: + - match: "((<)(kbd)(>))([^<]+)((</)(kbd)(>))" + scope: markup.kbd.markdown + captures: + 1: meta.tag.other.html + 2: punctuation.definition.tag.begin.html + 3: entity.name.tag.other.html + 4: punctuation.definition.tag.end.html + 5: markup.kbd.content.markdown + 6: meta.tag.other.html + 7: punctuation.definition.tag.begin.html + 8: entity.name.tag.other.html + 9: punctuation.definition.tag.end.html diff --git a/Markdown.tmLanguage b/Markdown.tmLanguage deleted file mode 100644 index d8ea3786..00000000 --- a/Markdown.tmLanguage +++ /dev/null @@ -1,2277 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>fileTypes</key> - <array> - <string>md</string> - <string>mdown</string> - <string>markdown</string> - <string>markdn</string> - </array> - <key>foldingStartMarker</key> - <string>(?x) - (<(?i:head|body|table|thead|tbody|tfoot|tr|div|select|fieldset|style|script|ul|ol|form|dl)\b.*?> - |<!--(?!.*-->) - |\{\s*($|\?>\s*$|//|/\*(.*\*/\s*$|(?!.*?\*/))) - )</string> - <key>foldingStopMarker</key> - <string>(?x) - (</(?i:head|body|table|thead|tbody|tfoot|tr|div|select|fieldset|style|script|ul|ol|form|dl)> - |^\s*--> - |(^|\s)\} - )</string> - <key>keyEquivalent</key> - <string>^~M</string> - <key>name</key> - <string>Markdown GFM</string> - <key>patterns</key> - <array> - <dict> - <key>begin</key> - <string>(?x)^ - (?= [ ]{,3}> - | ([ ]{4}|\t)(?!$) - | [#]{1,6}\s*+ - | [ ]{,3}(?<marker>[-*_])([ ]{,2}\k<marker>){2,}[ \t]*+$ - )</string> - <key>comment</key> - <string> - We could also use an empty end match and set - applyEndPatternLast, but then we must be sure that the begin - pattern will only match stuff matched by the sub-patterns. - </string> - <key>end</key> - <string>(?x)^ - (?! [ ]{,3}> - | ([ ]{4}|\t) - | [#]{1,6}\s*+ - | [ ]{,3}(?<marker>[-*_])([ ]{,2}\k<marker>){2,}[ \t]*+$ - )</string> - <key>name</key> - <string>meta.block-level.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#block_quote</string> - </dict> - <dict> - <key>include</key> - <string>#block_raw</string> - </dict> - <dict> - <key>include</key> - <string>#heading</string> - </dict> - <dict> - <key>include</key> - <string>#separator</string> - </dict> - </array> - </dict> - <dict> - <key>begin</key> - <string>^[ ]{0,3}([*+-])(?=\s)</string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.list_item.markdown</string> - </dict> - </dict> - <key>end</key> - <string>^(?=\S)</string> - <key>name</key> - <string>markup.list.unnumbered.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#fenced-code-blocks</string> - </dict> - <dict> - <key>include</key> - <string>#list-paragraph</string> - </dict> - </array> - </dict> - <dict> - <key>begin</key> - <string>^[ ]{0,3}([0-9]+\.)(?=\s)</string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.list_item.markdown</string> - </dict> - </dict> - <key>end</key> - <string>^(?=\S)</string> - <key>name</key> - <string>markup.list.numbered.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#fenced-code-blocks</string> - </dict> - <dict> - <key>include</key> - <string>#list-paragraph</string> - </dict> - </array> - </dict> - <dict> - <key>include</key> - <string>#fenced-code-blocks</string> - </dict> - <dict> - <key>begin</key> - <string>^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|noscript|form|fieldset|iframe|math|ins|del)\b[^>]*>)(?!.*?</\1>)</string> - <key>comment</key> - <string> - Markdown formatting is disabled inside block-level tags. - </string> - <key>end</key> - <string>(?<=^</\1>$\n)</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#tag-kbd</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - <key>name</key> - <string>meta.disable-markdown</string> - </dict> - <dict> - <key>begin</key> - <string>^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|noscript|form|fieldset|iframe|math|ins|del)\b[^>]*>)</string> - <key>comment</key> - <string>Same rule but for one line disables.</string> - <key>end</key> - <string>$\n?</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#tag-kbd</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - <key>name</key> - <string>meta.disable-markdown</string> - </dict> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.begin.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>constant.other.reference.link.markdown</string> - </dict> - <key>3</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.end.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.separator.key-value.markdown</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>meta.paragraph.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(?x: - \s* # Leading whitespace - (\[)(\^\d+?)(\])(:) # Reference name - [ \t]* # Optional whitespace - (.+?) # The footnote - [ \t]* # Optional whitespace - $ - )</string> - <key>name</key> - <string>meta.link.reference.footnote.markdown</string> - </dict> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.begin.markdown</string> - </dict> - <key>10</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>11</key> - <dict> - <key>name</key> - <string>string.other.link.description.title.markdown</string> - </dict> - <key>12</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>13</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>constant.other.reference.link.markdown</string> - </dict> - <key>3</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.end.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.separator.key-value.markdown</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - <key>6</key> - <dict> - <key>name</key> - <string>markup.underline.link.markdown</string> - </dict> - <key>7</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - <key>8</key> - <dict> - <key>name</key> - <string>string.other.link.description.title.markdown</string> - </dict> - <key>9</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(?x: - \s* # Leading whitespace - (\[)(.+?)(\])(:) # Reference name - [ \t]* # Optional whitespace - (<?)(\S+?)(>?) # The url - [ \t]* # Optional whitespace - (?: - ((\().+?(\))) # Match title in quotes… - | ((").+?(")) # or in parens. - )? # Title is optional - [ \t]* # Optional whitespace - $ - )</string> - <key>name</key> - <string>meta.link.reference.def.markdown</string> - </dict> - <dict> - <key>begin</key> - <string>^(?=\S)(?![=-]{3,}(?=$))</string> - <key>end</key> - <string>^(?:\s*$|(?=[ ]{,3}>)|(?=```|~~~))|(?=[ \t]*\n)(?<=^===|^====|=====|^---|^----|-----)[ \t]*\n|(?=^#)</string> - <key>name</key> - <string>meta.paragraph.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#inline</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.heading.markdown</string> - </dict> - </dict> - <key>match</key> - <string>^(={3,})(?=[ \t]*$)</string> - <key>name</key> - <string>markup.heading.1.markdown</string> - </dict> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.heading.markdown</string> - </dict> - </dict> - <key>match</key> - <string>^(-{3,})(?=[ \t]*$)</string> - <key>name</key> - <string>markup.heading.2.markdown</string> - </dict> - </array> - </dict> - </array> - <key>repository</key> - <dict> - <key>ampersand</key> - <dict> - <key>comment</key> - <string> - Markdown will convert this for us. We match it so that the - HTML grammar will not mark it up as invalid. - </string> - <key>match</key> - <string>&(?!([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+);)</string> - <key>name</key> - <string>meta.other.valid-ampersand.markdown</string> - </dict> - <key>block_quote</key> - <dict> - <key>begin</key> - <string>\G[ ]{,3}(>)[ ]?</string> - <key>beginCaptures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.blockquote.markdown</string> - </dict> - </dict> - <key>comment</key> - <string> - We terminate the block quote when seeing an empty line, a - separator or a line with leading > characters. The latter is - to “reset” the quote level for quoted lines. - </string> - <key>end</key> - <string>(?x)^ - (?= \s*$ - | [ ]{,3}(?<marker>[-*_])([ ]{,2}\k<marker>){2,}[ \t]*+$ - | [ ]{,3}> - )</string> - <key>name</key> - <string>markup.quote.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>begin</key> - <string>(?x)\G - (?= [ ]{,3}> - )</string> - <key>end</key> - <string>^</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#block_quote</string> - </dict> - </array> - </dict> - <dict> - <key>applyEndPatternLast</key> - <integer>1</integer> - <key>begin</key> - <string>(?x)\G - (?= ([ ]{4}|\t) - | [#]{1,6}\s*+ - | [ ]{,3}(?<marker>[-*_])([ ]{,2}\k<marker>){2,}[ \t]*+$ - )</string> - <key>end</key> - <string>^</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#block_raw</string> - </dict> - <dict> - <key>include</key> - <string>#heading</string> - </dict> - <dict> - <key>include</key> - <string>#separator</string> - </dict> - </array> - </dict> - <dict> - <key>begin</key> - <string>(?x)\G - (?! $ - | [ ]{,3}> - | ([ ]{4}|\t) - | [#]{1,6}\s*+ - | [ ]{,3}(?<marker>[-*_])([ ]{,2}\k<marker>){2,}[ \t]*+$ - )</string> - <key>end</key> - <string>$|(?<=\n)</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#inline</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - </dict> - </array> - </dict> - <key>block_raw</key> - <dict> - <key>match</key> - <string>\G([ ]{4}|\t).*$\n?</string> - <key>name</key> - <string>markup.raw.block.markdown</string> - </dict> - <key>bold_italic</key> - <dict> - <key>begin</key> - <string>(?x) - (?<!\w)(\*|_)(?=\1\1)(\1\1)(?=\S) # Open - (?= - ( - <[^>]*+> # HTML tags - | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> - # Raw - | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes - | \[ - ( - (?<square> # Named group - [^\[\]\\] # Match most chars - | \\. # Escaped chars - | \[ \g<square>*+ \] # Nested brackets - )*+ - \] - ( - ( # Reference Link - [ ]? # Optional space - \[[^\]]*+\] # Ref name - ) - | ( # Inline Link - \( # Opening paren - [ \t]*+ # Optional whtiespace - <?(.*?)>? # URL - [ \t]*+ # Optional whtiespace - ( # Optional Title - (?<title>['"]) - (.*?) - \k<title> - )? - \) - ) - ) - ) - | (?!(?<=\S)\1{3}(?!\1)). # Everything besides - # style closer - )++ - (?<=\S)\1{3}(?!\1) # Close - ) - </string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.bold.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>punctuation.definition.bold.markdown</string> - </dict> - </dict> - <key>end</key> - <string>(?<=\S)(\1{3})(?!\1)</string> - <key>name</key> - <string>markup.bold_italic.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>applyEndPatternLast</key> - <integer>1</integer> - <key>begin</key> - <string>(?=<[^>]*?>)</string> - <key>end</key> - <string>(?<=>)</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#tag-kbd</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - </dict> - <dict> - <key>include</key> - <string>#escape</string> - </dict> - <dict> - <key>include</key> - <string>#ampersand</string> - </dict> - <dict> - <key>include</key> - <string>#bracket</string> - </dict> - <dict> - <key>include</key> - <string>#raw</string> - </dict> - <dict> - <key>include</key> - <string>#italic</string> - </dict> - <dict> - <key>include</key> - <string>#strikethrough</string> - </dict> - <dict> - <key>include</key> - <string>#image-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inet</string> - </dict> - <dict> - <key>include</key> - <string>#link-email</string> - </dict> - <dict> - <key>include</key> - <string>#image-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref-literal</string> - </dict> - <dict> - <key>include</key> - <string>#link-footnote</string> - </dict> - </array> - </dict> - <key>bold</key> - <dict> - <key>begin</key> - <string>(?x) - (?<!\w)(\*\*|__)(?=\S) # Open - (?= - ( - <[^>]*+> # HTML tags - | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> - # Raw - | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes - | \[ - ( - (?<square> # Named group - [^\[\]\\] # Match most chars - | \\. # Escaped chars - | \[ \g<square>*+ \] # Nested brackets - )*+ - \] - ( - ( # Reference Link - [ ]? # Optional space - \[[^\]]*+\] # Ref name - ) - | ( # Inline Link - \( # Opening paren - [ \t]*+ # Optional whtiespace - <?(.*?)>? # URL - [ \t]*+ # Optional whtiespace - ( # Optional Title - (?<title>['"]) - (.*?) - \k<title> - )? - \) - ) - ) - ) - | (?!(?<=\S)\1). # Everything besides - # style closer - )++ - (?<=\S)\1 # Close - ) - </string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.bold.markdown</string> - </dict> - </dict> - <key>end</key> - <string>(?<=\S)(\1)</string> - <key>name</key> - <string>markup.bold.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>applyEndPatternLast</key> - <integer>1</integer> - <key>begin</key> - <string>(?=<[^>]*?>)</string> - <key>end</key> - <string>(?<=>)</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#tag-kbd</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - </dict> - <dict> - <key>include</key> - <string>#escape</string> - </dict> - <dict> - <key>include</key> - <string>#ampersand</string> - </dict> - <dict> - <key>include</key> - <string>#bracket</string> - </dict> - <dict> - <key>include</key> - <string>#raw</string> - </dict> - <dict> - <key>include</key> - <string>#bold_italic</string> - </dict> - <dict> - <key>include</key> - <string>#italic</string> - </dict> - <dict> - <key>include</key> - <string>#strikethrough</string> - </dict> - <dict> - <key>include</key> - <string>#image-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inet</string> - </dict> - <dict> - <key>include</key> - <string>#link-email</string> - </dict> - <dict> - <key>include</key> - <string>#image-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref-literal</string> - </dict> - <dict> - <key>include</key> - <string>#link-footnote</string> - </dict> - </array> - </dict> - <key>strikethrough</key> - <dict> - <key>begin</key> - <string>(?x) - (?<!\w)(~~)(?=[^\s~]) # Open - (?= - ( - <[^>]*+> # HTML tags - | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> - # Raw - | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes - | \[ - ( - (?<square> # Named group - [^\[\]\\] # Match most chars - | \\. # Escaped chars - | \[ \g<square>*+ \] # Nested brackets - )*+ - \] - ( - ( # Reference Link - [ ]? # Optional space - \[[^\]]*+\] # Ref name - ) - | ( # Inline Link - \( # Opening paren - [ \t]*+ # Optional whtiespace - <?(.*?)>? # URL - [ \t]*+ # Optional whtiespace - ( # Optional Title - (?<title>['"]) - (.*?) - \k<title> - )? - \) - ) - ) - ) - | (?!(?<=\S)\1). # Everything besides - # style closer - )++ - ) - </string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.strikethrough.markdown</string> - </dict> - </dict> - <key>end</key> - <string>(?<=\S)(\1)(?!\w)</string> - <key>name</key> - <string>markup.strikethrough.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>applyEndPatternLast</key> - <integer>1</integer> - <key>begin</key> - <string>(?=<[^>]*?>)</string> - <key>end</key> - <string>(?<=>)</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#tag-kbd</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - </dict> - <dict> - <key>include</key> - <string>#escape</string> - </dict> - <dict> - <key>include</key> - <string>#ampersand</string> - </dict> - <dict> - <key>include</key> - <string>#bracket</string> - </dict> - <dict> - <key>include</key> - <string>#raw</string> - </dict> - <dict> - <key>include</key> - <string>#bold_italic</string> - </dict> - <dict> - <key>include</key> - <string>#bold</string> - </dict> - <dict> - <key>include</key> - <string>#italic</string> - </dict> - <dict> - <key>include</key> - <string>#image-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inet</string> - </dict> - <dict> - <key>include</key> - <string>#link-email</string> - </dict> - <dict> - <key>include</key> - <string>#image-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref-literal</string> - </dict> - <dict> - <key>include</key> - <string>#link-footnote</string> - </dict> - </array> - </dict> - <key>bracket</key> - <dict> - <key>comment</key> - <string> - Markdown will convert this for us. We match it so that the - HTML grammar will not mark it up as invalid. - </string> - <key>match</key> - <string><(?![a-z/?\$!])</string> - <key>name</key> - <string>meta.other.valid-bracket.markdown</string> - </dict> - <key>escape</key> - <dict> - <key>match</key> - <string>\\[-`*_#+.!(){}\[\]\\>]</string> - <key>name</key> - <string>constant.character.escape.markdown</string> - </dict> - <key>heading</key> - <dict> - <key>begin</key> - <string>\G(#{1,6})(?!#)\s*(?=\S)</string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.heading.markdown</string> - </dict> - </dict> - <key>contentName</key> - <string>entity.name.section.markdown</string> - <key>end</key> - <string>[ \t]*(#*)$</string> - <key>name</key> - <string>markup.heading.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#inline</string> - </dict> - </array> - </dict> - <key>image-inline</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>10</key> - <dict> - <key>name</key> - <string>string.other.link.description.title.markdown</string> - </dict> - <key>11</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.markdown</string> - </dict> - <key>12</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.markdown</string> - </dict> - <key>13</key> - <dict> - <key>name</key> - <string>string.other.link.description.title.markdown</string> - </dict> - <key>14</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.markdown</string> - </dict> - <key>15</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.markdown</string> - </dict> - <key>16</key> - <dict> - <key>name</key> - <string>punctuation.definition.metadata.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>string.other.link.description.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>invalid.illegal.whitespace.markdown</string> - </dict> - <key>6</key> - <dict> - <key>name</key> - <string>punctuation.definition.metadata.markdown</string> - </dict> - <key>7</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - <key>8</key> - <dict> - <key>name</key> - <string>markup.underline.link.image.markdown</string> - </dict> - <key>9</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(?x: - \! # Images start with ! - (\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\]) - # Match the link text. - ([ ])? # Space not allowed - (\() # Opening paren for url - (<?)(\S+?)(>?) # The url - [ \t]* # Optional whitespace - (?: - ((\().+?(\))) # Match title in parens… - | ((").+?(")) # or in quotes. - )? # Title is optional - \s* # Optional whitespace - (\)) - )</string> - <key>name</key> - <string>meta.image.inline.markdown</string> - </dict> - <key>image-ref</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>string.other.link.description.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.begin.markdown</string> - </dict> - <key>6</key> - <dict> - <key>name</key> - <string>constant.other.reference.link.markdown</string> - </dict> - <key>7</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.end.markdown</string> - </dict> - </dict> - <key>match</key> - <string>\!(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(\[)(.*?)(\])</string> - <key>name</key> - <string>meta.image.reference.markdown</string> - </dict> - <key>inline</key> - <dict> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#escape</string> - </dict> - <dict> - <key>include</key> - <string>#ampersand</string> - </dict> - <dict> - <key>include</key> - <string>#bracket</string> - </dict> - <dict> - <key>include</key> - <string>#raw</string> - </dict> - <dict> - <key>include</key> - <string>#bold_italic</string> - </dict> - <dict> - <key>include</key> - <string>#bold</string> - </dict> - <dict> - <key>include</key> - <string>#italic</string> - </dict> - <dict> - <key>include</key> - <string>#strikethrough</string> - </dict> - <dict> - <key>include</key> - <string>#line-break</string> - </dict> - <dict> - <key>include</key> - <string>#image-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inet</string> - </dict> - <dict> - <key>include</key> - <string>#link-email</string> - </dict> - <dict> - <key>include</key> - <string>#image-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref-literal</string> - </dict> - <dict> - <key>include</key> - <string>#link-footnote</string> - </dict> - <dict> - <key>include</key> - <string>#tag-kbd</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - </dict> - <key>italic</key> - <dict> - <key>begin</key> - <string>(?x) - (?<!\w)(\*|_)(?=\S) # Open - (?= - ( - <[^>]*+> # HTML tags - | (?<raw>`+)([^`]|(?!(?<!`)\k<raw>(?!`))`)*+\k<raw> - # Raw - | \\[\\`*_{}\[\]()#.!+\->]?+ # Escapes - | \[ - ( - (?<square> # Named group - [^\[\]\\] # Match most chars - | \\. # Escaped chars - | \[ \g<square>*+ \] # Nested brackets - )*+ - \] - ( - ( # Reference Link - [ ]? # Optional space - \[[^\]]*+\] # Ref name - ) - | ( # Inline Link - \( # Opening paren - [ \t]*+ # Optional whtiespace - <?(.*?)>? # URL - [ \t]*+ # Optional whtiespace - ( # Optional Title - (?<title>['"]) - (.*?) - \k<title> - )? - \) - ) - ) - ) - | \1\1 # Must be bold closer - | (?!(?<=\S)\1). # Everything besides - # style closer - )++ - (?<=\S)\1 # Close - ) - </string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.italic.markdown</string> - </dict> - </dict> - <key>end</key> - <string>(?<=\S)(\1)((?!\1)|(?=\1\1))</string> - <key>name</key> - <string>markup.italic.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>applyEndPatternLast</key> - <integer>1</integer> - <key>begin</key> - <string>(?=<[^>]*?>)</string> - <key>end</key> - <string>(?<=>)</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#tag-kbd</string> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - </dict> - <dict> - <key>include</key> - <string>#escape</string> - </dict> - <dict> - <key>include</key> - <string>#ampersand</string> - </dict> - <dict> - <key>include</key> - <string>#bracket</string> - </dict> - <dict> - <key>include</key> - <string>#raw</string> - </dict> - <dict> - <key>include</key> - <string>#bold_italic</string> - </dict> - <dict> - <key>include</key> - <string>#bold</string> - </dict> - <dict> - <key>include</key> - <string>#strikethrough</string> - </dict> - <dict> - <key>include</key> - <string>#image-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inline</string> - </dict> - <dict> - <key>include</key> - <string>#link-inet</string> - </dict> - <dict> - <key>include</key> - <string>#link-email</string> - </dict> - <dict> - <key>include</key> - <string>#image-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref</string> - </dict> - <dict> - <key>include</key> - <string>#link-ref-literal</string> - </dict> - <dict> - <key>include</key> - <string>#link-footnote</string> - </dict> - </array> - </dict> - <key>line-break</key> - <dict> - <key>match</key> - <string> {2,}$</string> - <key>name</key> - <string>meta.dummy.line-break</string> - </dict> - <key>link-email</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>markup.underline.link.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(<)?((?:mailto:)?[-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(>)?</string> - <key>name</key> - <string>meta.link.email.lt-gt.markdown</string> - </dict> - <key>link-inet</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>markup.underline.link.markdown</string> - </dict> - <key>3</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(<)?(\b(?:https?|ftp|file|git):///?[^\s()<>\[\]]+)(>)?</string> - <key>name</key> - <string>meta.link.inet.markdown</string> - </dict> - <key>link-inline</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>10</key> - <dict> - <key>name</key> - <string>string.other.link.description.title.markdown</string> - </dict> - <key>11</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>12</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>13</key> - <dict> - <key>name</key> - <string>string.other.link.description.title.markdown</string> - </dict> - <key>14</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>15</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>16</key> - <dict> - <key>name</key> - <string>punctuation.definition.metadata.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>string.other.link.title.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>invalid.illegal.whitespace.markdown</string> - </dict> - <key>6</key> - <dict> - <key>name</key> - <string>punctuation.definition.metadata.markdown</string> - </dict> - <key>7</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - <key>8</key> - <dict> - <key>name</key> - <string>markup.underline.link.markdown</string> - </dict> - <key>9</key> - <dict> - <key>name</key> - <string>punctuation.definition.link.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(?x: - (\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\]) - # Match the link text. - ([ ])? # Space not allowed - (\() # Opening paren for url - (<?)(.*?)(>?) # The url - [ \t]* # Optional whitespace - (?: - ((\().+?(\))) # Match title in parens… - | ((").+?(")) # or in quotes. - )? # Title is optional - \s* # Optional whitespace - (\)) - )</string> - <key>name</key> - <string>meta.link.inline.markdown</string> - </dict> - <key>link-footnote</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.begin.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>constant.other.reference.link.markdown</string> - </dict> - <key>3</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.end.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(\[)(\^[^\]]*+)(\])</string> - <key>name</key> - <string>meta.link.reference.markdown</string> - </dict> - <key>link-ref</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>string.other.link.title.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.begin.markdown</string> - </dict> - <key>6</key> - <dict> - <key>name</key> - <string>constant.other.reference.link.markdown</string> - </dict> - <key>7</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.end.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(\[)([^\]]*+)(\])</string> - <key>name</key> - <string>meta.link.reference.markdown</string> - </dict> - <key>link-ref-literal</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.begin.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>string.other.link.title.markdown</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.definition.string.end.markdown</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.begin.markdown</string> - </dict> - <key>6</key> - <dict> - <key>name</key> - <string>punctuation.definition.constant.end.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(\[)((?<square>[^\[\]\\]|\\.|\[\g<square>*+\])*+)(\])[ ]?(?:(\[)(\]))?</string> - <key>name</key> - <string>meta.link.reference.literal.markdown</string> - </dict> - <key>list-paragraph</key> - <dict> - <key>patterns</key> - <array> - <dict> - <key>begin</key> - <string>\G\s+(?=\S)</string> - <key>end</key> - <string>^\s*$</string> - <key>name</key> - <string>meta.paragraph.list.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#inline</string> - </dict> - <dict> - <key>match</key> - <string>\G\s*([*\-+]|[0-9]+\.)\s+</string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.list_item.markdown</string> - </dict> - </dict> - </dict> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-code-blocks</string> - </dict> - </array> - </dict> - </array> - </dict> - <key>raw</key> - <dict> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>punctuation.definition.raw.markdown</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>markup.raw.inline.content.markdown</string> - </dict> - <key>3</key> - <dict> - <key>name</key> - <string>punctuation.definition.raw.markdown</string> - </dict> - </dict> - <key>match</key> - <string>(`+)((?:[^`]|(?!(?<!`)\1(?!`))`)*+)(\1)</string> - <key>name</key> - <string>markup.raw.inline.markdown</string> - </dict> - <key>separator</key> - <dict> - <key>match</key> - <string>\G[ ]{,3}([-*_])([ ]{,2}\1){2,}[ \t]*$\n?</string> - <key>name</key> - <string>meta.separator.markdown</string> - </dict> - <key>fenced-html</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(html|html5)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>text.html.basic</string> - </dict> - </array> - </dict> - <key>fenced-xml</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(xml)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>text.xml</string> - </dict> - </array> - </dict> - <key>fenced-diff</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(diff|patch)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.diff</string> - </dict> - </array> - </dict> - <key>fenced-perl</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(perl)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.perl</string> - </dict> - </array> - </dict> - <key>fenced-php</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(php)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.php</string> - </dict> - </array> - </dict> - <key>fenced-css</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(css)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.css</string> - </dict> - </array> - </dict> - <key>fenced-less</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(less)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.less</string> - </dict> - </array> - </dict> - <key>fenced-java</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(java)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.java</string> - </dict> - </array> - </dict> - <key>fenced-c</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(c)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.c</string> - </dict> - </array> - </dict> - <key>fenced-c++</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(c\+\+|cpp)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.c++</string> - </dict> - </array> - </dict> - <key>fenced-c#</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(c(?:s|sharp|#))\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.cs</string> - </dict> - </array> - </dict> - <key>fenced-yaml</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(yaml)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.yaml</string> - </dict> - </array> - </dict> - <key>fenced-sql</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(sql)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.sql</string> - </dict> - </array> - </dict> - <key>fenced-shell</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(sh|shell|bash)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.shell</string> - </dict> - </array> - </dict> - <key>fenced-sass</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(sass)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.sass</string> - </dict> - </array> - </dict> - <key>fenced-scss</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(scss)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.scss</string> - </dict> - </array> - </dict> - <key>fenced-scala</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(scala)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.scala</string> - </dict> - </array> - </dict> - <key>fenced-obj-c</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(obj(ective-)?c)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.objc</string> - </dict> - </array> - </dict> - <key>fenced-coffee</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(coffee|cjsx)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.coffee</string> - </dict> - </array> - </dict> - <key>fenced-js</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(js|jsx|json|javascript)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.js</string> - </dict> - </array> - </dict> - <key>fenced-ts</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(ts|typescript)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.ts</string> - </dict> - </array> - </dict> - <key>fenced-tsx</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(tsx)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.tsx</string> - </dict> - </array> - </dict> - <key>fenced-ruby</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(ruby)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.ruby</string> - </dict> - </array> - </dict> - <key>fenced-python</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(py|python)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.python</string> - </dict> - </array> - </dict> - <key>fenced-lisp</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(lisp)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.lisp</string> - </dict> - </array> - </dict> - <key>fenced-lua</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(lua)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.lua</string> - </dict> - </array> - </dict> - <key>fenced-scheme</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(scheme)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.scheme</string> - </dict> - </array> - </dict> - <key>fenced-swift</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(swift)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.swift</string> - </dict> - </array> - </dict> - <key>fenced-clojure</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,})\s*(clojure)\s*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>source.clojure</string> - </dict> - </array> - </dict> - <key>fenced-undefined</key> - <dict> - <key>begin</key> - <string>^(\s*[`~]{3,}).*$</string> - <key>end</key> - <string>^(\1)\n</string> - <key>name</key> - <string>markup.raw.block.markdown markup.raw.block.fenced.markdown</string> - </dict> - <key>fenced-code-blocks</key> - <dict> - <key>patterns</key> - <array> - <dict> - <key>include</key> - <string>#fenced-html</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-xml</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-diff</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-perl</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-php</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-css</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-less</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-java</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-c</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-c++</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-c#</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-yaml</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-sql</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-shell</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-sass</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-scss</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-scala</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-obj-c</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-coffee</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-js</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-ts</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-tsx</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-ruby</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-python</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-lisp</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-lua</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-scheme</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-swift</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-clojure</string> - </dict> - <dict> - <key>include</key> - <string>#fenced-undefined</string> - </dict> - </array> - </dict> - <key>tag-kbd</key> - <dict> - <key>name</key> - <string>markup.kbd.markdown</string> - <key>match</key> - <string>((<)(kbd)(>))([^<]+)((</)(kbd)(>))</string> - <key>captures</key> - <dict> - <key>1</key> - <dict> - <key>name</key> - <string>meta.tag.other.html</string> - </dict> - <key>2</key> - <dict> - <key>name</key> - <string>punctuation.definition.tag.begin.html</string> - </dict> - <key>3</key> - <dict> - <key>name</key> - <string>entity.name.tag.other.html</string> - </dict> - <key>4</key> - <dict> - <key>name</key> - <string>punctuation.definition.tag.end.html</string> - </dict> - <key>5</key> - <dict> - <key>name</key> - <string>markup.kbd.content.markdown</string> - </dict> - <key>6</key> - <dict> - <key>name</key> - <string>meta.tag.other.html</string> - </dict> - <key>7</key> - <dict> - <key>name</key> - <string>punctuation.definition.tag.begin.html</string> - </dict> - <key>8</key> - <dict> - <key>name</key> - <string>entity.name.tag.other.html</string> - </dict> - <key>9</key> - <dict> - <key>name</key> - <string>punctuation.definition.tag.end.html</string> - </dict> - </dict> - </dict> - </dict> - <key>scopeName</key> - <string>text.html.markdown.gfm</string> - <key>uuid</key> - <string>423378C0-3E42-11E3-AA6E-0800200C9A66</string> -</dict> -</plist> From 70daf31f4a444a688ef0272b354d44ae523f43e2 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Wed, 26 Jul 2017 17:36:38 +0800 Subject: [PATCH 06/18] front matter borrowed code from MarkdownExtended --- Markdown.sublime-syntax | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Markdown.sublime-syntax b/Markdown.sublime-syntax index 6635aff7..27fb41dd 100644 --- a/Markdown.sublime-syntax +++ b/Markdown.sublime-syntax @@ -10,6 +10,36 @@ file_extensions: scope: text.html.markdown.gfm contexts: main: + - match: (?=(?<!\s)---(\s*coffee|\s*json)?\n$) + push: front-matter + - match: "" + push: body + front-matter: + - match: (?<!\s)---\n$ + push: + - meta_scope: markup.raw.yaml.front-matter + - meta_content_scope: source.yaml + - match: ^---\s + pop: true + - include: scope:source.yaml + - match: (?<!\s)---\s*coffee\n$ + push: + - meta_scope: markup.raw.coffee.front-matter + - meta_content_scope: source.coffee + - match: ^---\s + pop: true + - include: scope:source.coffee + - match: (?<!\s)---\s*json\n$ + push: + - meta_scope: markup.raw.json.front-matter + - meta_content_scope: source.json + - match: ^---\s + pop: true + - include: scope:source.json + - match: "" + pop: true + push: body + body: - match: |- (?x)^ (?= [ ]{,3}> From 67445a09fc6413aaca26457c7a74a44d0ed9282c Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Wed, 26 Jul 2017 17:54:51 +0800 Subject: [PATCH 07/18] latext support borrowed code from Markdown Extended --- Markdown.sublime-syntax | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Markdown.sublime-syntax b/Markdown.sublime-syntax index 27fb41dd..465d3c26 100644 --- a/Markdown.sublime-syntax +++ b/Markdown.sublime-syntax @@ -690,6 +690,7 @@ contexts: - include: link-ref-literal - include: link-footnote - include: tag-kbd + - include: latex-inline - include: scope:text.html.basic italic: - match: |- @@ -852,6 +853,7 @@ contexts: - include: scope:text.html.basic - include: fenced-code-blocks raw: + - include: latex-display - match: '(`+)((?:[^`]|(?!(?<!`)\1(?!`))`)*+)(\1)' scope: markup.raw.inline.markdown captures: @@ -944,3 +946,36 @@ contexts: 7: punctuation.definition.tag.begin.html 8: entity.name.tag.other.html 9: punctuation.definition.tag.end.html + + latex-inline: + - match: \\\$ + - match: |- + (?x) + (\$)(?=\S) + (?= + (?: + \\\\ + |\\\$ + |[^\$] + )*? + \S\$(?:[^a-zA-Z0-9]|$) + ) + scope: string.other.math.latex punctuation.definition.string.begin.latex + push: + - meta_scope: text.tex.latex meta.environment.math.latex + - include: scope:text.tex.latex#macros + - include: scope:text.tex.latex#math-content + - match: \$ + scope: string.other.math.latex punctuation.definition.string.end.latex + pop: true + + latex-display: + - match: \$\$ + scope: string.other.math.latex punctuation.definition.string.begin.latex + push: + - meta_scope: text.tex.latex meta.environment.math.latex + - include: scope:text.tex.latex#macros + - include: scope:text.tex.latex#math-content + - match: \$\$ + scope: string.other.math.latex punctuation.definition.string.end.latex + pop: true From bd3bc4a1b9bf877eb641f77196f17522b18ee41b Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Thu, 27 Jul 2017 10:39:36 +0800 Subject: [PATCH 08/18] fix header nav wieh front matter --- folding.py | 5 +++++ messages/2.2.4.md | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/folding.py b/folding.py index 8c6270c1..109cf4e0 100644 --- a/folding.py +++ b/folding.py @@ -18,6 +18,8 @@ def all_headings(view): text = view.substr(sublime.Region(0, view.size())) it = re.finditer(r'^(#{1,6}(?!#))|^(-{3,}|={3,})', text, re.M) for m in it: + if '.front-matter' in view.scope_name(m.start()): + continue if re.match(r'^(-{3,}|={3,})$', m.group()): title_end = m.start() - 1 title_begin = text.rfind('\n', 0, title_end) + 1 @@ -79,6 +81,7 @@ def run(self, edit): view.fold(reg) sublime.status_message('%d region%s %sfolded' % (len(sections), 's' if len(sections) > 1 else '', 'un' if shouldUnfold else '')) + class FoldSectionContextCommand(FoldSectionCommand): def is_visible(self): @@ -106,6 +109,7 @@ def is_visible(self): hasSection = True return hasSection + class UnfoldSectionContextCommand(FoldSectionCommand): def is_visible(self): @@ -133,6 +137,7 @@ def is_visible(self): return False return hasSection + class ShowFoldAllSectionsCommand(MDETextCommand): def run(self, edit): diff --git a/messages/2.2.4.md b/messages/2.2.4.md index 8bb0981e..0704f2dc 100644 --- a/messages/2.2.4.md +++ b/messages/2.2.4.md @@ -5,10 +5,15 @@ feedback you can use [GitHub issues][issues]. ## Bug Fixes -* Fix an issue that occationally prevents creating link references with command +* Fix an issue that occationally prevents creating link references with command. +* Fix an issue that breaks navigating through headers while front matter is present. ## New Features +* Latex math expressions are highlighted now: + - $\frac{d}{dx}\left( \int_{0}^{x} f(u)\,du\right)=f(x).$ +* Front matter (yaml, coffee, json) highlight + ## Changes [issues]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues From d08d4e22fbd60e74c1692a0b65a1004e9617fa00 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Thu, 27 Jul 2017 13:31:22 +0800 Subject: [PATCH 09/18] fix path in test --- tests/syntax_test_GFM.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/syntax_test_GFM.md b/tests/syntax_test_GFM.md index 79ca8c84..5676530c 100644 --- a/tests/syntax_test_GFM.md +++ b/tests/syntax_test_GFM.md @@ -1,4 +1,4 @@ -<!-- SYNTAX TEST "Packages/MarkdownEditing/Markdown.tmLanguage" --> +<!-- SYNTAX TEST "Packages/MarkdownEditing/Markdown.sublime-syntax" --> Inline styles ============= From b925890acafba63f5870425fe3772c2d4cbea093 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Thu, 27 Jul 2017 14:00:02 +0800 Subject: [PATCH 10/18] Mention MarkdownTOC --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 920559f3..7340fe6f 100644 --- a/README.md +++ b/README.md @@ -229,6 +229,8 @@ Now open palette and choose "Preview in Browser" and you will get a WYSIWYG edit Knockdown offers useful Markdown features and a custom Markdown theme. All of its unique features except its theme are ported to MarkdownEditing and some of them are actually improved further in MarkdownEditing. * [Sublime Markdown Extended][] * [SmartMarkdown][] +* [MarkdownTOC][] + - Sublime Text 3 plugin for generating a Table of Contents (TOC) in a Markdown document. * See https://packagecontrol.io/search/markdown for more. ## Known Bugs @@ -282,6 +284,7 @@ MarkdownEditing is released under the [MIT License][opensource]. [Knockdown]: https://github.com/aziz/knockdown/ [Sublime Markdown Extended]: https://github.com/jonschlinkert/sublime-markdown-extended [SmartMarkdown]: https://github.com/demon386/SmartMarkdown +[MarkdownTOC]: https://github.com/naokazuterada/MarkdownTOC [#158]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues/158 [brettterpstra]: http://brettterpstra.com [github 9]: https://github.com/maliayas From 6322be102355c7e6b3c0e4b33eed721b1f3bb294 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Thu, 27 Jul 2017 14:14:27 +0800 Subject: [PATCH 11/18] fix front matter caused title finding bug --- decide_title.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/decide_title.py b/decide_title.py index c0fe1a8c..8fa52df1 100644 --- a/decide_title.py +++ b/decide_title.py @@ -12,20 +12,19 @@ def on_modified_async(self, view): it = re.finditer(r'^(#{1,6}(?!#))|^(-{3,}|={3,})', text, re.M) title = '' for m in it: + if '.front-matter' in view.scope_name(m.start()): + continue if re.match(r'^(-{3,}|={3,})$', m.group()): title_end = m.start() - 1 title_begin = text.rfind('\n', 0, title_end) + 1 - title = text[title_begin: title_end] else: title_begin = m.end() title_end = re.search('(' + m.group() + ')?(\n|$)', text[title_begin:]).start() + title_begin - title = text[title_begin: title_end] - break + title_begin = m.start() + 1 + if 'markup.raw.block.markdown' not in view.scope_name(title_begin).split(' '): + break if len(title) == 0: - firstLineEnd = text.find('\n') - if firstLineEnd == -1: - firstLineEnd = len(text) - title = text[0: firstLineEnd] + title = text[title_begin: title_end] title = title.strip() if view.file_name() is None and len(title) > 0: From 6919393cce9b8187de96e1a53b65cee6f0c9a787 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Wed, 2 Aug 2017 14:32:13 +0800 Subject: [PATCH 12/18] Add golang highlight Close #456 --- Markdown.sublime-syntax | 8 ++++++++ messages/2.2.4.md | 1 + 2 files changed, 9 insertions(+) diff --git a/Markdown.sublime-syntax b/Markdown.sublime-syntax index 465d3c26..815101e7 100644 --- a/Markdown.sublime-syntax +++ b/Markdown.sublime-syntax @@ -403,6 +403,13 @@ contexts: - match: ^(\1)\n pop: true - include: scope:source.clojure + fenced-go: + - match: '^(\s*[`~]{3,})\s*(go|golang)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.go fenced-code-blocks: - include: fenced-html - include: fenced-xml @@ -433,6 +440,7 @@ contexts: - include: fenced-scheme - include: fenced-swift - include: fenced-clojure + - include: fenced-go - include: fenced-undefined fenced-coffee: - match: '^(\s*[`~]{3,})\s*(coffee|cjsx)\s*$' diff --git a/messages/2.2.4.md b/messages/2.2.4.md index 0704f2dc..208125dc 100644 --- a/messages/2.2.4.md +++ b/messages/2.2.4.md @@ -13,6 +13,7 @@ feedback you can use [GitHub issues][issues]. * Latex math expressions are highlighted now: - $\frac{d}{dx}\left( \int_{0}^{x} f(u)\,du\right)=f(x).$ * Front matter (yaml, coffee, json) highlight +* Go Programming Language highlight in code blocks ## Changes From 66367ed12d59aaf93a332c13adfa4f365ce1d678 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Wed, 2 Aug 2017 17:10:11 +0800 Subject: [PATCH 13/18] refactor readme file relates to #455 --- README.md | 283 ++++++++++++++++++++++------------------ screenshots/arcdark.png | Bin 0 -> 52389 bytes 2 files changed, 157 insertions(+), 126 deletions(-) create mode 100644 screenshots/arcdark.png diff --git a/README.md b/README.md index 7340fe6f..b0b938ae 100644 --- a/README.md +++ b/README.md @@ -2,43 +2,54 @@ Markdown plugin for Sublime Text. Provides a decent Markdown color scheme (light and dark) with more __robust__ syntax highlighting and useful Markdown editing features for Sublime Text. 3 flavors are supported: Standard Markdown, __GitHub flavored Markdown__, MultiMarkdown. -![MarkdownEditing][github] +![MarkdownEditing][LightTheme] -[Dark][github 2] and [yellow][github 3] theme available, plus [thirdparty themes](#additional-color-themes). See [configuration](#configuration) section to learn **how to change the theme**. +[Dark][DarkTheme] and [Yellow][YellowTheme] and [ArcDark][ArcDarkTheme] theme available, plus [thirdparty themes](#additional-color-themes). See [configuration](#configuration) section to learn **how to change the theme**. ## Overview -* [Installation](#installation) -* [Features](#features) -* [Key Bindings](#key-bindings) -* [GFM Specific Features](#gfm-specific-features) -* [Commands for Command Palette](#commands-for-command-palette) -* [Configuration](#configuration) -* [Tips](#tips) -* [Similar Plugins](#similar-plugins) -* [Known Bugs](#known-bugs) -* [Contributing](#contributing) -* [Credits](#credits) -* [Donation](#donation) -* [License](#license) +<!-- MarkdownTOC autolink="true" bracket="round" markdown_preview="markdown" --> + +- [Installation](#installation) + - [Package Control](#package-control) + - [Manual Installation](#manual-installation) +- [Features](#features) +- [Key Bindings](#key-bindings) +- [GFM Specific Features](#gfm-specific-features) +- [Commands for Command Palette](#commands-for-command-palette) + - [General Commands](#general-commands) + - [Links, References and Footnotes](#links-references-and-footnotes) + - [Folding and Navigation](#folding-and-navigation) +- [Configuration](#configuration) + - [Additional color themes:](#additional-color-themes) +- [Tips](#tips) +- [Enable WYSIWYG](#enable-wysiwyg) +- [Troubleshooting](#troubleshooting) + - [Error loading syntax file...](#error-loading-syntax-file) +- [Related Plugins](#related-plugins) +- [Known Bugs](#known-bugs) +- [Contributing](#contributing) +- [Credits](#credits) +- [Donation](#donation) +- [License](#license) + +<!-- /MarkdownTOC --> ## Installation -> __Important Note About Installation__ -> -> Are you getting this error after installation: _**Error loading syntax file** "Packages/Markdown/Markdown.tmLanguage": Unable to open Packages/Markdown/Markdown.tmLanguage_? This is caused by open markdown files at the install time. You have to __manually change their syntax to your newly installed Markdown syntax__. Read the below paragraph for more details on this. - -_Note_: Sublime text has a native tiny package for Markdown. However, when MarkdownEditing is enabled, native package causes some conflicts. For this reason, MarkdownEditing will automatically disable it. Since it doesn't bring anything new over MarkdownEditing, this is not a loss. But remember, when you disable MarkdownEditing, you have to reenable the native one manually (if you want). +You can install MarkdownEditing either from Package Control (recommended) or manually. Package Control automatically download the package and keeps it up-to-date. Manual installation is required if you need to tweak the code. If you are using Sublime Text 2, you have to disable the native package _manually_. To do that, add `Markdown` to your `ignored_packages` list in ST user settings: "ignored_packages": [..., "Markdown"], +> Getting "Error loading syntax file..."? See [this](#error-loading-syntax-file). + ### Package Control -The preferred method of installation is via [Sublime Package Control][wbond]. +The preferred method of installation is via [Sublime Package Control][PackageControl]. -1. [Install Sublime Package Control][wbond 2] +1. [Install Sublime Package Control][InstallPackageControl] 2. From inside Sublime Text, open Package Control's Command Pallet: <kbd>CTRL</kbd> <kbd>SHIFT</kbd> <kbd>P</kbd> (Windows, Linux) or <kbd>CMD</kbd> <kbd>SHIFT</kbd> <kbd>P</kbd> on Mac. 3. Type `install package` and hit Return. A list of available packages will be displayed. 4. Type `MarkdownEditing` and hit Return. The package will be downloaded to the appropriate directory. @@ -46,33 +57,45 @@ The preferred method of installation is via [Sublime Package Control][wbond]. ### Manual Installation -1. Download or clone this repository to a directory `MarkdownEditing` in the Sublime Text Packages directory for your platform: - * Mac: `git clone https://github.com/SublimeText-Markdown/MarkdownEditing.git ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/MarkdownEditing` - * Windows: `git clone https://github.com/SublimeText-Markdown/MarkdownEditing.git %APPDATA%\Sublime/ Text/ 2/\MarkdownEditing` - * Linux: `git clone https://github.com/SublimeText-Markdown/MarkdownEditing.git ~/.Sublime\ Text\ 2/Packages/MarkdownEditing` -2. Restart Sublime Text to complete installation. Open a Markdown file and this custom theme. The features listed above should now be available. +1. In Sublime Text, open the menu "Preferences" -> "Browse Packages...". This is the Sublime Text Packages directory. +2. [Download and unzip](https://github.com/SublimeText-Markdown/MarkdownEditing/archive/master.zip) or [clone](https://help.github.com/articles/cloning-a-repository/) this repository to a directory `MarkdownEditing` in the Sublime Text Packages directory. +3. The folder structure should look like `.../Sublime Text 3/Packages/MarkdownEditing/[files]`. +4. Restart Sublime Text to complete installation. Open a Markdown file. The features listed below should now be available. ## Features -* Asterisks and underscores are autopaired and will wrap selected text - - If you start an empty pair and hit backspace, both elements are deleted - - If you start an empty pair and hit space, the right element is deleted -* Backticks are paired -* At the end of a list item, pressing <kbd>Enter</kbd> will automatically insert the new list item bullet. +You can access most features through Command Palette. You can launch it from `Tools -> Command Palette...`. MarkdownEditing commands start with `MarkdownEditing:`. And they are only visible when a markdown file is open and active. + +* __Pairing__ + - Asterisks and underscores are autopaired and will wrap selected text. + - If you start an empty pair and hit backspace, both elements are deleted. + - If you start an empty pair and hit space, the right element is deleted. + - Backticks are paired. So entering ` will expand to `(cursor here)`. +* __List__ + - At the end of a list item, pressing <kbd>Enter</kbd> will automatically insert the new list item bullet. - Pressing <kbd>Tab</kbd> on the blank list item will indent it and switch the list bullet to another one (Order is `*`, `-`, `+` in a cycle). - Pressing <kbd>Shift</kbd> <kbd>Tab</kbd> on the blank list item will unindent it in the same way as above. - Sequential <kbd>Tab</kbd> s or <kbd>Shift</kbd> <kbd>Tab</kbd> s are supported. - - You can disable automatic bullet switching or choose which bullets to be used, in your settings file. - - If a list item contains a [GFM task][GFM], pressing <kbd>Enter</kbd> at the end of the line will continue with a new blank task. -* At the end of a blockquote line, pressing <kbd>Enter</kbd> will automatically extend blockquote. -* Selecting some text and pressing <kbd>></kbd> will convert it to blockquote. The first and the last line don't have to be fully selected; partial select works, too. -* Left bracket pairing is modified to eliminate the selection and leave the cursor at a point where you can insert a `[]` or `()` pair for a link -* Displays Markdown headers in the Project Symbol List (<kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>R</kbd>). They will start with `#`, so you will know they belong to markdown files at a glance. Also they will be on top of the list because of the precedence of `#`. -* <kbd>~</kbd> wraps selected text with `~~` (strikethrough). -* Typing `#` when there's a selection will surround it with `#` to make it a headline. Multiple presses add additional hashes, increasing the level of the header. Once you hit 6 hashes, it will reset to 0 on the next press. The `mde.match_header_hashes` will determine if the `#` are mirrored on both sides or just at the beginning of the line. -* Typing return at the end of a line that begins with hashmarks will insert closing hashmarks on the headline. They're not required for Markdown, it's just aesthetics, and you can change the `mde.match_header_hashes` option in your settings to enable (disabled by default). -* Setext-style headers can be completed with `Tab`. That is, typing `Tab` on a line containing only `=` or `-` characters will add or remove enough characters to it to match the length of the line above. -* New documents will be named automatically based on the first header. + - You can disable automatic bullet switching or choose which bullets to be used, in your settings file (`mde.list_indent_bullets`). + - If a list item contains a [GFM task][], pressing <kbd>Enter</kbd> at the end of the line will continue with a new blank task. +* __Blockquote__ + - At the end of a blockquote line, pressing <kbd>Enter</kbd> will automatically extend blockquote. + - Selecting some text and pressing <kbd>></kbd> will convert it to blockquote. The first and the last line don't have to be fully selected; partial select works, too. +* __Link__ + - Left bracket pairing is modified to eliminate the selection and leave the cursor at a point where you can insert a `[]` or `()` pair for a link. + - If you leave the cursor on a link, you can right click and jump between reference and url. +* __Navigation__ + - Displays Markdown headers in the Project Symbol List (`Goto -> Goto Symbol in Project...`). They will start with `#`, so you will know they belong to markdown files at a glance. Also they will be on top of the list because of the precedence of `#`. + - Headers also appear in Document Symbol List (`Goto -> Goto Symbol...`) + - You can fold current section with <kbd>Ctrl</kbd> <kbd>Tab</kbd> + - You can navigate between adjacent headers with `Find Next(Previous) Heading` command. +* __Strikethrough__ + - <kbd>~</kbd> wraps selected text with `~~` (strikethrough). When you for instance select the word "foo" and hit `~`, the result will be `~~foo~~`. +* __Header__ + - Typing `#` when there's a selection will surround it with `#` to make it a headline. Multiple presses add additional hashes, increasing the level of the header. Once you hit 6 hashes, it will reset to 0 on the next press. The `mde.match_header_hashes` will determine if the `#` are mirrored on both sides or just at the beginning of the line. + - Typing return at the end of a line that begins with hashmarks will insert closing hashmarks on the headline. They're not required for Markdown, it's just aesthetics, and you can change the `mde.match_header_hashes` option in your settings to enable (disabled by default). + - Setext-style headers can be completed with `Tab`. That is, typing `Tab` on a line containing only `=` or `-` characters will add or remove enough characters to it to match the length of the line above. + - New documents will be named automatically based on the first header. ## Key Bindings @@ -91,83 +114,78 @@ The preferred method of installation is via [Sublime Package Control][wbond]. ## GFM Specific Features +[GFM][] means GitHub Flavored Markdown is the dialect of Markdown that is currently supported for user content on GitHub.com and GitHub Enterprise. It has [some unique features][GFMFeatures]: + Underscores in words doesn't mess with bold or italic style: -![underscore-in-words][github 5] +![underscore-in-words][GFM-UnderscoreInWords] Fenced code blocks gets syntax highlighting inside: -![fenced-code-block][github 6] +![fenced-code-block][GFM-FencedCodeBlock] Keyboard shortcuts gets highlighted like in GitHub: -![keyboard-shortcut][github 7] +![keyboard-shortcut][GFM-KeyboardShortcut] Strikethrough is supported: -![strikethrough][github 8] +![strikethrough][GFM-Strikethrough] ## Commands for Command Palette -### Fix Underlined Headers - -Adjusts every setext-style header to add or remove `=` or `-` characters as needed to match the lengths of their header text. - -### Convert Underlined Headers to ATX - -Converts every setext-style header into an ATX style header. If something is selected only the headers in the selections will be converted, otherwise the conversion will be applied to the whole view. - -### Add Missing Link Labels - -Scans document for referenced link usages (`[some link][some_ref]` and `[some link][]`) and checks if they are all defined. If there are undefined link references, command will automatically create their definition snippet at the bottom of the file. - -### Markdown Lint - -Performs lint on current Markdown file. See [lint rules](lint_docs/RULES.md). Some of the linting rules are customizable via user settings file. - -### Switch List Bullet Type - -Switches the highlighted list between numbered and bulleted style. - -### Magic Footnotes Command - -Adds a footnote after the word under cursor. If cursor is already on a footnote, jumps to its definition or reference. - -### Gather Missing Footnotes - -Add definition stubs (if there is none) for all footnotes references. - -### Jump Reference - -Jumps cursor between definitions and references. - -### New Reference - -Adds a new link under cursor. - -### New Inline Link - -Adds a new inline link under cursor. - -### New Inline Image - -Adds a new inline image under cursor. - -### New Image - -Adds a new image under cursor. - -### New Footnote - -Adds a footnote under cursor. - -### Delete Reference - -Deletes the definition and references of a link. - -### Organize References - -Sorts and gives a report on current link references usage. +You can launch Command Palette from `Tools -> Command Palette...`. MarkdownEditing commands start with `MarkdownEditing:`. And they are only visible when a markdown file is open and active. + +### General Commands + +* __Fix Underlined Headers__ + Adjusts every setext-style header to add or remove `=` or `-` characters as needed to match the lengths of their header text. +* __Convert Underlined Headers to ATX__ + Converts every setext-style header into an ATX style header. If something is selected only the headers in the selections will be converted, otherwise the conversion will be applied to the whole view. +* __Markdown Lint__ + Performs lint on current Markdown file. See [lint rules](lint_docs/RULES.md). Some of the linting rules are customizable via user settings file. +* __Change color scheme...__ + Lists built-in Markdown color schemes for you to preview and use. +* __Switch List Bullet Type__ + Switches the highlighted list between numbered and bulleted style. + +### Links, References and Footnotes + +* __Add Missing Link Labels__ + Scans document for referenced link usages (`[some link][some_ref]` and `[some link][]`) and checks if they are all defined. If there are undefined link references, command will automatically create their definition snippet at the bottom of the file. +* __Magic Footnotes Command__ + Adds a footnote after the word under cursor. If cursor is already on a footnote, jumps to its definition or reference. +* __Gather Missing Footnotes__ + Add definition stubs (if there is none) for all footnotes references. +* __Jump Reference__ + Jumps cursor between definitions and references. +* __New Reference__ + Adds a new link under cursor. +* __New Inline Link__ + Adds a new inline link under cursor. +* __New Inline Image__ + Adds a new inline image under cursor. +* __New Image__ + Adds a new image under cursor. +* __New Footnote__ + Adds a footnote under cursor. +* __Delete Reference__ + Deletes the definition and references of a link. +* __Organize References__ + Sorts and gives a report on current link references usage. + +### Folding and Navigation + +Remeber you can <kbd>Ctrl</kbd> <kbd>R</kbd> (in document) and <kbd>Ctrl</kbd> <kbd>Shift</kbd> <kbd>R</kbd> (project-wise) for quick navigation for all headers. + +* __Toggle Folding Current Section__ + Folds/unfolds current section. +* __Fold Level 1-4 Sections__ + Fold all sections under headers of specific level. +* __Fold/Unfold All Sections__ + Self explanatory. +* __Find Next/Previous Heading__ + You have option to find just same or higher level or any level ## Configuration @@ -222,6 +240,16 @@ Install them if you haven't. Then Now open palette and choose "Preview in Browser" and you will get a WYSIWYG editor. +## Troubleshooting + +### Error loading syntax file... + +__Are you getting this error after installation: _**Error loading syntax file** "Packages/Markdown/Markdown.tmLanguage": Unable to open Packages/Markdown/Markdown.tmLanguage_?__ + +> This is caused by open markdown files at the install time. You have to __manually change their syntax to your newly installed Markdown syntax__. Read the below paragraph for more details on this. + +_Note_: Sublime text has a native tiny package for Markdown. However, when MarkdownEditing is enabled, native package causes some conflicts. For this reason, MarkdownEditing will automatically disable it. Since it doesn't bring anything new over MarkdownEditing, this is not a loss. But remember, when you disable MarkdownEditing, you have to reenable the native one manually (if you want). + ## Related Plugins * [Knockdown][] @@ -245,7 +273,7 @@ See `CONTRIBUTING.md` file. ## Credits -MarkdownEditing was originally created by [Brett Terpstra][brettterpstra] and has become a community project with the goal of consolidating the best features from the varied collection of Markdown packages for Sublime Text. Current development is headed up by [Ali Ayas][github 9] and [Felix Hao][github 10]. +MarkdownEditing was originally created by [Brett Terpstra][brettterpstra] and has become a community project with the goal of consolidating the best features from the varied collection of Markdown packages for Sublime Text. Current development is headed up by [Ali Ayas][maliayas] and [Felix Hao][felixhao28]. Related blog posts from Brett: * http://brettterpstra.com/2012/05/17/markdown-editing-for-sublime-text-2-humble-beginnings/ @@ -253,42 +281,45 @@ Related blog posts from Brett: This plugin contains portions of code from [Knockdown][]. -Footnote commands were submitted by [J. Nicholas Geist][github 4] and originated at [geekabouttown][geekabouttown]. +Footnote commands were submitted by [J. Nicholas Geist][] and originated at [geekabouttown][geekabouttown]. ## Donation You can support [contributors](https://github.com/SublimeText-Markdown/MarkdownEditing/graphs/contributors) of this project individually. Every contributor is welcomed to add his/her line below with any content. Ordering shall be alphabetically by GitHub username. -* [@felixhao28][github 10]: <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9QV2RFV2J8UZS"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" alt="[paypal]" /></a> -* [@maliayas][github 9]: <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=W2NXRPD43YSCU&lc=TR&item_name=open-source&item_number=markdown-editing&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" alt="[paypal]" /></a> ![donation received](http://maliayas.com/business/donation/badge.php?project=markdown_editing) +* [@felixhao28][felixhao28]: <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9QV2RFV2J8UZS"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" alt="[paypal]" /></a> +* [@maliayas][maliayas]: <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=W2NXRPD43YSCU&lc=TR&item_name=open-source&item_number=markdown-editing&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" alt="[paypal]" /></a> ![donation received](http://maliayas.com/business/donation/badge.php?project=markdown_editing) ## License MarkdownEditing is released under the [MIT License][opensource]. -[github]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/light.png -[github 2]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/dark.png -[github 3]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/yellow.png -[wbond]: http://wbond.net/sublime_packages/package_control -[wbond 2]: http://wbond.net/sublime_packages/package_control/installation -[GFM]: https://help.github.com/articles/github-flavored-markdown -[github 5]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/underscore-in-words.png -[github 6]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/fenced-code-block.png -[github 7]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/keyboard-shortcut.png -[github 8]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/strikethrough.png +[LightTheme]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/light.png +[DarkTheme]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/dark.png +[YellowTheme]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/yellow.png +[ArcDarkTheme]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/arcdark.png +[PackageControl]: http://wbond.net/sublime_packages/package_control +[InstallPackageControl]: http://wbond.net/sublime_packages/package_control/installation +[GFM task]: https://github.github.com/gfm/#task-list-items-extension- +[GFM]: https://github.github.com/gfm/ +[GFMFeatures]: https://guides.github.com/features/mastering-markdown/ +[GFM-UnderscoreInWords]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/underscore-in-words.png +[GFM-FencedCodeBlock]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/fenced-code-block.png +[GFM-KeyboardShortcut]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/keyboard-shortcut.png +[GFM-Strikethrough]: https://raw.github.com/SublimeText-Markdown/MarkdownEditing/master/screenshots/strikethrough.png [linkBlackboardTheme]: https://github.com/mdesantis/MarkdownEditing/blob/blackboard-theme/MarkdownEditor-Blackboard.tmTheme [mdesantis]: https://github.com/mdesantis [avivace]: https://github.com/avivace [tips]: https://github.com/SublimeText-Markdown/MarkdownEditing/wiki/Tips [Wiki]: https://github.com/SublimeText-Markdown/MarkdownEditing/wiki -[Knockdown]: https://github.com/aziz/knockdown/ -[Sublime Markdown Extended]: https://github.com/jonschlinkert/sublime-markdown-extended -[SmartMarkdown]: https://github.com/demon386/SmartMarkdown +[Knockdown]: https://github.com/aziz/knockdown/ +[Sublime Markdown Extended]: https://github.com/jonschlinkert/sublime-markdown-extended +[SmartMarkdown]: https://github.com/demon386/SmartMarkdown [MarkdownTOC]: https://github.com/naokazuterada/MarkdownTOC [#158]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues/158 [brettterpstra]: http://brettterpstra.com -[github 9]: https://github.com/maliayas -[github 10]: https://github.com/felixhao28 -[github 4]: https://github.com/jngeist +[maliayas]: https://github.com/maliayas +[felixhao28]: https://github.com/felixhao28 +[J. Nicholas Geist]: https://github.com/jngeist [geekabouttown]: http://geekabouttown.com/posts/sublime-text-2-markdown-footnote-goodness [opensource]: http://www.opensource.org/licenses/MIT diff --git a/screenshots/arcdark.png b/screenshots/arcdark.png new file mode 100644 index 0000000000000000000000000000000000000000..6a242e3ac57d59480c1a6e644d834df5b2e27dcb GIT binary patch literal 52389 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 literal 0 HcmV?d00001 From 31de5c8d94c32c44857a379d6f79680d16e1cfdd Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Wed, 2 Aug 2017 17:20:04 +0800 Subject: [PATCH 14/18] fix a bug in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0b938ae..201afa69 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ You can access most features through Command Palette. You can launch it from `To - Asterisks and underscores are autopaired and will wrap selected text. - If you start an empty pair and hit backspace, both elements are deleted. - If you start an empty pair and hit space, the right element is deleted. - - Backticks are paired. So entering ` will expand to `(cursor here)`. + - Backticks are paired. So entering `` ` `` will expand to `` `(cursor here)` ``. * __List__ - At the end of a list item, pressing <kbd>Enter</kbd> will automatically insert the new list item bullet. - Pressing <kbd>Tab</kbd> on the blank list item will indent it and switch the list bullet to another one (Order is `*`, `-`, `+` in a cycle). From 00deb800dd98e3d170bb775abb241a196d2e887d Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Wed, 2 Aug 2017 17:51:59 +0800 Subject: [PATCH 15/18] add comments --- references.py | 82 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/references.py b/references.py index eb686762..7bc156e8 100644 --- a/references.py +++ b/references.py @@ -22,16 +22,20 @@ def hasScope(scope_name, to_find): + """Test to_find's existence in scope_name.""" return to_find in scope_name.split(" ") class Obj(object): + """A utility obj for anoymous object.""" def __init__(self, **kwargs): + """Take keyword arguments.""" self.__dict__.update(kwargs) def getMarkers(view, name=''): + """Find all markers.""" # returns {name -> Region} markers = [] name = re.escape(name) @@ -66,6 +70,7 @@ def getMarkers(view, name=''): def getReferences(view, name=''): + """Find all reference definitions.""" # returns {name -> Region} refs = [] name = re.escape(name) @@ -86,15 +91,15 @@ def getReferences(view, name=''): def isMarkerDefined(view, name): - # returns bool + """Return True if a marker is defined by that name.""" return len(getReferences(view, name)) > 0 def getCurrentScopeRegion(view, pt): - # returns Region + """Extend the region under current scope.""" scope = view.scope_name(pt) l = pt - while l > 0 and view.scope_name(l-1) == scope: + while l > 0 and view.scope_name(l - 1) == scope: l -= 1 r = pt while r < view.size() and view.scope_name(r) == scope: @@ -103,7 +108,7 @@ def getCurrentScopeRegion(view, pt): def findScopeFrom(view, pt, scope, backwards=False): - # returns number + """Find the nearest position of a scope from given position.""" if backwards: while pt >= 0 and not hasScope(view.scope_name(pt), scope): pt -= 1 @@ -114,6 +119,7 @@ def findScopeFrom(view, pt, scope, backwards=False): def get_reference(view, pos): + """Try to match a marker or reference on given position. Return a tuple (matched, is_definition, name).""" scope = view.scope_name(pos).split(" ") if definition_scope_name in scope or footnote_scope_name in scope: if refname_scope_name in scope: @@ -121,7 +127,7 @@ def get_reference(view, pos): defname = view.substr(getCurrentScopeRegion(view, pos)) elif refname_start_scope_name in scope: # Starting "[" - defname = view.substr(getCurrentScopeRegion(view, pos+1)) + defname = view.substr(getCurrentScopeRegion(view, pos + 1)) else: # URL or footnote marker_pt = findScopeFrom(view, pos, refname_scope_name, True) @@ -154,18 +160,18 @@ def get_reference(view, pos): class ReferenceJumpCommand(MDETextCommand): - # reference_jump command + """Jump between definition and reference.""" def description(self): + """Description for package control.""" return 'Jump between definition and reference' def run(self, edit): + """Run command callback.""" view = self.view edit_regions = [] markers = getMarkers(view) refs = getReferences(view) - missingMarkers = [] - missingRefs = [] for sel in view.sel(): matched, is_definition, defname = get_reference(view, sel.begin()) if matched: @@ -196,19 +202,22 @@ def run(self, edit): class ReferenceJumpContextCommand(ReferenceJumpCommand): + """Jump between definition and reference. Used in context menu.""" def is_visible(self): + """Return True if cursor is on a marker or reference.""" return ReferenceJumpCommand.is_visible(self) and any(get_reference(self.view, sel.begin())[0] for sel in self.view.sel()) def is_url(contents): - # Returns if contents contains an URL + """Return if contents contains an URL.""" re_match_urls = re.compile(r"""((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.‌​][a-z]{2,4}/)(?:[^\s()<>]+|(([^\s()<>]+|(([^\s()<>]+)))*))+(?:(([^\s()<>]+|(‌​([^\s()<>]+)))*)|[^\s`!()[]{};:'".,<>?«»“”‘’]))""", re.DOTALL) m = re_match_urls.search(contents) return True if m else False def mangle_url(url): + """Mangle URL for links.""" url = url.strip() if re.match(r'^([a-z0-9-]+\.)+\w{2,4}', url, re.IGNORECASE): url = 'http://' + url @@ -216,7 +225,7 @@ def mangle_url(url): def append_reference_link(edit, view, name, url): - # Detect if file ends with \n + r"""Detect if file ends with \n.""" if view.substr(view.size() - 1) == '\n': nl = '' else: @@ -228,7 +237,7 @@ def append_reference_link(edit, view, name, url): def suggest_default_link_name(name, image): - # Camel case impl. + """Suggest default link name in camel case.""" ret = '' name_segs = name.split() if len(name_segs) > 1: @@ -242,6 +251,7 @@ def suggest_default_link_name(name, image): def check_for_link(view, link): + """Check if the link already defined. Return the name if so.""" refs = getReferences(view) link = link.strip() for name in refs: @@ -254,9 +264,10 @@ def check_for_link(view, link): class ReferenceNewReferenceCommand(MDETextCommand): - # reference_new_reference command + """Create a new reference.""" def run(self, edit, image=False): + """Run command callback.""" view = self.view edit_regions = [] contents = sublime.get_clipboard().strip() @@ -286,12 +297,11 @@ def run(self, edit, image=False): class ReferenceNewInlineLinkCommand(MDETextCommand): - # reference_new_inline_link command + """Create a new inline link.""" def run(self, edit, image=False): + """Run command callback.""" view = self.view - edit_regions = [] - suggested_name = False contents = sublime.get_clipboard().strip() link = mangle_url(contents) if is_url(contents) else "" link = link.replace("$", "\\$") @@ -302,20 +312,23 @@ def run(self, edit, image=False): class ReferenceNewInlineImage(MDETextCommand): - # reference_new_inline_image command + """Create a new inline image.""" def run(self, edit): + """Run command callback.""" self.view.run_command("reference_new_inline_link", {"image": True}) class ReferenceNewImage(MDETextCommand): - # reference_new_image command + """Create a new image.""" def run(self, edit): + """Run command callback.""" self.view.run_command("reference_new_reference", {"image": True}) def get_next_footnote_marker(view): + """Get the number of the next footnote.""" refs = getReferences(view) footnotes = [int(ref[1:]) for ref in refs if view.substr(refs[ref].regions[0])[0] == "^"] @@ -336,15 +349,16 @@ def target_loc(num): else: break for i in range(len(footnotes)): - if footnotes[i] != i+1: - return i+1 + if footnotes[i] != i + 1: + return i + 1 return len(footnotes) + 1 class ReferenceNewFootnote(MDETextCommand): - # reference_new_footnote command + """Create a new footnote.""" def run(self, edit): + """Run command callback.""" view = self.view markernum = get_next_footnote_marker(view) markernum_str = '[^%s]' % markernum @@ -363,9 +377,10 @@ def run(self, edit): class ReferenceDeleteReference(MDETextCommand): - # reference_delete_reference command + """Delete a reference.""" def run(self, edit): + """Run command callback.""" view = self.view edit_regions = [] markers = getMarkers(view) @@ -377,25 +392,25 @@ def run(self, edit): if defname_key in markers: for marker in markers[defname_key].regions: if defname[0] == "^": - edit_regions.append(sublime.Region(marker.begin()-1, marker.end()+1)) + edit_regions.append(sublime.Region(marker.begin() - 1, marker.end() + 1)) else: l = findScopeFrom(view, marker.begin(), marker_begin_scope_name, True) - if l > 0 and view.substr(sublime.Region(l-1, l)) == "!": - edit_regions.append(sublime.Region(l-1, l+1)) + if l > 0 and view.substr(sublime.Region(l - 1, l)) == "!": + edit_regions.append(sublime.Region(l - 1, l + 1)) else: - edit_regions.append(sublime.Region(l, l+1)) + edit_regions.append(sublime.Region(l, l + 1)) if hasScope(view.scope_name(marker.end()), marker_text_end_scope_name): - if view.substr(sublime.Region(marker.end()+1, marker.end()+2)) == '[': + if view.substr(sublime.Region(marker.end() + 1, marker.end() + 2)) == '[': # [Text][] r = findScopeFrom(view, marker.end(), marker_end_scope_name, False) - edit_regions.append(sublime.Region(marker.end(), r+1)) + edit_regions.append(sublime.Region(marker.end(), r + 1)) else: # [Text] - edit_regions.append(sublime.Region(marker.end(), marker.end()+1)) + edit_regions.append(sublime.Region(marker.end(), marker.end() + 1)) else: # [Text][name] r = findScopeFrom(view, marker.begin(), marker_text_end_scope_name, True) - edit_regions.append(sublime.Region(r, marker.end()+1)) + edit_regions.append(sublime.Region(r, marker.end() + 1)) if defname_key in refs: for ref in refs[defname_key].regions: edit_regions.append(view.full_line(ref.begin())) @@ -412,9 +427,10 @@ def delete_all(index): class ReferenceOrganize(MDETextCommand): - # reference_organize command + """Sort and report all references.""" def run(self, edit): + """Run command callback.""" view = self.view # reorder @@ -440,8 +456,8 @@ def run(self, edit): flatrefs.sort(key=lambda x: marker_order[x[0].lower()] if x[0].lower() in marker_order else 9999) view.run_command("left_delete") - if view.size() >= 2 and view.substr(sublime.Region(view.size()-2, view.size())) == "\n\n": - view.erase(edit, sublime.Region(view.size()-1, view.size())) + if view.size() >= 2 and view.substr(sublime.Region(view.size() - 2, view.size())) == "\n\n": + view.erase(edit, sublime.Region(view.size() - 1, view.size())) for fn_tuple in flatfns: view.insert(edit, view.size(), fn_tuple[1]) view.insert(edit, view.size(), "\n") @@ -523,8 +539,10 @@ def get_times_string(n): class GatherMissingLinkMarkersCommand(MDETextCommand): + """Gather all missing references and creates them.""" def run(self, edit): + """Run command callback.""" view = self.view refs = getReferences(view) markers = getMarkers(view) From 787c70b5e767894d97ed8c33280236542af90fa5 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Thu, 3 Aug 2017 15:47:39 +0800 Subject: [PATCH 16/18] convert inline links to references close #426 --- Context.sublime-menu | 4 ++ Default.sublime-commands | 8 +++ decide_title.py | 3 +- messages/2.2.4.md | 9 +++- references.py | 111 ++++++++++++++++++++++++++++++++++++--- 5 files changed, 126 insertions(+), 9 deletions(-) diff --git a/Context.sublime-menu b/Context.sublime-menu index c9417f12..b2c9c0c5 100644 --- a/Context.sublime-menu +++ b/Context.sublime-menu @@ -10,5 +10,9 @@ { "caption": "MDE: Jump Reference", "command": "reference_jump_context" +}, +{ + "caption": "MDE: Convert inline link to reference", + "command": "convert_inline_link_to_reference" } ] \ No newline at end of file diff --git a/Default.sublime-commands b/Default.sublime-commands index f9f2e5c6..115c9679 100644 --- a/Default.sublime-commands +++ b/Default.sublime-commands @@ -144,5 +144,13 @@ { "caption": "MarkdownEditing: Change color scheme...", "command": "mde_color_activate" + }, + { + "caption": "MarkdownEditing: Convert all inline links to references", + "command": "convert_inline_links_to_references" + }, + { + "caption": "MarkdownEditing: Convert inline link to reference", + "command": "convert_inline_link_to_reference" } ] diff --git a/decide_title.py b/decide_title.py index 8fa52df1..664691f5 100644 --- a/decide_title.py +++ b/decide_title.py @@ -11,6 +11,7 @@ def on_modified_async(self, view): text = view.substr(sublime.Region(0, view.size())) it = re.finditer(r'^(#{1,6}(?!#))|^(-{3,}|={3,})', text, re.M) title = '' + title_begin = None for m in it: if '.front-matter' in view.scope_name(m.start()): continue @@ -23,7 +24,7 @@ def on_modified_async(self, view): title_begin = m.start() + 1 if 'markup.raw.block.markdown' not in view.scope_name(title_begin).split(' '): break - if len(title) == 0: + if len(title) == 0 and title_begin is not None: title = text[title_begin: title_end] title = title.strip() diff --git a/messages/2.2.4.md b/messages/2.2.4.md index 208125dc..2b6f043c 100644 --- a/messages/2.2.4.md +++ b/messages/2.2.4.md @@ -12,8 +12,13 @@ feedback you can use [GitHub issues][issues]. * Latex math expressions are highlighted now: - $\frac{d}{dx}\left( \int_{0}^{x} f(u)\,du\right)=f(x).$ -* Front matter (yaml, coffee, json) highlight -* Go Programming Language highlight in code blocks +* Front matter (yaml, coffee, json) highlight. +* Go Programming Language highlight in code blocks. +* Convert between inline links and references. + - Command: MarkdownEditing: Convert all inline links to references + - Command: MarkdownEditing: Convert inline link to references + + Only appear if cursor is on an inline link + + Also appear in context menu ## Changes diff --git a/references.py b/references.py index 7bc156e8..6765a5ee 100644 --- a/references.py +++ b/references.py @@ -2,6 +2,7 @@ import sublime_plugin import re import operator +from functools import partial try: from MarkdownEditing.mdeutils import * except ImportError: @@ -107,13 +108,15 @@ def getCurrentScopeRegion(view, pt): return sublime.Region(l, r) -def findScopeFrom(view, pt, scope, backwards=False): +def findScopeFrom(view, pt, scope, backwards=False, char=None): """Find the nearest position of a scope from given position.""" if backwards: - while pt >= 0 and not hasScope(view.scope_name(pt), scope): + while pt >= 0 and (not hasScope(view.scope_name(pt), scope) or + (char is not None and view.substr(pt) != char)): pt -= 1 else: - while pt < view.size() and not hasScope(view.scope_name(pt), scope): + while pt < view.size() and (not hasScope(view.scope_name(pt), scope) or + (char is not None and view.substr(pt) != char)): pt += 1 return pt @@ -245,7 +248,7 @@ def suggest_default_link_name(name, image): ret += word.capitalize() if len(ret) > 30: break - return ('image' if image else 'link') + ret + return ('image' if image else '') + ret else: return name @@ -274,7 +277,7 @@ def run(self, edit, image=False): link = mangle_url(contents) if is_url(contents) else "" suggested_name = "" if len(link) > 0: - # If link already exists, reuse existing reference + # If link already exists, reuse existing reference suggested_link_name = suggested_name = check_for_link(view, link) for sel in view.sel(): text = view.substr(sel) @@ -555,9 +558,105 @@ def run(self, edit): whitespace_at_end = view.find(r'\s*\z', 0) view.replace(edit, whitespace_at_end, "\n") - # If there is not already a reference list at the and, insert a new line at the end + # If there is not already a reference list at the end, insert a new line at the end if not view.find(r'\n\s*\[[^\]]*\]:.*\s*\z', 0): view.insert(edit, view.size(), "\n") for link in missings: view.insert(edit, view.size(), '[%s]: \n' % link) + + +def convert2ref(view, edit, link_span, name, omit_name=False): + """Convert single link to reference.""" + view.sel().clear() + link = view.substr(sublime.Region(link_span.a + 1, link_span.b - 1)) + if omit_name: + view.replace(edit, link_span, '[]') + link_span = sublime.Region(link_span.a + 1, link_span.a + 1) + offset = len(link) + else: + view.replace(edit, link_span, '[%s]' % name) + link_span = sublime.Region(link_span.a + 1, link_span.a + 1 + len(name)) + offset = len(link) - len(name) + view.sel().add(link_span) + view.show_at_center(link_span) + + _viewsize = view.size() + view.insert(edit, _viewsize, '[%s]: %s\n' % (name, link)) + reference_span = sublime.Region(_viewsize + 1, _viewsize + 1 + len(name)) + view.sel().add(reference_span) + return offset + + +class ConvertInlineLinkToReferenceCommand(MDETextCommand): + """Convert an inline link to reference.""" + + def is_visible(self): + """Return True if cursor is on a marker or reference.""" + for sel in self.view.sel(): + scope_name = self.view.scope_name(sel.b) + if hasScope(scope_name, 'meta.link.inline.markdown'): + return True + return False + + def run(self, edit, name=None): + """Run command callback.""" + view = self.view + pattern = r"\[([^\]]+)\]\((?!#)([^\)]+)\)" + + # Remove all whitespace at the end of the file + whitespace_at_end = view.find(r'\s*\z', 0) + view.replace(edit, whitespace_at_end, "\n") + + # If there is not already a reference list at the end, insert a new line at the end + if not view.find(r'\n\s*\[[^\]]*\]:.*\s*\z', 0): + view.insert(edit, view.size(), "\n") + + link_spans = [] + + for sel in view.sel(): + scope_name = view.scope_name(sel.b) + if not hasScope(scope_name, 'meta.link.inline.markdown'): + continue + start = findScopeFrom(view, sel.b, marker_begin_scope_name, backwards=True) + end = findScopeFrom(view, sel.b, 'punctuation.definition.metadata.markdown', char=')') + 1 + text = view.substr(sublime.Region(start, end)) + m = re.match(pattern, text) + if m is None: + continue + text = m.group(1) + link = m.group(2) + link_span = sublime.Region(start + m.span(2)[0] - 1, start + m.span(2)[1] + 1) + if is_url(link): + link = mangle_url(link) + if len(link) > 0: + if name is None: + # If link already exists, reuse existing reference + suggested_name = check_for_link(view, link) + if suggested_name is None: + is_image = view.substr(start - 1) == '!' if start > 0 else False + suggested_name = suggest_default_link_name(text, is_image) + + _name = name if name is not None else suggested_name + link_spans.append((link_span, _name, _name == text)) + + offset = 0 + for link_span in link_spans: + _link_span = sublime.Region(link_span[0].a + offset, link_span[0].b + offset) + offset -= convert2ref(view, edit, _link_span, link_span[1], link_span[2]) + + +class ConvertInlineLinksToReferencesCommand(MDETextCommand): + """Convert inline links to references.""" + + def run(self, edit): + """Run command callback.""" + view = self.view + pattern = r"(?<=\]\()(?!#)([^\)]+)(?=\))" + + _sel = [] + for sel in view.sel(): + _sel.append(sel) + view.sel().clear() + view.sel().add_all(view.find_all(pattern)) + view.run_command('convert_inline_link_to_reference') From ec3540fec69b6b6e2dee6f474e2d7dfb345433a7 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Thu, 3 Aug 2017 15:55:41 +0800 Subject: [PATCH 17/18] jump reference bugfix --- references.py | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/references.py b/references.py index 6765a5ee..7dbb7544 100644 --- a/references.py +++ b/references.py @@ -1,12 +1,27 @@ +""" +Commands related to links, references and footnotes. + +Exported commands: + ReferenceJumpCommand + ReferenceJumpContextCommand + ReferenceNewReferenceCommand + ReferenceNewInlineLinkCommand + ReferenceNewInlineImage + ReferenceNewImage + ReferenceNewFootnote + ReferenceDeleteReference + ReferenceOrganize + GatherMissingLinkMarkersCommand + ConvertInlineLinkToReferenceCommand + ConvertInlineLinksToReferencesCommand +""" import sublime -import sublime_plugin import re import operator -from functools import partial try: - from MarkdownEditing.mdeutils import * + from MarkdownEditing.mdeutils import MDETextCommand except ImportError: - from mdeutils import * + from mdeutils import MDETextCommand refname_scope_name = "constant.other.reference.link.markdown" definition_scope_name = "meta.link.reference.def.markdown" @@ -175,6 +190,8 @@ def run(self, edit): edit_regions = [] markers = getMarkers(view) refs = getReferences(view) + missing_markers = [] + missing_refs = [] for sel in view.sel(): matched, is_definition, defname = get_reference(view, sel.begin()) if matched: @@ -183,25 +200,25 @@ def run(self, edit): if defname_key in markers: edit_regions.extend(markers[defname_key].regions) else: - missingMarkers.append(defname) + missing_markers.append(defname) else: if defname_key in refs: edit_regions.extend(refs[defname_key].regions) else: - missingRefs.append(defname) + missing_refs.append(defname) if len(edit_regions) > 0: sels = view.sel() sels.clear() sels.add_all(edit_regions) view.show(edit_regions[0]) - if len(missingRefs) + len(missingMarkers) > 0: + if len(missing_refs) + len(missing_markers) > 0: # has something missing - if len(missingMarkers) == 0: - sublime.status_message("The definition%s of %s cannot be found." % ("" if len(missingRefs) == 1 else "s", ", ".join(missingRefs))) - elif len(missingRefs) == 0: - sublime.status_message("The marker%s of %s cannot be found." % ("" if len(missingMarkers) == 1 else "s", ", ".join(missingMarkers))) + if len(missing_markers) == 0: + sublime.status_message("The definition%s of %s cannot be found." % ("" if len(missing_refs) == 1 else "s", ", ".join(missing_refs))) + elif len(missing_refs) == 0: + sublime.status_message("The marker%s of %s cannot be found." % ("" if len(missing_markers) == 1 else "s", ", ".join(missing_markers))) else: - sublime.status_message("The definition%s of %s and the marker%s of %s cannot be found." % ("" if len(missingRefs) == 1 else "s", ", ".join(missingRefs), "" if len(missingMarkers) == 1 else "s", ", ".join(missingMarkers))) + sublime.status_message("The definition%s of %s and the marker%s of %s cannot be found." % ("" if len(missing_refs) == 1 else "s", ", ".join(missing_refs), "" if len(missing_markers) == 1 else "s", ", ".join(missing_markers))) class ReferenceJumpContextCommand(ReferenceJumpCommand): From 6fde81329e717cb5ca2fce34c96aee739edf7622 Mon Sep 17 00:00:00 2001 From: Felix Hao <felixhao28@gmail.com> Date: Mon, 4 Sep 2017 16:52:21 +0800 Subject: [PATCH 18/18] add Kotlin support Close #458 --- Markdown.sublime-syntax | 8 ++++++++ messages/2.2.4.md | 1 + 2 files changed, 9 insertions(+) diff --git a/Markdown.sublime-syntax b/Markdown.sublime-syntax index 815101e7..4cf45f9e 100644 --- a/Markdown.sublime-syntax +++ b/Markdown.sublime-syntax @@ -410,6 +410,13 @@ contexts: - match: ^(\1)\n pop: true - include: scope:source.go + fenced-kotlin: + - match: '^(\s*[`~]{3,})\s*(kt|kotlin)\s*$' + push: + - meta_scope: markup.raw.block.markdown markup.raw.block.fenced.markdown + - match: ^(\1)\n + pop: true + - include: scope:source.Kotlin fenced-code-blocks: - include: fenced-html - include: fenced-xml @@ -441,6 +448,7 @@ contexts: - include: fenced-swift - include: fenced-clojure - include: fenced-go + - include: fenced-kotlin - include: fenced-undefined fenced-coffee: - match: '^(\s*[`~]{3,})\s*(coffee|cjsx)\s*$' diff --git a/messages/2.2.4.md b/messages/2.2.4.md index 2b6f043c..a8dd1b92 100644 --- a/messages/2.2.4.md +++ b/messages/2.2.4.md @@ -14,6 +14,7 @@ feedback you can use [GitHub issues][issues]. - $\frac{d}{dx}\left( \int_{0}^{x} f(u)\,du\right)=f(x).$ * Front matter (yaml, coffee, json) highlight. * Go Programming Language highlight in code blocks. +* Kotlin Programming Language highlight in code blocks (requires Kotlin package). * Convert between inline links and references. - Command: MarkdownEditing: Convert all inline links to references - Command: MarkdownEditing: Convert inline link to references