<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body::-webkit-scrollbar {
width: 10px;
height: 10px;
background: #23272e;
}
body::-webkit-scrollbar-thumb {
background: rgba(78, 86, 102, 0.38);
}
.bg span::selection {
background: rgba(103, 118, 150, 0.19);
}
.bg::after {
content: '';
display: block;
height: 0;
visibility: hidden;
clear: both;
}
</style>
</head>
<body>
<script class="sc">
class Token extends Array {
grammer = {
string: {
single: /^'{1}[^']*'{1}/,
double: /^"{1}[^"]*"{1}/,
inverted: /^`{1}\n*[^`]*\n*`{1}/,
unclosed: /^['"`].*/
},
regExp: /^\/{1}.+\/{1}/,
comment: {
t1: /^\/{2}.*/,
t2: /^\/\*.*\*\//s,
t3: /^\/\*.*/s
},
operator: /^[\~\!\+\-\*\/\%\=\^\&\|\<\>]+/,
punctuation: /^[\@\#\(\)\{\}\[\]\:\;\,\.\?\\]+/,
space: /^ +/,
number: /^\d+/,
functional: /^[^'"`\!\@\#\%\^\&\*\(\)\-\+\=\{\}\[\]\:\;\<\>\?\/\\\s\d\.\,\|]+(?= *\()/,
word: /^[^'"`\!\@\#\%\^\&\*\(\)\-\+\=\{\}\[\]\:\;\<\>\?\/\\\s\.\,\|]+/,
};
keywords = ["var", "const", "let", "for", "do", "while", "if", "else", "try", "catch"
, "finally", "with", "debugger", "delete", "in", "constructor", "class", "extends", "void",
"yield", "async", "await", "new", "switch", "case", "default", "of", "function", "import", "export"
, "as", "typeof", "instanceof", "break", "continue", "return", "throw", "package"];
constructor(str) {
super();
this.source = str;
let cap = null;
let times = 0;
let g = this.grammer;
let that = this;
let index = 0;
let arr = [];
while (str) {
if ((cap = g.string.single.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "string",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.string.double.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "string",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.string.inverted.exec(str))) {
let match = cap[0];
let len = match.length;
if (match.indexOf('\n') != -1) {
let a = match.split("\n");
a.forEach(item => {
let obj = {
type: "string",
text: item,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
that.push(arr);
arr = [];
});
} else {
let obj = {
type: "string",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
}
str = str.slice(len);
}
if ((cap = g.string.unclosed.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "string",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.regExp.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "RegExp",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.comment.t1.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "comment",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.comment.t2.exec(str))) {
let match = cap[0];
let len = match.length;
if (match.indexOf('\n') != -1) {
let a = match.split("\n");
a.forEach(item => {
let obj = {
type: "comment",
text: item,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
that.push(arr);
arr = [];
});
} else {
let obj = {
type: "comment",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
}
str = str.slice(len);
}
if ((cap = g.comment.t3.exec(str))) {
let match = cap[0];
let len = match.length;
if (match.indexOf('\n') != -1) {
let a = match.split("\n");
a.forEach(item => {
let obj = {
type: "comment",
text: item,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
that.push(arr);
arr = [];
});
} else {
let obj = {
type: "comment",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
}
str = str.slice(len);
}
if ((cap = g.operator.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "operator",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.space.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "space",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.number.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "number",
text: match,
color: ""
};
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.punctuation.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "punctuation",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if ((cap = g.functional.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: 'method',
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
/*if ((cap = g.method.exec(str))) {
let dot = cap.groups.dot;
let code = cap.groups.code;
let len = dot.length + code.length;
let obj = {
type: "punctuation",
text: dot,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
let obj2 = {
type: "method",
text: code,
color: ""
}
let color2 = that.colorize(obj2);
obj2.color = color2;
arr.push(obj2);
str = str.slice(len);
}*/
if ((cap = g.word.exec(str))) {
let match = cap[0];
let len = match.length;
let obj = {
type: "word",
text: match,
color: ""
}
let color = that.colorize(obj);
obj.color = color;
arr.push(obj);
str = str.slice(len);
}
if (str.startsWith('\n')) {
str = str.slice(1);
this.push(arr);
arr = [];
}
if (!str) {
this.push(arr);
break;
}
++times;
if (times >= 50000) break;
}
}
colorize(token) {
if (token.type == "string") {
return "#98c379";
}
if (token.type == "number"
|| token.type == "RegExp"
|| token.text == "true"
|| token.text == 'false'
|| token.text == "null"
|| token.text == "undefined") {
return "#d19a66"
}
if (token.type == "comment") {
return "#7f848e";
}
if (token.type == 'operator') {
return "#56b6c2";
}
if (token.type == "punctuation" || /\s+/.test(token.text)) {
return "#abb2bf";
}
if (token.text == "this"
|| token.text == "super"
|| token.text == "document"
|| token.text == "window"
|| /^[A-Z]/.test(token.text)) {
return "#e5c07b";
}
if (this.keywords.indexOf(token.text) != -1) {
return "#c678dd";
}
if (token.type == "method") {
return "#61afef";
}
if (token.type == "word") {
return "#e06c75";
}
}
toHTML() {
let cont = document.createElement("div");
for (let i = 0; i < this.length; ++i) {
let item = this[i];
let row = document.createElement('div');
let wrap = document.createElement('span');
cont.appendChild(row);
row.appendChild(wrap);
for (let j = 0; j < item.length; ++j) {
let span = document.createElement('span');
span.style.color = item[j].color;
span.innerHTML = item[j].text.replace(/ /g, " ");
wrap.appendChild(span);
}
}
return cont.outerHTML;
}
}
let bg = document.createElement('div');
let codeview = document.createElement('div');
let lineNumbers = document.createElement('div');
let code = document.querySelector('.sc')
.textContent.split("\n")
.filter(item => {
return item != "";
}).map(item => {
return item.replace(/\s{8}/, "");
}).join("\n");
bg.classList.add('bg');
bg.style.cssText = `
background-color: #23272e;
font-size: 14px;
line-height: 20px;
font-family: Consolas;
min-width: 1500px;
`
codeview.style.cssText = `
float:left;
padding-left: 10px;
`
lineNumbers.style.cssText = `
float:left;
cursor: pointer;
user-select: none;
color: #495162;
padding-right: 10px;
box-shadow: 2px 0 5px rgba(0,0,0,0.2);
padding-left: 10px;
`
document.body.appendChild(bg);
bg.appendChild(lineNumbers);
bg.appendChild(codeview);
let token = new Token(code);
codeview.innerHTML = token.toHTML();
for(let i = 0; i < token.length; i++) {
let lineno = document.createElement('div')
lineno.innerHTML = i+1;
lineNumbers.appendChild(lineno);
}
</script>
</body>
</html>