Skip to content

Instantly share code, notes, and snippets.

@dglittle
Created April 21, 2013 09:40
Show Gist options
  • Save dglittle/5429091 to your computer and use it in GitHub Desktop.
Save dglittle/5429091 to your computer and use it in GitHub Desktop.
highlightDiff function for highlighting the differences between two strings using html. The differences are highlighted with yellow spans.
// example:
// var ret = highlightDiff("hello earth", "hello mars")
// console.log(ret)
// {
// "a": "hello <span style=\"background-color:yellow\">earth</span>",
// "b": "hello <span style=\"background-color:yellow\">mars</span>"
// }
function highlightDiff(a, b) {
a = a.match(/\w+|\S+|\s+/g)
if (!a) a = []
b = b.match(/\w+|\S+|\s+/g)
if (!b) b = []
for (var i = 0; i < a.length; i++)
a[i] = ':' + a[i]
for (var i = 0; i < b.length; i++)
b[i] = ':' + b[i]
diff(a, b)
function toHTML(tokens) {
var htmlChars = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'/': '&#x2F;'
}
function escapeHtml(s) {
return s.replace(/[&<>'"\/]/g, function (s) {
return htmlChars[s]
})
}
var yellow = false
var s = []
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i]
if (typeof token == "string") {
if (!yellow) {
yellow = true
s.push('<span style="background-color:yellow">')
}
s.push(escapeHtml(token.substring(1)))
} else {
if (yellow) {
yellow = false
s.push('</span>')
}
s.push(escapeHtml(token.text.substring(1)))
}
}
if (yellow) {
yellow = false
s.push('</span>')
}
return s.join('')
}
return {
a : toHTML(a),
b : toHTML(b)
}
// much of the "diff" function below comes from the web,
// but I forget where,
// please put the source here if you know it
function diff( o, n ) {
var ns = new Object();
var os = new Object();
for ( var i = 0; i < n.length; i++ ) {
if ( ns[ n[i] ] == null )
ns[ n[i] ] = { rows: new Array(), o: null };
ns[ n[i] ].rows.push( i );
}
for ( var i = 0; i < o.length; i++ ) {
if ( os[ o[i] ] == null )
os[ o[i] ] = { rows: new Array(), n: null };
os[ o[i] ].rows.push( i );
}
for ( var i in ns ) {
if ( ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1 ) {
n[ ns[i].rows[0] ] = { text: n[ ns[i].rows[0] ], row: os[i].rows[0] };
o[ os[i].rows[0] ] = { text: o[ os[i].rows[0] ], row: ns[i].rows[0] };
}
}
for ( var i = 0; i < n.length - 1; i++ ) {
if ( n[i].text != null && n[i+1].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
n[i+1] == o[ n[i].row + 1 ] ) {
n[i+1] = { text: n[i+1], row: n[i].row + 1 };
o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1 };
}
}
for ( var i = n.length - 1; i > 0; i-- ) {
if ( n[i].text != null && n[i-1].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
n[i-1] == o[ n[i].row - 1 ] ) {
n[i-1] = { text: n[i-1], row: n[i].row - 1 };
o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1 };
}
}
return { o: o, n: n };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment