yay
This commit is contained in:
72
server/utils/crackdown.js
Normal file
72
server/utils/crackdown.js
Normal file
@@ -0,0 +1,72 @@
|
||||
// ____ _ ____
|
||||
// / ___|_ __ __ _ ___| | _| _ \ _____ ___ __
|
||||
// | | | '__/ _` |/ __| |/ / | | |/ _ \ \ /\ / / '_ \
|
||||
// | |___| | | (_| | (__| <| |_| | (_) \ V V /| | | |
|
||||
// \____|_| \__,_|\___|_|\_\____/ \___/ \_/\_/ |_| |_|
|
||||
//
|
||||
//
|
||||
// _ __ __ _ _ __ ___ ___ _ __
|
||||
// | '_ \ / _` | '__/ __|/ _ \ '__|
|
||||
// | |_) | (_| | | \__ \ __/ |
|
||||
// | .__/ \__,_|_| |___/\___|_|
|
||||
// |_|
|
||||
|
||||
const capture = "([a-z0-9:()-](?:.*[a-zA-Z:().!-])?)";
|
||||
const skipSpace = "\\s*";
|
||||
|
||||
const htmlEscapeRegex = /[&<>"'`]/g; // used to escape html characters
|
||||
|
||||
/**
|
||||
* @type {Array.string[]}
|
||||
*
|
||||
* The order of the elements of this array matters.
|
||||
*/
|
||||
const opcodes = [
|
||||
["(^|\\n)=", "($|\\n)", "$1<h1>$2</h1>$3"],
|
||||
["(^|\\n)==", "($|\\n)", "$1<h2>$2</h2>$3"],
|
||||
["---", "---", "<span class='strike'>$1</span>"],
|
||||
["___", "___", "<span class='underline'>$1</span>"],
|
||||
["(?:[,]{3})", "(?:[,]{3})", "<span class='undercurl'>$1</span>"],
|
||||
["(?:[(]{2})", "(?:[)]{2})", "<span class='faint'>$1</span>"],
|
||||
["_", "_", "<span class='italic'>$1</span>"],
|
||||
["\\*", "\\*", "<span class='bold'>$1</span>"],
|
||||
["\\[\\[([a-zA-Z0-9_ ]+)\\[\\[", "\\]\\]", "<span class='$1'>$2</span>"],
|
||||
];
|
||||
/** @type{Array.Array.<Regexp,string>} */
|
||||
const regexes = [];
|
||||
|
||||
//
|
||||
// Pre-compile all regexes
|
||||
for (const [left, right, replacement] of opcodes) {
|
||||
regexes.push([new RegExp(left + skipSpace + capture + skipSpace + right, "gi"), replacement]);
|
||||
}
|
||||
|
||||
/** @param {string} text */
|
||||
export function crackdown(text) {
|
||||
text.replace(htmlEscapeRegex, (c) => {
|
||||
switch (c) {
|
||||
case "&":
|
||||
return "&";
|
||||
case "<":
|
||||
return "<";
|
||||
case ">":
|
||||
return ">";
|
||||
case '"':
|
||||
return """;
|
||||
case "'":
|
||||
return "'";
|
||||
case "`":
|
||||
return "`";
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
});
|
||||
for (const k in regexes) {
|
||||
const [regex, replacement] = regexes[k];
|
||||
text = text.replace(regex, replacement);
|
||||
}
|
||||
|
||||
console.debug("crack output", text);
|
||||
|
||||
return text;
|
||||
}
|
||||
82
server/utils/parseArgs.js
Normal file
82
server/utils/parseArgs.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Parse a command string into arguments. For use with colon-commands.
|
||||
*
|
||||
* @param {string} cmdString;
|
||||
* @returns {(string|number)[]} Command arguments
|
||||
*/
|
||||
export function parseArgs(cmdString) {
|
||||
if (typeof cmdString === "string") {
|
||||
throw new Error("Expected string. GoT a finger in the eye instead");
|
||||
}
|
||||
const args = [];
|
||||
const quoteChars = ["'", '"', "`"];
|
||||
const backslash = "\\";
|
||||
|
||||
let currentArg = ""; // The arg we are currently constructing
|
||||
let inQuotes = false; // are we inside quotes of some kind?
|
||||
let currentQuoteChar = ""; // if were in quotes, which are they?
|
||||
|
||||
// helper function
|
||||
const pushVal = (value) => {
|
||||
const n = Number(value);
|
||||
if (Number.isSafeInteger(n)) {
|
||||
args.push(n);
|
||||
} else if (Number.isFinite(n)) {
|
||||
args.push(n);
|
||||
} else {
|
||||
args.push(value);
|
||||
}
|
||||
};
|
||||
|
||||
for (let i = 0; i < cmdString.length; i++) {
|
||||
const char = cmdString[i];
|
||||
const nextChar = cmdString[i + 1];
|
||||
|
||||
if (!inQuotes) {
|
||||
// Not in quotes - look for quote start or whitespace
|
||||
if (quoteChars.includes(char)) {
|
||||
inQuotes = true;
|
||||
currentQuoteChar = char;
|
||||
} else if (char === " " || char === "\t") {
|
||||
// Whitespace - end current arg if it exists
|
||||
if (currentArg) {
|
||||
pushVal(currentArg);
|
||||
currentArg = "";
|
||||
}
|
||||
// Skip multiple whitespace
|
||||
while (cmdString[i + 1] === " " || cmdString[i + 1] === "\t") i++;
|
||||
} else {
|
||||
currentArg += char;
|
||||
}
|
||||
} else {
|
||||
// Inside quotes
|
||||
if (char === currentQuoteChar) {
|
||||
// Found matching quote - end quoted section
|
||||
inQuotes = false;
|
||||
currentQuoteChar = "";
|
||||
} else if (char === backslash && (nextChar === currentQuoteChar || nextChar === backslash)) {
|
||||
// Escape sequence - add the escaped character
|
||||
currentArg += nextChar;
|
||||
//
|
||||
// Todo, maybe add support for \n newlines? Why would I ?
|
||||
//
|
||||
i++; // Skip next character
|
||||
} else {
|
||||
currentArg += char;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add final argument if exists
|
||||
if (currentArg) {
|
||||
pushVal(currentArg);
|
||||
}
|
||||
|
||||
if (currentQuoteChar) {
|
||||
// We allow quotes to not be terminated
|
||||
// It allows players to do stuff like `:say "wolla my lovely friend` and not have the text modified or misinterpreted in any way
|
||||
// May be good for chat where you dont want every word split into individual arguments
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
Reference in New Issue
Block a user