-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
127 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,99 @@ | ||
const Sob = { | ||
stringToWords(str) { return str.match(/\b(\w+)\b/g) }, | ||
const Sob = { }; | ||
|
||
stringToChars(str) { return Array.from(str) }, | ||
Sob.stringToWords = (str) => str.match(/\b(\w+)\b/g); | ||
|
||
stringToUTF16(str) { | ||
const utf16 = []; | ||
for (let i = 0; i < str.length; i += 1) { | ||
utf16.push(str.charCodeAt(i)); | ||
} | ||
return utf16; | ||
}, | ||
Sob.stringToChars = (str) => Array.from(str); | ||
|
||
stringToUTF8(str) { | ||
const utf8 = []; | ||
for (let i = 0; i < str.length; i += 1) { | ||
let code = str.charCodeAt(i); | ||
if (code < 0x80) { | ||
utf8.push(code); | ||
} else if (code < 0x800) { | ||
utf8.push(0xc0 | (code >> 6)); | ||
utf8.push(0x80 | (code & 0x3f)); | ||
} else if (code < 0xd800 || code >= 0xe000) { | ||
utf8.push(0xe0 | (code >> 12)); | ||
utf8.push(0x80 | ((code >> 6) & 0x3f)); | ||
utf8.push(0x80 | (code & 0x3f)); | ||
} else { | ||
i += 1; | ||
code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff)); | ||
utf8.push(0xf0 | (code >>18)); | ||
utf8.push(0x80 | ((code>>12) & 0x3f)); | ||
utf8.push(0x80 | ((code>>6) & 0x3f)); | ||
utf8.push(0x80 | (code & 0x3f)); | ||
} | ||
Sob.stringToUTF16 = (str) => { | ||
const utf16 = []; | ||
for (let i = 0; i < str.length; i += 1) { | ||
utf16.push(str.charCodeAt(i)); | ||
} | ||
return utf16; | ||
}; | ||
|
||
Sob.stringToUTF8 = (str) => { | ||
const utf8 = []; | ||
for (let i = 0; i < str.length; i += 1) { | ||
let code = str.charCodeAt(i); | ||
if (code < 0x80) { | ||
utf8.push(code); | ||
} else if (code < 0x800) { | ||
utf8.push(0xc0 | (code >> 6)); | ||
utf8.push(0x80 | (code & 0x3f)); | ||
} else if (code < 0xd800 || code >= 0xe000) { | ||
utf8.push(0xe0 | (code >> 12)); | ||
utf8.push(0x80 | ((code >> 6) & 0x3f)); | ||
utf8.push(0x80 | (code & 0x3f)); | ||
} else { | ||
i += 1; | ||
code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff)); | ||
utf8.push(0xf0 | (code >>18)); | ||
utf8.push(0x80 | ((code>>12) & 0x3f)); | ||
utf8.push(0x80 | ((code>>6) & 0x3f)); | ||
utf8.push(0x80 | (code & 0x3f)); | ||
} | ||
return utf8; | ||
}, | ||
} | ||
return utf8; | ||
}; | ||
|
||
Sob.sanitiseHTML = (html) => html | ||
.replace("&", "&") | ||
.replace("<", "<") | ||
.replace(">", ">") | ||
.replace("\"", """) | ||
.replace("'", "'"); | ||
|
||
Sob.sanitiseEscapes = (str) => { | ||
let chars = { | ||
"\n" : "\\n", "\r" : "\\r", | ||
"\f" : "\\f", "\t" : "\\t", | ||
"\b" : "\\b", | ||
"\"" : "\\\"", "\'" : "\\'", | ||
}; | ||
return Sob.stringToChars(str).map(x => chars[x] ?? x).join(""); | ||
}; | ||
|
||
sanitiseHTML(html) { | ||
return html | ||
.replace("&", "&") | ||
.replace("<", "<") | ||
.replace(">", ">") | ||
.replace("\"", """) | ||
.replace("'", "'"); | ||
}, | ||
Sob.showList = (xs, each=undefined) => { | ||
let first = true; | ||
let sb = ""; | ||
for (const x of xs) { | ||
if (!first) { | ||
sb += ", "; | ||
} | ||
first = false; | ||
sb += each == undefined ? x : each(x); | ||
} | ||
return sb; | ||
}; | ||
|
||
sanitiseEscapes(str) { | ||
let chars = { | ||
"\n" : "\\n", "\r" : "\\r", | ||
"\f" : "\\f", "\t" : "\\t", | ||
"\b" : "\\b", | ||
"\"" : "\\\"", "\'" : "\\'", | ||
}; | ||
return Sob.stringToChars(str).map(x => chars[x] ?? x).join(""); | ||
}, | ||
Sob.HTMLBuilder = class { | ||
constructor() { this.text = "" } | ||
toString() { return this.text } | ||
write(text) { this.text += text } | ||
|
||
showList(xs, each=undefined) { | ||
let first = true; | ||
let sb = ""; | ||
for (const x of xs) { | ||
if (!first) { | ||
sb += ", "; | ||
writeTag(tags, content=undefined) { | ||
const tagsOpen = Array.isArray(tags) ? tags : [tags]; | ||
const tagsClose = tagsOpen.map(tag => tag.split()[0]); | ||
for (const tag of tagsOpen) { | ||
this.text += `<${tag}>`; | ||
} | ||
if (content != undefined) { | ||
if (content instanceof Function) { | ||
content(this); | ||
} else { | ||
this.write(content); | ||
} | ||
first = false; | ||
sb += each == undefined ? x : each(x); | ||
} | ||
return sb; | ||
}, | ||
}; | ||
for (const tag of tagsClose) { | ||
this.text += `</${tag}>`; | ||
} | ||
} | ||
|
||
writeVoidTag(tags) { | ||
const tagsOpen = Array.isArray(tags) ? tags : [tags]; | ||
for (const tag of tagsOpen) { | ||
this.text += `<${tag} />`; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,45 @@ | ||
function getTextContent() { | ||
return document.getElementById("src").value; | ||
const getTextContent = () => document.getElementById("src").value; | ||
const setResultHTML = html => document.getElementById("dest").innerHTML = html; | ||
|
||
function writeResult(sb, title, content) { | ||
sb.writeTag("div", sb => { | ||
sb.writeTag("b", title); | ||
sb.write(": "); | ||
sb.writeTag("code", content); | ||
}); | ||
} | ||
|
||
function setResultHTML(html) { | ||
document.getElementById("dest").innerHTML = html; | ||
function writeDetails(sb, title, content) { | ||
sb.writeTag("details", sb => { | ||
sb.writeTag(["summary", "b"], title); | ||
sb.writeTag(["code"], content); | ||
}); | ||
} | ||
|
||
function getCounts() { | ||
const text = getTextContent(); | ||
const words = Sob.stringToWords(text); | ||
const chars = Sob.stringToChars(text); | ||
const bytes = Sob.stringToUTF8(text); | ||
let sb = ""; | ||
sb += "<p>" | ||
sb += `<b>#words</b>: <code>${words.length}</code><br>` | ||
sb += `<b>#characters</b>: <code>${chars.length}</code><br>` | ||
sb += `<b>#bytes</b>: <code>${bytes.length}</code>` | ||
sb += "</p>" | ||
sb += "<details><summary>expand word list</summary><pre><code style=\"text-wrap : wrap\">" | ||
sb += "[" + Sob.showList(words, x => `"${Sob.sanitiseEscapes(x)}"`) + "]"; | ||
sb += "</code></pre></details>" | ||
sb += "<details><summary>expand character list</summary><pre><code style=\"text-wrap : wrap\">" | ||
sb += "[" + Sob.showList(chars, x => `'${Sob.sanitiseEscapes(x)}'`) + "]"; | ||
sb += "</code></pre></details>" | ||
sb += "<details><summary>expand byte list</summary><pre><code style=\"text-wrap : wrap\">" | ||
sb += "[" + Sob.showList(bytes) + "]"; | ||
sb += "</code></pre></details>" | ||
let sb = new Sob.HTMLBuilder; | ||
sb.writeTag("p", sb => { | ||
writeResult(sb, "#words", words.length); | ||
writeResult(sb, "#characters", chars.length); | ||
writeResult(sb, "#bytes", bytes.length); | ||
}); | ||
writeDetails(sb, "expand word list", | ||
"[" + Sob.showList(words, x => `"${Sob.sanitiseEscapes(x)}"`) + "]" | ||
); | ||
writeDetails(sb, "expand character list", | ||
"[" + Sob.showList(chars, x => `'${Sob.sanitiseEscapes(x)}'`) + "]" | ||
); | ||
writeDetails(sb, "expand byte list", | ||
"[" + Sob.showList(bytes) + "]" | ||
); | ||
setResultHTML(sb); | ||
console.log("got counts"); | ||
} | ||
|
||
function getStats() { | ||
|
||
} |