diff --git a/src/languages/abc.js b/src/languages/abc.js index 324acf5..ad5646a 100644 --- a/src/languages/abc.js +++ b/src/languages/abc.js @@ -5,85 +5,220 @@ Website: https://abcnotation.com Category: common */ + export default function(hljs) { - const accidentalDirectivePrefix = `(?<=%%(propagate|writeout)-accidentals.*)`; - const fontDirectivePrefix = `(?<=%%(title|subtitle|composer|parts|tempo|gchord|annotation|info|text|vocal|words|set)font.*)`; - const textDirectivePrefix = `(?<=%%(text|center)\\s)`; + const untilCommentOrEndOfLine = /(?=[%\n])/ + + const inlineHeader = { + scope: "inline-header", + begin: /\[[MLQPRIV]:/, + end: /]/, + contains: [ + { + scope: "header-content", + match: /[^\]]*/, + endsWithParent: true + } + ] + } + + const note = { + scope: "note", + match: /[_^]?[_^=]?[A-Ga-gZz][,']*\d*\/*\d*-?/ + } + + const barLine = { + scope: "bar", + match: /(\|\]|\|\||\[\||\|:|:\||::|\|)\d*([,\-]\d)*/, + } + + const tuple = { + scope: "tuple", + match: /\([2-9](:[1-9])?(:[1-9])?/ + } + + const graceNotes = { + scope: "grace", + begin: /\{/, end: /\}/, + contains: [ + { + scope: "note", + match: /[_^]?[_^=]?[A-Ga-gZz][,']*\d*\/*\d*-?/ + }, + ], + } + + const chord = { + scope: "chord", // That is: [Ace] + begin: /\[/, end: /\]\d*\/*\d*/, + contains: [ + { + scope: "note", + match: /[_^]?[_^=]?[A-Ga-gZz][,']*\d*-?/ + }, + ], + } + + const chordSymbol = { + scope: "chord-symbol", // That is: "Am" + begin: '"', end: '"' + } + + const decoration = { + scope: "decoration", + begin: "!", end: "!" + } + const decorationShortcut = { + scope: "decoration", + match: /[\.\~HLMOPSTuv]/ + } + const overlay = { + scope: "overlay", + match: /&/ + } + + const comment = hljs.COMMENT("%", "$") + + const space = { + scope: "space", + match: / / + } + const error = { + scope: "error", + match: /./ + } return { name: "Abc Notation", aliases: ["abc"], contains: [ - // fields + // + // header lines and directives (that is, everything except music lines + // { - scope: "meta", - match: /^[XTCOAMLQPZNGHKRBDFSImrsUVWw+]:/ + scope: "header", + match: /^[XTCOAMLQPZNGHKRBDFSImrsUVW+]:/ }, - // text content in fields + // content of header lines { - scope: "meta string", - match: /(?<=[COAZHBDFS]:).*/ + scope: "title", + match: /(?<=\nT:)[^%\n]*/ }, - // title content, lyrics content { - scope: "title", - match: /(?<=[TWw]:).*/ + scope: "part", + match: /(?<=\nP:)[^%\n]*/ + }, + { + scope: "tempo", + match: /(?<=\nQ:)[^%\n]*/ }, - // duplets, triplets, quadruplets, etc. { - scope: "operator", - match: /\([2-9]/ + scope: "key", + match: /(?<=\nK:)[^%\n]*/ }, - // chord symbols - hljs.QUOTE_STRING_MODE, - // numbers - hljs.NUMBER_MODE, - // decorations { - scope: "string", - begin: "!", end: "!" + scope: "meter", + match: /(?<=\nM:)[^%\n]*/ }, - // repeat symbols, bar symbols { - scope: "operator", - match: /(\|\||::|\[?:*\|(:|\[?[1-9])*\]?)/ + scope: "voice", + match: /(?<=\nV:)[^%\n]*/ }, { - scope: "operator", - match: /\[".+?"/ + scope: "history", + match: /(?<=\nH:)[^%\n]*/ }, - // ties, slurs, grace notes, chords, unisons { - scope: "operator", - match: /(?