From efc02ff21e93ceda1a090ef8c9f4d237713b07d7 Mon Sep 17 00:00:00 2001 From: deathaxe Date: Fri, 29 Mar 2024 21:38:22 +0100 Subject: [PATCH] [LaTeX] Rewrite BibTex This commit... 1. rewrites BibTeX using named contexts only. 2. adjusts symbol lists A major intent is to provide stacked meta scopes for a) #3952 and b) enable syntax based folding. Note: It appears #3952 is not related with how meta and punctuation scopes are organized. Changed syntax can't fix it. --- LaTeX/Bibtex.sublime-syntax | 390 +++++++++++++------- LaTeX/Symbol List - Commands.tmPreferences | 11 +- LaTeX/Symbol List - Constants.tmPreferences | 17 + LaTeX/Symbol List - Labels.tmPreferences | 2 - LaTeX/Symbol List - Sections.tmPreferences | 2 - LaTeX/tests/syntax_test_bibtex.bib | 91 ++++- 6 files changed, 372 insertions(+), 141 deletions(-) create mode 100644 LaTeX/Symbol List - Constants.tmPreferences diff --git a/LaTeX/Bibtex.sublime-syntax b/LaTeX/Bibtex.sublime-syntax index 6cfac69a2f..1750f1c1d3 100644 --- a/LaTeX/Bibtex.sublime-syntax +++ b/LaTeX/Bibtex.sublime-syntax @@ -2,8 +2,6 @@ --- # Grammar based on description from # http://artis.imag.fr/~Xavier.Decoret/resources/xdkbibtex/bibtex_summary.html#comment -# -# TODO: Does not support @preamble name: BibTeX scope: text.bibtex version: 2 @@ -17,138 +15,280 @@ first_line_match: |- ) variables: - var: '\b[a-zA-Z]\w*' + ident: '[[:alpha:]][[:alnum:]]*\b' + var: '[[:alpha:]]\w*\b' contexts: main: - - match: "@Comment" - scope: punctuation.definition.comment.bibtex - push: - - meta_scope: comment.line.at-sign.bibtex - - match: $\n? - pop: 1 - - match: '((@)[Ss]tring)\s*(\{)\s*({{var}})' + - include: bibtex + + bibtex: + - include: line-comments + - include: comments + - include: declarations + - include: preambles + - include: entries + +###[ COMMENTS ]################################################################# + + line-comments: + - match: \% + scope: punctuation.definition.comment.tex + push: line-comment-body + + line-comment-body: + - meta_scope: comment.line.percentage.tex + - match: $\n? + pop: 1 + + comments: + - match: (@)Comment\b + scope: keyword.declaration.comment.bibtex captures: - 1: keyword.other.string-constant.bibtex - 2: punctuation.definition.keyword.bibtex - 3: punctuation.section.string-constant.begin.bibtex - 4: entity.name.constant.bibtex - push: - - meta_scope: meta.string-constant.braces.bibtex - - match: '\}' - scope: punctuation.section.string-constant.end.bibtex - pop: 1 - - include: string_content - - include: variables - - include: operators - - match: '((@)[Ss]tring)\s*(\()\s*({{var}})' + 1: punctuation.definition.keyword.bibtex + push: comment-args + + comment-args: + - meta_scope: comment.line.at-sign.bibtex + - match: $\n? + pop: 1 + +###[ DECLARATIONS ]############################################################# + + declarations: + - match: (@)(?i:string)\b + scope: meta.declaration.bibtex keyword.declaration.constant.bibtex captures: - 1: keyword.other.string-constant.bibtex - 2: punctuation.definition.keyword.bibtex - 3: punctuation.section.string-constant.begin.bibtex - 4: entity.name.constant.bibtex - push: - - meta_scope: meta.string-constant.parenthesis.bibtex - - match: \) - scope: punctuation.section.string-constant.end.bibtex - pop: 1 - - include: string_content - - include: variables - - include: operators - - match: '((@)[a-zA-Z]+)\s*(\{)\s*([^\s,]*)' + 1: punctuation.definition.keyword.bibtex + push: declaration-args + + declaration-args: + - meta_content_scope: meta.declaration.bibtex + - match: \{ + scope: punctuation.section.braces.begin.bibtex + set: + - declaration-brace-body + - declaration-assignment + - declaration-name + - match: \( + scope: punctuation.section.parens.begin.bibtex + set: + - declaration-paren-body + - declaration-assignment + - declaration-name + - include: else-pop + + declaration-name: + - match: '{{var}}' + scope: entity.name.constant.bibtex + pop: 1 + - include: else-pop + + declaration-assignment: + - match: = + scope: keyword.operator.assignment.bibtex + pop: 1 + - include: else-pop + + declaration-brace-body: + - meta_scope: meta.declaration.arguments.bibtex meta.braces.bibtex + - match: \} + scope: punctuation.section.braces.end.bibtex + pop: 1 + - include: operators + - include: strings + - include: variables + + declaration-paren-body: + - meta_scope: meta.declaration.arguments.bibtex meta.parens.bibtex + - match: \) + scope: punctuation.section.parens.end.bibtex + pop: 1 + - include: operators + - include: strings + - include: variables + +###[ ENTRIES ]################################################################## + + entries: + - match: (@){{ident}} + scope: meta.entry.bibtex keyword.declaration.entry.bibtex captures: - 1: keyword.other.entry-type.bibtex - 2: punctuation.definition.keyword.bibtex - 3: punctuation.section.entry.begin.bibtex - 4: entity.name.type.entry-key.bibtex - push: - - meta_scope: meta.entry.braces.bibtex - - meta_content_scope: meta.mapping.bibtex - - match: '\}' - scope: punctuation.section.entry.end.bibtex - pop: 1 - - match: '([a-zA-Z]+)(\s*(=)\s*)' - captures: - 1: meta.mapping.key.bibtex string.unquoted.key.bibtex - 2: meta.mapping.bibtex - 3: punctuation.separator.key-value.bibtex - push: - - clear_scopes: 1 - - meta_content_scope: meta.mapping.value.bibtex - - match: (?=[,}]) - pop: 1 - - include: string_content - - include: integer - - include: variables - - include: operators - - match: \, - scope: punctuation.separator.sequence.bibtex - - match: '((@)[a-zA-Z]+)\s*(\()\s*([^\s,]*)' + 1: punctuation.definition.keyword.bibtex + push: entry-args + + entry-args: + - meta_content_scope: meta.entry.bibtex + - match: \{ + scope: punctuation.section.braces.begin.bibtex + set: brace-entry-name + - match: \( + scope: punctuation.section.parens.begin.bibtex + set: paren-entry-name + - include: else-pop + + brace-entry-name: + - meta_scope: meta.entry.arguments.bibtex meta.braces.bibtex + - match: '[^\s,}]+' + scope: entity.name.type.entry-key.bibtex + push: brace-mapping-body + - match: (?=\S) + push: brace-mapping-body + + brace-mapping-body: + - meta_content_scope: meta.mapping.bibtex + - match: \} + scope: punctuation.section.braces.end.bibtex + pop: 2 + - match: ({{ident}})(\s*(=)\s*) + captures: + 1: meta.mapping.key.bibtex string.unquoted.key.bibtex + 2: meta.mapping.bibtex + 3: punctuation.separator.key-value.bibtex + push: brace-mapping-value + - include: line-comments + - include: separators + + brace-mapping-value: + - clear_scopes: 1 + - meta_content_scope: meta.mapping.value.bibtex + - match: (?=[,}]) + pop: 1 + - include: numbers + - include: operators + - include: strings + - include: variables + + paren-entry-name: + - meta_scope: meta.entry.arguments.bibtex meta.parens.bibtex + - match: '[^\s,)]+' + scope: entity.name.type.entry-key.bibtex + push: paren-mapping-body + - match: (?=\S) + push: paren-mapping-body + + paren-mapping-body: + - meta_content_scope: meta.mapping.bibtex + - match: \) + scope: punctuation.section.parens.end.bibtex + pop: 2 + - match: ({{ident}})(\s*(=)\s*) + captures: + 1: meta.mapping.key.bibtex string.unquoted.key.bibtex + 2: meta.mapping.bibtex + 3: punctuation.separator.key-value.bibtex + push: paren-mapping-value + - include: line-comments + - include: separators + + paren-mapping-value: + - clear_scopes: 1 + - meta_content_scope: meta.mapping.value.bibtex + - match: (?=[,)]) + pop: 1 + - include: numbers + - include: operators + - include: strings + - include: variables + +###[ PREAMBLES ]################################################################ + + preambles: + - match: (@)(?i:preamble)\b + scope: meta.preamble.bibtex keyword.declaration.preamble.bibtex captures: - 1: keyword.other.entry-type.bibtex - 2: punctuation.definition.keyword.bibtex - 3: punctuation.section.entry.begin.bibtex - 4: entity.name.type.entry-key.bibtex - push: - - meta_scope: meta.entry.parenthesis.bibtex - - meta_content_scope: meta.mapping.bibtex - - match: \) - scope: punctuation.section.entry.end.bibtex - pop: 1 - - match: '([a-zA-Z]+)(\s*(=)\s*)' - captures: - 1: meta.mapping.key.bibtex string.unquoted.key.bibtex - 2: meta.mapping.bibtex - 3: punctuation.separator.key-value.bibtex - push: - - clear_scopes: 1 - - meta_content_scope: meta.mapping.value.bibtex - - match: (?=[,)]) - pop: 1 - - include: string_content - - include: integer - - include: variables - - include: operators - - match: \, - scope: punctuation.separator.sequence.bibtex - - match: '[^@\n]' - push: - - meta_scope: comment.block.bibtex - - match: (?=@) - pop: 1 - integer: + 1: punctuation.definition.keyword.bibtex + push: preamble-args + + preamble-args: + - meta_content_scope: meta.preamble.bibtex + - match: \{ + scope: punctuation.section.braces.begin.bibtex + set: preable-brace-body + - match: \( + scope: punctuation.section.parens.begin.bibtex + set: preable-paren-body + - include: else-pop + + preable-brace-body: + - meta_scope: meta.preamble.arguments.bibtex meta.braces.bibtex + - match: \} + scope: punctuation.section.braces.end.bibtex + pop: 1 + - include: operators + - include: strings + - include: variables + + preable-paren-body: + - meta_scope: meta.preamble.arguments.bibtex meta.parens.bibtex + - match: \) + scope: punctuation.section.parens.end.bibtex + pop: 1 + - include: operators + - include: strings + - include: variables + +###[ LITERALS ]################################################################# + + numbers: - match: \d+ scope: meta.number.integer.decimal.bibtex constant.numeric.value.bibtex - variables: - - match: '{{var}}' - scope: variable.other.constant.bibtex + + strings: + - match: \{ + scope: punctuation.definition.string.begin.bibtex + push: brace-quoted-string-body + - match: \" + scope: punctuation.definition.string.begin.bibtex + push: double-quoted-string-body + + brace-quoted-string-body: + - meta_include_prototype: false + - meta_scope: meta.string.bibtex string.quoted.other.bibtex + - match: \} + scope: punctuation.definition.string.end.bibtex + pop: 1 + - match: \@ + scope: invalid.illegal.at-sign.bibtex + - include: nested-braces + + double-quoted-string-body: + - meta_include_prototype: false + - meta_scope: meta.string.bibtex string.quoted.double.bibtex + - match: \" + scope: punctuation.definition.string.end.bibtex + pop: 1 + - match: \\['"] + scope: constant.character.escape.bibtex + - include: nested-braces + + nested-braces: + - match: \{ + push: nested-brace-body + + nested-brace-body: + - match: \} + pop: 1 + - include: nested-braces + +###[ OPERATORS ]################################################################ + operators: - match: \# scope: keyword.operator.concatenation.bibtex - nested_braces: - - match: '\{' - scope: punctuation.definition.group.begin.bibtex - push: - - match: '\}' - scope: punctuation.definition.group.end.bibtex - pop: 1 - - include: nested_braces - string_content: - - match: '"' - scope: punctuation.definition.string.begin.bibtex - push: - - meta_scope: string.quoted.double.bibtex - - match: '"' - scope: punctuation.definition.string.end.bibtex - pop: 1 - - include: nested_braces - - match: '\{' - scope: punctuation.definition.string.begin.bibtex - push: - - meta_scope: string.quoted.other.braces.bibtex - - match: '\}' - scope: punctuation.definition.string.end.bibtex - pop: 1 - - match: "@" - scope: invalid.illegal.at-sign.bibtex - - include: nested_braces + + separators: + - match: ',' + scope: punctuation.separator.sequence.bibtex + +###[ VARIABLES ]################################################################ + + variables: + - match: '{{var}}' + scope: variable.other.constant.bibtex + +###[ PROTOTYPES ]############################################################### + + else-pop: + - match: (?=\S) + pop: 1 diff --git a/LaTeX/Symbol List - Commands.tmPreferences b/LaTeX/Symbol List - Commands.tmPreferences index 8fbfed1fcb..0bc4a0c242 100644 --- a/LaTeX/Symbol List - Commands.tmPreferences +++ b/LaTeX/Symbol List - Commands.tmPreferences @@ -1,16 +1,17 @@ - name - Symbol List scope - entity.name.newcommand.latex, entity.name.definition.tex, entity.name.constant.tex + + entity.name.definition.tex, + entity.name.newcommand.latex + settings showInSymbolList 1 - showInIndexedSymbolList - 1 + showInIndexedSymbolList + 1 diff --git a/LaTeX/Symbol List - Constants.tmPreferences b/LaTeX/Symbol List - Constants.tmPreferences new file mode 100644 index 0000000000..947a36c8c4 --- /dev/null +++ b/LaTeX/Symbol List - Constants.tmPreferences @@ -0,0 +1,17 @@ + + + + scope + + entity.name.constant.bibtex, + entity.name.constant.tex + + settings + + showInSymbolList + 1 + showInIndexedSymbolList + 1 + + + diff --git a/LaTeX/Symbol List - Labels.tmPreferences b/LaTeX/Symbol List - Labels.tmPreferences index 6f435bf2eb..0960f33d31 100644 --- a/LaTeX/Symbol List - Labels.tmPreferences +++ b/LaTeX/Symbol List - Labels.tmPreferences @@ -1,8 +1,6 @@ - name - Symbol List scope entity.name.label.latex settings diff --git a/LaTeX/Symbol List - Sections.tmPreferences b/LaTeX/Symbol List - Sections.tmPreferences index dcb4512121..e64e526b53 100644 --- a/LaTeX/Symbol List - Sections.tmPreferences +++ b/LaTeX/Symbol List - Sections.tmPreferences @@ -1,8 +1,6 @@ - name - Symbol List scope meta.section.latex settings diff --git a/LaTeX/tests/syntax_test_bibtex.bib b/LaTeX/tests/syntax_test_bibtex.bib index 9a766d5815..5b075ee9d5 100644 --- a/LaTeX/tests/syntax_test_bibtex.bib +++ b/LaTeX/tests/syntax_test_bibtex.bib @@ -1,30 +1,107 @@ % SYNTAX TEST "Packages/LaTeX/Bibtex.sublime-syntax" -@string(mar = "march") -@string(aw = "Addison-Wesley") -%<- keyword.other.string-constant.bibtex punctuation.definition.keyword.bibtex -%^^^^^^ keyword.other.string-constant.bibtex +@string{mar = "march"} +% <- meta.declaration.bibtex keyword.declaration.constant.bibtex punctuation.definition.keyword.bibtex +%^^^^^^ meta.declaration.bibtex keyword.declaration.constant.bibtex +% ^^^^^^^^^^^^^^^ meta.declaration.arguments.bibtex meta.braces.bibtex +% ^ punctuation.section.braces.begin.bibtex +% ^^^ entity.name.constant.bibtex +% ^ keyword.operator.assignment.bibtex +% ^^^^^^^ meta.string.bibtex string.quoted.double.bibtex +% ^ punctuation.section.braces.end.bibtex + +@string(aw = {Addison-{Wesley}}) +% <- meta.declaration.bibtex keyword.declaration.constant.bibtex punctuation.definition.keyword.bibtex +%^^^^^^ meta.declaration.bibtex keyword.declaration.constant.bibtex +% ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.arguments.bibtex meta.parens.bibtex +% ^ punctuation.section.parens.begin.bibtex % ^^ entity.name.constant.bibtex +% ^ keyword.operator.assignment.bibtex +% ^ punctuation.definition.string.begin.bibtex +% ^^^^^^^^^^^^^^^^^^ meta.string.bibtex string.quoted.other.bibtex +% ^ punctuation.definition.string.end.bibtex +% ^ punctuation.section.parens.end.bibtex + +@PREAMBLE{" +% <- meta.preamble.bibtex keyword.declaration.preamble.bibtex punctuation.definition.keyword.bibtex +%^^^^^^^^ meta.preamble.bibtex keyword.declaration.preamble.bibtex +% ^ meta.preamble.arguments.bibtex meta.braces.bibtex punctuation.section.braces.begin.bibtex +% ^ meta.preamble.arguments.bibtex meta.braces.bibtex meta.string.bibtex string.quoted.double.bibtex punctuation.definition.string.begin.bibtex +% ^ meta.preamble.arguments.bibtex meta.braces.bibtex meta.string.bibtex string.quoted.double.bibtex - punctuation +\makeatletter +\providecommand\dosomething[0]{} +\makeatother +% <- meta.preamble.arguments.bibtex meta.braces.bibtex meta.string.bibtex string.quoted.double.bibtex +%^^^^^^^^^^^^ meta.preamble.arguments.bibtex meta.braces.bibtex meta.string.bibtex string.quoted.double.bibtex +"} +% <- meta.preamble.arguments.bibtex meta.braces.bibtex meta.string.bibtex string.quoted.double.bibtex punctuation.definition.string.end.bibtex +%^ meta.preamble.arguments.bibtex meta.braces.bibtex punctuation.section.braces.end.bibtex +% ^ - meta.preamble + +@book +% <- meta.entry.bibtex keyword.declaration.entry.bibtex punctuation.definition.keyword.bibtex +%^^^^ meta.entry.bibtex keyword.declaration.entry.bibtex +% ^ meta.entry.bibtex - keyword + +@book(paren) +% <- meta.entry.bibtex keyword.declaration.entry.bibtex punctuation.definition.keyword.bibtex +%^^^^ meta.entry.bibtex keyword.declaration.entry.bibtex +% ^^^^^^^ meta.entry.arguments.bibtex meta.parens.bibtex +% ^ punctuation.section.parens.begin.bibtex +% ^^^^^ entity.name.type.entry-key.bibtex +% ^ punctuation.section.parens.end.bibtex +% ^ - meta.entry + +@book(paren, author="Nobody") +% <- meta.entry.bibtex keyword.declaration.entry.bibtex punctuation.definition.keyword.bibtex +%^^^^ meta.entry.bibtex keyword.declaration.entry.bibtex +% ^^^^^^ meta.entry.arguments.bibtex meta.parens.bibtex - meta.mapping +% ^^^^^^^^^^^^^^^^^ meta.entry.arguments.bibtex meta.parens.bibtex meta.mapping - meta.mapping meta.mapping +% ^^^^^^ meta.mapping.key.bibtex string.unquoted.key.bibtex +% ^ meta.mapping.bibtex punctuation.separator.key-value.bibtex +% ^^^^^^^^ meta.mapping.value.bibtex meta.string.bibtex string.quoted.double.bibtex +% ^ meta.entry.arguments.bibtex meta.parens.bibtex punctuation.section.parens.end.bibtex - meta.mapping + +@book{knuth97} +% <- meta.entry.bibtex keyword.declaration.entry.bibtex punctuation.definition.keyword.bibtex +%^^^^ meta.entry.bibtex keyword.declaration.entry.bibtex +% ^^^^^^^^^ meta.entry.arguments.bibtex +% ^ punctuation.section.braces.begin.bibtex +% ^^^^^^^ entity.name.type.entry-key.bibtex +% ^ punctuation.section.braces.end.bibtex +% ^ - meta.entry @book{knuth97, -%<- keyword.other.entry-type.bibtex punctuation.definition.keyword.bibtex -%^^^^ keyword.other.entry-type.bibtex +% <- meta.entry.bibtex keyword.declaration.entry.bibtex punctuation.definition.keyword.bibtex +%^^^^ meta.entry.bibtex - meta.mapping +% ^^^^^^^^ meta.entry.arguments.bibtex meta.braces.bibtex - meta.mapping +% ^^ meta.entry.arguments.bibtex meta.braces.bibtex meta.mapping.bibtex +%^^^^ keyword.declaration.entry.bibtex +% ^ punctuation.section.braces.begin.bibtex % ^^^^^^^ entity.name.type.entry-key.bibtex +% ^ punctuation.separator.sequence.bibtex author = {Donald E. Knuth}, +% ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.entry.arguments.bibtex meta.braces.bibtex - meta.mapping meta.mapping % ^^^^^^ meta.mapping.key.bibtex string.unquoted.key.bibtex % ^^^^^^ meta.mapping.bibtex % ^ punctuation.separator.key-value.bibtex -% ^^^^^^^^^^^^^^^^^ meta.mapping.value.bibtex string.quoted.other.braces.bibtex +% ^^^^^^^^^^^^^^^^^ meta.mapping.value.bibtex meta.string.bibtex string.quoted.other.bibtex % ^ punctuation.definition.string.begin.bibtex % ^ punctuation.definition.string.end.bibtex % ^ punctuation.separator.sequence.bibtex title = {The Art of Computer Programming, Vol. 1: Fundamental Algorithms}, +% ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.bibtex string.quoted.other.bibtex edition = {3}, +% ^^^ meta.string.bibtex string.quoted.other.bibtex publisher = aw, % ^^ variable.other.constant.bibtex date = 1997, % ^^^^ meta.number.integer.decimal.bibtex constant.numeric.value.bibtex month = "1~" # mar, +% ^^^^^^^^^^ meta.mapping.value.bibtex % ^ keyword.operator.concatenation.bibtex +% ^^^ variable.other.constant.bibtex +% ^ punctuation.separator.sequence.bibtex isbn = {978-0-201-89683-1} } +% <- meta.entry.arguments.bibtex punctuation.section.braces.end.bibtex \ No newline at end of file