README
@fav/text.diff
Get diff between two texts.
"fav" is an abbreviation of "favorite" and also the acronym of "for all versions". This package is intended to support all Node.js versions and many browsers as possible. At least, this package supports Node.js >= v0.10 and major Web browsers: Chrome, Firefox, IE11, Edge, Vivaldi and Safari.
Install
To install from npm:
$ npm install --save @fav/text.diff
NOTE: npm < 2.7.0 does not support scoped package, but even old version Node.js supports it. So when you use such older npm, you should download this package from github.com, and move it in node_modules/@fav/text.diff/
directory manually.
Usage
For Node.js:
var diff = require('@fav/text.diff');
diff('AB', 'ABC')
// => [{ type: 'a', src: { start: 2, end: 2 }, dest: { start: 2, end: 3 } }]
diff('ABC', 'BC')
// => [{ type: 'd', src: { start: 0, end: 1 }, dest: { start: 0, end: 0 } }]
diff('abc', 'adc')
// => [{ type: 'c', src: { start: 1, end: 2 }, dest: { start: 1, end: 2 } }]
For Web browsers:
<script src="fav.text.diff.min.js"></script>
<script>
var diff = fav.text.diff;
diff('AB', 'ABC')
// => [{ type: 'a', src: { start: 2, end: 2 }, dest: { start: 2, end: 3 } }]
diff('ABC', 'BC')
// => [{ type: 'd', src: { start: 0, end: 1 }, dest: { start: 0, end: 0 } }]
diff('abc', 'adc')
// => [{ type: 'c', src: { start: 1, end: 2 }, dest: { start: 1, end: 2 } }]
</script>
API
diff(srcText, destText [, opts]) => Array
Get differenece of two texts. The result is an array of edit infos from srcText to destText.
Parameter:
Parameter | Type | Description |
---|---|---|
srcText | string | A text before editing. |
destText | string | A text after editing. |
opts | object | comparing options. |
The comparing options are as follows:
Option | Type | Description |
---|---|---|
delimRe |
RegExp | A regular expression to split text blocks. If this option is not specified, this function splits and compares by characters. |
ignoreCase |
boolean | If true, this function compares text blocks with ignoring upper/lower case. |
normalizeSpaces |
boolean | If true, this function compares text blocks with replacing continuous whitespaces included them to one whitespace. |
Return:
The array of edit informations. The edit info is an object of which properties is as follows:
Property | Description |
---|---|
type |
The edit type. This property can have following values: 'a' (Adding), 'd' (Deleting), and 'c' (Changing). |
src |
The range of indexies in srcText to be editted. This is an object which has two indexes: start and end . |
dest |
The range of indexies in destText to be editted. This is an object which has two indexes: start and end . |
diff.lines(srcText, destText [, opts]) => Array
Get difference of two texts by line. The result is an array of edit infos from srcText to destText.
Parameter | Type | Description |
---|---|---|
srcText | string | A text before editing. |
destText | string | A text after editing. |
opts | object | comparing options. |
The comparing options are as follows:
Option | Type | Description |
---|---|---|
ignoreCase |
boolean | If true, this function compares text blocks with ignoring upper/lower case. |
normalizeSpaces |
boolean | If true, this function compares text blocks with replacing continuous whitespaces included them to one whitespace. |
Return:
The array of edit informations. The edit info is an object of which properties is as follows:
Property | Description |
---|---|
type |
The edit type. This property can have following values: 'a' (Adding), 'd' (Deleting), and 'c' (Changing). |
src |
The range of indexies in srcText to be editted. This is an object which has two indexes: start and end . |
dest |
The range of indexies in destText to be editted. This is an object which has two indexes: start and end . |
lines.src |
The range of line indexes in srcText to be editted. This is an object which has two line indexes: start and end . |
lines.dest |
The range of line indexes in destText to be editted. This is an object which has two line indexes: start and end . |
The line index is zero-based. The ways to get lines to be editted are as follows:
const srcText = 'aaa\nbbb\nccc\nddd';
const dstText = 'aaa\nbb\ncccc\ne\nddd';
diff.lines(srcText, dstText).forEach(d => {
const src = srcText.slice(d.src.start, d.src.end);
const dst = dstText.slice(d.dest.start, d.dest.end);
if (src) console.log('< ' + src.replace(/\n/g, '\n< '));
if (src && dst) console.log('---');
if (dst) console.log('> ' + dst.replace(/\n/g, '\n> '));
});
// => < bbb
// < ccc
// ---
// > bb
// > cccc
// > e
or
const srcText = 'aaa\nbbb\nccc\nddd';
const dstText = 'aaa\nbb\ncccc\ne\nddd';
diff.lines(srcText, dstText).forEach(d => {
const srcLines = srcText.split('\n')
.slice(d.lines.src.start, d.lines.src.end);
const dstLines = dstText.split('\n')
.slice(d.lines.dest.start, d.lines.dest.end);
console.log(srcLines.map(line => '< ' + line).join('\n'));
if (srcLines.length && dstLines.length) console.log('---');
console.log(dstLines.map(line => '> ' + line).join('\n'));
});
// => < bbb
// < ccc
// ---
// > bb
// > cccc
// > e
The way to get line numbers as in diff normal format is as follows:
const srcText = 'aaa\nbbb\nccc\nddd';
const dstText = 'aaa\nbb\ncccc\ne\nddd';
function getLineNo(range) {
if (range.start === range.end) return range.start; // Minus line index
var st = range.start + 1; // Plus start line index to start line No.
var ed = range.end; // Plus end line index to last line No.
if (st === ed) return st;
return st + ',' + ed;
}
diff.lines(srcText, dstText).forEach(d => {
console.log(getLineNo(d.lines.src) + d.type + getLineNo(d.lines.dest));
});
// => 2,3c2,4
Checked
Node.js (4〜12)
Platform | 11 | 12 |
---|---|---|
macOS | ◯ | ◯ |
Windows10 | ◯ | ◯ |
Linux | ◯ | ◯ |
Platform | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|
macOS | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ |
Windows10 | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ |
Linux | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ |
io.js (1〜3)
Platform | 1 | 2 | 3 |
---|---|---|---|
macOS | ◯ | ◯ | ◯ |
Windows10 | ◯ | ◯ | ◯ |
Linux | ◯ | ◯ | ◯ |
Node.js (〜0.12)
Platform | 0.8 | 0.9 | 0.10 | 0.11 | 0.12 |
---|---|---|---|---|---|
macOS | ◯ | ◯ | ◯ | ◯ | ◯ |
Windows10 | ◯ | ◯ | ◯ | ◯ | ◯ |
Linux | ◯ | ◯ | ◯ | ◯ | ◯ |
Web browsers
Platform | Chrome | Firefox | Vivaldi | Safari | Edge | IE11 |
---|---|---|---|---|---|---|
macOS | ◯ | ◯ | ◯ | ◯ | -- | -- |
Windows10 | ◯ | ◯ | ◯ | -- | ◯ | ◯ |
Linux | ◯ | ◯ | ◯ | -- | -- | -- |
License
Copyright (C) 2019 Takayuki Sato
This program is free software under MIT License. See the file LICENSE in this distribution for more details.