Automatically detect UTF8 character encoding in output

This commit is contained in:
n1474335 2024-03-26 13:33:00 +00:00
parent 16dfb3fac6
commit 65ffd8d65d
No known key found for this signature in database
GPG key ID: D15457B7B4AF3F37
7 changed files with 270 additions and 147 deletions

View file

@ -62,7 +62,8 @@ class InputWaiter {
this.inputTextEl = document.getElementById("input-text");
this.inputChrEnc = 0;
this.eolSetManually = false;
this.eolState = 0; // 0 = unset, 1 = detected, 2 = manual
this.encodingState = 0; // 0 = unset, 1 = detected, 2 = manual
this.initEditor();
this.inputWorker = null;
@ -116,7 +117,9 @@ class InputWaiter {
label: "Input",
eolHandler: this.eolChange.bind(this),
chrEncHandler: this.chrEncChange.bind(this),
chrEncGetter: this.getChrEnc.bind(this)
chrEncGetter: this.getChrEnc.bind(this),
getEncodingState: this.getEncodingState.bind(this),
getEOLState: this.getEOLState.bind(this)
}),
// Mutable state
@ -156,6 +159,8 @@ class InputWaiter {
]
});
if (this.inputEditorView) this.inputEditorView.destroy();
this.inputEditorView = new EditorView({
state: initialState,
parent: this.inputTextEl
@ -166,30 +171,18 @@ class InputWaiter {
* Handler for EOL change events
* Sets the line separator
* @param {string} eol
* @param {boolean} manual - a flag for whether this was set by the user or automatically
* @param {boolean} [manual=false]
*/
eolChange(eol, manual=false) {
const eolVal = eolCodeToSeq[eol];
if (eolVal === undefined) return;
const eolBtn = document.querySelector("#input-text .eol-value");
if (manual) {
this.eolSetManually = true;
eolBtn.classList.remove("font-italic");
} else {
eolBtn.classList.add("font-italic");
}
this.eolState = manual ? 2 : this.eolState;
if (this.eolState < 2 && eolVal === this.getEOLSeq()) return;
if (eolVal === this.getEOLSeq()) return;
if (!manual) {
// Pulse
eolBtn.classList.add("pulse");
setTimeout(() => {
eolBtn.classList.remove("pulse");
}, 2000);
if (this.eolState === 1) {
// Alert
this.app.alert(`Input EOL separator has been changed to ${eolCodeToName[eol]}`, 5000);
this.app.alert(`Input end of line separator has been detected and changed to ${eolCodeToName[eol]}`, 5000);
}
// Update the EOL value
@ -210,14 +203,24 @@ class InputWaiter {
return this.inputEditorView.state.lineBreak;
}
/**
* Returns whether the input EOL sequence was set manually or has been detected automatically
* @returns {number} - 0 = unset, 1 = detected, 2 = manual
*/
getEOLState() {
return this.eolState;
}
/**
* Handler for Chr Enc change events
* Sets the input character encoding
* @param {number} chrEncVal
* @param {boolean} [manual=false]
*/
chrEncChange(chrEncVal) {
chrEncChange(chrEncVal, manual=false) {
if (typeof chrEncVal !== "number") return;
this.inputChrEnc = chrEncVal;
this.encodingState = manual ? 2 : this.encodingState;
this.inputChange();
}
@ -229,6 +232,14 @@ class InputWaiter {
return this.inputChrEnc;
}
/**
* Returns whether the input character encoding was set manually or has been detected automatically
* @returns {number} - 0 = unset, 1 = detected, 2 = manual
*/
getEncodingState() {
return this.encodingState;
}
/**
* Sets word wrap on the input editor
* @param {boolean} wrap
@ -908,7 +919,7 @@ class InputWaiter {
*/
afterPaste(e) {
// If EOL has been fixed, skip this.
if (this.eolSetManually) return;
if (this.eolState > 1) return;
const inputText = this.getInput();
@ -930,17 +941,23 @@ class InputWaiter {
}, 0);
if (total === 0) return;
// If CRLF not zero and more than half the highest alternative, choose CRLF
// Find most prevalent line ending sequence
const highest = Object.entries(eolCharCounts).reduce((acc, curr) => {
return curr[1] > acc[1] ? curr : acc;
}, ["LF", 0]);
let choice = highest[0];
// If CRLF not zero and more than half the highest alternative, choose CRLF
if ((eolCharCounts.CRLF * 2) > highest[1]) {
this.eolChange("CRLF");
return;
choice = "CRLF";
}
// Else choose max
this.eolChange(highest[0]);
const eolVal = eolCodeToSeq[choice];
if (eolVal === this.getEOLSeq()) return;
// Setting automatically
this.eolState = 1;
this.eolChange(choice);
}
/**
@ -1276,8 +1293,13 @@ class InputWaiter {
this.manager.output.removeAllOutputs();
this.manager.output.terminateZipWorker();
this.eolSetManually = false;
this.manager.output.eolSetManually = false;
this.eolState = 0;
this.encodingState = 0;
this.manager.output.eolState = 0;
this.manager.output.encodingState = 0;
this.initEditor();
this.manager.output.initEditor();
const tabsList = document.getElementById("input-tabs");
const tabsListChildren = tabsList.children;