move python over to c-like and new multiline string

This commit is contained in:
MathMan05
2026-07-22 15:11:13 -05:00
parent 0d667d1049
commit a2b47aa3bc
4 changed files with 39 additions and 107 deletions
+12 -18
View File
@@ -3,7 +3,6 @@
"names":["js","ts","javascript"],
"keywords": ["break", "case", "catch", "class", "const", "continue", "debugger", "default", "delete", "do","else", "export", "extends", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "return", "super", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "yield", "let", "await", "true", "false", "null", "undefined"],
"firstLineShebang": true,
"hashComments": false,
"doubleSlashComments": true,
"multilineSlashComments": true,
"JSLikeTemplateStrings": true
@@ -11,37 +10,32 @@
{
"names":["h","c"],
"keywords":["auto", "break", "case", "char", "continue", "do", "default", "const", "double", "else", "enum", "extern", "for", "if", "goto", "float", "int", "long", "register", "return", "signed", "static", "sizeof", "short", "struct", "switch", "typedef", "union", "void", "while", "volatile", "unsigned"],
"firstLineShebang": false,
"hashComments": true,
"doubleSlashComments": true,
"multilineSlashComments": true,
"JSLikeTemplateStrings": false
"multilineSlashComments": true
},
{
"names":["json"],
"keywords":["true","false","null"],
"firstLineShebang": false,
"hashComments": false,
"doubleSlashComments": false,
"multilineSlashComments": false,
"JSLikeTemplateStrings": false
"keywords":["true","false","null"]
},
{
"names":["go"],
"keywords":["break","default","func","interface","select","case","defer","go","map","struct","chan","else","goto","package","switch","const","fallthrough","if","range","type","continue", "for","import","return","var"],
"firstLineShebang": false,
"hashComments": false,
"doubleSlashComments": true,
"multilineSlashComments": true,
"JSLikeTemplateStrings": false
"multilineSlashComments": true
},
{
"names": ["cs", "csharp"],
"keywords": ["abstract", "add", "alias", "allows", "and", "args", "as", "ascending", "async", "await", "base", "bool", "break", "by", "byte", "case", "catch", "char", "checked", "class", "closed", "const", "continue", "decimal", "default", "delegate", "descending", "do", "double", "dynamic", "else", "enum", "equals", "event", "explicit", "extension", "extern", "field", "file", "finally", "fixed", "float", "for", "foreach", "from", "get", "global", "goto", "group", "if", "implicit", "in", "init", "interface", "internal", "into", "is", "join", "let", "lock", "long", "managed", "nameof", "namespace", "new", "nint", "not", "notnull", "nuint", "null", "object", "on", "operator", "or", "orderby", "out", "override", "params", "partial", "private", "protected", "public", "readonly", "record", "ref", "remove", "required", "return", "safe", "sbyte", "scoped", "sealed", "select", "set", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "try", "typeof", "uint", "ulong", "unchecked", "unmanaged", "unsafe", "ushort", "using", "value", "var", "virtual", "void", "volatile", "when", "where", "while", "with", "yield", "true", "false"],
"firstLineShebang": true,
"hashComments": false,
"firstLineShebang":true,
"doubleSlashComments": true,
"multilineSlashComments": true,
"JSLikeTemplateStrings": false
}
"multiLine":"\"\"\""
},
{
"names": ["py", "python"],
"keywords": ["False", "None", "True", "and", "as", "assert", "async", "await", "break", "class", "continue", "def", "del", "elif", "else", "except", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "raise", "return", "try", "while", "with", "yield"],
"hashComments": true,
"multiLine":"\"\"\""
}
]
+26 -8
View File
@@ -3,14 +3,30 @@ import {hcolors} from "../colors.js";
interface clikeConf {
names: string[];
keywords: string[];
firstLineShebang: boolean;
hashComments: boolean;
doubleSlashComments: boolean;
multilineSlashComments: boolean;
JSLikeTemplateStrings: boolean;
firstLineShebang?: boolean;
hashComments?: boolean;
doubleSlashComments?: boolean;
multilineSlashComments?: boolean;
JSLikeTemplateStrings?: boolean;
multiLine?: string;
}
function regex(config: clikeConf): RegExp {
const conds = [] as string[];
if (config.multiLine && "escape" in RegExp) {
const chars = config.multiLine;
const charArr = [...chars];
const matchOpts = [`\\\\(?:.|\s|\\n)`, `(?:[^${charArr[0]}]|\\n)`] as string[];
for (let i = 0; i < chars.length - 1; i++) {
matchOpts.push(
RegExp.escape(config.multiLine.slice(0, i + 1)) + `(?:(?=\\\\)|\\n|[^${charArr[i + 1]}]|$)`,
);
}
conds.push(
`(${RegExp.escape(config.multiLine)}(?:${matchOpts.join("|")})*(?:${RegExp.escape(config.multiLine)})?)`,
);
}
conds.push(`\'(\\\\(.|\\n)|[^"\\n\\\\])*\'?`);
conds.push(`"(\\\\(.|\\n)|[^"\\n\\\\])*"?`);
if (config.hashComments) {
conds.push("#.*");
}
@@ -27,10 +43,10 @@ function regex(config: clikeConf): RegExp {
conds.push("`(\\\\.|[^`])*`?");
}
conds.push("(.|\n)");
return new RegExp(
'"(\\\\(.|\\n)|[^"\\n\\\\])*"?|\'(\\\\(.|\\n)|[^"\\n\\\\])*\'?|\\s+|[a-zA-Z][a-zA-Z0-9]*|[0-9][a-zA-Z0-9]*\\.?[a-zA-Z0-9]*|' +
conds.join("|"),
"gm",
"\\s+|[a-z_A-Z][a-z_A-Z0-9]*|[0-9][a-z_A-Z0-9]*\\.?[a-zA-Z_0-9]*|" + conds.join("|"),
"g",
);
}
let j: undefined | clikeConf[] = undefined;
@@ -48,6 +64,7 @@ export async function canLex(lang: string) {
}
function* lex(code: string, config: clikeConf) {
const r = regex(config);
console.log(r);
const keywords = new Set(config.keywords);
if (config.firstLineShebang) {
const m = code.match(/^#!.*\n?/m);
@@ -60,6 +77,7 @@ function* lex(code: string, config: clikeConf) {
}
}
const matches = Array.from(code.matchAll(r));
console.log(matches);
let i = -1;
function identifyTypeOfWord(word: string) {
if (keywords.has(word)) {
+1 -10
View File
@@ -1,6 +1,5 @@
import {canLex} from "./clike/lex.js";
import {highlightFromLex} from "./highlight.js";
import {lex as pylex} from "./python/lex.js";
import {lex as xmlex} from "./xml/lex.js";
export async function highlight(
elm: HTMLElement,
@@ -17,15 +16,7 @@ export async function highlight(
if (skipEnd) {
content = content.slice(0, content.length - skipEnd);
}
if (lang === "py" || lang === "python") {
highlightFromLex(elm, pylex(content), skipStart);
} else if (
lang === "xml" ||
lang === "html" ||
lang === "htmlx" ||
lang === "qml" ||
lang === "gmx"
) {
if (lang === "xml" || lang === "html" || lang === "htmlx" || lang === "qml" || lang === "gmx") {
highlightFromLex(elm, xmlex(content), skipStart);
} else {
const clike = await canLex(lang);
-71
View File
@@ -1,71 +0,0 @@
import {hcolors} from "../colors.js";
const r =
/"""((\\(.|\n)|[^"\\]|"(?!")|""(?!"))*)(""")?|"(\\(.|\n)|[^"\n\\])*"?|'(\\(.|\n)|[^"\n\\])*'?|\s+|#.*|[~()\[\]|:;`=+\-*\/\\&^%$.]|[a-zA-Z][a-zA-Z0-9]*|[0-9][a-zA-Z0-9]*\.?[a-zA-Z0-9]*|./gm;
const keywords = new Set([
"False",
"None",
"True",
"and",
"as",
"assert",
"async",
"await",
"break",
"class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"finally",
"for",
"from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"nonlocal",
"not",
"or",
"pass",
"raise",
"return",
"try",
"while",
"with",
"yield",
]);
export function* lex(code: string) {
for (const [lex] of code.matchAll(r)) {
if (lex.startsWith("#")) {
yield {
type: hcolors.comment,
content: lex,
};
} else if (lex.match(/^("|')/)) {
yield {
type: hcolors.string,
content: lex,
};
} else if (lex.match(/^[0-9]/)) {
yield {
type: hcolors.number,
content: lex,
};
} else if (lex.match(/^[a-zA-Z]/)) {
yield {
type: keywords.has(lex) ? hcolors.keyword : hcolors.identifier,
content: lex,
};
} else {
yield {
type: hcolors.symbol,
content: lex,
};
}
}
}