diff --git a/syntaxes/textmate/feature.mts b/syntaxes/textmate/feature.mts new file mode 100644 index 000000000..37512940b --- /dev/null +++ b/syntaxes/textmate/feature.mts @@ -0,0 +1,6 @@ +/** + * Feature Flags + */ +export const SYNTAX_WITH_BOLD_ITALIC = false; +export const SYNTAX_WITH_MATH = false; +export const SYNTAX_WITH_LANGS = true; diff --git a/syntaxes/textmate/fenced.mts b/syntaxes/textmate/fenced.mts index d38a68594..f2b3547f0 100644 --- a/syntaxes/textmate/fenced.mts +++ b/syntaxes/textmate/fenced.mts @@ -1,5 +1,6 @@ import * as textmate from "./textmate.mjs"; import { languages as rawLanguages } from "./fenced.meta.mjs"; +import { SYNTAX_WITH_LANGS } from "./feature.mjs"; const IDENTIFIER_BARE = /[\p{XID_Start}_][\p{XID_Continue}_\-]*/u; @@ -84,8 +85,7 @@ const genLang = ( }; }; -const RENDER_LANGS = true; -export const blockRawLangs = RENDER_LANGS ? rawLanguages.map(genLang) : []; +export const blockRawLangs = SYNTAX_WITH_LANGS ? rawLanguages.map(genLang) : []; export const inlineRaw: textmate.Pattern = { name: "markup.raw.inline.typst string.other.raw.typst", diff --git a/syntaxes/textmate/main.mts b/syntaxes/textmate/main.mts index ece2cb4b4..0a33ef273 100644 --- a/syntaxes/textmate/main.mts +++ b/syntaxes/textmate/main.mts @@ -9,6 +9,7 @@ import { import * as fs from "fs"; import * as path from "path"; import { fileURLToPath } from "node:url"; +import { SYNTAX_WITH_BOLD_ITALIC, SYNTAX_WITH_MATH } from "./feature.mjs"; // JS-Snippet to generate pattern function generatePattern(maxDepth: number, lb: string, rb: string) { @@ -66,11 +67,7 @@ const codeBlock: textmate.Pattern = { name: "meta.brace.curly.typst", }, }, - patterns: [ - { - include: "#code", - }, - ], + patterns: [{ include: "#code" }], }; const contentBlock: textmate.Pattern = { @@ -87,14 +84,7 @@ const contentBlock: textmate.Pattern = { name: "meta.brace.square.typst", }, }, - patterns: [ - { - include: "#contentBlock", - }, - { - include: "#markup", - }, - ], + patterns: [{ include: "#contentBlock" }, { include: "#markup" }], }; const primitiveColors: textmate.Pattern = { @@ -115,6 +105,7 @@ const primitiveTypes: textmate.PatternMatch = { }; const IDENTIFIER = /(? { name: "keyword.operator.assignment.typst", }, }, - patterns: [ - { - include: "#expression", - }, - ], + patterns: [{ include: "#expression" }], }, ], }; @@ -669,11 +614,7 @@ const expressions = (): textmate.Grammar => { name: "meta.brace.round.typst", }, }, - patterns: [ - { - include: "#literalContent", - }, - ], + patterns: [{ include: "#literalContent" }], }, ], }; @@ -688,9 +629,7 @@ const expressions = (): textmate.Grammar => { name: "punctuation.separator.comma.typst", match: /,/, }, - { - include: "#expression", - }, + { include: "#expression" }, ], }; @@ -1397,6 +1336,96 @@ const funcCallOrPropAccess = (strict: boolean): textmate.Pattern => { }; }; +const mathCallArgs: textmate.Pattern = { + // name: "meta.call.args.typst", + begin: /\(/, + end: /\)/, + beginCaptures: { + "0": { + name: "meta.brace.round.typst", + }, + }, + endCaptures: { + "0": { + name: "meta.brace.round.typst", + }, + }, + patterns: [{ include: "#mathPatternOrArgsBody" }], +}; + +const mathPatternOrArgsBody: textmate.Pattern = { + patterns: [ + { include: "#comments" }, + { + match: /,/, + name: "punctuation.separator.comma.typst", + }, + { include: "#markupMath" }, + ], +}; + +const mathFuncCallOrPropAccess = (strict: boolean): textmate.Pattern => { + return { + name: "meta.expr.call.typst", + begin: lookAhead( + strict + ? new RegExp( + /(\.)?/.source + MATH_IDENTIFIER.source + /(?=\(|\[)/.source + ) + : new RegExp( + /(\.\s*)?/.source + MATH_IDENTIFIER.source + /\s*(?=\(|\[)/.source + ) + ), + end: strict + ? /(?:(?<=\)|\])(?:(?![\[\(\.])|$))|(?=[\s;\,\}\]\)]|$)/ + : /(?:(?<=\)|\])(?:(?![\[\(\.])|$))|(?=[\n;\,\}\]\)]|$)/, + patterns: [ + // todo: comments? + // { + // include: "#comments", + // }, + { + match: /\./, + name: "keyword.operator.accessor.typst", + }, + { + match: new RegExp( + MATH_IDENTIFIER.source + + (strict ? /(?=\(|\[)/.source : /\s*(?=\(|\[)/.source) + ), + name: "entity.name.function.typst", + patterns: [ + { + include: "#primitiveFunctions", + }, + ], + }, + { + include: "#mathIdentifier", + }, + // empty args + { + // name: "meta.call.args.typst", + match: /(\()\s*(\))/, + captures: { + "1": { + name: "meta.brace.round.typst", + }, + "2": { + name: "meta.brace.round.typst", + }, + }, + }, + { + include: "#mathCallArgs", + }, + { + include: "#contentBlock", + }, + ], + }; +}; + // todo: #x => y should be parsed as |#x|=>|y // https://github.com/microsoft/vscode-textmate/blob/main/test-cases/themes/syntaxes/TypeScript.tmLanguage.json const arrowFunc: textmate.Pattern = { @@ -1499,6 +1528,7 @@ export const typst: textmate.Grammar = { markupHeading, markupBrace, mathBrace, + mathMoreBrace, ...expressions().repository, @@ -1516,6 +1546,9 @@ export const typst: textmate.Grammar = { // funcCallOrPropAccess: funcCallOrPropAccess(false), callArgs, patternOrArgsBody, + strictMathFuncCallOrPropAccess: mathFuncCallOrPropAccess(true), + mathCallArgs, + mathPatternOrArgsBody, codeBlock, contentBlock, arrowFunc,