((.|\n)*?)<\/del>)/g, "");
+ }
+
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports.PrinterUtils = new PrinterUtils();
+ } else if (typeof global.PrinterUtils === 'undefined') {
+ global.PrinterUtils = new PrinterUtils();
+ }
+
+})(this);
+/*
+ *
+ * HtmlPrinter (html-printer.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function (global, undefined) {
+
+ var diffParser = require("./diff-parser.js").DiffParser;
+ var printerUtils = require("./printer-utils.js").PrinterUtils;
+ var utils = require("./utils.js").Utils;
+
+ function SideBySidePrinter() {
+ }
+
+ SideBySidePrinter.prototype.generateSideBySideJsonHtml = function (diffFiles, config) {
+ return "\n" +
+ diffFiles.map(function (file) {
+
+ var diffs;
+ if (file.blocks.length) diffs = generateSideBySideFileHtml(file, config);
+ else diffs = generateEmptyDiff();
+
+ return "
\n" +
+ " \n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ " \n" +
+ " " + diffs.left +
+ " \n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ " \n" +
+ " " + diffs.right +
+ " \n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n";
+ }).join("\n") +
+ "
\n";
+ };
+
+ function generateSideBySideFileHtml(file, config) {
+ var fileHtml = {};
+ fileHtml.left = "";
+ fileHtml.right = "";
+
+ file.blocks.forEach(function (block) {
+
+ fileHtml.left += "\n" +
+ " | \n" +
+ " " +
+ " " + utils.escape(block.header) + " " +
+ " | \n" +
+ "
\n";
+
+ fileHtml.right += "\n" +
+ " | \n" +
+ " " +
+ " " +
+ " | \n" +
+ "
\n";
+
+ var oldLines = [], newLines = [];
+ var tmpHtml = "";
+
+ for (var i = 0; i < block.lines.length; i++) {
+ var line = block.lines[i];
+ var escapedLine = utils.escape(line.content);
+
+ if (line.type == diffParser.LINE_TYPE.CONTEXT && !oldLines.length && !newLines.length) {
+ fileHtml.left += generateSingleLineHtml(line.type, line.oldNumber, escapedLine);
+ fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine);
+ } else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length && !newLines.length) {
+ fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", "");
+ fileHtml.right += generateSingleLineHtml(line.type, line.newNumber, escapedLine);
+ } else if (line.type == diffParser.LINE_TYPE.DELETES && !newLines.length) {
+ oldLines.push(line);
+ } else if (line.type == diffParser.LINE_TYPE.INSERTS && oldLines.length > newLines.length) {
+ newLines.push(line);
+ } else {
+ var j = 0;
+ var oldLine, newLine;
+ var oldEscapedLine, newEscapedLine;
+
+ if (oldLines.length === newLines.length) {
+ for (j = 0; j < oldLines.length; j++) {
+ oldLine = oldLines[j];
+ newLine = newLines[j];
+ oldEscapedLine = utils.escape(oldLine.content);
+ newEscapedLine = utils.escape(newLine.content);
+
+ config.isCombined = file.isCombined;
+
+ var diff = printerUtils.diffHighlight(oldEscapedLine, newEscapedLine, config);
+
+ fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, diff.o);
+ fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, diff.n);
+ }
+ } else {
+ tmpHtml = processLines(oldLines, newLines);
+ fileHtml.left += tmpHtml.left;
+ fileHtml.right += tmpHtml.right;
+ }
+
+ oldLines = [];
+ newLines = [];
+ i--;
+ }
+ }
+
+ tmpHtml = processLines(oldLines, newLines);
+ fileHtml.left += tmpHtml.left;
+ fileHtml.right += tmpHtml.right;
+ });
+
+ return fileHtml;
+ }
+
+ function processLines(oldLines, newLines) {
+ var fileHtml = {};
+ fileHtml.left = "";
+ fileHtml.right = "";
+
+ var maxLinesNumber = Math.max(oldLines.length, newLines.length);
+ for (j = 0; j < maxLinesNumber; j++) {
+ var oldLine = oldLines[j];
+ var newLine = newLines[j];
+
+ if (oldLine && newLine) {
+ fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, utils.escape(oldLine.content));
+ fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, utils.escape(newLine.content));
+ } else if (oldLine) {
+ fileHtml.left += generateSingleLineHtml(oldLine.type, oldLine.oldNumber, utils.escape(oldLine.content));
+ fileHtml.right += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", "");
+ } else if (newLine) {
+ fileHtml.left += generateSingleLineHtml(diffParser.LINE_TYPE.CONTEXT, "", "", "");
+ fileHtml.right += generateSingleLineHtml(newLine.type, newLine.newNumber, utils.escape(newLine.content));
+ } else {
+ console.error("How did it get here?");
+ }
+ }
+
+ return fileHtml;
+ }
+
+ function generateSingleLineHtml(type, number, content) {
+ return "\n" +
+ " | " + number + " | \n" +
+ " " +
+ " " + content + " " +
+ " | \n" +
+ "
\n";
+ }
+
+ function generateEmptyDiff() {
+ var fileHtml = {};
+ fileHtml.right = "";
+
+ fileHtml.left = "\n" +
+ " | " +
+ " " +
+ "File without changes" +
+ " " +
+ " | \n" +
+ "
\n";
+
+ return fileHtml;
+ }
+
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports.SideBySidePrinter = new SideBySidePrinter();
+ } else if (typeof global.SideBySidePrinter === 'undefined') {
+ global.SideBySidePrinter = new SideBySidePrinter();
+ }
+
+})(this);
+/*
+ *
+ * LineByLinePrinter (line-by-line-printer.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function (global, undefined) {
+
+ var diffParser = require("./diff-parser.js").DiffParser;
+ var printerUtils = require("./printer-utils.js").PrinterUtils;
+ var utils = require("./utils.js").Utils;
+
+ function LineByLinePrinter() {
+ }
+
+ LineByLinePrinter.prototype.generateLineByLineJsonHtml = function (diffFiles, config) {
+ return "\n" +
+ diffFiles.map(function (file) {
+
+ var diffs;
+ if (file.blocks.length) diffs = generateFileHtml(file, config);
+ else diffs = generateEmptyDiff();
+
+ return "
\n" +
+ " \n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ " \n" +
+ " " + diffs +
+ " \n" +
+ "
\n" +
+ "
\n" +
+ "
\n" +
+ "
\n";
+ }).join("\n") +
+ "
\n";
+ };
+
+ function generateFileHtml(file, config) {
+ return file.blocks.map(function (block) {
+
+ var lines = "\n" +
+ " | \n" +
+ " " +
+ " " + utils.escape(block.header) + " " +
+ " | \n" +
+ "
\n";
+
+ var oldLines = [], newLines = [];
+ var processedOldLines = [], processedNewLines = [];
+
+ for (var i = 0; i < block.lines.length; i++) {
+ var line = block.lines[i];
+ var escapedLine = utils.escape(line.content);
+
+ if (line.type == diffParser.LINE_TYPE.CONTEXT && !oldLines.length && !newLines.length) {
+ lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
+ } else if (line.type == diffParser.LINE_TYPE.INSERTS && !oldLines.length && !newLines.length) {
+ lines += generateLineHtml(line.type, line.oldNumber, line.newNumber, escapedLine);
+ } else if (line.type == diffParser.LINE_TYPE.DELETES && !newLines.length) {
+ oldLines.push(line);
+ } else if (line.type == diffParser.LINE_TYPE.INSERTS && oldLines.length > newLines.length) {
+ newLines.push(line);
+ } else {
+ var j = 0;
+ var oldLine, newLine;
+ var oldEscapedLine, newEscapedLine;
+
+ if (oldLines.length === newLines.length) {
+ for (j = 0; j < oldLines.length; j++) {
+ oldLine = oldLines[j];
+ newLine = newLines[j];
+ oldEscapedLine = utils.escape(oldLine.content);
+ newEscapedLine = utils.escape(newLine.content);
+
+ config.isCombined = file.isCombined;
+ var diff = printerUtils.diffHighlight(oldEscapedLine, newEscapedLine, config);
+
+ processedOldLines += generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, diff.o);
+ processedNewLines += generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, diff.n);
+ }
+
+ lines += processedOldLines + processedNewLines;
+ } else {
+ lines += processLines(oldLines, newLines);
+ }
+
+ oldLines = [];
+ newLines = [];
+ processedOldLines = [];
+ processedNewLines = [];
+ i--;
+ }
+ }
+
+ lines += processLines(oldLines, newLines);
+
+ return lines;
+ }).join("\n");
+ }
+
+ function processLines(oldLines, newLines) {
+ var lines = "";
+
+ for (j = 0; j < oldLines.length; j++) {
+ var oldLine = oldLines[j];
+ var oldEscapedLine = utils.escape(oldLine.content);
+ lines += generateLineHtml(oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine);
+ }
+
+ for (j = 0; j < newLines.length; j++) {
+ var newLine = newLines[j];
+ var newEscapedLine = utils.escape(newLine.content);
+ lines += generateLineHtml(newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine);
+ }
+
+ return lines;
+ }
+
+ function generateLineHtml(type, oldNumber, newNumber, content) {
+ return "\n" +
+ " | " +
+ " " + utils.valueOrEmpty(oldNumber) + " " +
+ " " + utils.valueOrEmpty(newNumber) + " " +
+ " | \n" +
+ " " +
+ " " + content + " " +
+ " | \n" +
+ "
\n";
+ }
+
+ function generateEmptyDiff() {
+ return "\n" +
+ " | " +
+ " " +
+ "File without changes" +
+ " " +
+ " | \n" +
+ "
\n";
+ }
+
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports.LineByLinePrinter = new LineByLinePrinter();
+ } else if (typeof global.LineByLinePrinter === 'undefined') {
+ global.LineByLinePrinter = new LineByLinePrinter();
+ }
+
+})(this);
+/*
+ *
+ * HtmlPrinter (html-printer.js)
+ * Author: rtfpessoa
+ *
+ */
+
+(function (global, undefined) {
+
+ var lineByLinePrinter = require("./line-by-line-printer.js").LineByLinePrinter;
+ var sideBySidePrinter = require("./side-by-side-printer.js").SideBySidePrinter;
+
+ function HtmlPrinter() {
+ }
+
+ HtmlPrinter.prototype.generateLineByLineJsonHtml = lineByLinePrinter.generateLineByLineJsonHtml;
+
+ HtmlPrinter.prototype.generateSideBySideJsonHtml = sideBySidePrinter.generateSideBySideJsonHtml;
+
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports.HtmlPrinter = new HtmlPrinter();
+ } else if (typeof global.HtmlPrinter === 'undefined') {
+ global.HtmlPrinter = new HtmlPrinter();
+ }
+
+})(this);
+/*
+ *
+ * Diff to HTML (diff2html.js)
+ * Author: rtfpessoa
+ *
+ * Diff commands:
+ * git diff
+ */
+
+(function (global, undefined) {
+
+ var diffParser = require("./diff-parser.js").DiffParser;
+ var htmlPrinter = require("./html-printer.js").HtmlPrinter;
+
+ function Diff2Html() {
+ }
+
+ /*
+ * config
+ * {
+ * "wordByWord" : true (default)
+ * OR
+ * "charByChar" : true
+ * }
+ *
+ */
+
+ /*
+ * Generates pretty html from string diff input
+ */
+ Diff2Html.prototype.getPrettyHtmlFromDiff = function (diffInput, config) {
+ var diffJson = diffParser.generateDiffJson(diffInput);
+ var configOrEmpty = config || {};
+ return htmlPrinter.generateLineByLineJsonHtml(diffJson, configOrEmpty);
+ };
+
+ /*
+ * Generates json object from string diff input
+ */
+ Diff2Html.prototype.getJsonFromDiff = function (diffInput) {
+ return diffParser.generateDiffJson(diffInput);
+ };
+
+ /*
+ * Generates pretty html from a json object
+ */
+ Diff2Html.prototype.getPrettyHtmlFromJson = function (diffJson, config) {
+ var configOrEmpty = config || {};
+ return htmlPrinter.generateLineByLineJsonHtml(diffJson, configOrEmpty);
+ };
+
+ /*
+ * Generates pretty side by side html from string diff input
+ */
+ Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function (diffInput, config) {
+ var diffJson = diffParser.generateDiffJson(diffInput);
+
+ var configOrEmpty = config || {};
+ return htmlPrinter.generateSideBySideJsonHtml(diffJson, configOrEmpty);
+ };
+
+ /*
+ * Generates pretty side by side html from a json object
+ */
+ Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function (diffJson, config) {
+ var configOrEmpty = config || {};
+ return htmlPrinter.generateSideBySideJsonHtml(diffJson, configOrEmpty);
+ };
+
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports.Diff2Html = new Diff2Html();
+ } else if (typeof global.Diff2Html === 'undefined') {
+ global.Diff2Html = new Diff2Html();
+ }
+
+})(this);
diff --git a/dist/diff2html.min.css b/dist/diff2html.min.css
new file mode 100644
index 0000000..1a518fe
--- /dev/null
+++ b/dist/diff2html.min.css
@@ -0,0 +1 @@
+.d2h-wrapper{display:block;margin:0 auto;text-align:left;width:100%}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-file-header{padding:5px 10px;border-bottom:1px solid #d8d8d8;background-color:#f7f7f7;font:13px Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.d2h-file-stats{display:inline;font-size:12px;text-align:center;max-width:15%}.d2h-lines-added{background-color:#ceffce;border:1px solid #b4e2b4;color:#399839;border-radius:5px 0 0 5px;padding:2px;width:25px}.d2h-lines-deleted{background-color:#f7c8c8;border:1px solid #e9aeae;color:#c33;border-radius:0 5px 5px 0;padding:2px;width:25px}.d2h-file-name{display:inline;height:33px;line-height:33px;max-width:80%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.d2h-diff-table{border-collapse:collapse;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;height:18px;line-height:18px;width:100%}.d2h-files-diff{width:100%}.d2h-file-diff{overflow-x:scroll}.d2h-file-side-diff{display:inline-block;overflow-x:scroll;width:50%;margin-right:-4px}.d2h-code-line{display:block;white-space:pre;padding:0 10px;height:18px;line-height:18px;margin-left:80px;color:inherit;overflow-x:inherit;background:none}.d2h-code-side-line.hljs{display:block;white-space:pre;padding:0 10px;height:18px;line-height:18px;margin-left:50px;color:inherit;overflow-x:inherit;background:none}.d2h-code-line del,.d2h-code-side-line del{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#ffb6ba;border-radius:.2em}.d2h-code-line ins,.d2h-code-side-line ins{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#97f295;border-radius:.2em}.line-num1{display:inline-block;float:left;width:30px;overflow:hidden;text-overflow:ellipsis}.line-num2{display:inline-block;float:right;width:30px;overflow:hidden;text-overflow:ellipsis}.d2h-code-linenumber{position:absolute;width:2%;min-width:65px;padding-left:10px;padding-right:10px;height:18px;line-height:18px;background-color:#fff;color:rgba(0,0,0,0.3);text-align:right;border:solid #eee;border-width:0 1px 0 1px;cursor:pointer}.d2h-code-side-linenumber{position:absolute;width:35px;padding-left:10px;padding-right:10px;height:18px;line-height:18px;background-color:#fff;color:rgba(0,0,0,0.3);text-align:right;border:solid #eee;border-width:0 1px 0 1px;cursor:pointer;overflow:hidden;text-overflow:ellipsis}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;color:rgba(0,0,0,0.3);border-color:#d5e4f2}
\ No newline at end of file
diff --git a/dist/diff2html.min.js b/dist/diff2html.min.js
new file mode 100644
index 0000000..3d44f3a
--- /dev/null
+++ b/dist/diff2html.min.js
@@ -0,0 +1 @@
+function require(){return global}var global=this;!function(global,undefined){var JsDiff=function(){function map(arr,mapper,that){if(Array.prototype.map)return Array.prototype.map.call(arr,mapper,that);for(var other=new Array(arr.length),i=0,n=arr.length;n>i;i++)other[i]=mapper.call(that,arr[i],i,arr);return other}function clonePath(path){return{newPos:path.newPos,components:path.components.slice(0)}}function removeEmpty(array){for(var ret=[],i=0;i/g,">"),n=n.replace(/"/g,""")}function buildValues(components,newString,oldString,useLongestToken){for(var componentPos=0,componentLen=components.length,newPos=0,oldPos=0;componentLen>componentPos;componentPos++){var component=components[componentPos];if(component.removed)component.value=oldString.slice(oldPos,oldPos+component.count).join(""),oldPos+=component.count;else{if(!component.added&&useLongestToken){var value=newString.slice(newPos,newPos+component.count);value=map(value,function(value,i){var oldValue=oldString[oldPos+i];return oldValue.length>value.length?oldValue:value}),component.value=value.join("")}else component.value=newString.slice(newPos,newPos+component.count).join("");newPos+=component.count,component.added||(oldPos+=component.count)}}return components}function canonicalize(obj,stack,replacementStack){stack=stack||[],replacementStack=replacementStack||[];for(var i,i=0;i=diagonalPath;diagonalPath+=2){var basePath,addPath=bestPath[diagonalPath-1],removePath=bestPath[diagonalPath+1];oldPos=(removePath?removePath.newPos:0)-diagonalPath,addPath&&(bestPath[diagonalPath-1]=undefined);var canAdd=addPath&&addPath.newPos+1=0&&oldLen>oldPos;if(canAdd||canRemove){!canAdd||canRemove&&addPath.newPos=newLen&&oldPos+1>=oldLen)return done(buildValues(basePath.components,newString,oldString,self.useLongestToken));bestPath[diagonalPath]=basePath}else bestPath[diagonalPath]=undefined}editLength++}var self=this;if(newString===oldString)return done([{value:newString}]);if(!newString)return done([{value:oldString,removed:!0}]);if(!oldString)return done([{value:newString,added:!0}]);newString=this.tokenize(newString),oldString=this.tokenize(oldString);var newLen=newString.length,oldLen=oldString.length,maxEditLength=newLen+oldLen,bestPath=[{newPos:-1,components:[]}],oldPos=this.extractCommon(bestPath[0],newString,oldString,0);if(bestPath[0].newPos+1>=newLen&&oldPos+1>=oldLen)return done([{value:newString.join("")}]);var editLength=1;if(callback)!function exec(){setTimeout(function(){return editLength>maxEditLength?callback():void(execEditLength()||exec())},0)}();else for(;maxEditLength>=editLength;){var ret=execEditLength();if(ret)return ret}},pushComponent:function(components,added,removed){var last=components[components.length-1];last&&last.added===added&&last.removed===removed?components[components.length-1]={count:last.count+1,added:added,removed:removed}:components.push({count:1,added:added,removed:removed})},extractCommon:function(basePath,newString,oldString,diagonalPath){for(var newLen=newString.length,oldLen=oldString.length,newPos=basePath.newPos,oldPos=newPos-diagonalPath,commonCount=0;newLen>newPos+1&&oldLen>oldPos+1&&this.equals(newString[newPos+1],oldString[oldPos+1]);)newPos++,oldPos++,commonCount++;return commonCount&&basePath.components.push({count:commonCount}),basePath.newPos=newPos,oldPos},equals:function(left,right){var reWhitespace=/\S/;return left===right||this.ignoreWhitespace&&!reWhitespace.test(left)&&!reWhitespace.test(right)},tokenize:function(value){return value.split("")}};var CharDiff=new Diff,WordDiff=new Diff(!0),WordWithSpaceDiff=new Diff;WordDiff.tokenize=WordWithSpaceDiff.tokenize=function(value){return removeEmpty(value.split(/(\s+|\b)/))};var CssDiff=new Diff(!0);CssDiff.tokenize=function(value){return removeEmpty(value.split(/([{}:;,]|\s+)/))};var LineDiff=new Diff,TrimmedLineDiff=new Diff;TrimmedLineDiff.ignoreTrim=!0,LineDiff.tokenize=TrimmedLineDiff.tokenize=function(value){for(var retLines=[],lines=value.split(/^/m),i=0;i=0;i--){for(var d=diff[i],j=0;j"):change.removed&&ret.push(""),ret.push(escapeHTML(change.value)),change.added?ret.push("