diff --git a/src/webpage/highlighter/clike/langs.json b/src/webpage/highlighter/clike/langs.json index bbbb4bc..c7079ec 100644 --- a/src/webpage/highlighter/clike/langs.json +++ b/src/webpage/highlighter/clike/langs.json @@ -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":"\"\"\"" + } ] diff --git a/src/webpage/highlighter/clike/lex.ts b/src/webpage/highlighter/clike/lex.ts index 255fa58..da019d9 100644 --- a/src/webpage/highlighter/clike/lex.ts +++ b/src/webpage/highlighter/clike/lex.ts @@ -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)) { diff --git a/src/webpage/highlighter/index.ts b/src/webpage/highlighter/index.ts index f790e49..ac4f746 100644 --- a/src/webpage/highlighter/index.ts +++ b/src/webpage/highlighter/index.ts @@ -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); diff --git a/src/webpage/highlighter/python/lex.ts b/src/webpage/highlighter/python/lex.ts deleted file mode 100644 index f1449a7..0000000 --- a/src/webpage/highlighter/python/lex.ts +++ /dev/null @@ -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, - }; - } - } -}