/* ---------------------------------------------------------------------------- Question Server question file merger GitLab: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ------------------------------------------------------------------------- */ var utils = require('./utils.js'); var actions = require('./actions.js'); Main(); function Main() { const params = GetParams(); console.log(params); var oldData = ""; var sum = 0; var r = ReadData(utils.ReadFile(params[0])); console.log(r.result.toString()); console.log("\n\n"); console.log("errors:"); console.log(r.logs.join("\n")); /*for (var i = 0; i < params.length; i++) { const data = utils.ReadFile(params[i]); } console.log("-------------"); console.log("Sum: " + sum); console.log("Simplifying..."); var newData = Simplify(oldData); var nr = actions.NLoad(newData); console.log("New result: " + nr.count); utils.WriteFile(newData, "newData"); console.log("File written!");*/ } function GetParams() { return process.argv.splice(2); } /*Question object * q: question * a: answer * i: image * */ function Question(q, a, i) { this.Q = q; this.A = a; this.I = i; this.toString = function() { var r = "?" + this.Q + "\n!" + this.A; if (this.I) r += "\n>" + this.I; return r; }; this.HasQuestion = function() { return this.Q != undefined; }; this.HasAnswer = function() { return this.A != undefined; }; this.HasImage = function() { return this.I != undefined; }; this.IsComplete = function() { return this.HasQuestion() && this.HasAnswer(); }; this.Compare = function(q2) { const qmatchpercent = CompareString(this.Q, q2.Q); const amatchpercent = CompareString(this.A, q2.A); const imatchpercent = I ? CompareString(this.I, q2.I) : 0; return (qmatchpercent + amatchpercent + imatchpercent) / 3; }; const CompareString = function(s1, s2) { s1 = SimplifyStringForComparison(s1).split(" "); s2 = SimplifyStringForComparison(s2).split(" "); var match = 0; for (var i = 0; i < s1.length; i++) { if (s2.includes(s1[i])) { match++; } } var percent = Math.round(((match / s1.length) * 100).toFixed(2)); // matched words percent var lengthDifference = Math.abs(s2.length - s1.length); percent -= lengthDifference * 3; if (percent < 0) percent = 0; return percent; }; } function Subject(n) { this.Name = n; this.Questions = []; this.AddQuestion = function(q) { this.Questions.push(q); }; this.toString = function() { var r = []; for (var i = 0; i < this.Questions.length; i++) r.push(this.Questions[i].toString()); return "+" + this.Name + "\n" + r.join("\n"); }; } function QuestionDB() { this.Subjects = []; this.AddQuestion = function(subj, q) { var i = 0; while (i < this.Subjects.length && this.Subjects[i].Name != subj) i++; if (i < this.Subjects.length) this.Subjects[i].AddQuestion(q); else { const n = new Subject(subj); n.AddQuestion(q); this.Subjects.push(n); } }; this.toString = function() { var r = []; for (var i = 0; i < this.Subjects.length; i++) r.push(this.Subjects[i].toString()); return r.join("\n\n"); }; } /* * Returns a question database from the given data. * Parameter should be raw read file in string with "\n"-s * TODO: ??? -s are not listed as errors, tho works correctly * */ function ReadData(data) { const d = data.split("\n"); const r = new QuestionDB(); var logs = []; var currSubj = ""; // the current subjects name var ExpectedIdentifier = ['+', '?']; let currQuestion = new Question(); var i = -1; while (i < d.length) { let currIdentifier; let skipped = 0; do { if (skipped >= 1) logs.push(i + ": " + d[i]); i++; if (i >= d.length) return { result: r, logs: logs }; currIdentifier = d[i][0]; skipped++; } while (!ExpectedIdentifier.includes(currIdentifier) && i < d.length); let currData = d[i].substring(1); if (currIdentifier == '+') { currSubj = currData; ExpectedIdentifier = ['?']; continue; } if (currIdentifier == '?') { if (currQuestion.IsComplete()) { r.AddQuestion(currSubj, currQuestion); currQuestion = new Question(); } // overwriting is allowed here, bcus: // ?????!> currQuestion.Q = currData; ExpectedIdentifier = ['!', '?']; continue; } if (currIdentifier == '!') { // if dont have question continue if (!currQuestion.HasQuestion()) throw "No question! (A)"; // dont allow overwriting // ?!!!! if (!currQuestion.HasAnswer()) { currQuestion.A = currData; } ExpectedIdentifier = ['?', '>', '+']; continue; } if (currIdentifier == '>') { // if dont have question or answer continue if (!currQuestion.HasQuestion()) throw "No question! (I)"; if (!currQuestion.HasAnswer()) throw "No asnwer! (I)"; // dont allow overwriting // ?!>>> if (!currQuestion.HasImage()) { currQuestion.I = currData; } ExpectedIdentifier = ['?', '+']; continue; } } return { result: r, logs: logs }; } function SortQuestions(dataObj) { /* * Sort questions by something * */ } function RemoveDuplicates(dataObj) { // TODO: compare and delete /* * removes duplicates from a read data by comparing every question after sorting * */ } function SimplifyStringForComparison(value) { value = RemoveUnnecesarySpaces(value).toLowerCase(); var removableChars = [",", ".", ":", "!"]; for (var i = 0; i < removableChars.length; i++) { var regex = new RegExp(removableChars[i], "g"); value.replace(regex, ""); } return value; } function RemoveUnnecesarySpaces(toremove) { toremove = NormalizeSpaces(toremove); while (toremove.includes(" ")) // while the text includes double spaces replaces all of them with a single one { toremove = toremove.replace(/ /g, " "); } return toremove.trim(); } function NormalizeSpaces(input) { return input.replace(/\s/g, ' '); }