From cd7d1743880f7480b6e5c2a6e8bb5aab72675346 Mon Sep 17 00:00:00 2001 From: Kyler <59854022+KylerOlsen@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:39:18 -0700 Subject: [PATCH] worked on stuff --- editor.css | 55 +++++++++++++++++------ editor.js | 111 ++++++++++++++++++++++++++++++++++++++++------ syntax_test.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ test.html | 1 + 4 files changed, 257 insertions(+), 28 deletions(-) create mode 100644 syntax_test.py diff --git a/editor.css b/editor.css index 8502075..719b5c6 100644 --- a/editor.css +++ b/editor.css @@ -43,18 +43,19 @@ November 2023 .idle-light .literal.string { color: #00aa00 } .idle-light .literal.string .format { color: #00aa00 } .idle-light .escape { color: #000000 } -.idle-light .name { color: #000000 } -.idle-light .name.variable { color: #000000 } -.idle-light .name.constant{ color: #000000 } -.idle-light .name.function { color: #0000ff } -.idle-light .name.class { color: #0000ff } -.idle-light .name.attribute { color: #000000 } -.idle-light .name.property { color: #000000 } +.idle-light .identifier { color: #000000 } +.idle-light .identifier.variable { color: #000000 } +.idle-light .identifier.constant{ color: #000000 } +.idle-light .identifier.function { color: #0000ff } +.idle-light .identifier.class { color: #0000ff } +.idle-light .identifier.attribute { color: #000000 } +.idle-light .identifier.property { color: #000000 } .idle-light .keyword { color: #ff7700 } .idle-light .keyword.operator { color: #ff7700 } .idle-light .builtin { color: #900090 } .idle-light .operator { color: #000000 } .idle-light .punctuation { color: #000000 } +.idle-light .whitespace { color: #000000 } .idle-dark .view-code { background-color: #002240; color: #ffffff; } .idle-dark .edit-code { caret-color: #ffffff; } @@ -67,15 +68,41 @@ November 2023 .idle-dark .literal.string { color: #02ff02 } .idle-dark .literal.string .format { color: #02ff02 } .idle-dark .escape { color: #ffffff } -.idle-dark .name { color: #ffffff } -.idle-dark .name.variable { color: #ffffff } -.idle-dark .name.constant{ color: #ffffff } -.idle-dark .name.function { color: #5e5eff } -.idle-dark .name.class { color: #5e5eff } -.idle-dark .name.attribute { color: #ffffff } -.idle-dark .name.property { color: #ffffff } +.idle-dark .identifier { color: #ffffff } +.idle-dark .identifier.variable { color: #ffffff } +.idle-dark .identifier.constant{ color: #ffffff } +.idle-dark .identifier.function { color: #5e5eff } +.idle-dark .identifier.class { color: #5e5eff } +.idle-dark .identifier.attribute { color: #ffffff } +.idle-dark .identifier.property { color: #ffffff } .idle-dark .keyword { color: #ff8000 } .idle-dark .keyword.operator { color: #ff8000 } .idle-dark .builtin { color: #ff00ff } .idle-dark .operator { color: #ffffff } .idle-dark .punctuation { color: #ffffff } +.idle-dark .whitespace { color: #ffffff } + +.idle-test .view-code { background-color: #442240; color: #ff0000; } +.idle-test .edit-code { caret-color: #ff0000; } +.idle-test .token { color: #ffffff } +.idle-test .comment { color: #c0c0c0; font-style: italic; } +.idle-test .output { color: #808080 } +.idle-test .error { color: #ff0080 } +.idle-test .literal { color: #00ffff } +.idle-test .literal.number { color: #008080 } +.idle-test .literal.string { color: #00ff00 } +.idle-test .literal.string .format { color: #0000ff } +.idle-test .escape { color: #ffff80 } +.idle-test .identifier { color: #ffff00 } +.idle-test .identifier.variable { color: #808000 } +.idle-test .identifier.constant{ color: #008000 } +.idle-test .identifier.function { color: #8080ff } +.idle-test .identifier.class { color: #80ff80 } +.idle-test .identifier.attribute { color: #800000 } +.idle-test .identifier.property { color: #800080 } +.idle-test .keyword { color: #ff8000 } +.idle-test .keyword.operator { color: #ff8080 } +.idle-test .builtin { color: #ff00ff } +.idle-test .operator { color: #000080 } +.idle-test .punctuation { color: #8000ff } +.idle-test .whitespace { background-color: #ffffff } diff --git a/editor.js b/editor.js index abc486b..98ef28e 100644 --- a/editor.js +++ b/editor.js @@ -25,8 +25,9 @@ class PythonEditor{ } textInput(e) { - let text = this.edit_code.innerHTML; - syntax_highlight(text).forEach(ele => this.view_code.appendChild(ele)); + let text = this.edit_code.innerText; + this.view_code.innerHTML = ""; + syntax_highlight_html(text).forEach(ele => this.view_code.appendChild(ele)); } handleKeyDown(e) { @@ -59,30 +60,112 @@ function insertTab() { function syntax_highlight(text) { const whitespace = " \n\t"; + const digit_start = "0123456789."; + const digit_second = "bBoO"; + const digit_continue = "0123456789._"; const string_start = `'"`; + const string_alt_start = [ + `r'`, `r"`, `rf`, `rb`, `rF`, `rB`, + `R'`, `R"`, `Rf`, `Rb`, `RF`, `RB`, + `f'`, `f"`, `fr`, `fR`, + `F'`, `F"`, `Fr`, `FR`, + `b'`, `b"`, `br`, `bR`, + `B'`, `B"`, `Br`, `BR`, + ]; - const elements = []; + const tokens = []; var char = text.substr(0, 1); text = text.substr(1); while (text.length) { - const element = document.createElement("span"); - var token_type = ""; + const token = {'token_type': '', 'value':''}; - if (whitespace.includes(char)) - token_type = "whitespace"; - else if (string_start.includes(char)) - token_type = "string"; + // Whitespace + if (whitespace.includes(char)) { + token.token_type = "whitespace"; + while (text.length && whitespace.includes(char)) { + token.value += char; + char = text.substr(0, 1); text = text.substr(1); + } + } - while (text.length) { - if (token_type == "whitespace" && !whitespace.includes(char)) - break; - element.innerText.concat(char); + // Comments + else if (char == '#') { + token.token_type = "comment"; + while (text.length && char != "\n") { + token.value += char; + char = text.substr(0, 1); text = text.substr(1); + } + } + + // String literals + else if (string_start.includes(char) || (string_alt_start.includes(char + text.substr(0, 1)))) { + var depth = 1; + var start; + if (string_start.includes(char)) { + token.token_type = "string"; + start = char; + } else { + token.value += char; + char = text.substr(0, 1); text = text.substr(1); + if (!string_start.includes(char)) { + token.value += char; + char = text.substr(0, 1); text = text.substr(1); + } + if (token.value.includes('r') || token.value.includes('R')) + token.token_type += "raw-"; + if (token.value.includes('f') || token.value.includes('F')) + token.token_type += "f-"; + if (token.value.includes('b') || token.value.includes('B')) + token.token_type += "byte-"; + token.token_type += "string"; + start = char; + } + if (text.substr(0, 1) == start && text.substr(1, 1) == start) depth = 3; + token.value += char; + char = text.substr(0, 1); text = text.substr(1); + + while (text.length && depth && (depth > 1 || char != '\n')) { + token.value += char; + if (char == start && depth == 1) depth--; + else if (char == start && text.substr(0, 1) == start && depth == 2) depth--; + else if (char == start && text.substr(0, 1) == start && text.substr(1, 1) == start && depth == 3) depth--; + char = text.substr(0, 1); text = text.substr(1); + } + } + + else { + token.token_type = "token"; + token.value = char; char = text.substr(0, 1); text = text.substr(1); } - elements.push(element); + tokens.push(token); } + return tokens; +} + +function syntax_highlight_html(text) { + const tokens = syntax_highlight(text); + const elements = []; + var last = "whitespace"; + + tokens.forEach(token => { + const element = document.createElement("span"); + if (token.token_type == "whitespace") + element.classList.add("whitespace"); + else if (token.token_type == "comment") + element.classList.add("comment"); + else if (token.token_type.substr(-6) == "string") { + element.classList.add("literal"); + element.classList.add("string"); + } else + element.classList.add("token"); + element.innerText = token.value; + elements.push(element); + last = token.token_type; + }) + return elements; } diff --git a/syntax_test.py b/syntax_test.py new file mode 100644 index 0000000..d357568 --- /dev/null +++ b/syntax_test.py @@ -0,0 +1,118 @@ +# Python Syntax Test + +# Segments written by Kyler or (and mostly at that) from python docs + +if 1900 < year < 2100 and 1 <= month <= 12 \ + and 1 <= day <= 31 and 0 <= hour < 24 \ + and 0 <= minute < 60 and 0 <= second < 60: # Looks like a valid date + return 1 + +month_names = ['Januari', 'Februari', 'Maart', # These are the + 'April', 'Mei', 'Juni', # Dutch names + 'Juli', 'Augustus', 'September', # for the months + 'Oktober', 'November', 'December'] # of the year + +# Here is an example of a correctly (though confusingly) +# indented piece of Python code: +def perm(l): + # Compute the list of all permutations of l + if len(l) <= 1: + return [l] + r = [] + for i in range(len(l)): + s = l[:i] + l[i+1:] + p = perm(s) + for x in p: + r.append(l[i:i+1] + x) + return r + +def perm2(l): + for i in range(len(l)): + s = l[:i] + l[i+1:] + p = perm(l[:i] + l[i+1:]) + for x in p: + r.append(l[i:i+1] + x) + return r + +'This string will not include \ +backslashes or newline characters.' + +re.compile("[A-Za-z_]" # letter or underscore + "[A-Za-z0-9_]*" # letter, digit or underscore + ) + +# Some examples of formatted string literals: + +name = "Fred" +f"He said his name is {name!r}." + +f"He said his name is {repr(name)}." # repr() is equivalent to !r + +width = 10 +precision = 4 +value = decimal.Decimal("12.34567") +f"result: {value:{width}.{precision}}" # nested fields + +today = datetime(year=2017, month=1, day=27) +f"{today:%B %d, %Y}" # using date format specifier + +f"{today=:%B %d, %Y}" # using date format specifier and debugging + +number = 1024 +f"{number:#0x}" # using integer format specifier + +foo = "bar" +f"{ foo = }" # preserves whitespace + +line = "The mill's closed" +f"{line = }" + +f"{line = :20}" + +f"{line = !r:20}" + +newline = ord('\n') +f"newline: {newline}" + +def foo(): + f"Not a docstring" + +foo.__doc__ is None + +# Triple and Multiline + +"""Test" test""" + +"""test +# test +test""" + +# Some examples of integer literals: +7 +2147483647 +0o177 +0b100110111 +3 +79228162514264337593543950336 +0o377 +0xdeadbeef +100_000_000_000 +0b_1110_0101 + +# Some examples of floating point literals: +3.14 +10. +.001 +1e100 +3.14e-10 +0e0 +3.14_15_93 + +# Some examples of imaginary literals: +3.14j +10.j +10j +.001j +1e100j +3.14e-10j +3.14_15_93j diff --git a/test.html b/test.html index 63c9e43..e28a372 100644 --- a/test.html +++ b/test.html @@ -33,6 +33,7 @@ November 2023