/** * @name JavaScript * @support basic syntax, regex, jsdoc, json, template literals * @detect ⛔ reported as TypeScript */ export default /** @satisfies {import('../index.js').ShjGrammar} */ ([ { // js objects match: /(("|')((?!\2)[^\r\n\\]|\\[^])*\2|[a-zA-Z]\w*)(?=\s*:)/g }, { // jsdoc comments match: /\/\*\*((?!\*\/)[^])*(\*\/)?/g, type: 'cmnt', sub: 'jsdoc' }, { // comments match: /\/\/.*\n?|\/\*((?!\*\/)[^])*(\*\/)?/g, type: 'cmnt', sub: 'todo' }, { expand: 'str' }, { match: /`((?!`)[^]|\\[^])*`?/g, type: 'str', sub: [ { match: new class { exec(str) { let i = this.lastIndex, j, f = _ => { while (++i < str.length - 2) if (str[i] == '{') f(); else if (str[i] == '}') return; }; for (; i < str.length; ++i) if (str[i - 1] != '\\' && str[i] == '$' && str[i + 1] == '{') { j = i++; f(i); this.lastIndex = i + 1; return { index: j, 0: str.slice(j, i + 1) }; } return null; } }(), sub: [ { type: 'kwd', match: /^\${|}$/g }, { match: /(?!^\$|{)[^]+(?=}$)/g, sub: 'js' } ] } ] }, { type: 'kwd', // (?|(?.^-]+/g }, { type: 'class', match: /\b[A-Z][\w_]*\b/g }, { type: 'func', match: /[a-zA-Z$_][\w$_]*(?=\s*((\?\.)?\s*\(|=\s*(\(?[\w,{}\[\])]+\)? =>|function\b)))/g } ]);