diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7f629db --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +/.github/ export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +*.cmd export-ignore +*.png export-ignore \ No newline at end of file diff --git a/.github/workflows/ci-syntax-tests.yml b/.github/workflows/ci-syntax-tests.yml new file mode 100644 index 0000000..5bbdedc --- /dev/null +++ b/.github/workflows/ci-syntax-tests.yml @@ -0,0 +1,83 @@ +name: CI Syntax Tests + +on: + push: + push: + - '**' + paths: + - '.github/workflows/ci-syntax-tests.yml' + - '**.sublime-syntax' + - '**/syntax_test_*' + - '**.tmPreferences' + pull_request: + branches: + - '**' + paths: + - '.github/workflows/ci-syntax-tests.yml' + - '**.sublime-syntax' + - '**/syntax_test_*' + - '**.tmPreferences' + workflow_dispatch: + +jobs: + syntax_tests: + name: Sublime Text ${{ matrix.build }} + runs-on: ubuntu-latest + timeout-minutes: 15 # default is 6 hours! + strategy: + matrix: + include: + - build: 4126 + default_packages: v4126 + - build: 4143 + default_packages: v4143 + - build: latest # latest available ST build + default_packages: master + steps: + - name: Checkout Default Packages + uses: actions/checkout@v3 + with: + repository: sublimehq/Packages + ref: ${{ matrix.default_packages }} + path: st_syntax_tests/Data/Packages + + - name: Delete default package tests + run: |- + find st_syntax_tests/Data/Packages/*/ -type f -name 'syntax_test*' -exec rm -v '{}' \; + + - name: Prepare dummy syntaxes + run: |- + packages=st_syntax_tests/Data/Packages + scopes=( + source.less + source.sass + source.scss + source.stylus + ) + mkdir -vp "$packages/Default" + for scope in ${scopes[@]}; do + cat << SYNTAX > "$packages/Default/$scope.sublime-syntax" + %YAML 1.2 + --- + scope: $scope + + contexts: + main: [] + SYNTAX + done + + - name: Checkout MDX + uses: actions/checkout@v3 + with: + path: st_syntax_tests/Data/Packages/MDX + + - name: Run Syntax Tests for Sublime Text ${{ matrix.build }} + run: |- + if [[ "${{ matrix.build }}" == "latest" ]]; then + wget -O st_syntax_tests.tar.xz https://download.sublimetext.com/latest/dev/linux/x64/syntax_tests + else + wget -O st_syntax_tests.tar.xz https://download.sublimetext.com/st_syntax_tests_build_${{ matrix.build }}_x64.tar.xz + fi + tar xf st_syntax_tests.tar.xz + cd st_syntax_tests + ./syntax_tests diff --git a/.gitignore b/.gitignore index 496ee2c..153c8d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.DS_Store \ No newline at end of file +.DS_Store +*.cmd diff --git a/MDX.sublime-syntax b/MDX.sublime-syntax deleted file mode 100644 index 441d12f..0000000 --- a/MDX.sublime-syntax +++ /dev/null @@ -1,1353 +0,0 @@ -%YAML 1.2 ---- -name: MDX -file_extensions: - - mdx -scope: text.html.markdown.jsx - -variables: - ident: '[_$a-zA-Z][$\w]*' - -contexts: - main: - - include: core - - include: scope:text.html.markdown#markdown - - prototype: - - include: comments - - core: - - include: literal-function-labels - - include: literal-arrow-function-labels - - include: literal-labels - - include: literal-for - - include: literal-switch - - include: expression - - include: literal-punctuation - - expression: - # - include: merge-conflits - - include: literal-regexp # before operators and keywords to avoid ambiguities - - include: literal-jsx - # - include: es7-decorators - - include: support-class - - include: support-other - - - include: literal-function - - include: literal-arrow-function - - include: literal-prototype # after literal-function, which includes some prototype strings - - - include: literal-keywords - - - include: literal-method - - include: literal-module - - include: literal-class - # - include: flowtype-declaration - - - include: literal-number # after literal-method since short methods can be numbers - - include: literal-template-string - - include: literal-string - - include: literal-language-constant - - include: literal-language-variable - - - include: literal-constructor - - include: literal-method-call - - include: literal-function-call - - # - include: brackets - - # - include: literal-operators - # - include: literal-variable - - round-brackets: - - match: \( - scope: meta.brace.round.begin.js - push: - - meta_scope: meta.group.braces.round.js - - match: \) - scope: meta.brace.round.end.js - pop: true - - include: expression - - square-brackets: - - match: \[ - scope: meta.brace.square.begin.js - push: - - meta_scope: meta.group.braces.square.js - - match: \] - scope: meta.brace.square.end.js - pop: true - - include: expression - - curly-brackets: - - match: '{' - scope: meta.brace.curly.begin.js - push: - - meta_scope: meta.group.braces.curly.js - - match: '}' - scope: meta.brace.curly.end.js - pop: true - - include: main - - brackets: - - include: round-brackets - - include: square-brackets - - include: curly-brackets - - comments: - - match: /\*\*(?!/) - scope: punctuation.definition.comment.js - push: - - meta_scope: comment.block.documentation.js - - match: \*/ - scope: punctuation.definition.comment.js - pop: true - - - match: /\* - scope: punctuation.definition.comment.begin.js - push: - - meta_scope: comment.block.js - - match: \*/ - scope: punctuation.definition.comment.end.js - pop: true - - # - match: (?>) - # scope: comment.block.html.js - # captures: - # 0: punctuation.definition.comment.js - - - match: // - scope: punctuation.definition.comment.js - push: - - meta_scope: comment.line.double-slash.js - - match: $\n? - pop: true - - # - match: ^#! - # scope: punctuation.definition.comment.js - # push: - # - meta_scope: comment.line.shebang.js - # - match: $ - # pop: true - - function-declaration-parameters: - - match: \( - scope: punctuation.definition.parameters.begin.js - push: - - include: flowtype-annotation - - match: \) - scope: punctuation.definition.parameters.end.js - pop: true - - match: (?import|export|default|from|as)\b - scope: keyword.operator.module.js - - literal-class: - # e.g. class MyClass extends OtherClass { } - - match: (?extends|>|{)) - pop: true - - class_extends: - - match: \b(extends)\b - scope: storage.type.extends.js - set: - - match: (?={) - pop: true - - include: flowtype-polymorph - - include: expression - - match: (?={) - pop: true - - class_body: - - match: '{' - scope: punctuation.definition.class.body.begin.js - set: - - match: '}' - scope: punctuation.definition.class.body.end.js - pop: true - - include: es7-decorators - - include: class-properties - - include: class-method-definition - - include: class-method-storage - - include: brackets - - # flowtype-declaration: - # - match: (?; - # e.g. static (o: ?void): {[key: any]: any}; - # e.g. return(value: R): { done: true, value: R }; - # e.g. (o: T): T; - - match: (@@[_$a-zA-Z][$\w]*|static|return)(?=\s*[<(])|(?=\s*<) - scope: keyword.operator.flowtype.js - push: - - meta_scope: meta.short-method.flowtype.js - - match: (?=\s*[;{]) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - include: flowtype-annotation - - include: curly-brackets - - # In objects and flow annotations it can't be assumed that a start quote - # or start square-bracket is for a method - it may be a computed property. - # For multi-line quoted short methods and computed property methods, only - # the polymorphism constraints and parameters are matched. - - match: (?<=[]"''])\s*(?=[<(]) - push: - - meta_scope: meta.class-method.computed.js - - match: (?=\s*[;{]) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - include: flowtype-annotation - - include: curly-brackets - - - match: >- - (?x) - ((?>get|set)\s+) - (?> - ((')((?>[^'\\]|\\.)*)('))| - ((")((?>[^"\\]|\\.)*)("))| - (([_$a-zA-Z][$\w]*|\d+)) - )(?=\s*[<(]) - captures: - 1: storage.type.js - 2: string.quoted.js - 3: punctuation.definition.string.begin.js - 4: entity.name.function.js - 5: punctuation.definition.string.end.js - 6: string.quoted.js - 7: punctuation.definition.string.begin.js - 8: entity.name.function.js - 9: punctuation.definition.string.end.js - 10: string.unquoted.js - 11: entity.name.function.js - push: - - meta_scope: meta.class-accessor.js - - match: (?=\s*[;{]) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - include: flowtype-annotation - - include: curly-brackets - - - match: >- - (?x) - (?> - ((')((?>[^'\\]|\\.)*)('))| - ((")((?>[^"\\]|\\.)*)("))| - (([_$a-zA-Z][$\w]*|\d+)) - )(?=\s*[<(]) - captures: - 1: string.quoted.js - 2: punctuation.definition.string.begin.js - 3: entity.name.function.js - 4: punctuation.definition.string.end.js - 5: string.quoted.js - 6: punctuation.definition.string.begin.js - 7: entity.name.function.js - 8: punctuation.definition.string.end.js - 9: string.unquoted.js - 10: entity.name.function.js - push: - - meta_scope: meta.class-method.js - - match: (?=\s*[;{]) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - include: flowtype-annotation - - include: curly-brackets - - class-method-storage: - - match: (?static|declare)\b - scope: storage.modifier.js - - - match: (?- - (?x) - (?:\b(static)\s+)? - (?:\b(async)\s+)? - (?:(\*)\s*)? - (?> - ((')((?>[^'\\]|\\.)*)('))| - ((")((?>[^"\\]|\\.)*)("))| - (([_$a-zA-Z][$\w]*|\d+)) - ) - (?=\s*(\((?>(?>[^()]+)|\g<-1>)*\))(?>\s|/\*.*\*/)*\{) - captures: - 1: storage.type.js - 2: storage.type.js - 3: keyword.generator.asterisk.js - 4: string.quoted.js - 5: punctuation.definition.string.begin.js - 6: entity.name.function.js - 7: punctuation.definition.string.end.js - 8: string.quoted.js - 9: punctuation.definition.string.begin.js - 10: entity.name.function.js - 11: punctuation.definition.string.end.js - 12: string.unquoted.js - 13: entity.name.function.js - push: - - meta_scope: meta.method.js - - match: (?<=\)) - pop: true - - include: function-declaration-parameters - - # getter/setter - - match: >- - (?x) - \b(?:(static)\s+)? - (get|set)\s+ - ({{ident}}|\d+)\s* - (?=(\((?>(?>[^()]+)|\g<-1>)*\))(?>\s|/\*.*\*/)*\{) - captures: - 1: storage.type.js - 2: storage.type.accessor.js - 3: entity.name.accessor.js - push: - - meta_scope: meta.accessor.js - - match: (?<=\)) - pop: true - - include: function-declaration-parameters - - literal-prototype: - # e.g. Sound.prototype = { } when extending an object - - match: ({{ident}})(\.)(prototype)\s*(=)\s* - scope: meta.prototype.declaration.js - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: variable.language.prototype.js - 4: keyword.operator.assignment.js - - # e.g. Sound.prototype - - match: ({{ident}})(\.)(prototype)\b - scope: meta.prototype.access.js - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: variable.language.prototype.js - - literal-function: - # e.g. function play(arg1, arg2) { } - # e.g. play = function(arg1, arg2) { } - - match: >- - (?x) - (?:({{ident}})\s*(=)\s*)? - (?:(async)\s+)? - (function)(?>\s*(\*)|(?=[\s(<])) - \s*({{ident}})? - captures: - 1: entity.name.function.js - 2: keyword.operator.assignment.js - 3: storage.type.js - 4: storage.type.function.js - 5: keyword.generator.asterisk.js - 6: entity.name.function.js - push: - - meta_scope: meta.function.js - - match: (?<=\)) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - # e.g. Sound.prototype.play = function(arg1, arg2) { } - - match: >- - (?x) - (\b_?[A-Z][$\w]*)? - (\.)(prototype) - (\.)({{ident}}) - \s*(=) - \s*(?:(async)\s+)? - \s*(function)(?>\s*(\*)|(?=[\s(<])) - \s*({{ident}})?\s* - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: variable.language.prototype.js - 4: keyword.operator.accessor.js - 5: entity.name.function.js - 6: keyword.operator.assignment.js - 7: storage.type.js - 8: storage.type.function.js - 9: keyword.generator.asterisk.js - 10: entity.name.function.js - push: - - meta_scope: meta.function.prototype.js - - match: (?<=\)) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - # e.g. Sound.play = function(arg1, arg2) { } - - match: >- - (?x) - (\b_?[A-Z][$\w]*)? - (\.)({{ident}}) - \s*(=) - \s*(?:(async)\s+)? - \s*(function)(?>\s*(\*)|(?=[\s(<])) - \s*({{ident}})?\s* - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: entity.name.function.js - 4: keyword.operator.assignment.js - 5: storage.type.js - 6: storage.type.function.js - 7: keyword.generator.asterisk.js - 8: entity.name.function.js - push: - - meta_scope: meta.function.static.js - - match: (?<=\)) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - literal-function-labels: - # e.g. play: function(arg1, arg2) { } - # e.g. "play": function(arg1, arg2) { } - - match: >- - (?x) - (?> - ((')((?>[^'\\]|\\.)*)('))| - ((")((?>[^"\\]|\\.)*)("))| - (({{ident}}|\d+)) - ) - \s*(:) - \s*(?:\b(async)\s+)? - \s*(function)(?>\s*(\*)|(?=[\s(<])) - \s*({{ident}})? - captures: - 1: string.quoted.js - 2: punctuation.definition.string.begin.js - 3: entity.name.function.js - 4: punctuation.definition.string.end.js - 5: string.quoted.js - 6: punctuation.definition.string.begin.js - 7: entity.name.function.js - 8: punctuation.definition.string.end.js - 9: string.unquoted.js - 10: entity.name.function.js - 11: punctuation.separator.key-value.js - 12: storage.type.js - 13: storage.type.function.js - 14: keyword.generator.asterisk.js - 15: entity.name.function.js - push: - - meta_scope: meta.function.json.js - - match: (?<=\)) - pop: true - - include: flowtype-polymorph - - include: function-declaration-parameters - - literal-arrow-function: - # e.g. (args) => { } - # e.g. play = (args) => { } - - match: >- - (?x) - (?:({{ident}})\s*(=)\s*)? - (?:\b(async)\s+)? - (?=(\((?>(?>[^()]+)|\g<-1>)*\))\s*(=>)) - captures: - 1: entity.name.function.js - 2: keyword.operator.assignment.js - 3: storage.type.js - push: - - meta_scope: meta.function.arrow.js - - match: (?<=\))\s*(=>) - captures: - 1: storage.type.function.arrow.js - pop: true - - include: function-declaration-parameters - - # e.g. arg => { } - # e.g. play = arg => { } - - match: >- - (?x) - (?:({{ident}})\s*(=)\s*)? - (?:(async)\s+)? - \b({{ident}})\s*(=>) - scope: meta.function.arrow.js - captures: - 1: entity.name.function.js - 2: keyword.operator.assignment.js - 3: storage.type.js - 4: variable.parameter.function.js - 5: storage.type.function.arrow.js - - # e.g. Sound.prototype.play = (args) => { } - - match: >- - (?x) - (\b_?[A-Z][$\w]*)? - (\.)(prototype) - (\.)({{ident}}) - \s*(=) - \s*(async)? - \s*(?=(\((?>(?>[^()]+)|\g<-1>)*\))\s*(=>)) - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: variable.language.prototype.js - 4: keyword.operator.accessor.js - 5: entity.name.function.js - 6: keyword.operator.assignment.js - 7: storage.type.js - push: - - meta_scope: meta.prototype.function.arrow.js - - match: (?<=\))\s*(=>) - captures: - 1: storage.type.function.arrow.js - pop: true - - include: function-declaration-parameters - - # e.g. Sound.prototype.play = arg => { } - - match: >- - (?x) - (\b_?[A-Z][$\w]*)? - (\.)(prototype) - (\.)({{ident}}) - \s*(=) - \s*(async)? - \s*\b({{ident}})\s*(=>) - scope: meta.prototype.function.arrow.js - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: variable.language.prototype.js - 4: keyword.operator.accessor.js - 5: entity.name.function.js - 6: keyword.operator.assignment.js - 7: storage.type.js - 8: variable.parameter.function.js - 9: storage.type.function.arrow.js - - # e.g. Sound.play = (args) => { } - - match: >- - (?x) - (\b_?[A-Z][$\w]*)? - (\.)({{ident}}) - \s*(=) - \s*(async)? - \s*(?=(\((?>(?>[^()]+)|\g<-1>)*\))\s*(=>)) - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: entity.name.function.js - 4: keyword.operator.assignment.js - 5: storage.type.js - push: - - meta_scope: meta.function.static.arrow.js - - match: (?<=\))\s*(=>) - captures: - 1: storage.type.function.arrow.js - pop: true - - include: function-declaration-parameters - - # e.g. Sound.play = arg => { } - - match: >- - (?x) - (\b_?[A-Z][$\w]*)? - (\.)({{ident}}) - \s*(=) - \s*(async)? - \s*\b({{ident}})\s*(=>) - scope: meta.function.static.arrow.js - captures: - 1: entity.name.class.js - 2: keyword.operator.accessor.js - 3: entity.name.function.js - 4: keyword.operator.assignment.js - 5: storage.type.js - 6: variable.parameter.function.js - 7: storage.type.function.arrow.js - - literal-arrow-function-labels: - # e.g. play: (args) => { } - # e.g. "play": (args) => { } - - match: >- - (?x) - (?> - ((')((?>[^'\\]|\\.)*)('))| - ((")((?>[^"\\]|\\.)*)("))| - (({{ident}}|\d+)) - ) - \s*(:) - \s*(?:\b(async)\s+)? - \s*(?=(\((?>(?>[^()]+)|\g<-1>)*\))\s*(=>)) - captures: - 1: string.quoted.js - 2: punctuation.definition.string.begin.js - 3: entity.name.function.js - 4: punctuation.definition.string.end.js - 5: string.quoted.js - 6: punctuation.definition.string.begin.js - 7: entity.name.function.js - 8: punctuation.definition.string.end.js - 9: string.unquoted.js - 10: entity.name.function.js - 11: punctuation.separator.key-value.js - 12: storage.type.js - push: - - meta_scope: meta.function.json.arrow.js - - match: (?<=\))\s*(=>) - captures: - 1: storage.type.function.arrow.js - pop: true - - include: function-declaration-parameters - - # e.g. play: arg => { } - # e.g. "play": arg => { } - - match: >- - (?x) - (?> - ((')((?>[^'\\]|\\.)*)('))| - ((")((?>[^"\\]|\\.)*)("))| - (({{ident}}|\d+)) - ) - \s*(:) - \s*(?:\b(async)\s+)? - \s*\b({{ident}})\s*(=>) - scope: meta.function.json.arrow.js - captures: - 1: string.quoted.js - 2: punctuation.definition.string.begin.js - 3: entity.name.function.js - 4: punctuation.definition.string.end.js - 5: string.quoted.js - 6: punctuation.definition.string.begin.js - 7: entity.name.function.js - 8: punctuation.definition.string.end.js - 9: string.unquoted.js - 10: entity.name.function.js - 11: punctuation.separator.key-value.js - 12: storage.type.js - 13: variable.parameter.function.js - 14: storage.type.function.arrow.js - - literal-function-call: - - match: ({{ident}})\s*(\(\s*\)) - scope: meta.function-call.without-arguments.js - captures: - 1: variable.function.js - 2: meta.group.braces.round.function.arguments.js - - - match: ({{ident}})\s*(?=\() - scope: meta.function-call.with-arguments.js - captures: - 1: variable.function.js - - - match: ({{ident}})\s*(?=`) - scope: meta.function-call.tagged-template.js - captures: - 1: variable.function.js - - literal-method-call: - - match: >- - (?x) - (?:(?<=\.)|\b) - ([A-Z][$\w]*)\s*(\.) - ({{ident}})\s* - (\(\s*\)) - scope: meta.function-call.static.without-arguments.js - captures: - 1: variable.other.class.js - 2: keyword.operator.accessor.js - 3: variable.function.js - 4: meta.group.braces.round.function.arguments.js - - - match: >- - (?x) - (?:(?<=\.)|\b) - ([A-Z][$\w]*)\s*(\.) - ({{ident}})\s* - (?=\() - scope: meta.function-call.static.with-arguments.js - captures: - 1: variable.other.class.js - 2: keyword.operator.accessor.js - 3: variable.function.js - - - match: >- - (?x) - (?<=\.) - ({{ident}})\s* - (\(\s*\)) - scope: meta.function-call.method.without-arguments.js - captures: - 1: variable.function.js - 2: meta.group.braces.round.function.arguments.js - - - match: >- - (?x) - (?<=\.) - ({{ident}})\s* - (?=\() - scope: meta.function-call.method.with-arguments.js - captures: - 1: variable.function.js - - literal-language-variable: - - match: (?const|let|var)\b - scope: storage.type.js - - literal-keywords: - - include: literal-keyword-storage - - - match: (?await|yield))\b(?:\s*(\*))? - captures: - 1: keyword.control.flow.js - 2: keyword.generator.asterisk.js - - - match: (?if|else)\b - scope: keyword.control.conditional.js - - - match: (?catch|finally|throw|try)\b - scope: keyword.control.trycatch.js - - - match: (?break|continue|do|goto|while|case|default)\b - scope: keyword.control.loop.js - - - match: (?enum|public|package|private|interface|protected)\b - scope: keyword.other.reserved.js - - - match: (?delete|instanceof|in|new|of|typeof|void|with)\b - scope: keyword.operator.js - - - match: >- - (?x) - !(?!=)| # logical-not right-to-left right - && | # logical-and left-to-right both - \|\| | # logical-or left-to-right both - scope: keyword.operator.logical.js - - - match: >- - (?x) - =(?!=)| # assignment right-to-left both - scope: keyword.operator.assignment.js - - - match: >- - (?x) - %= | # assignment right-to-left both - &= | # assignment right-to-left both - \*= | # assignment right-to-left both - \+= | # assignment right-to-left both - -= | # assignment right-to-left both - /= | # assignment right-to-left both - \^= | # assignment right-to-left both - \|= | # assignment right-to-left both - <<= | # assignment right-to-left both - >>= | # assignment right-to-left both - >>>= | # assignment right-to-left both - scope: keyword.operator.assignment.augmented.js - - - match: >- - (?x) - ~ | # bitwise-not right-to-left right - << | # bitwise-shift left-to-right both - >>> | # bitwise-shift left-to-right both - >> | # bitwise-shift left-to-right both - & | # bitwise-and left-to-right both - \^ | # bitwise-xor left-to-right both - \| # bitwise-or left-to-right both - scope: keyword.operator.bitwise.js - - - match: >- - (?x) - <= | # relational left-to-right both - >= | # relational left-to-right both - < | # relational left-to-right both - > # relational left-to-right both - scope: keyword.operator.relational.js - - - match: >- - (?x) - === | # equality left-to-right both - !== | # equality left-to-right both - == | # equality left-to-right both - != # equality left-to-right both - scope: keyword.operator.comparison.js - - - match: >- - (?x) - -- | # decrement n/a right-or-left - \+\+ | # increment n/a right-or-left - / | # division left-to-right both - % | # modulus left-to-right both - \* | # multiplication left-to-right both - \+ | # addition left-to-right both - - # subtraction left-to-right both - scope: keyword.operator.arithmetic.js - - - match: '[?:]' - scope: keyword.operator.ternary.js - - - match: (?- - (?x) - (? - ((')((?>[^'\\]|\\.)*)('))| - ((")((?>[^"\\]|\\.)*)(")) - )\s*:) - push: - - match: ':' - scope: punctuation.separator.key-value.js - pop: true - - include: literal-string - - - match: (?- - (?xi) - (?:\B[-+])? - (?: - \b0b[0-1]*| # binary - \b0o[0-7]*| # octal - \b0x[0-9a-f]*| # hex - ( - \B\.[0-9]+| # e.g. .999 - \b[0-9]+(\.[0-9]*)? # e.g. 999.999, 999. or 999 - )(e[-+]?[0-9]+)? # e.g. e+123, E-123 - ) - scope: constant.numeric.js - - - match: (?:\B[-+]|\b)(Infinity)\b - scope: constant.language.infinity.js - - literal-punctuation: - - match: ; - scope: punctuation.terminator.statement.js - - - match: ',' - scope: meta.delimiter.comma.js - - literal-regexp: - # ignore ++, -- since they're uncommon, distinguishing them is not possible in sublime text, see: - # http://stackoverflow.com/questions/5519596/when-parsing-javascript-what-determines-the-meaning-of-a-slash - - match: >- - (?x) - (?<= - \.|\(|,|{|}|\[|;|<|>|<=|>=|==|!=|===|!==|\+|-|\*|%|\+\+|--|<<|>>|>>>|&|\||\^|!|~|&&|\|\||\?|:|=|\+=|-=|\*=|%=|<<=|>>=|>>>=|&=|\|=|\^=|/|/=| - \Wnew|\Wdelete|\Wvoid|\Wtypeof|\Winstanceof|\Win|\Wdo|\Wreturn|\Wcase|\Wthrow|\Wyield - ^new|^delete|^void|^typeof|^instanceof|^in|^do|^return|^case|^throw|^yield|^ - )\s* - (/) - (?!/|\*|$) - captures: - 1: punctuation.definition.string.begin.js - push: - - meta_scope: string.regexp.js - - match: (/)([gimy]*) - captures: - 1: punctuation.definition.string.end.js - 2: keyword.other.js - pop: true - - include: scope:source.regexp.js - - literal-string: - - match: (["']) - scope: punctuation.definition.string.quoted.begin.js - push: - - meta_include_prototype: false - - meta_scope: string.quoted.js - - match: \n - scope: invalid.illegal.newline.js - pop: true - - match: \1 - scope: punctuation.definition.string.quoted.end.js - pop: true - - include: string-content - - literal-template-string: - - match: '`' - scope: keyword.other.template.begin.js - push: template-string-body - - template-string-body: - - meta_include_prototype: false - - meta_scope: string.interpolated.js - - match: \\` - scope: constant.character.escape.js - - match: '`' - scope: keyword.other.template.end.js - pop: true - - match: \${ - scope: keyword.other.substitution.begin.js - set: - - match: '}' - scope: keyword.other.substitution.end.js - set: template-string-body - - include: expression - - include: string-content - - string-content: - # https://mathiasbynens.be/notes/javascript-escapes - - match: \\\s*\n - scope: constant.character.escape.newline.js - - - match: \\([1-7][0-7]{0,2}|[0-7]{2,3}|[bfnrtv0'"\\]|x\h{2}|u\{\h+\}|u\h{4}) - scope: constant.character.escape.js - - literal-variable: - # e.g. CONSTANT - - match: _*?[A-Z][_$\dA-Z]*\b - scope: variable.other.constant.js - - # e.g. Class.property - - match: \b([A-Z][$\w]*)\s*(\.)({{ident}}) - scope: meta.property.class.js - captures: - 1: variable.other.class.js - 2: keyword.operator.accessor.js - 3: variable.other.property.static.js - - # e.g. obj.property - - match: (?Eval|Range|Reference|Syntax|Type|URI)?Error)\b - scope: support.class.error.js - - - match: \b(?>Buffer)\b - scope: support.class.node.js - - support-other: - - match: (?document|window)\b - scope: support.type.object.dom.js - - - match: (?global|GLOBAL|root|__dirname|__filename)\b - scope: support.type.object.node.js - - - match: (?|\Wreturn|^return|^)(?=\s*<[_$a-zA-Z]) - push: - - meta_content_scope: meta.jsx.js - - match: (?<=/>|>) - pop: true - - include: jsx-tag-start - - jsx-attribute-assignment: - - match: = - scope: keyword.operator.assignment.jsx - - jsx-attribute-name: - - match: '[_$a-zA-Z][-$\w]*' - scope: entity.other.attribute-name.jsx - - jsx-attributes: - - include: jsx-attribute-name - - include: jsx-attribute-assignment - - include: jsx-string-quoted - - include: jsx-evaluated-code - - jsx-entities: - - match: '&(?:[a-zA-Z0-9]+|#\d+|#x\h+);' - scope: constant.character.entity.jsx - - match: '&\S*;' - scope: invalid.illegal.bad-ampersand.jsx - - jsx-evaluated-code: - - match: \{ - scope: punctuation.section.embedded.begin.jsx - push: - - meta_scope: meta.embedded.expression.jsx - - match: \} - scope: punctuation.section.embedded.end.jsx - pop: true - - include: expression - - jsx-string-quoted: - - match: (["']) - scope: punctuation.definition.string.begin.jsx - push: - - meta_include_prototype: false - - meta_scope: string.quoted.jsx - - match: \1 - scope: punctuation.definition.string.end.jsx - pop: true - - include: jsx-entities - - jsx-tag-end: - - match: '>' - scope: meta.tag.jsx punctuation.definition.tag.end.jsx - push: - - meta_include_prototype: false - - match: (?=)|(/>) - captures: - 1: meta.tag.jsx punctuation.definition.tag.begin.jsx - 2: meta.tag.jsx entity.name.tag.jsx - 3: meta.tag.jsx punctuation.definition.tag.end.jsx - 4: meta.tag.jsx punctuation.definition.tag.end.jsx - pop: true - - include: jsx-tag-end - - include: jsx-attributes - - - match: '<' - scope: invalid.illegal.tag.incomplete.jsx - - # https://github.com/wycats/javascript-decorators - # es7-decorators: - # - match: (@)([_$a-zA-Z][$\w]*)\b - # scope: tag.decorator.js - # captures: - # 1: punctuation.definition.tag.js - # 2: entity.name.tag.js - - merge-conflits: - - match: ^([<]{7})\s(.+)$ - captures: - 1: invalid.illegal.conflict-marker.merge-into.js - 2: invalid.illegal.string.js - - match: ^([=|]{7})$ - captures: - 1: invalid.illegal.conflict-marker.separator.js - - match: ^([>]{7})\s(.+)$ - captures: - 1: invalid.illegal.conflict-marker.other-commit.js - 2: invalid.illegal.string.js - - # flowtype-polymorph: - # # http://flowtype.org/blog/2015/03/12/Bounded-Polymorphism.html - # - match: '<' - # scope: punctuation.section.flowtype.begin.js - # push: - # - meta_scope: meta.flowtype.polymorph.js - # - match: '>' - # scope: punctuation.section.flowtype.end.js - # pop: true - # - include: flowtype-tokens - - # flowtype-annotation: - # - match: (?:(\?)\s*)?(:) - # captures: - # 1: keyword.operator.flowtype.optional.js - # 2: keyword.operator.flowtype.annotation.js - # push: - # - meta_scope: meta.flowtype.annotation.js - # - include: flowtype-tokens - # - match: (?=\S) - # pop: true - - # flowtype-brackets: - # - match: '{' - # scope: punctuation.section.flowtype.begin.js - # push: - # - match: '}' - # scope: punctuation.section.flowtype.end.js - # pop: true - # - include: flowtype-tokens - - # flowtype-identifier: - # - include: support-class - - # - match: \b(?:any|bool|boolean|mixed|number|string|void)\b - # scope: constant.other.primitve.flowtype.js - - # - match: '[_$a-zA-Z][$\w]*' - # scope: variable.other.flowtype.js - - # - match: \? - # scope: keyword.operator.flowtype.optional.js - - # flowtype-tokens: - # - match: (?<=[:?|&=])(?=\s*{) - # push: - # - match: (?<=}) - # pop: true - # - include: flowtype-brackets - - # - match: \s*([|&])\s* - # scope: meta.flowtype.set.js - # captures: - # 1: keyword.operator.flowtype.other.js - - # - match: '[*:?&|.]|\.\.\.|\b(typeof)\b' - # scope: keyword.operator.flowtype.other.js - - # - match: '<' - # scope: punctuation.section.flowtype.begin.js - # push: - # - match: '>' - # scope: punctuation.section.flowtype.end.js - # pop: true - # - include: flowtype-tokens - - # - match: \[ - # scope: punctuation.section.flowtype.begin.js - # push: - # - match: \] - # scope: punctuation.section.flowtype.end.js - # pop: true - # - include: flowtype-tokens - - # - match: \( - # scope: punctuation.section.flowtype.begin.js - # push: - # - match: \) - # scope: punctuation.section.flowtype.end.js - # pop: true - # - include: flowtype-tokens - - # - match: '=>' - # scope: keyword.operator.flowtype.js - # push: - # - meta_scope: meta.flowtype.function.js - # - match: (?<=}|[_$a-zA-Z]) - # pop: true - # - include: flowtype-brackets - # - include: flowtype-identifier - # - include: comments - - # - include: flowtype-identifier - # - include: literal-string - # - include: comments diff --git a/README.md b/README.md index 9cec575..81d3638 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,9 @@ MDX === -[MDX](https://github.com/mdx-js/mdx) syntax definitions for [Sublime Text](https://www.sublimetext.com). - -![](https://user-images.githubusercontent.com/359871/46480043-fea47980-c7b5-11e8-9dd4-9e39066d22f3.png) - -It works but isn’t perfect. - -_MDX.sublime-syntax_ was adapted from [babel-sublime](https://github.com/babel/babel-sublime). - -> **Note** -> -> This version is no longer maintained. -> -> It is shipped for backward compatibility reasons and to respect the original authors efforts. -> -> see: https://github.com/jonsuh/mdx-sublime -> -> **A fully working MDX syntax definition requires ST4126+.** +[MDX](https://github.com/mdx-js/mdx) syntax definitions for [Sublime Text](https://www.sublimetext.com) based on its HTML, Markdown and JSX syntaxes. +![](preview.png) ## Installation ### Package Control diff --git a/Syntaxes/Embeddings/HTML (for MDX).sublime-syntax b/Syntaxes/Embeddings/HTML (for MDX).sublime-syntax new file mode 100644 index 0000000..6282170 --- /dev/null +++ b/Syntaxes/Embeddings/HTML (for MDX).sublime-syntax @@ -0,0 +1,131 @@ +%YAML 1.2 +--- +# This syntax adds JSX interpolation to tags and components for use in MDX. +# http://www.sublimetext.com/docs/syntax.html +scope: text.html.embedded.mdx +version: 2 +hidden: true + +extends: Packages/HTML/HTML.sublime-syntax + +variables: + + jsx_component_start: |- + (?x: [$A-Z_-] | [a-z]{{jsx_component_char}}*\s*[.:] ) + + jsx_component_char: '[^.:/?!\s<>=]' + +contexts: + + prototype: + - meta_prepend: true + - include: jsx-interpolations + +###[ CUSTOM HTML ]############################################################ + + tag-html: + # Keep only tags with special attribute handling. + # No further distinction of different html tag types desired for MDX. + - include: script-tag + - include: style-tag + + tag-other: + # jsx component tags + - include: jsx-components + # native html or foreign tags + - match: ' + scope: punctuation.definition.tag.end.html + pop: 1 + - include: jsx-string-interpolations + + tag-attribute-value-content: + - meta_prepend: true + - include: jsx-string-interpolations + + strings-common-content: + - meta_prepend: true + - include: jsx-string-interpolations + +###[ JSX COMPONENTS ]###################################################### + + jsx-components: + # mimic component scopes from JSX.sublime-syntax to ensure consistency + - match: + scope: meta.tag.js punctuation.definition.tag.end.js + pop: 1 + +###[ JSX INTERPOLATIONS ]################################################## + + jsx-string-interpolations: + - match: \{ + scope: punctuation.section.interpolation.begin.markdown + push: jsx-string-interpolation-body + + jsx-string-interpolation-body: + - clear_scopes: 1 + - meta_include_prototype: false + - meta_scope: meta.interpolation.markdown + - meta_content_scope: source.jsx.embedded.markdown + - include: jsx-interpolation-body + + jsx-interpolations: + - match: \{ + scope: punctuation.section.interpolation.begin.markdown + push: jsx-interpolation-body + + jsx-interpolation-body: + - meta_include_prototype: false + - meta_scope: meta.interpolation.markdown + - meta_content_scope: source.jsx.embedded.markdown + - match: \} + scope: punctuation.section.interpolation.end.markdown + pop: 1 + - include: scope:source.jsx#script + apply_prototype: true diff --git a/Syntaxes/Embeddings/JSX (for MDX).sublime-syntax b/Syntaxes/Embeddings/JSX (for MDX).sublime-syntax new file mode 100644 index 0000000..a92bde0 --- /dev/null +++ b/Syntaxes/Embeddings/JSX (for MDX).sublime-syntax @@ -0,0 +1,21 @@ +%YAML 1.2 +--- +# This helper syntax is used to for import/export statements in MDX. +# It ensures them to get popped off stack if semicolon is missing. +# http://www.sublimetext.com/docs/syntax.html +scope: source.jsx.embedded.mdx +version: 2 +hidden: true + +extends: Packages/JavaScript/JSX.sublime-syntax + +contexts: + expect-semicolon: + - meta_append: true + - match: $ + pop: 1 + + expression-end: + - meta_append: true + - match: $ + pop: 1 diff --git a/Syntaxes/Embeddings/Markdown (for MDX).sublime-syntax b/Syntaxes/Embeddings/Markdown (for MDX).sublime-syntax new file mode 100644 index 0000000..738f21f --- /dev/null +++ b/Syntaxes/Embeddings/Markdown (for MDX).sublime-syntax @@ -0,0 +1,3205 @@ +%YAML 1.2 +--- +# This definition aims to meet CommonMark specifications +# http://spec.commonmark.org/ +# with GitHub Formatted Markdown extensions +# https://github.github.com/gfm/ +# and has a few extras like Markdown Extra's footnotes +# https://michelf.ca/projects/php-markdown/extra/#footnotes +# +# The scope suffix should indicate which flavor of Markdown the feature came from, +# to help make this syntax definition easier to maintain. +scope: text.html.markdown.for-mdx +version: 2 +hidden: true + +variables: + atx_heading: (?:[ ]{,3}[#]{1,6}(?:[ \t]|$)) # between 0 and 3 spaces, followed 1 to 6 hashes, followed by at least one space or tab or by end of the line + atx_heading_space: (?:(?=[ \t]+#+[ \t]*$)|[ \t]+|$) # consume spaces only if heading is not empty to ensure `atx_heading_end` can fully match closing hashes + atx_heading_end: (?:[ \t]+(#+))?[ \t]*($\n?) # \n is optional so ## is matched as end punctuation in new document (at eof) + + setext_heading_or_paragraph: ^(?:[ ]{,3}=+|(?=[ ]{,3}\S)) # between 0 and 3 spaces, followed by non-whitespace (consume equal signs as paragraphs may start with them) + setext_heading_escape: ^(?=[ ]{,3}(?:=+|-+)[ \t]*$) # between 0 and 3 spaces, followed by at least one hyphen or equal sign (setext underline can be of any length) + setext_heading1_escape: ^(?=[ ]{,3}=+[ \t]*$) # between 0 and 3 spaces, followed by at least one equal sign (setext underline can be of any length) + setext_heading1_end: ^[ ]{,3}(=+)[ \t]*$(\n?) # between 0 and 3 spaces, followed by at least one equal sign (setext underline can be of any length) + setext_heading2_end: ^[ ]{,3}(-+)[ \t]*$(\n?) # between 0 and 3 spaces, followed by at least one hyphen (setext underline can be of any length) + + list_setext_heading_or_paragraph: (?:[ \t]*=+|(?=[ \t]*\S)) # any number of spaces, followed by non-whitespace (consume equal signs as paragraphs may start with them) + list_setext_heading_escape: ^(?=[ \t]{2,}(?:==+|--+)[ \t]*$) # two or more spaces, followed by at least one hyphen or equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + list_setext_heading1_escape: ^(?=[ \t]{2,}==+[ \t]*$) # two or more spaces, followed by at least one equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + list_setext_heading1_end: ^[ \t]{2,}(==+)[ \t]*$(\n?) # two or more spaces, followed by at least one equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + list_setext_heading2_end: ^[ \t]{2,}(--+)[ \t]*$(\n?) # two or more spaces, followed by at least one hyphen (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + + block_quote: (?:[ ]{,3}(>)[ ]?) # between 0 and 3 spaces, followed by a greater than sign, (followed by any character or the end of the line = "only care about optional space!") + indented_code_block: (?:[ ]{4}|[ ]{0,3}\t) # a visual tab of width 4 consisting of 4 spaces or 0 to 3 spaces followed by 1 tab + + first_list_item: (?:[ ]{,3}(?:1[.)]|[*+-])\s) # between 0 and 3 spaces, followed by either: at least one integer and a full stop or a parenthesis, or (a star, plus or dash), followed by whitespace + list_item: (?:[ ]{,3}(?:\d{1,9}[.)]|[*+-])\s) # between 0 and 3 spaces, followed by either: at least one integer and a full stop or a parenthesis, or (a star, plus or dash), followed by whitespace + + thematic_break: |- + (?x: + [ ]{,3} # between 0 to 3 spaces + (?: # followed by one of the following: + [-](?:[ \t]*[-]){2,} # - a dash, followed by the following at least twice: any number of spaces or tabs followed by a dash + | [*](?:[ \t]*[*]){2,} # - a star, followed by the following at least twice: any number of spaces or tabs followed by a star + | [_](?:[ \t]*[_]){2,} # - an underscore, followed by the following at least twice: any number of spaces or tabs followed by an underscore + ) + [ \t]*$ # followed by any number of tabs or spaces, followed by the end of the line + ) + + backticks: |- + (?x: + (`{4})(?![\s`])(?:[^`]+(?=`)|(?!`{4})`+(?!`))+(`{4})(?!`) # 4 backticks, followed by at least one non whitespace, non backtick character, followed by (less than 4 backticks, or at least one non backtick character) at least once, followed by exactly 4 backticks + | (`{3})(?![\s`])(?:[^`]+(?=`)|(?!`{3})`+(?!`))+(`{3})(?!`) # 3 backticks, followed by at least one non whitespace, non backtick character, followed by (less than 3 backticks, or at least one non backtick character) at least once, followed by exactly 3 backticks + | (`{2})(?![\s`])(?:[^`]+(?=`)|(?!`{2})`+(?!`))+(`{2})(?!`) # 2 backticks, followed by at least one non whitespace, non backtick character, followed by (less than 2 backticks, or at least one non backtick character) at least once, followed by exactly 2 backticks + | (`{1})(?![\s`])(?:[^`]+(?=`)|(?!`{1})`+(?!`))+(`{1})(?!`) # 1 backtick, followed by at least one non whitespace, non backtick character, followed by ( at least one non backtick character) at least once, followed by exactly 1 backtick + ) + escapes: \\[-+*/!"#$%&'(),.:;<=>?@\[\\\]^_`{|}~] + + balance_square_brackets: |- + (?x: + (?: + (?:{{escapes}})+ # escape characters + | [^\[\]`\\]+(?=[\[\]`\\]|$) # anything that isn't a square bracket or a backtick or the start of an escape character + | {{backticks}} # inline code + | \[(?: # nested square brackets (one level deep) + [^\[\]`]+(?=[\[\]`]) # anything that isn't a square bracket or a backtick + {{backticks}}? # balanced backticks + )*\] # closing square bracket + )+ + ) + balance_square_brackets_and_emphasis: |- + (?x: + (?: + (?:{{escapes}})+ # escape characters + | [^\[\]`\\_*]+(?=[\[\]`\\_*]|$) # anything that isn't a square bracket, a backtick, the start of an escape character, or an emphasis character + | {{backticks}} # inline code + | \[(?: # nested square brackets (one level deep) + [^\[\]`]+(?=[\[\]`]) # anything that isn't a square bracket or a backtick + {{backticks}}? # balanced backticks + )*\] # closing square bracket + )+ # at least one character + ) + balance_square_brackets_pipes_and_emphasis: |- + (?x: + (?: + (?:{{escapes}})+ # escape characters + | [^\[\]`\\_*|]+(?=[\[\]`\\_*|]|$) # anything that isn't a square bracket, a backtick, the start of an escape character, or an emphasis character + | {{backticks}} # inline code + | \[(?: # nested square brackets (one level deep) + [^\[\]`]+(?=[\[\]`]) # anything that isn't a square bracket or a backtick + {{backticks}}? # balanced backticks + )*\] # closing square bracket + )+ # at least one character + ) + balanced_emphasis: |- + (?x: + \* (?!\*){{balance_square_brackets_and_emphasis}}+\* (?!\*) + | \*\* {{balance_square_brackets_and_emphasis}}+\*\* + | _ (?!_) {{balance_square_brackets_and_emphasis}}+_ (?!_) + | __ {{balance_square_brackets_and_emphasis}}+__ + ) + + table_cell: |- + (?x: + # Pipes inside other inline spans (such as emphasis, code, etc.) will not break a cell, + # emphasis in table cells can't span multiple lines + (?: + {{balance_square_brackets_pipes_and_emphasis}} + | {{balanced_emphasis}} + )+ # at least one character + ) + table_first_row: |- + (?x: + # at least 2 non-escaped pipe chars on the line + (?:{{table_cell}}?\|){2} + + # something other than whitespace followed by a pipe char or hyphen, + # followed by something other than whitespace and the end of the line + | (?! \s*\-\s+ | \s+\|){{table_cell}}\|(?!\s+$) + ) + + fenced_code_block_start: |- + (?x: + ([ \t]*) + ( + (`){3,} # 3 or more backticks + (?![^`]*`) # not followed by any more backticks on the same line + | # or + (~){3,} # 3 or more tildas + ) + \s* # allow for whitespace between code block start and info string + ) + fenced_code_block_language: |- + (?x: # first word of an infostring is used as language specifier + ( + [[:alpha:]] # starts with a letter to make sure not to hit any attribute annotation + [^`\s]* # optionally followed by any nonwhitespace character (except backticks) + ) + ) + fenced_code_block_trailing_infostring_characters: |- + (?x: + ( + \s* # any whitespace, or .. + | + \s[^`]* # any characters (except backticks), separated by whitespace ... + ) + $\n? # ... until EOL + ) + fenced_code_block_end: |- + (?x: + [ \t]* + ( + \2 # the backtick/tilde combination that opened the code fence + (?:\3|\4)* # plus optional additional closing characters + ) + \s*$ # any amount of whitespace until EOL + ) + fenced_code_block_escape: ^{{fenced_code_block_end}} + + # https://spec.commonmark.org/0.30/#email-autolink + email_domain_commonmark: '[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?' + email_user_commonmark: '[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+' + + # https://spec.commonmark.org/0.30/#html-blocks + html_block: |- + (?x: + [ ]{,3} + (?: + {{html_tag_block_end_at_close_tag}} # html block type 1 + | {{html_tag_block_end_at_blank_line}} # html block type 6 + | {{html_block_open_tag}} # html block type 7 + | {{html_block_close_tag}} # html block type 7 + | {{html_block_comment}} # html block type 2 + | {{html_block_decl}} # html block type 4 + | {{html_block_cdata}} # html block type 5 + | {{html_block_preprocessor}} # html block type 3 + ) + ) + html_block_comment: + +import Title from '../components/Title.astro' +| <- meta.import.js keyword.control.import-export.js +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.js + +export const authors = [ + { name: 'Jane', email: 'hi@jane.com' }, + { name: 'John', twitter: '@john2002' }, +] +| <- meta.export.js meta.sequence.js punctuation.section + +export const published = new Date('2022-02-01') +| <- meta.export.js keyword.control.import-export.js +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export.js + +export default ({children}) => ( +| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ source.jsx.embedded.markdown meta.export.js +| ^^^^^^^^^^ meta.function.parameters.js meta.binding.destructuring.mapping.js + +| ^ meta.tag punctuation.definition.tag.begin +| ^^^ meta.tag entity.name.tag +| ^ meta.tag punctuation.definition.tag.end + {children} +| ^^^^^^^^^^ meta.export.js meta.function.js meta.block.js meta.group.js meta.jsx.js meta.interpolation.js + +| ^^ meta.tag punctuation.definition.tag.begin +| ^^^ meta.tag entity.name.tag +| ^ meta.tag punctuation.definition.tag.end +); + +JavaScript statements don't interrupt paragraphs, +export or import are normal words. +| <- meta.paragraph.markdown - keyword +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown - keyword + +Javascript statements must be separated by an empty line. + +export const me = null +| <- source.jsx.embedded.markdown meta.export.js keyword.control.import-export.js +|^^^^^^^^^^^^^^^^^^^^^^ source.jsx.embedded.markdown meta.export.js +|^^^^^ keyword.control + + + + +# A subheading with and {name.toString()} +| <- markup.heading.1.markdown punctuation.definition.heading.begin.markdown +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.heading.1.markdown - meta.interpolation +| ^ meta.tag - meta.tag.name +| ^^^^^^^^^^ meta.tag.name +| ^^ meta.tag - meta.tag.name - meta.tag.attributes +| ^^^^^^^^^^^^^^^^^ markup.heading.1.markdown meta.interpolation.markdown +| ^ markup.heading.1.markdown meta.whitespace.newline.markdown + + # Also A {Title} # +| <- markup.heading.1.markdown +|^^^^^^^^^^^^^^^^^^^^^^^^ markup.heading.1.markdown + +The {frontmatter.title} +| <- markup.heading.1.markdown entity.name.section.markdown +|^^^ markup.heading.1.markdown - meta.interpolation +| ^^^^^^^^^^^^^^^^^^^ markup.heading.1.markdown meta.interpolation.markdown +| ^ markup.heading.1.markdown - meta.interpolation +=== + + A subheading with and {name.toString()} + |<- markup.heading.2.markdown entity.name.section.markdown + |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ markup.heading.2.markdown - meta.interpolation + | ^ meta.tag - meta.tag.name + | ^^^^^^^^^^ meta.tag.name + | ^^ meta.tag - meta.tag.name - meta.tag.attributes + | ^^^^^^^^^^^^^^^^^ markup.heading.2.markdown meta.interpolation.markdown + | ^ markup.heading.2.markdown - meta.interpolation + --- + + + + +1. list {item} +| <- markup.list.numbered.bullet.markdown +|^ markup.list.numbered.bullet.markdown punctuation.definition.list_item.markdown +| ^^^^^^^^^^^^^^^^^^^^ markup.list.numbered.markdown +| ^^^ meta.tag +| ^^^^^^ meta.interpolation.markdown +| ^^^^ meta.tag + + + + +Foo | Bar +--- | --- +| <- meta.table.header-separator.markdown-gfm punctuation.section.table-header.markdown +|^^^^^^^^^^ meta.table.header-separator.markdown-gfm + +Foo | Bar +--- | --- +baz | zoo +| <- meta.table.markdown-gfm +|^^^^^^^^^^ meta.table.markdown-gfm + + + + +This is a single +paragraph +| <- meta.paragraph.markdown meta.tag punctuation.definition.tag.begin +|^^^^^^^^^^^^^^^^ meta.paragraph.markdown + +

paragraph

+| <- meta.paragraph.markdown meta.tag punctuation.definition.tag.begin +|^^^^^^^^^^^^^^^^ meta.paragraph.markdown + + + + +

**plain** {variable}

+| <- meta.paragraph.markdown meta.tag punctuation.definition.tag.begin.html +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown +|^^^ meta.tag +| ^^^^^^^^^ markup.bold.markdown +| ^^^^^^^^^^ meta.interpolation.markdown +| ^^^^^ meta.tag + +

+ Try and change the background _color_ to `tomato`. +| ^^^^^^^ markup.italic.markdown +| ^^^^^^^^ markup.raw.inline.markdown +

+| <- meta.tag +|^^^ meta.tag + + +| <- meta.paragraph.markdown meta.tag.sgml.cdata.html punctuation.definition.tag.begin.html +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown meta.tag.sgml.cdata.html +| ^^^^^^^^^ meta.string.html string.unquoted.cdata.html +| ^^^^^^^^^^^^^^ meta.string.html meta.interpolation.markdown +| ^^^^^^^^ meta.string.html string.unquoted.cdata.html + + + + + + + + +
+| <- meta.paragraph.markdown meta.tag.html punctuation.definition.tag.begin.html +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown meta.tag.html +|^^ entity.name.tag.native.html +| ^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.style.html +| ^^^^^ entity.other.attribute-name.style.html +| ^ punctuation.separator.key-value.html +| ^ meta.string.html string.quoted.double.html punctuation.definition.string.begin.html +| ^^^^^^^^^^ meta.string.html meta.interpolation.html source.css.embedded.html +| ^ meta.string.html string.quoted.double.html punctuation.definition.string.end.html +| ^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.event.html +| ^^^^^^^ entity.other.attribute-name.event.html +| ^ punctuation.separator.key-value.html +| ^ meta.string.html string.quoted.double.html punctuation.definition.string.begin.html +| ^^^^^^^^^^ meta.string.html meta.interpolation.html source.js.embedded.html meta.function-call.js +| ^ meta.string.html string.quoted.double.html punctuation.definition.string.end.html +| ^ punctuation.definition.tag.end.html + + + + + +| <- meta.tag punctuation.definition.tag.begin +|^^^^^^^ meta.tag.name +| ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown meta.tag.attributes +| ^^ meta.paragraph.markdown meta.tag - meta.tag.attributes +|^^^^^^ entity.name.tag.component +| ^^^^^ meta.attribute-with-value.html - meta.string - meta.interpolation +| ^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.html meta.string.html meta.interpolation.markdown +| ^^^^ entity.other.attribute-name.html +| ^ punctuation.separator.key-value.html +| ^ punctuation.section.interpolation.begin +| ^^^^^^^^^^^^^^^^^^ source.jsx.embedded.markdown +| ^ punctuation.section.interpolation.end.markdown +| ^^ punctuation.definition.tag.end + + +| <- meta.paragraph.markdown meta.tag punctuation.definition.tag.begin +|^^^^^^^^^^^^ meta.paragraph.markdown meta.tag.name +| ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.paragraph.markdown meta.tag.attributes meta.attribute-with-value.html +| ^^ meta.paragraph.markdown meta.tag punctuation.definition.tag.end +|^^^ entity.name.tag.component +| ^ punctuation.accessor +| ^^^ entity.name.tag.component +| ^ punctuation.accessor +| ^^^ entity.name.tag.component +| ^^^^ entity.other.attribute-name +| ^ punctuation.separator.key-value +| ^^^^^^^^^^^^^^^^^^^^ meta.string.html meta.interpolation.markdown + + + +{ } +| <- meta.interpolation.markdown punctuation.section.interpolation.begin.markdown +|^^^^^^^^^^^^^^^ meta.interpolation.markdown source.jsx.embedded.markdown +| ^ meta.interpolation.markdown punctuation.section.interpolation.end.markdown +| ^ meta.tag punctuation.definition.tag.begin +| ^^^^^^^^^^ meta.tag.name +| ^^ meta.tag punctuation.definition.tag.end + +{

**plain** {variable}

} +| <- meta.interpolation.markdown punctuation.section.interpolation.begin.markdown +|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.markdown source.jsx.embedded.markdown +| ^ meta.interpolation.markdown punctuation.section.interpolation.end.markdown +| ^^^^ meta.tag +| ^ punctuation.definition.tag.begin +| ^^ entity.name.tag.native +| ^ punctuation.definition.tag.end +| ^^^^^^^^^ - markup +| ^^^^^^^^^^ meta.interpolation +| ^^^^^ meta.tag +| ^^ punctuation.definition.tag.begin +| ^^ entity.name.tag.native +| ^ punctuation.definition.tag.end + +

+| <- meta.paragraph.markdown meta.tag punctuation.definition.tag.begin.html +|^^ meta.paragraph.markdown meta.tag - meta.attribute-with-value +| ^^^^^^ meta.paragraph.markdown meta.tag meta.attribute-with-value.style.html - meta.interpolation +| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute-with-value.style.html meta.interpolation.markdown +| ^ meta.paragraph.markdown meta.tag - meta.attribute-with-value - meta.interpolation