Ejemplo n.º 1
1
 public static int GetLevel(string Source, string Destination)
 {
     Differ DiffMaker = new Differ();
     SideBySideDiffBuilder SideBySideDiffer = new SideBySideDiffBuilder(DiffMaker);
     SideBySideDiffModel SideBySideDiffResult = SideBySideDiffer.BuildDiffModel(Source, Destination);
     return GetLevel(SideBySideDiffResult, Source, Destination);
 }
        public ActionResult Index(int id, List<int> grSel) {
            var db = new ZkDataContext();
            var post = db.ForumPosts.Find(id);

            string txt1;
            string txt2;

            if (grSel != null && grSel.Any())
            {
                if (grSel.Count > 1)
                {
                    txt1 = db.ForumPostEdits.Find(grSel.Min()).NewText;
                    txt2 = db.ForumPostEdits.Find(grSel.Max()).NewText;
                } else
                {
                    var edit = db.ForumPostEdits.Find(grSel.First());
                    txt1 = edit.OriginalText;
                    txt2 = edit.NewText;
                }

                var sd = new SideBySideDiffBuilder(new Differ());
                ViewBag.DiffModel = sd.BuildDiffModel(txt1, txt2);
            } else
            {
                var edit = post.ForumPostEdits.OrderByDescending(x => x.ForumPostEditID).FirstOrDefault();
                if (edit != null)
                {
                    var sd = new SideBySideDiffBuilder(new Differ());
                    ViewBag.DiffModel = sd.BuildDiffModel(edit.OriginalText, edit.NewText);
                }
            }


            return View("PostHistoryIndex", post);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// measure differential between two files
        /// </summary>
        public static DiffCounter Count(
            string originalFile, string modifiedFile)
        {
            var original = File.ReadAllText(@originalFile);
            var modified = File.ReadAllText(@modifiedFile);

            var d = new Differ();
            var counter = new DiffCounter();
            var side = new SideBySideDiffBuilder(d);
            var result = side.BuildDiffModel(original, modified);

            // added, modified, and unmodified at modified file
            foreach (var line in result.NewText.Lines) {
                if (line.Type == ChangeType.Inserted) {
                    counter.AddedCount++;
                }
                if (line.Type == ChangeType.Modified) {
                    counter.ModifiedCount++;
                }
                if (line.Type == ChangeType.Unchanged) {
                    counter.EqualCount++;
                }
            }

            // deleted from original file
            foreach (var line in result.OldText.Lines) {
                if (line.Type == ChangeType.Deleted) {
                    counter.DeletedCount++;
                }
            }

            return counter;
        }
            public void Will_build_diffModel_for_duplicate_strings()
            {
                string text = "a\nb\nc\nd\n\n";
                string[] textLines = new[] {"a", "b", "c", "d", ""};
                var differ = new Mock<IDiffer>();
                differ.Setup(x => x.CreateLineDiffs(text, text, true))
                    .Returns(new DiffResult(textLines, textLines, new List<DiffBlock>()));
                differ.Setup(x => x.CreateWordDiffs(It.IsAny<string>(), It.IsAny<string>(), false, It.IsAny<char[]>()))
                    .Returns(new DiffResult(new string[0], new string[0], new List<DiffBlock>()));
                var builder = new SideBySideDiffBuilder(differ.Object);

                var bidiff = builder.BuildDiffModel(text, text);

                Assert.NotNull(bidiff);
                Assert.Equal(textLines.Length, bidiff.OldText.Lines.Count);
                Assert.Equal(textLines.Length, bidiff.NewText.Lines.Count);
                for (int i = 0; i < textLines.Length; i++)
                {
                    Assert.Equal(textLines[i], bidiff.OldText.Lines[i].Text);
                    Assert.Equal(ChangeType.Unchanged, bidiff.OldText.Lines[i].Type);
                    Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position);
                    Assert.Equal(textLines[i], bidiff.NewText.Lines[i].Text);
                    Assert.Equal(ChangeType.Unchanged, bidiff.NewText.Lines[i].Type);
                    Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position);
                }
            }
            public void Will_throw_is_NewText_is_null()
            {
                var differ = new Mock<IDiffer>();
                var builder = new SideBySideDiffBuilder(differ.Object);

                var ex = Record.Exception(() => builder.BuildDiffModel("asa", null));

                Assert.IsType<ArgumentNullException>(ex);
                var an = (ArgumentNullException) ex;
                Assert.Equal("newText", an.ParamName);
            }
Ejemplo n.º 6
0
        private void RunFileDiff(string fileA, string fileB)
        {
            var textA = LoadText(fileA);
            var textB = LoadText(fileB);

            var differ = new SideBySideDiffBuilder(new Differ());
            var diffResult = differ.BuildDiffModel(textA, textB);

            var formattedData = _formatter.Format(diffResult);
            _writer.Write(formattedData);
        }
Ejemplo n.º 7
0
 internal static string[] DoSideBySideDiff(string SourceText, string DestinationText)
 {
     string[] Result = new string[3];
     Differ DiffMaker = new Differ();
     SideBySideDiffBuilder SideBySideDiffer = new SideBySideDiffBuilder(DiffMaker);
     SideBySideDiffModel SideBySideDiffResult = SideBySideDiffer.BuildDiffModel(SourceText, DestinationText);
     int DiffLevel = IronDiffer.GetLevel(SideBySideDiffResult, SourceText, DestinationText);
     Result[0] = FullDiff(SideBySideDiffResult.OldText.Lines);
     Result[1] = FullDiff(SideBySideDiffResult.NewText.Lines);
     Result[2] = DiffLevel.ToString();
     return Result;
 }
        public SideBySideFlowDocumentDiffGenerator(string leftText, string rightText)
        {
            Initialise();

            var differ = new SideBySideDiffBuilder(new Differ());
            var diffRes = differ.BuildDiffModel(leftText, rightText);

            LeftDocument = GenerateFlowDocument(diffRes.OldText);
            RightDocument = GenerateFlowDocument(diffRes.NewText);

            FirstModifiedLineVerticalOffset = diffRes.OldText.Lines.FindIndex(l => l.Type != ChangeType.Unchanged)*_lineHeight;
        }
Ejemplo n.º 9
0
        public void GenerateDiffView()
        {
            if (_inDiff) return;
            lock (_mutex)
            {
                if (_inDiff) return;
                _inDiff = true;
            }

            _differ = new SideBySideDiffBuilder(new Differ());

            var diffRes = _differ.BuildDiffModel(_leftText, _rightText);

            FirstModifiedLine = diffRes.NewText.Lines.FindIndex(l => l.Type != ChangeType.Unchanged);
            GenerateDiffPanes(diffRes.OldText, diffRes.NewText);

            _inDiff = false;
        }
            public void Will_pass_correct_word_separators_to_create_word_diff()
            {
                string text = "a\nb\nc\nd\n\n";
                string[] textLines = new[] {"a", "b", "c", "d", ""};
                char[] chars = null;
                var differ = new Mock<IDiffer>();
                differ.Setup(x => x.CreateLineDiffs(text, text, true))
                    .Returns(new DiffResult(textLines, textLines, new List<DiffBlock> {new DiffBlock(1, 1, 1, 1)}));
                differ.Setup(x => x.CreateWordDiffs(It.IsAny<string>(), It.IsAny<string>(), false, It.IsAny<char[]>()))
                    .Returns(new DiffResult(new string[0], new string[0], new List<DiffBlock>()))
                    .Callback<string, string, bool, char[]>((a, b, c, d) => chars = d);
                var builder = new SideBySideDiffBuilder(differ.Object);

                builder.BuildDiffModel(text, text);

                Assert.Equal(SideBySideDiffBuilder.WordSeparaters.Length, chars.Length);
                foreach (var c in SideBySideDiffBuilder.WordSeparaters)
                {
                    Assert.Contains(c, chars);
                }
            }
            public void Will_build_diffModel_when_newText_is_empty()
            {
                string textNew = "";
                string textOld = "z\ny\nx\nw\n";
                string[] textLinesNew = new string[] {};
                string[] textLinesOld = new[] {"z", "y"};
                var differ = new Mock<IDiffer>();
                differ.Setup(x => x.CreateLineDiffs(textOld, textNew, true))
                    .Returns(new DiffResult(textLinesOld, textLinesNew, new List<DiffBlock> {new DiffBlock(0, 2, 0, 0)}));
                var builder = new SideBySideDiffBuilder(differ.Object);

                var bidiff = builder.BuildDiffModel(textOld, textNew);

                Assert.NotNull(bidiff);
                Assert.Equal(2, bidiff.OldText.Lines.Count);
                Assert.Equal(2, bidiff.NewText.Lines.Count);

                for (int j = 0; j < textLinesOld.Length; j++)
                {
                    Assert.Equal(textLinesOld[j], bidiff.OldText.Lines[j].Text);
                    Assert.Equal(ChangeType.Deleted, bidiff.OldText.Lines[j].Type);
                    Assert.Equal(j + 1, bidiff.OldText.Lines[j].Position);

                    Assert.Null(bidiff.NewText.Lines[j].Text);
                    Assert.Equal(ChangeType.Imaginary, bidiff.NewText.Lines[j].Type);
                    Assert.False(bidiff.NewText.Lines[j].Position.HasValue);
                }
            }
Ejemplo n.º 12
0
        public virtual ActionResult Diff(string folderName, string parentFolder, string uuid, int v1, int v2)
        {
            TextFolder textFolder = new TextFolder(Repository, folderName).AsActual();
            var schema = textFolder.GetSchema().AsActual();

            var textContent = schema.CreateQuery().WhereEquals("UUID", uuid).FirstOrDefault();

            var version1 = VersionManager.GetVersion(textContent, v1);
            var version1Content = new TextContent(version1.TextContent);
            var version2 = VersionManager.GetVersion(textContent, v2);
            var version2Content = new TextContent(version2.TextContent);

            var sideBySideDiffBuilder = new SideBySideDiffBuilder(new Differ());

            var model = new TextContentDiffModel() { UUID = uuid, Version1Name = v1, Version2Name = v2 };

            foreach (var k in textContent.Keys)
            {
                var version1Text = version1Content[k] != null ? version1Content[k].ToString() : "";

                var version2Text = version2Content[k] != null ? version2Content[k].ToString() : "";

                var diffModel = sideBySideDiffBuilder.BuildDiffModel(version1Text, version2Text);

                model.Version1.Add(k, diffModel.OldText);
                model.Version2.Add(k, diffModel.NewText);

            }

            return View(model);
        }
Ejemplo n.º 13
0
        // 创建展示两个 OPAC 记录差异的 HTML 字符串
        // parameters:
        //      strNewText  如果为 "",表示内容全部被删除,依然会输出对照格式;如果为 null,表示只输出左边的部分
        // return:
        //      -1  出错
        //      0   成功。两边相等
        //      1   两边不相等
        public static int DiffOpacHtml(
            string strOldText,
            string strNewText,
            out string strHtml,
            out string strError)
        {
            strError = "";
            strHtml = "";

            if (string.IsNullOrEmpty(strOldText) == true && string.IsNullOrEmpty(strNewText) == true)
                return 0;

            var marc_differ = new Differ();
            var marc_builder = new SideBySideDiffBuilder(marc_differ);
            var marc_diff_result = marc_builder.BuildDiffModel(strOldText, 
                strNewText == null? "" : strNewText);

            Debug.Assert(marc_diff_result.OldText.Lines.Count == marc_diff_result.NewText.Lines.Count, "");

            /*
    public enum ChangeType
    {
        Unchanged,
        Deleted,
        Inserted,
        Imaginary,
        Modified
    }
             * */

            bool bChanged = false;

            StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096);

            for (int index = 0; index < marc_diff_result.NewText.Lines.Count; index++)
            {
                var newline = marc_diff_result.NewText.Lines[index];
                var oldline = marc_diff_result.OldText.Lines[index];

                if (string.IsNullOrEmpty(newline.Text) == true
                    && string.IsNullOrEmpty(oldline.Text) == true)
                    continue;

                if (oldline.Type != ChangeType.Unchanged
                    || newline.Type != ChangeType.Unchanged)
                    bChanged = true;

                string strLineClass = "datafield";
                if (strNewText == null)
                {
                    strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                    // 创建一个字段的 HTML 局部 三个 <td>
                    strResult.Append(BuildOpacFieldHtml(ChangeType.Unchanged, oldline.Text));
                    strResult.Append("\r\n</tr>");
                    continue;
                }

                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                // 创建一个字段的 HTML 局部 三个 <td>
                strResult.Append(BuildOpacFieldHtml(oldline.Type, oldline.Text));
                strResult.Append(SEP);
                strResult.Append(BuildOpacFieldHtml(newline.Type, newline.Text));
                strResult.Append("\r\n</tr>");
            }

            strResult.Append("</table>");
            strHtml = strResult.ToString();

            if (bChanged == false)
                return 0;

            return 1;
        }
Ejemplo n.º 14
0
        static string DiffXml(
            int nLevel,
            string strOldFragmentXml,
            XmlNodeType old_nodetype,
            string strNewFragmentXml,
            XmlNodeType new_nodetype)
        {
            if (string.IsNullOrEmpty(strOldFragmentXml) == true && string.IsNullOrEmpty(strNewFragmentXml) == true)
                return "";

            if (old_nodetype != XmlNodeType.Element || new_nodetype != XmlNodeType.Element)
            {
                if (old_nodetype == XmlNodeType.Element)
                    strOldFragmentXml = GetIndentXml(strOldFragmentXml);
                if (new_nodetype == XmlNodeType.Element)
                    strNewFragmentXml = GetIndentXml(strNewFragmentXml);
                return GetPlanTextDiffHtml(
                    nLevel,
                    strOldFragmentXml,
                    strNewFragmentXml);
            }

            string strOldChildren = "";
            string strOldBegin = "";
            string strOldEnd = "";
            List<XmlNode> old_childnodes = null;
            string strOldElementName = "";
            GetComparableXmlString(strOldFragmentXml,
                out strOldChildren,
                out old_childnodes,
                out strOldElementName,
                out strOldBegin,
                out strOldEnd);

            string strNewChildren = "";
            string strNewBegin = "";
            string strNewEnd = "";
            List<XmlNode> new_childnodes = null;
            string strNewElementName = "";
            GetComparableXmlString(strNewFragmentXml,
                out strNewChildren,
                out new_childnodes,
                out strNewElementName,
                out strNewBegin,
                out strNewEnd);

            bool bSpecialCompare = false;   // 是否属于特殊情况: 根元素名不相同,但仍需要比较下级
            if (strOldElementName != strNewElementName
                && nLevel == 0)
                bSpecialCompare = true;

            if (strOldElementName != strNewElementName && bSpecialCompare == false)
            {
                // 元素名不一样了并且不是根级别,就没有必要做细节比较了
                // 意思是说如果是根级别,即便根元素名不一样,也要比较其下级
                if (old_nodetype == XmlNodeType.Element)
                    strOldFragmentXml = GetIndentXml(strOldFragmentXml);
                if (new_nodetype == XmlNodeType.Element)
                    strNewFragmentXml = GetIndentXml(strNewFragmentXml);
                return GetPlanTextDiffHtml(
    nLevel,
    strOldFragmentXml,
    strNewFragmentXml);
            }

            string strLineClass = "datafield";
            StringBuilder strResult = new StringBuilder(4096);

            if (nLevel > 0 || bSpecialCompare == true)
            {
                ChangeType begin_type = ChangeType.Unchanged;
                if (strOldBegin != strNewBegin)
                    begin_type = ChangeType.Modified;

                // Begin
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                strResult.Append(BuildFragmentFieldHtml(nLevel, begin_type, strOldBegin));
                strResult.Append(SEP);
                strResult.Append(BuildFragmentFieldHtml(nLevel, begin_type, strNewBegin));
                strResult.Append("\r\n</tr>");
            }

            // return "\r\n<td class='content' colspan='3'></td>";

            if (string.IsNullOrEmpty(strOldChildren) == false || string.IsNullOrEmpty(strNewChildren) == false)
            {
                var xml_differ = new Differ();
                var xml_builder = new SideBySideDiffBuilder(xml_differ);
                var xml_diff_result = xml_builder.BuildDiffModel(strOldChildren, strNewChildren);

                Debug.Assert(xml_diff_result.OldText.Lines.Count == xml_diff_result.NewText.Lines.Count, "");
                int old_index = 0;
                int new_index = 0;
                for (int index = 0; index < xml_diff_result.NewText.Lines.Count; index++)
                {
                    var newline = xml_diff_result.NewText.Lines[index];
                    var oldline = xml_diff_result.OldText.Lines[index];

                    XmlNode new_node = null;
                    if (newline.Type != ChangeType.Imaginary)
                        new_node = new_childnodes[new_index++];

                    XmlNode old_node = null;
                    if (oldline.Type != ChangeType.Imaginary)
                        old_node = old_childnodes[old_index++];

                    if (newline.Type == ChangeType.Modified)
                    {
                        strResult.Append(DiffXml(nLevel + 1,
                            oldline.Text,
                            old_node.NodeType,
                            newline.Text,
                            new_node.NodeType));
                        continue;
                    }

                    string strOldText = "";
                    if (old_node != null && old_node.NodeType == XmlNodeType.Element)
                        strOldText = GetIndentXml(oldline.Text);
                    else 
                        strOldText = oldline.Text;

                    string strNewText = "";
                    if (new_node != null && new_node.NodeType == XmlNodeType.Element)
                        strNewText = GetIndentXml(newline.Text);
                    else
                        strNewText = newline.Text;

                    strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                    // 创建一个 XML 字段的 HTML 局部 三个 <td>
                    strResult.Append(BuildFragmentFieldHtml(nLevel + 1, oldline.Type, strOldText));
                    strResult.Append(SEP);
                    strResult.Append(BuildFragmentFieldHtml(nLevel + 1, newline.Type, strNewText));
                    strResult.Append("\r\n</tr>");
                }
            }

            if (nLevel > 0 || bSpecialCompare == true)
            {
                ChangeType end_type = ChangeType.Unchanged;
                if (strOldEnd != strNewEnd)
                    end_type = ChangeType.Modified;

                // End
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                strResult.Append(BuildFragmentFieldHtml(nLevel, end_type, strOldEnd));
                strResult.Append(SEP);
                strResult.Append(BuildFragmentFieldHtml(nLevel, end_type, strNewEnd));
                strResult.Append("\r\n</tr>");
            }

            return strResult.ToString();
        }
            public void Will_build_diffModel_for_partially_different_documents()
            {
                string textOld = "1\n2\na\nb\nc\nd\n\n";
                string textNew = "1\n2\nz\ny\nx\nw\n";
                string[] textLinesOld = new[] {"1", "2", "a", "b", "c", "d", ""};
                string[] textLinesNew = new[] {"1", "2", "z", "y", "x", "w"};
                var differ = new Mock<IDiffer>();
                differ.Setup(x => x.CreateLineDiffs(textOld, textNew, true))
                    .Returns(new DiffResult(textLinesOld, textLinesNew, new List<DiffBlock> {new DiffBlock(2, 5, 2, 4)}));
                differ.Setup(x => x.CreateWordDiffs(It.IsAny<string>(), It.IsAny<string>(), false, It.IsAny<char[]>()))
                    .Returns(new DiffResult(new string[0], new string[0], new List<DiffBlock>()));
                var builder = new SideBySideDiffBuilder(differ.Object);

                var bidiff = builder.BuildDiffModel(textOld, textNew);

                Assert.NotNull(bidiff);
                Assert.Equal(7, bidiff.OldText.Lines.Count);
                Assert.Equal(7, bidiff.NewText.Lines.Count);
                int i = 0;
                for (; i < 2; i++)
                {
                    Assert.Equal(textLinesNew[i], bidiff.NewText.Lines[i].Text);
                    Assert.Equal(ChangeType.Unchanged, bidiff.NewText.Lines[i].Type);
                    Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position);

                    Assert.Equal(textLinesOld[i], bidiff.OldText.Lines[i].Text);
                    Assert.Equal(ChangeType.Unchanged, bidiff.OldText.Lines[i].Type);
                    Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position);
                }

                for (; i < Math.Min(textLinesOld.Length, textLinesNew.Length); i++)
                {
                    Assert.Equal(textLinesOld[i], bidiff.OldText.Lines[i].Text);
                    Assert.Equal(ChangeType.Modified, bidiff.OldText.Lines[i].Type);
                    Assert.Equal(i + 1, bidiff.OldText.Lines[i].Position);

                    Assert.Equal(textLinesNew[i], bidiff.NewText.Lines[i].Text);
                    Assert.Equal(ChangeType.Modified, bidiff.NewText.Lines[i].Type);
                    Assert.Equal(i + 1, bidiff.NewText.Lines[i].Position);
                }

                if (textLinesOld.Length < textLinesNew.Length)
                {
                    for (int j = i; j < textLinesNew.Length; j++)
                    {
                        Assert.Equal(textLinesNew[j], bidiff.NewText.Lines[j].Text);
                        Assert.Equal(ChangeType.Inserted, bidiff.NewText.Lines[j].Type);
                        Assert.Equal(j + 1, bidiff.NewText.Lines[j].Position);

                        Assert.Null(bidiff.OldText.Lines[j].Text);
                        Assert.Equal(ChangeType.Imaginary, bidiff.OldText.Lines[j].Type);
                        Assert.False(bidiff.OldText.Lines[j].Position.HasValue);
                    }
                }
                else
                {
                    for (int j = i; j < textLinesOld.Length; j++)
                    {
                        Assert.Equal(textLinesOld[j], bidiff.OldText.Lines[j].Text);
                        Assert.Equal(ChangeType.Deleted, bidiff.OldText.Lines[j].Type);
                        Assert.Equal(j + 1, bidiff.OldText.Lines[j].Position);

                        Assert.Null(bidiff.NewText.Lines[j].Text);
                        Assert.Equal(ChangeType.Imaginary, bidiff.NewText.Lines[j].Type);
                        Assert.False(bidiff.NewText.Lines[j].Position.HasValue);
                    }
                }
            }
Ejemplo n.º 16
0
        public async Task<ActionResult> CompareBlobs(Errorable<BlobID.Partial> epida, Errorable<BlobID.Partial> epidb)
        {
            if (epida.HasErrors || epidb.HasErrors) return Json(new { errors = (epida.Errors + epidb.Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            // Resolve the partial IDs:
            var eids = await cms.blrepo.ResolvePartialIDs(epida.Value, epidb.Value);
            if (eids[0].HasErrors || eids[1].HasErrors) return Json(new { errors = (eids[0].Errors + eids[1].Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            BlobID idA = eids[0].Value;
            BlobID idB = eids[1].Value;

            // Get the Blobs:
            var ebls = await cms.blrepo.GetBlobs(idA, idB);
            if (ebls[0].HasErrors || ebls[1].HasErrors) return Json(new { errors = (ebls[0].Errors + ebls[1].Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            IStreamedBlob blA = ebls[0].Value, blB = ebls[1].Value;

            // Stream in both blobs' contents to string values:
            var etextA = await blA.ReadStreamAsync<string>(async st => { using (var sr = new StreamReader(st, Encoding.UTF8)) return (Errorable<string>)await sr.ReadToEndAsync(); });
            if (etextA.HasErrors) return ErrorJson(etextA);
            
            var etextB = await blB.ReadStreamAsync<string>(async st => { using (var sr = new StreamReader(st, Encoding.UTF8)) return (Errorable<string>)await sr.ReadToEndAsync(); });
            if (etextB.HasErrors) return ErrorJson(etextB);

            // TODO: update to a better diff engine that supports merging...

            // Create a diff engine:
            IDiffer differ = new Differ();
            ISideBySideDiffBuilder builder = new SideBySideDiffBuilder(differ);

            // Run the diff engine to get the output model:
            // NOTE: I would prefer it to read in via a Stream but perhaps that is not possible given the algorithm implemented.
            var sxs = builder.BuildDiffModel(etextA.Value, etextB.Value);

            // Return the result as JSON:
            return Json(sxs.ToJSON(), JsonRequestBehavior.AllowGet);
        }
Ejemplo n.º 17
0
 public static SideBySideDiffModel GetDiff(string Source, string Destination)
 {
     Differ DiffMaker = new Differ();
     SideBySideDiffBuilder SideBySideDiffer = new SideBySideDiffBuilder(DiffMaker);
     return SideBySideDiffer.BuildDiffModel(Source, Destination);
 }
            public void Will_build_diffModel_for_partially_different_lines()
            {
                string textOld = "m is h";
                string textNew = "m ai is n h";
                string[] textLinesOld = new[] {"m is h"};
                string[] textLinesNew = new[] {"m ai is n h"};
                var differ = new Mock<IDiffer>();
                differ.Setup(x => x.CreateLineDiffs(textOld, textNew, true))
                    .Returns(new DiffResult(textLinesOld, textLinesNew, new List<DiffBlock> {new DiffBlock(0, 1, 0, 1)}));
                differ.Setup(x => x.CreateWordDiffs(It.IsAny<string>(), It.IsAny<string>(), false, It.IsAny<char[]>()))
                    .Returns(new DiffResult(
                                 new[] {"m ", "is ", "h"},
                                 new[] {"m ", "ai ", "is ", "n ", "h"},
                                 new List<DiffBlock> {new DiffBlock(1, 0, 1, 1), new DiffBlock(3, 0, 3, 1)}));
                var builder = new SideBySideDiffBuilder(differ.Object);

                var bidiff = builder.BuildDiffModel(textOld, textNew);

                Assert.NotNull(bidiff);
                Assert.Equal(1, bidiff.OldText.Lines.Count);
                Assert.Equal(1, bidiff.NewText.Lines.Count);
                Assert.Equal(bidiff.NewText.Lines[0].SubPieces[0].Type, ChangeType.Unchanged);
                Assert.Equal(bidiff.NewText.Lines[0].SubPieces[1].Type, ChangeType.Inserted);
                Assert.Equal(bidiff.NewText.Lines[0].SubPieces[2].Type, ChangeType.Unchanged);
                Assert.Equal(bidiff.NewText.Lines[0].SubPieces[3].Type, ChangeType.Inserted);
                Assert.Equal(bidiff.NewText.Lines[0].SubPieces[4].Type, ChangeType.Unchanged);

                Assert.Equal(bidiff.OldText.Lines[0].SubPieces[0].Type, ChangeType.Unchanged);
                Assert.Equal(bidiff.OldText.Lines[0].SubPieces[1].Type, ChangeType.Imaginary);
                Assert.Equal(bidiff.OldText.Lines[0].SubPieces[2].Type, ChangeType.Unchanged);
                Assert.Equal(bidiff.OldText.Lines[0].SubPieces[3].Type, ChangeType.Imaginary);
                Assert.Equal(bidiff.OldText.Lines[0].SubPieces[4].Type, ChangeType.Unchanged);
            }
Ejemplo n.º 19
-2
        // 创建展示两个 MARC 记录差异的 HTML 字符串
        // return:
        //      -1  出错
        //      0   成功
        public static int DiffHtml(
            string strOldTitle,
            string strOldMarc,
            string strOldFragmentXml,
            string strOldImageFragment,
            string strNewTitle,
            string strNewMarc,
            string strNewFragmentXml,
            string strNewImageFragment,
            out string strHtml,
            out string strError)
        {
            strError = "";
            strHtml = "";
            // int nRet = 0;

            if (string.IsNullOrEmpty(strOldMarc) == true && string.IsNullOrEmpty(strNewMarc) == true)
                return 0;

            string strOldHeader = "";
            string strNewHeader = "";
            string strOldBody = "";
            string strNewBody = "";

            SplitMarc(strOldMarc,
                out strOldHeader,
                out strOldBody);
            SplitMarc(strNewMarc,
                out strNewHeader,
                out strNewBody);

            if (strOldHeader.Length < 24)
                strOldHeader = strOldHeader.PadRight(24, '?');
            if (strNewHeader.Length < 24)
                strNewHeader = strNewHeader.PadRight(24, '?');

            var marc_differ = new MarcDiffer();
            var marc_builder = new MarcDiffBuilder(marc_differ);
            var marc_diff_result = marc_builder.BuildDiffModel(strOldBody, strNewBody);

            Debug.Assert(marc_diff_result.OldText.Lines.Count == marc_diff_result.NewText.Lines.Count, "");

            /*
    public enum ChangeType
    {
        Unchanged,
        Deleted,
        Inserted,
        Imaginary,
        Modified
    }
             * */

            StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096);

            if (string.IsNullOrEmpty(strOldTitle) == false
                || string.IsNullOrEmpty(strNewTitle) == false)
            {
                string strLineClass = "header";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(BuildHeaderHtml(false, strOldTitle));
                strResult.Append(SEP);
                strResult.Append(BuildHeaderHtml(false, strNewTitle));
                strResult.Append("\r\n</tr>");
            }


            {
                string strLineClass = "header";
                bool bModified = strOldHeader != strNewHeader;
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(BuildHeaderHtml(bModified, strOldHeader));
                strResult.Append(SEP);
                strResult.Append(BuildHeaderHtml(bModified, strNewHeader));
                strResult.Append("\r\n</tr>");
            }

            if (string.IsNullOrEmpty(strOldImageFragment) == false
|| string.IsNullOrEmpty(strNewImageFragment) == false)
            {
                string strLineClass = "header";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(GetImageHtml(strOldImageFragment));
                strResult.Append(SEP);
                strResult.Append(GetImageHtml(strNewImageFragment));
                strResult.Append("\r\n</tr>");
            }


            for (int index = 0; index < marc_diff_result.NewText.Lines.Count; index++)
            {
                var newline = marc_diff_result.NewText.Lines[index];
                var oldline = marc_diff_result.OldText.Lines[index];

                if (string.IsNullOrEmpty(newline.Text) == true
                    && string.IsNullOrEmpty(oldline.Text) == true)
                    continue;

                string strLineClass = "datafield";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                // 创建一个字段的 HTML 局部 三个 <td>
                strResult.Append(BuildFieldHtml( oldline.Type, oldline.Text));
                strResult.Append(SEP);
                strResult.Append(BuildFieldHtml(newline.Type, newline.Text));
                strResult.Append("\r\n</tr>");

#if NO
                if (newline.Type == ChangeType.Unchanged)
                {

                }
                else if (newline.Type == ChangeType.Inserted)
                {

                }
                else if (newline.Type == ChangeType.Modified)
                {

                }
                else if (oldline.Type == ChangeType.Deleted)
                {

                }
#endif
            }

#if NO
            if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false)
            {
                var xml_differ = new Differ();
                var xml_builder = new SideBySideDiffBuilder(xml_differ);
                var xml_diff_result = xml_builder.BuildDiffModel(GetComparableXmlString(strOldFragmentXml), GetComparableXmlString(strNewFragmentXml));

                Debug.Assert(xml_diff_result.OldText.Lines.Count == xml_diff_result.NewText.Lines.Count, "");

                for (int index = 0; index < xml_diff_result.NewText.Lines.Count; index++)
                {
                    var newline = xml_diff_result.NewText.Lines[index];
                    var oldline = xml_diff_result.OldText.Lines[index];

                    string strLineClass = "datafield";

                    if (newline.Type == ChangeType.Modified)
                    {

                    }

                    strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                    // 创建一个 XML 字段的 HTML 局部 三个 <td>
                    strResult.Append(BuildFragmentFieldHtml(oldline.Type, oldline.Text));
                strResult.Append(SEP);
                    strResult.Append(BuildFragmentFieldHtml(newline.Type, newline.Text));
                    strResult.Append("\r\n</tr>");
                }

            }
#endif

            if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false)
            {
                string strLineClass = "sepline";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                strResult.Append("<td class='sepline' colspan='3'>&nbsp;</td>");
                strResult.Append("<td class='cross'>&nbsp;</td>");
                strResult.Append("<td class='sepline' colspan='3'>&nbsp;</td>");
                strResult.Append("\r\n</tr>");
            }

            strResult.Append(DiffXml(
                0,
                strOldFragmentXml,
                XmlNodeType.Element,
                strNewFragmentXml,
                XmlNodeType.Element));

            strResult.Append("</table>");
            strHtml = strResult.ToString();

            return 0;
        }