adding BraceMatching operation

This commit is contained in:
DBHeise 2019-04-12 18:44:26 +00:00
parent 8d0fcf37c5
commit 85b98f1111
4 changed files with 206 additions and 1 deletions

View file

@ -230,7 +230,8 @@
"Escape string", "Escape string",
"Unescape string", "Unescape string",
"Pseudo-Random Number Generator", "Pseudo-Random Number Generator",
"Sleep" "Sleep",
"Brace Matching"
] ]
}, },
{ {

View file

@ -0,0 +1,102 @@
/**
* @author DBHeise [david@heiseink.com]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import Operation from "../Operation";
//import OperationError from "../errors/OperationError";
/**
* Brace Matching operation
*/
class BraceMatching extends Operation {
/**
* BraceMatching constructor
*/
constructor() {
super();
this.name = "Brace Matching";
this.module = "Default";
this.description = "Extracts nested grouping";
this.infoURL = "https://wikipedia.org/wiki/Brace_matching";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "Open Brace Character",
type: "string",
value: "("
},
{
name: "Close Brace Character",
type: "string",
value: ")"
},
{
name: "String Chars",
type: "string",
value: "\"'"
},
{
name: "Escape Char",
type: "string",
value: "\\"
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [openChar, closeChar, strChars, escChar] = args;
let ans = "";
let isInString = false;
let nestLevel = 0;
let stringChar = null;
for (let i = 0; i < input.length; i++) {
const ch = input[i];
if (ch === openChar) {
if (!isInString) {
nestLevel++;
if (nestLevel === 1) {
continue;
}
}
} else if (ch === closeChar) {
if (!isInString) {
nestLevel--;
if (nestLevel < 1) {
break;
}
}
}
if (ch === escChar) {
ans += ch;
ans += input[i + 1];
i++;
continue;
} else if (stringChar && ch === stringChar) {
isInString = false;
stringChar = null;
} else if (strChars.indexOf(ch) > -1) {
if (!isInString) {
isInString = true;
stringChar = ch;
}
}
if (nestLevel > 0) {
ans += ch;
}
}
return ans;
}
}
export default BraceMatching;

View file

@ -90,6 +90,7 @@ import "./tests/Typex";
import "./tests/BLAKE2b"; import "./tests/BLAKE2b";
import "./tests/BLAKE2s"; import "./tests/BLAKE2s";
import "./tests/Protobuf"; import "./tests/Protobuf";
import "./tests/BraceMatching";
// Cannot test operations that use the File type yet // Cannot test operations that use the File type yet
//import "./tests/SplitColourChannels"; //import "./tests/SplitColourChannels";

View file

@ -0,0 +1,101 @@
/**
* Brace Matching tests.
*
* @author DBHeise [david@heiseink.com]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/
import TestRegister from "../TestRegister";
TestRegister.addTests([
{
name: "Brace Matching Simple",
input: "(test)",
expectedOutput: "test",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["(", ")", "\"'", "\\"]
}
]
},
{
name: "Brace Matching Simple with extra text",
input: "this is a simple (test) of this function",
expectedOutput: "test",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["(", ")", "\"'", "\\"]
}
]
},
{
name: "Brace Matching Simple with strings",
input: "{test \"}\"}",
expectedOutput: "test \"}\"",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["{", "}", "\"'", "\\"]
}
]
},
{
name: "Brace Matching Simple with strings 2",
input: "{test '}'}",
expectedOutput: "test '}'",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["{", "}", "\"'", "\\"]
}
]
},
{
name: "Brace Matching Simple nested",
input: "[this [test] good]",
expectedOutput: "this [test] good",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["[", "]", "\"'", "\\"]
}
]
},
{
name: "Brace Matching Simple escaped",
input: "<test \\> foo bar>",
expectedOutput: "test \\> foo bar",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["<", ">", "\"'", "\\"]
}
]
},
{
name: "Brace Matching Complex multi nesting 1",
input: "(((((test)))))(((((test)))))",
expectedOutput: "((((test))))",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["(", ")", "\"'", "\\"]
}
]
},
{
name: "Brace Matching Complex multi nesting 2",
input: "(((((test))))(((((test))))))",
expectedOutput: "((((test))))(((((test)))))",
recipeConfig: [
{
"op": "Brace Matching",
"args": ["(", ")", "\"'", "\\"]
}
]
}
]);