rtfpessoa / diff2html

Pretty diff to html javascript library (diff2html)
https://diff2html.xyz
MIT License
2.87k stars 278 forks source link

Uncaught TypeError: diffInput.replace is not a function #202

Closed rickywu closed 5 years ago

rickywu commented 5 years ago

Seems this issue closed 3 years ago but I still got this error, download diff_match_patch.js from https://github.com/google/diff-match-patch and change path if needed

try this sample

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
  <TITLE>Diff, Match and Patch: Demo of Diff</TITLE>
  <SCRIPT SRC="./diff_match_patch.js"></SCRIPT>
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="./diff2html.css">

<!-- Javascripts -->
<script type="text/javascript" src="./diff2html.js"></script>
</HEAD>

<BODY>
<H1>Diff, Match and Patch</H1>
<H2>Demo of Diff</H2>

<P>Diff takes two texts and finds the differences.  This implementation works on a character by character basis.
The result of any diff may contain 'chaff', irrelevant small commonalities which complicate the output.
A post-diff cleanup algorithm factors out these trivial commonalities.</P>

<SCRIPT>
var dmp = new diff_match_patch();

function launch() {
  var text1 = document.getElementById('text1').value;
  var text2 = document.getElementById('text2').value;
  dmp.Diff_Timeout = parseFloat(document.getElementById('timeout').value);
  dmp.Diff_EditCost = parseFloat(document.getElementById('editcost').value);

  var ms_start = (new Date()).getTime();
  var d = dmp.diff_main(text1, text2, false);
  var ms_end = (new Date()).getTime();

  if (document.getElementById('semantic').checked) {
    dmp.diff_cleanupSemantic(d);
  }
  if (document.getElementById('efficiency').checked) {
    dmp.diff_cleanupEfficiency(d);
  }

  var diffHtml = Diff2Html.getPrettyHtml(
    d,
    {inputFormat: 'diff', showFiles: true, matching: 'lines', outputFormat: 'side-by-side'}
  );
  document.getElementById('outputdiv').innerHTML = diffHtml;

  /*var ds = dmp.diff_prettyHtml(d);
  document.getElementById('outputdiv').innerHTML = ds + '<BR>Time: ' + (ms_end - ms_start) / 1000 + 's';*/
}
</SCRIPT>

<FORM action="#" onsubmit="return false">
<TABLE WIDTH="100%"><TR>
  <TD WIDTH="50%">
<H3>Text Version 1:</H3>
<TEXTAREA ID="text1" STYLE="width: 100%" ROWS=10>I am the very model of a modern Major-General,
I've information vegetable, animal, and mineral,
I know the kings of England, and I quote the fights historical,
From Marathon to Waterloo, in order categorical.</TEXTAREA></TD>
  <TD WIDTH="50%">
<H3>Text Version 2:</H3>
<TEXTAREA ID="text2" STYLE="width: 100%" ROWS=10>I am the very model of a cartoon individual,
My animation's comical, unusual, and whimsical,
I'm quite adept at funny gags, comedic theory I have read,
From wicked puns and stupid jokes to anvils that drop on your head.</TEXTAREA></TD>
</TR></TABLE>

<H3>Diff timeout:</H3>
<P><INPUT TYPE="text" SIZE=3 MAXLENGTH=5 VALUE="1" ID="timeout"> seconds<BR>
If the mapping phase of the diff computation takes longer than this, then the computation
is truncated and the best solution to date is returned.  While guaranteed to be correct,
it may not be optimal.  A timeout of '0' allows for unlimited computation.</P>

<H3>Post-diff cleanup:</H3>
<DL>
<DT><INPUT TYPE="radio" NAME="cleanup" ID="semantic" CHECKED>
<LABEL FOR="semantic">Semantic Cleanup</LABEL></DT>
<DD>Increase human readability by factoring out commonalities which are likely to be
coincidental.</DD>
<DT><INPUT TYPE="radio" NAME="cleanup" ID="efficiency">
<LABEL FOR="efficiency">Efficiency Cleanup</LABEL>,
edit cost: <INPUT TYPE="text" SIZE=3 MAXLENGTH=5 VALUE="4" ID="editcost">
<DD>Increase computational efficiency by factoring out short commonalities which are
not worth the overhead.  The larger the edit cost, the more agressive the cleanup.</DD>
<DT><INPUT TYPE="radio" NAME="cleanup" ID="raw">
<LABEL FOR="raw">No Cleanup</LABEL></DT>
<DD>Raw output.</DD>
</DL>

<P><INPUT TYPE="button" onClick="launch()" VALUE="Compute Diff"></P>
</FORM>

<DIV ID="outputdiv"></DIV>

<HR>
Back to <A HREF="https://github.com/google/diff-match-patch">Diff, Match and Patch</A>

</BODY>
</HTML>
rtfpessoa commented 5 years ago

@rickywu what is the value of d?

rickywu commented 5 years ago

@rtfpessoa copy the code save as html and open it in browser, you can see the two texts and d is the diff from these two input box

rtfpessoa commented 5 years ago

@rickywu if it would be that easy I could have done it. Time is always short to help. In general as a generic note please provide as much information as possible to help other people instead of trying for them to fix your problems.

Still, after a quick look in the documentation of google/diff-match-patch it does not seem to provide a unified diff which is the required input for diff2html. You need to generate the output from other tool probably.

Check https://github.com/rtfpessoa/diff2html/issues/198 as an alternative. or look for another diff tool in npmjs.org

rickywu commented 5 years ago
    var dmp = new diff_match_patch();
    var a = dmp.diff_linesToChars_(firstDescribe, secondDescribe);
    var lineText1 = a.chars1;
    var lineText2 = a.chars2;
    var lineArray = a.lineArray;
    var diffs = dmp.diff_main(lineText1, lineText2, false);
    dmp.diff_charsToLines_(diffs, lineArray);
    console.info(diffs);
    let patchMake = dmp.patch_make(firstDescribe,diffs);
    let patchToText = dmp.patch_toText(patchMake);

Then patchToText can be used for diff2html

rtfpessoa commented 5 years ago

That should work

ghiscoding commented 3 months ago
    var dmp = new diff_match_patch();
    var a = dmp.diff_linesToChars_(firstDescribe, secondDescribe);
    var lineText1 = a.chars1;
    var lineText2 = a.chars2;
    var lineArray = a.lineArray;
    var diffs = dmp.diff_main(lineText1, lineText2, false);
    dmp.diff_charsToLines_(diffs, lineArray);
    console.info(diffs);
    let patchMake = dmp.patch_make(firstDescribe,diffs);
    let patchToText = dmp.patch_toText(patchMake);

Then patchToText can be used for diff2html

This was a great start but was not enough to get it fully working because Git diff seems to require having the 2 files being diffed at the start of the diff header. So with that in mind, I was able to get it working by prefixing the a and b files as shown below, it needs more tweaks for carriage return but it's a good start as you can see in the print screen below

  let patchToText = `diff --git a/file.txt b/file.txt
--- a/file.txt
+++ b/file.txt
`;

  patchToText += dmp.patch_make(text1Ref.value, diffs);

HTML Preview

image

EDIT

in the end, I found this Stack Overflow Create unified diff text for diff2html in browser and the answer to use jsdiff works a lot better and it's super short.

const diff = JSDiff.createTwoFilesPatch('file', 'file', text1Ref.value, text2Ref.value);
const diffHtml = html(diff, { drawFileList: true, matching: 'lines', outputFormat: 'side-by-side' });

which now gives the following, it's so much better with line number and everything :) image