diff --git a/.github/workflows/syntax-tests.yml b/.github/workflows/syntax-tests.yml index aa1f57d..7aedd31 100644 --- a/.github/workflows/syntax-tests.yml +++ b/.github/workflows/syntax-tests.yml @@ -21,10 +21,8 @@ jobs: strategy: matrix: include: - - build: 3211 - default_packages: v3211 - - build: 4107 - default_packages: v4107 + - build: 4143 + default_packages: v4143 - build: 4180 default_packages: v4180 - build: latest diff --git a/CoffeeScript Literate.sublime-syntax b/CoffeeScript Literate.sublime-syntax index c058105..0607209 100644 --- a/CoffeeScript Literate.sublime-syntax +++ b/CoffeeScript Literate.sublime-syntax @@ -3,6 +3,9 @@ # http://www.sublimetext.com/docs/syntax.html name: CoffeeScript (Literate) scope: source.litcoffee +version: 2 + +extends: Packages/Markdown/Markdown.sublime-syntax file_extensions: - litcoffee @@ -10,474 +13,45 @@ file_extensions: - coffee.md contexts: - main: - - match: |- - (?x)^ - (?= ([ ]{4}|\t)(?!$)) - push: - - meta_scope: markup.raw.block.markdown - - match: |- - (?x)^ - (?! ([ ]{4}|\t)) - pop: true - - include: block_raw - # 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. - - match: |- - (?x)^ - (?= [ ]{,3}>. - | [#]{1,6}\s*+ - | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ - ) - push: - - meta_scope: meta.block-level.markdown - - match: |- - (?x)^ - (?! [ ]{,3}>. - | [#]{1,6}\s*+ - | [ ]{,3}(?[-*_])([ ]{,2}\k){2,}[ \t]*+$ - ) - pop: true - - include: block_quote - - 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: 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: list-paragraph - # Markdown formatting is disabled inside block-level tags. - - match: '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b)(?!.*?)' - push: - - meta_scope: meta.disable-markdown - - match: (?<=^$\n) - pop: true - - include: scope:text.html.basic - # Same rule but for one line disables. - - match: '^(?=<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b)' - push: - - meta_scope: meta.disable-markdown - - match: $\n? - pop: true - - include: scope:text.html.basic - - 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 - \s* # Optional whitespace - $ - ) - scope: meta.link.reference.def.markdown - captures: - 1: punctuation.definition.constant.markdown - 2: constant.other.reference.link.markdown - 3: punctuation.definition.constant.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: - # 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. - - match: '\G[ ]{,3}(>)(?!$)[ ]?' - 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: 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 - block_raw: - - include: scope:source.coffee#script - bold: - - match: |- - (?x) - (\*\*|__)(?=\S) # Open - (?= - ( - <[^>]*+> # 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: scope:text.html.basic - - match: (?<=>) - pop: true - - include: escape - - include: ampersand - - include: bracket - - include: raw - - include: italic - - include: image-inline - - include: link-inline - - include: link-inet - - include: link-email - - include: image-ref - - include: link-ref-literal - - include: link-ref - bracket: - # Markdown will convert this for us. We match it so that the - # HTML grammar will not mark it up as invalid. - - match: '<(?![a-z/?\$!])' - scope: meta.other.valid-bracket.markdown - escape: - - match: '\\[-`*_#+.!(){}\[\]\\>]' - scope: constant.character.escape.markdown - 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: \s*(#*)$\n? - 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 - 3: 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.begin.markdown - 5: punctuation.definition.constant.markdown - 6: constant.other.reference.link.markdown - 7: punctuation.definition.constant.markdown - inline: - - include: escape - - include: ampersand - - include: bracket - - include: raw - - include: bold - - include: italic - - include: line-break - - include: image-inline - - include: link-inline - - include: link-inet - - include: link-email - - include: image-ref - - include: link-ref-literal - - include: link-ref - italic: - - match: |- - (?x) - (\*|_)(?=\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: scope:text.html.basic - - match: (?<=>) - pop: true - - include: escape - - include: ampersand - - include: bracket - - include: raw - - include: bold - - include: image-inline - - include: link-inline - - include: link-inet - - include: link-email - - include: image-ref - - include: link-ref-literal - - include: link-ref - 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-inet: - - match: (<)((?:https?|ftp)://.*?)(>) - scope: meta.link.inet.markdown - captures: - 1: punctuation.definition.link.markdown - 2: markup.underline.link.markdown - 3: punctuation.definition.link.markdown - link-inline: + + markdown: + - meta_prepend: true + - meta_scope: text.html.markdown.litcoffee + - include: coffee-indented-code-blocks + + list-block-content: + - meta_prepend: true + - include: coffee-indented-code-blocks + + coffee-indented-code-blocks: + - match: '{{indented_code_block}}' + scope: meta.embedded.litcoffee source.coffee.embedded.markdown + embed: scope:source.coffee + embed_scope: meta.embedded.litcoffee source.coffee.embedded.markdown + escape: ^(?=\s*$) + + fenced-syntaxes: + - meta_append: true + - include: fenced-coffee + + fenced-coffee: - 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: '^\s*([*+-]|[0-9]+\.)' - comment: Match the list punctuation - captures: - 1: punctuation.definition.list_item.markdown - numeric: - - match: '(?<!\$)\b((0([box])[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?))\b' - scope: constant.numeric.coffee - raw: - - match: '(`+)([^`]|(?!(?<!`)\1(?!`))`)*+(\1)' - scope: markup.raw.inline.markdown - captures: - 1: punctuation.definition.raw.markdown - 3: punctuation.definition.raw.markdown - separator: - - match: '\G[ ]{,3}([-*_])([ ]{,2}\1){2,}[ \t]*$\n?' - scope: meta.separator.markdown + (?x) + {{fenced_code_block_start}} + (?i:\s*(coffee(?:script)?|cjsx|cson|iced)) + {{fenced_code_block_trailing_infostring_characters}} + captures: + 0: meta.code-fence.definition.begin.coffee.markdown-gfm + 2: punctuation.definition.raw.code-fence.begin.markdown + 5: constant.other.language-name.markdown + 6: comment.line.infostring.markdown + 7: meta.fold.code-fence.begin.markdown + embed: scope:source.coffee + embed_scope: + markup.raw.code-fence.coffee.markdown-gfm + source.coffee + escape: '{{fenced_code_block_escape}}' + escape_captures: + 0: meta.code-fence.definition.end.coffee.markdown-gfm + 1: punctuation.definition.raw.code-fence.end.markdown + 2: meta.fold.code-fence.end.markdown diff --git a/tests/syntax_test_scope.litcoffee b/tests/syntax_test_scope.litcoffee index 59dcdbc..7c4f1ef 100644 --- a/tests/syntax_test_scope.litcoffee +++ b/tests/syntax_test_scope.litcoffee @@ -1,32 +1,35 @@ | SYNTAX TEST "CoffeeScript Literate.sublime-syntax" # Heading -| <- meta.block-level.markdown markup.heading.markdown punctuation.definition.heading.markdown -|^^^^^^^^^ meta.block-level.markdown markup.heading.markdown +| <- markup.heading.1.markdown punctuation.definition.heading.begin.markdown +|^^^^^^^^^ text.html.markdown.litcoffee markup.heading.1.markdown # Indendet Code Block class App.Router extends Snakeskin.Router - | <- markup.raw.block.markdown meta.class.coffee storage.type.class.coffee - |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.raw.block.markdown meta.class.coffee - - @index: () => - | ^^^^^^ meta.function.identifier.coffee entity.name.function.coffee - | ^^ meta.function.coffee - | ^^ meta.function.parameters.coffee - | ^^^ meta.function.coffee - | ^^ keyword.declaration.function.coffee + | <- meta.embedded.litcoffee source.coffee.embedded.markdown meta.class.coffee storage.type.class.coffee + |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.embedded.litcoffee source.coffee.embedded.markdown meta.class.coffee + index: () => @ensureData((data) => @_parseDates(data, ['trending', 'new', 'top']) App.layout.renderExchange('index', data, ['index', 'search']) ) +- In list items + + class App.Router extends Snakeskin.Router + | <- markup.list.unnumbered.markdown meta.embedded.litcoffee source.coffee.embedded.markdown meta.class.coffee storage.type.class.coffee + |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.list.unnumbered.markdown meta.embedded.litcoffee source.coffee.embedded.markdown meta.class.coffee + index: () => + @ensureData((data) => + @_parseDates(data, ['trending', 'new', 'top']) + App.layout.renderExchange('index', data, ['index', 'search']) + ) + > Not in block quotes > > class App.Router extends Snakeskin.Router -|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block-level.markdown markup.quote.markdown - markdup.raw - -# https://github.com/SublimeText/CoffeeScript/issues/203 +| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.quote.markdown markup.raw.block.markdown - source.coffee This is a test showcasing that multiline string interpolation is broken. Copy this post into a .litcoffee file and open it in Sublime to see the breakage. @@ -55,4 +58,4 @@ into a .litcoffee file and open it in Sublime to see the breakage. ...even this markdown is as well. :( | <- meta.paragraph.markdown -|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown \ No newline at end of file