aboutsummaryrefslogtreecommitdiff
path: root/lib/diff.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/diff.js')
-rw-r--r--lib/diff.js154
1 files changed, 152 insertions, 2 deletions
diff --git a/lib/diff.js b/lib/diff.js
index 769a8033b..ac9260737 100644
--- a/lib/diff.js
+++ b/lib/diff.js
@@ -1,6 +1,142 @@
var fs = require('fs');
var child_process = require('child_process');
+function cleanAndGetIndexes(text) {
+ var addRules = {
+ name: "add",
+ openTag: "{+",
+ replaceOpenTag: "",
+ closeTag: "+}",
+ replaceCloseTag: "",
+ }
+ var delRules = {
+ name: "del",
+ openTag: "[-",
+ replaceOpenTag: "",
+ closeTag: "-]",
+ replaceCloseTag: "",
+ }
+ var rules = [addRules, delRules];
+
+ TagTypeEnum = {
+ OPENING : 1,
+ CLOSING : 2
+ }
+
+ function tagLookup(rules, text, pos) {
+ var seen = false;
+ var type = null;
+ var rule = null;
+ for (var i = 0; i<rules.length; i++) {
+ var candidateTag = text.slice(pos, pos+rules[i].openTag.length);
+ // console.log("Comparing "+candidateTag+" with "+rules[i].openTag);
+ if (rules[i].openTag == candidateTag) {
+ seen = true;
+ type = TagTypeEnum.OPENING;
+ rule = i;
+ break;
+ }
+ var candidateTag = text.slice(pos, pos+rules[i].closeTag.length);
+ // console.log("Comparing "+candidateTag+" with "+rules[i].closeTag);
+ if (rules[i].closeTag == candidateTag) {
+ seen = true;
+ type = TagTypeEnum.CLOSING;
+ rule = i;
+ break;
+ }
+ }
+
+ return {seen: seen,
+ rule: rule,
+ type: type}
+ }
+
+ var finalText = "";
+ var posInFinalText = 0; // character that is going to be treated
+ // The position in the original text:
+ var posInText = 0; // character that is going to be treated
+ StateEnum = {
+ OUTSIDE_TAG : 1,
+ INSIDE_TAG : 2
+ }
+ var state = StateEnum.OUTSIDE_TAG;
+ var zones = [[],[]];
+ var currentTextBeginPos = 0;
+ var currentTextEndPos = null;
+ var currentTagBeginPos = null;
+ var currentTagEndPos = null;
+ var currentTag = null;
+
+ function forward() {
+ posInFinalText = posInFinalText + 1;
+ posInText = posInText + 1;
+ }
+
+ function seenOpeningTag() {
+ memorizeText();
+ currentTagBeginPos = posInFinalText;
+ finalText = finalText.concat(rules[currentTag].replaceOpenTag);
+ posInFinalText = posInFinalText + rules[currentTag].replaceOpenTag.length;
+ posInText = posInText + rules[currentTag].openTag.length;
+ currentTextBeginPos = posInText;
+ }
+
+ function seenClosingTag() {
+ memorizeText();
+ finalText = finalText.concat(rules[currentTag].replaceCloseTag);
+ posInFinalText = posInFinalText + rules[currentTag].replaceCloseTag.length;
+ posInText = posInText + rules[currentTag].closeTag.length;
+ currentTagEndPos = posInFinalText - 1;
+ zones[currentTag].push({begin: currentTagBeginPos, end: currentTagEndPos});
+ currentTextBeginPos = posInText;
+ }
+
+ function memorizeText() {
+ currentTextEndPos = posInText - 1;
+ if (currentTextEndPos >= currentTextBeginPos) {
+ finalText = finalText.concat(text.slice(currentTextBeginPos,currentTextEndPos+1));
+ }
+ }
+
+ function end() {
+ memorizeText();
+ }
+
+ function log_error(string) {
+ console.log(string);
+ }
+
+ while (posInText < text.length) {
+ var tag = tagLookup(rules, text, posInText);
+ if(tag.seen && tag.type == TagTypeEnum.OPENING) {
+ if (state != StateEnum.OUTSIDE_TAG) {
+ log_error("Opening tag while not outside tag (tags cannot be nested)");
+ return null;
+ }
+ currentTag = tag.rule;
+ seenOpeningTag();
+ state = StateEnum.INSIDE_TAG;
+ } else if(tag.seen && tag.type == TagTypeEnum.CLOSING) {
+ if (state != StateEnum.INSIDE_TAG) {
+ log_error("Closing tag while not inside tag.");
+ return null;
+ }
+ if (currentTag != tag.rule) {
+ log_error("Closing tag, but not of the same type as previously opened.");
+ return null;
+ }
+ seenClosingTag();
+ state = StateEnum.OUTSIDE_TAG;
+ } else {
+ forward();
+ }
+ }
+ end();
+
+ console.log(JSON.stringify(finalText)+JSON.stringify(zones));
+ return {text: finalText, zones: zones};
+}
+
function diffHandler(req, res, next) {
// console.log("req: "+JSON.stringify(JSON.decycle(req)));
// console.log("");
@@ -36,11 +172,25 @@ function diffHandler(req, res, next) {
{maxBuffer: 100000});
res.set('Content-Type', 'application/json');
- //res.end(JSON.stringify(result));
+ var cleaned = cleanAndGetIndexes(wdiffResult.stdout.toString());
+ if (cleaned == null) {
+ res.end(JSON.stringify({
+ computedDiff: "Failed to clean the diff",
+ zones: null
+ }));
+ } else {
res.end(JSON.stringify({
- computedDiff: wdiffResult.stdout.toString()
+ computedDiff: cleaned.text+
+ "\n//// for reference: ////\n"+ // for debug only
+ wdiffResult.stdout.toString(),
+ zones: cleaned.zones
//computedDiff: "aaa\nbbb[-ccc-]\n[-ddd-]eee\n[-fff-]\nsafe"
+ //computedDiff: "[-aaa-]"
+ //computedDiff: "aaa"
+ //computedDiff: "aa[--]a"
+ //computedDiff: "aa[-b-]"
}));
+ }
}
module.exports = {
diffHandler: diffHandler,