0.2.0 • Published 6 years ago

@fav/text.diff v0.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

@fav/text.diff NPM MIT License Build Status Build Status Coverage status

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:

ParameterTypeDescription
srcTextstringA text before editing.
destTextstringA text after editing.
optsobjectcomparing options.

The comparing options are as follows:

OptionTypeDescription
delimReRegExpA regular expression to split text blocks. If this option is not specified, this function splits and compares by characters.
ignoreCasebooleanIf true, this function compares text blocks with ignoring upper/lower case.
normalizeSpacesbooleanIf 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:

PropertyDescription
typeThe edit type. This property can have following values: 'a' (Adding), 'd' (Deleting), and 'c' (Changing).
srcThe range of indexies in srcText to be editted. This is an object which has two indexes: start and end.
destThe 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.

ParameterTypeDescription
srcTextstringA text before editing.
destTextstringA text after editing.
optsobjectcomparing options.

The comparing options are as follows:

OptionTypeDescription
ignoreCasebooleanIf true, this function compares text blocks with ignoring upper/lower case.
normalizeSpacesbooleanIf 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:

PropertyDescription
typeThe edit type. This property can have following values: 'a' (Adding), 'd' (Deleting), and 'c' (Changing).
srcThe range of indexies in srcText to be editted. This is an object which has two indexes: start and end.
destThe range of indexies in destText to be editted. This is an object which has two indexes: start and end.
lines.srcThe range of line indexes in srcText to be editted. This is an object which has two line indexes: start and end.
lines.destThe 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)

Platform1112
macOS
Windows10
Linux
Platform45678910
macOS
Windows10
Linux

io.js (1〜3)

Platform123
macOS
Windows10
Linux

Node.js (〜0.12)

Platform0.80.90.100.110.12
macOS
Windows10
Linux

Web browsers

PlatformChromeFirefoxVivaldiSafariEdgeIE11
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.

0.2.0

6 years ago

0.1.0

6 years ago