TextDiff XPages control – For visual comparison of text

A few years back I stumbled across Google’s diff-match-patch project which provides some handy algorithms for text manipulation. At the time of discovery I was doing ‘classic’ notes development. Although I probably could have implemented something that worked in lotuscript with RichText or Mime, it wasn’t a priority at the time and I never bothered.

Since then, I have been doing mainly XPages, and now that I have been also doing a bit of XPages Control development. I was mainly interested in the ‘diff’ algorithm so I decided the time was right to turn the diff algorithm into a useful XPages control, which takes 2 input strings and displays a visual difference between them.

The diff-match-patch algorithm / project is licenced under Apache Licence 2.0 so it is the same licence as most OpenNTF projects.

Overview

Basically the control takes a ‘from’ and ‘to’ input, and displays the visual diff. I guess it is best to show the example!

Here is some From and To Input that we will use for our examples. I have bound these textareas to viewScope ‘fromText’ and ‘toText’ but they could be bound to whatever text field you like

So then we will use the text diff like so:

Note the following picture is from my demo page so the actual output from the textdiff control is only what is inside the black box.

Algorithm parameters

For a good explanation of the algorithm parameters, I suggest you have a look at the google diff-match-patch webpage. But here is my best explanation!

  • cleanup – whether to perform some sort of cleanup to produce some more human readable results. I find ‘semantic’ is a good option
  • edit cost – only used for ‘efficiency’ cleanup
  • Timeout – don’t spend longer than this amount of seconds

Here is an example of output after changing the ‘cleanup’ option to ‘semantic’. Note that it has lengthened the change from single words to a longer run of words

Styling

The control has style and styleClass properties for the insert, delete and equals operations. Basically the control outputs a bunch of ‘<span>’s for each chunk of the diff operation. These outputs are either an insertion, a deletion or ‘equals’, and they have associated ‘insertStyle’ and ‘insertStyleClass’ properties.

Themable

All the above properties are themable. You can use the ‘Text.Diff’ control type to set properties for all textdiff controls or you can come up with a new ThemeId that can be applied as needed.

Here is an example using the following theme properties with a custom ThemeId

Installation

You have 2 choices

  • install my ‘Gregorbyte’ extension library
  • scavenge the necessary files from my github repo and install to your nsf

Install my Gregorbyte Extension Library

Go and get the latest release which should be an update site zip file.

Install this to your domino designer, and also to your domino server using your favourite update site method.

To Scavenge the necessary files from my github repo

You’ll need to put these java files in your Java section of your NSF:

  • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/component/UITextDiff.java
  • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/renderkit/TextDiffRenderer.java
  • /com.gregorbyte.xsp.controls/src/name/fraser/neil/plaintext/DiffMatchPatch.java

And this xsp-config (place in your WebContent/WEB-INF directory in you NSF using package explorer)

  • /com.gregorbyte.xsp.controls/src/com/gregorbyte/xsp/config/gregorbyte-textdiff.xsp-config

and add this entry to your faces-config.xml

Let me know if it works or doesn’t work in case I forgot something. I haven’t used this control heavily in production yet so there may be a bug here and there, please report it if so!

 

You may also like...

2 Responses

  1. Fredrik says:

    Can it do text diff with html content?

    • camerongregor says:

      Hi Fredrik, If you want the result to keep it’s html formatting, it might be tricky due to tags overlapping. I might give it a try to see the results and report back later.

      otherwise there are 2 options here

      1. do a diff of the actual html, where you can actually see tags as part of the diff. In this case no changes are needed, just
      2. do a diff of the ‘text’ only of the html, in this case, the control could pass the input through the ‘striptags’ html filter before performing the diff

Leave a Reply

Your email address will not be published. Required fields are marked *