initial page

This commit is contained in:
Rodrigo Fernandes 2014-09-06 17:28:50 +01:00
commit ff416f6554
7 changed files with 671 additions and 0 deletions

16
.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
# Eclipse
.classpath
.project
.settings/
# Intellij
.idea/
*.iml
*.iws
# Mac
.DS_Store
# Maven
log/
target/

20
LICENSE Normal file
View file

@ -0,0 +1,20 @@
Copyright 2014 Rodrigo Fernandes https://rtfpessoa.github.io/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

49
README.md Normal file
View file

@ -0,0 +1,49 @@
# Diff to Html by [rtfpessoa](https://github.com/rtfpessoa)
Diff to Html generates pretty HTML diffs from git word diff output.
## Features
* line-by-line diff (not side-by-side)
* char-by-char highlight
* new and old line numbers
* inserted and removed lines
* GitHub like style
## Setup
Import the diff2html.js in your html.
> Pretty Html From Git Word Diff Output
Diff2Html.getPrettyHtmlFromDiff(exInput);
> Intermediate Json From Git Word Diff Output
Diff2Html.getJsonFromDiff(exInput);
> Pretty Html From Json
Diff2Html.getPrettyHtmlFromJson(exInput);
> Check out the `template.html` for a complete example.
## Contributions
All the contributions are welcome.
To contribute just send a pull request with your feature,fix,... and it will be reviewed asap.
## License
Copyright 2014 Rodrigo Fernandes. Released under the terms of the MIT license.
## Thanks
This project is inspired in [pretty-diff](https://github.com/scottgonzalez/pretty-diff) by [Scott González](https://github.com/scottgonzalez).
---

133
diff2html.css Normal file
View file

@ -0,0 +1,133 @@
/*
*
* Diff to HTML (diff2html.css)
* Author: rtfpessoa
* Date: Friday 29 August 2014
* Last Update: Saturday 6 September 2014
*
*/
#d2h-wrapper {
display: block;
margin: 0 auto;
text-align: left;
width: 900px;
}
.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-block;
font-size: 12px;
text-align: center;
width: 70px;
}
.d2h-lines-added {
display: inline-block;
background-color: #ceffce;
border: 1px solid #b4e2b4;
color: #399839;
border-radius: 5px 0 0 5px;
padding: 2px;
width: 25px;
}
.d2h-lines-deleted {
display: inline-block;
background-color: #f7c8c8;
border: 1px solid #e9aeae;
color: #c33;
border-radius: 0 5px 5px 0;
padding: 2px;
width: 25px;
}
.d2h-file-name {
display: inline-block;
height: 33px;
line-height: 33px;
width: 750px;
}
.d2h-file-diff > div {
width: 100%;
}
.d2h-diff-table {
border-collapse: collapse;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
height: 18px;
line-height: 18px;
}
.d2h-code-line {
white-space: pre;
padding-left: 10px;
padding-right: 10px;
height: 18px;
line-height: 18px;
width: 776px;
overflow: hidden;
}
.d2h-code-line del {
display: inline-block;
margin-top: -1px;
text-decoration: none;
background-color: #f99;
font-weight: 700;
border-radius: 0.2em;
}
.d2h-code-line ins {
display: inline-block;
margin-top: -1px;
text-decoration: none;
background-color: #6f7;
font-weight: 700;
border-radius: 0.2em;
}
.d2h-code-linenumber {
width: 1%;
min-width: 30px;
padding-left: 10px;
padding-right: 10px;
height: 18px;
line-height: 18px;
color: rgba(0, 0, 0, 0.3);
text-align: right;
border: solid #eeeeee;
border-width: 0 1px 0 0;
cursor: pointer;
}
.d2h-del {
background-color: #f7c8c8;
border-color: #e9aeae;
}
.d2h-ins {
background-color: #ceffce;
border-color: #b4e2b4;
}
.d2h-info {
background-color: #f8fafd;
color: rgba(0, 0, 0, 0.3);
border-color: #d5e4f2;
}

383
diff2html.js Normal file
View file

@ -0,0 +1,383 @@
/*
*
* Diff to HTML (diff2html.js)
* Author: rtfpessoa
* Date: Friday 29 August 2014
* Last Update: Saturday 6 September 2014
*
* Diff command:
* git diff --word-diff-regex=. HEAD~1
*/
(function (window) {
var ClassVariable;
ClassVariable = (function () {
var LINE_TYPE = {
INSERTS: "d2h-ins",
ALL_NEW: "d2h-all-ins",
DELETES: "d2h-del",
ALL_DELETED: "d2h-all-del",
INSERTS_AND_DELETES: "d2h-ins-and-del",
CONTEXT: "d2h-cntx",
INFO: "d2h-info"
};
function Diff2Html() {
}
/*
* Generates pretty html from string diff input
*/
Diff2Html.prototype.getPrettyHtmlFromDiff = function (diffInput) {
var diffJson = generateDiffJson(diffInput);
return generateJsonHtml(diffJson);
};
/*
* Generates json object from string diff input
*/
Diff2Html.prototype.getJsonFromDiff = function (diffInput) {
return generateDiffJson(diffInput);
};
/*
* Generates pretty html from a json object
*/
Diff2Html.prototype.getPrettyHtmlFromJson = function (diffJson) {
return generateJsonHtml(diffJson);
};
var generateDiffJson = function (diffInput) {
var files = [],
currentFile = null,
currentBlock = null,
oldLine = null,
newLine = null;
var saveBlock = function () {
/* add previous block(if exists) before start a new file */
if (currentBlock) {
currentFile.blocks.push(currentBlock);
currentBlock = null;
}
};
var saveFile = function () {
/* add previous file(if exists) before start a new one */
if (currentFile) {
files.push(currentFile);
currentFile = null;
}
};
var startFile = function (line) {
saveBlock();
saveFile();
/* create file structure */
currentFile = {};
currentFile.blocks = [];
currentFile.deletedLines = 0;
currentFile.addedLines = 0;
/* save file paths, before and after the diff */
var values = /^diff --git a\/(\S+) b\/(\S+).*$/.exec(line);
currentFile.oldName = values[1];
currentFile.newName = values[2];
};
var startBlock = function (line) {
saveBlock();
var values = /^(@@ -(\d+),(\d+) \+(\d+),(\d+) @@).*/.exec(line);
/* create block metadata */
currentBlock = {};
currentBlock.lines = [];
currentBlock.oldStartLine = oldLine = values[2];
currentBlock.newStartLine = newLine = values[4];
currentBlock.header = line;
};
var createLine = function (line) {
/* Line Types */
var isLineWithInserts = /{\+.*?\+}/.exec(line);
var isNewLine = /^{\+.*?\+}$/.exec(line);
var isLineWithDeletes = /\[-.*?-\]/.exec(line);
var isRemovedLine = /^\[-.*?-\]$/.exec(line);
var isLineWithBoth = isLineWithInserts && isLineWithDeletes;
var isContextLine = !isLineWithInserts && !isLineWithDeletes;
var currentLine = {};
currentLine.content = line;
/* fill the line data */
if (isLineWithBoth) {
currentFile.deletedLines++;
currentFile.addedLines++;
currentLine.type = LINE_TYPE.INSERTS_AND_DELETES;
currentLine.oldNumber = oldLine++;
currentLine.newNumber = newLine++;
currentBlock.lines.push(currentLine);
} else if (isContextLine) {
currentLine.type = LINE_TYPE.CONTEXT;
currentLine.oldNumber = oldLine++;
currentLine.newNumber = newLine++;
currentBlock.lines.push(currentLine);
} else if (isNewLine) {
currentFile.addedLines++;
currentLine.type = LINE_TYPE.ALL_NEW;
currentLine.oldNumber = null;
currentLine.newNumber = newLine++;
currentBlock.lines.push(currentLine);
} else if (isRemovedLine) {
currentFile.deletedLines++;
currentLine.type = LINE_TYPE.ALL_DELETED;
currentLine.oldNumber = oldLine++;
currentLine.newNumber = null;
currentBlock.lines.push(currentLine);
} else if (isLineWithInserts) {
currentFile.addedLines++;
currentLine.type = LINE_TYPE.INSERTS;
currentLine.oldNumber = oldLine++;
currentLine.newNumber = newLine++;
currentBlock.lines.push(currentLine);
} else if (isLineWithDeletes) {
currentFile.deletedLines++;
currentLine.type = LINE_TYPE.DELETES;
currentLine.oldNumber = oldLine++;
currentLine.newNumber = newLine++;
currentBlock.lines.push(currentLine);
}
};
var diffLines = diffInput.split("\n");
diffLines.forEach(function (line) {
// Unmerged paths, and possibly other non-diffable files
// https://github.com/scottgonzalez/pretty-diff/issues/11
// Also, remove some useless lines
if (!line || startsWith(line, "*") ||
startsWith(line, "new") || startsWith(line, "index") ||
startsWith(line, "---") || startsWith(line, "+++")) {
return;
}
if (startsWith(line, "diff")) {
startFile(line);
} else if (currentFile && startsWith(line, "@@")) {
startBlock(line);
} else if (currentBlock) {
createLine(line);
}
});
saveBlock();
saveFile();
return files;
};
/*
* Line By Line HTML
*/
var generateJsonHtml = function (diffFiles) {
return "<div id=\"d2h-wrapper\">\n" +
diffFiles.map(function (file) {
return "<div class=\"d2h-file-wrapper\">\n" +
" <div class=\"d2h-file-header\">\n" +
" <div class=\"d2h-file-stats\">\n" +
" <span class=\"d2h-lines-added\">+" + file.addedLines + "</span>\n" +
" <span class=\"d2h-lines-deleted\">-" + file.deletedLines + "</span>\n" +
" </div>\n" +
" <div class=\"d2h-file-name\">" + getDiffName(file.oldName, file.newName) + "</div>\n" +
" </div>\n" +
" <div class=\"d2h-file-diff\">\n" +
" <div class=\"d2h-code-wrapper\">\n" +
" <table class=\"d2h-diff-table\">\n" +
" <tbody class=\"d2h-diff-tbody\">\n" +
" " + generateFileHtml(file) +
" </tbody>\n" +
" </table>\n" +
" </div>\n" +
" </div>\n" +
" </div>\n";
}).join("\n") +
"</div>\n";
};
var generateFileHtml = function (file) {
return file.blocks.map(function (block) {
return "<tr>\n" +
" <td class=\"d2h-code-linenumber " + LINE_TYPE.INFO + "\" colspan=\"2\"></td>\n" +
" <td class=\"" + LINE_TYPE.INFO + "\">" +
" <div class=\"d2h-code-line " + LINE_TYPE.INFO + "\">" + escape(block.header) + "</div>" +
" </td>\n" +
"</tr>\n" +
block.lines.map(function (line) {
var newLine = function () {
var lineData = {};
lineData.oldLine = valueOrEmpty(line.oldNumber);
lineData.newLine = valueOrEmpty(line.newNumber);
return lineData;
};
var escapedLine = escape(line.content);
var lines = [];
var lineData = {};
switch (line.type) {
case LINE_TYPE.INSERTS:
case LINE_TYPE.ALL_NEW:
lineData = newLine();
lineData.content = generateLineInsertions(escapedLine);
lineData.type = LINE_TYPE.INSERTS;
lines.push(lineData);
break;
case LINE_TYPE.DELETES:
case LINE_TYPE.ALL_DELETED:
lineData = newLine();
lineData.content = generateLineDeletions(escapedLine);
lineData.type = LINE_TYPE.DELETES;
lines.push(lineData);
break;
case LINE_TYPE.INSERTS_AND_DELETES:
lineData = newLine();
lineData.content = generateLineDeletions(escapedLine);
lineData.type = LINE_TYPE.DELETES;
lines.push(lineData);
lineData = newLine();
lineData.content = generateLineInsertions(escapedLine);
lineData.type = LINE_TYPE.INSERTS;
lines.push(lineData);
break;
default:
lineData = newLine();
lineData.content = escapedLine;
lineData.type = LINE_TYPE.CONTEXT;
lines.push(lineData);
break;
}
return lines.map(generateLineHtml).join("\n");
}).join("\n");
}).join("\n");
};
var generateLineHtml = function (line) {
return "<tr>\n" +
" <td class=\"d2h-code-linenumber " + line.type + "\">" + line.oldLine + "</td>\n" +
" <td class=\"d2h-code-linenumber " + line.type + "\">" + line.newLine + "</td>\n" +
" <td class=\"" + line.type + "\">" +
" <div class=\"d2h-code-line " + line.type + "\">" + line.content + "</div>" +
" </td>\n" +
"</tr>\n";
};
/*
* Side By Side HTML (work in progress)
*/
/*
* HTML Helpers
*/
var getDiffName = function (oldFilename, newFilename) {
return oldFilename === newFilename ? newFilename : oldFilename + " -> " + newFilename;
};
var generateLineInsertions = function (line) {
return line.slice(0).replace(/(\[-.*?-\])/g, "").
replace(/({\+(.*?)\+})/g, "<ins>$2</ins>");
};
var generateLineDeletions = function (line) {
return line.slice(0).replace(/({\+.*?\+})/g, "").
replace(/(\[-(.*?)-\])/g, "<del>$2</del>");
};
var removeDeletes = function (line) {
return line.slice(0).replace(/({\+.*?\+})/g, "").
replace(/(\[-.*?-\])/g, "");
};
var removeInserts = function (line) {
return line.slice(0).replace(/({\+.*?\+})/g, "").
replace(/(\[-.*?-\])/g, "");
};
var cleanLine = function (line) {
return line.slice(0).replace(/({\+(.*?)\+})/g, "$2").
replace(/(\[-(.*?)-\])/g, "$2");
};
/*
* Utils
*/
function escape(str) {
return str.slice(0)
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/\t/g, " ");
}
function startsWith(str, start) {
return str.indexOf(start) === 0;
}
function valueOrEmpty(value) {
return value ? value : "";
}
/* singleton pattern */
var instance;
return {
getInstance: function () {
if (instance === undefined) {
instance = new Diff2Html();
/* Hide the constructor so the returned objected can't be new'd */
instance.constructor = null;
}
return instance;
}
};
})();
window.Diff2Html = ClassVariable.getInstance();
return window.Diff2Html;
})(window);

1
diff2html.min.js vendored Normal file

File diff suppressed because one or more lines are too long

69
index.html Normal file
View file

@ -0,0 +1,69 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Diff to HTML by rtfpessoa</title>
<!--
Diff to HTML (template.html)
Author: rtfpessoa
Date: Friday 29 August 2014
Last Update: Saturday 6 September 2014
-->
<link rel="stylesheet" type="text/css" href="diff2html.css">
<script type="text/javascript" src="diff2html.js"></script>
<script>
var exInput = 'diff --git a/src/app/language/en.json b/src/app/language/en.json\n' +
'index ccf92c9..68b8345 100644\n' +
'--- a/src/app/language/en.json\n' +
'+++ b/src/app/language/en.json\n' +
'@@ -270,5 +270,6 @@\n' +
' "Open Item Details": "Open Item Details",\n' +
' "Add Item to Favorites": "Add Item to Favorites",\n' +
' "Mark as Seen": "Mark as Seen",\n' +
' "Open Settings": "Open Settings"{+,+}\n' +
'{+ "Custom...": "Custom..."+}\n' +
'}\n' +
'diff --git a/src/app/language/fr.json b/src/app/language/fr.json\n' +
'index 9c773c5..8fb637a 100644\n' +
'--- a/src/app/language/fr.json\n' +
'+++ b/src/app/language/fr.json\n' +
'@@ -266,5 +266,6 @@\n' +
' "Add Item to Favorites": "Ajouter aux favoris",\n' +
' "Mark as Seen": "Marquer comme vu",\n' +
' "Open this screen": "Afficher cette page",\n' +
' "Open Settings": "Ouvrir les Réglages"{+,+}\n' +
'{+ "Custom...": "Ajouter un fichier..."+}\n' +
'}\n' +
'diff --git a/src/app/vendor/videojsplugins.js b/src/app/vendor/videojsplugins.js\n' +
'index 10856e3..892b7ca 100644\n' +
'--- a/src/app/vendor/videojsplugins.js\n' +
'+++ b/src/app/vendor/videojsplugins.js\n' +
'@@ -83,7 +83,7 @@ videojs.plugin(\'customSubtitles\', function() {\n' +
' options[\'track\'] = {\n' +
' kind: function() { return \'subtitles\'; },\n' +
' player: player,\n' +
' label: function(){ return [-\'-]{+i18n.__("+}Custom...[-\'-]{+")+} },\n' +
' dflt: function(){ return false; },\n' +
' mode: function(){ return false; }\n' +
' };\n' +
'@@ -107,7 +107,7 @@ videojs.plugin(\'customSubtitles\', function() {\n' +
'\n' +
' CustomTrackMenuItem.prototype.loadSubtitle = function(filePath) {\n' +
' // TODO Delete old track\n' +
' this.track = this.player_.addTextTrack(\'subtitles\', [-\'-]{+i18n.__("+}Custom...[-\'-]{+")+}, \'00\', { src: filePath });\n' +
' vjs.TextTrackMenuItem.prototype.onClick.call(this); // redirect to TextTrackMenuItem.onClick\n' +
' }\n';
document.onreadystatechange = function () {
var diffHtml = Diff2Html.getPrettyHtmlFromDiff(exInput);
document.getElementsByTagName('body')[0].innerHTML = diffHtml;
}
</script>
</head>
<body>
</body>
</html>