Skip to content

Library to highlight the content difference between two HTML strings (htmldiff)

License

Notifications You must be signed in to change notification settings

Marc-Bernard-Tools/ABAP-HTML-Diff

Repository files navigation

Version

License Contributor Covenant REUSE Status

ABAP HTML Diff

Library to highlight the content difference between two HTML strings (htmldiff).

Made by Marc Bernard Tools giving back to the SAP Community

NO WARRANTIES, MIT License

HTML Diff

This is a diffing library that understands HTML. Best suited for cases when you want to show a diff of user-generated HTML.

An enhancement was made so the code can also produce the diff of two texts (tags are treated like text).

Prerequisites

SAP Basis 7.4 or higher

Installation

You can install ABAP Differ using abapGit either creating a new online repository for https://github.com/Marc-Bernard-Tools/ABAP-HTML-Diff or downloading the repository ZIP file and creating a new offline repository.

We recommend using package $HTMLDIFF.

Usage

Diffing HTML

The following produces the diff of two example HTML snippets:

DATA:
  lv_original TYPE string,
  lv_modified TYPE string,
  lv_diff     TYPE string,
  li_htmldiff TYPE REF TO zif_htmldiff.

lv_original = '\n'
  && '    <p>First paragraph.</p>\n'
  && '    <ul>\n'
  && '        <li>Item A</li>\n'
  && '        <li>Item B</li>\n'
  && '        <li>Item C</li>\n'
  && '    </ul>\n'
  && '    <img src="previous.jpg">\n'
  && '    <span>This is some interesting text.</span>\n'.

lv_modified = '\n'
  && '    <p>First paragraph.</p>\n'
  && '    <ul>\n'
  && '        <li>Item A</li>\n'
  && '        <li>Item B</li>\n'
  && '        <li>Item D</li>\n'
  && '    </ul>\n'
  && '    <img src="next.jpg">\n'
  && '    <span>This is some new text.</span>\n'.

REPLACE ALL OCCURRENCES OF '\n' IN lv_original WITH cl_abap_char_utilities=>newline.
REPLACE ALL OCCURRENCES OF '\n' IN lv_modified WITH cl_abap_char_utilities=>newline.
  
li_htmldiff = zcl_htmldiff=>create( ).
  
lv_diff = li_htmldiff->htmldiff(
  iv_before   = lv_original
  iv_after    = lv_modified
  iv_with_img = abap_false ).

Result:

    <p>First paragraph.</p>
    <ul>
        <li>Item A</li>
        <li>Item B</li>
        <li>Item <del>C</del><ins>D</ins></li>
    </ul>
    <img src='previous.jpg'><img src='next.jpg'>
    <span>This is some <del>interesting</del><ins>new</ins> text.</span>

By setting the image parameter to true, you can also mark changed images as deletions or insertions:

lv_diff = li_htmldiff->htmldiff(
  iv_before   = lv_original
  iv_after    = lv_modified
  iv_with_img = abap_true ).

Result:

    <p>First paragraph.</p>
    <ul>
        <li>Item A</li>
        <li>Item B</li>
        <li>Item <del>C</del><ins>D</ins></li>
    </ul>
    <del><img src='previous.jpg'></del><ins><img src='next.jpg'></ins>
    <span>This is some <del>interesting</del><ins>new</ins> text.</span>

There are a few other options you can set in the constructor/create statement:

  • iv_inserts: Show <ins> tags (default: on)
  • iv_deletes: Show <del> tags (default: on)
  • iv_css_classes: Add CSS classes to <ins> and <del> tags (default: off)
  • iv_support_chinese: Treat Chinese characters as individual words (default: off)

Using CSS classes, the result will distinguish between inserts (class diffins), deletes (class diffdel), and updates (class diffmod).

See the test classes for more examples.

Diffing Text

The following produces the diff of two example text snippets:

DATA:
  lv_original TYPE string,
  lv_modified TYPE string,
  lv_diff     TYPE string,
  li_htmldiff TYPE REF TO zif_htmldiff.

lv_original = 'a c'.

lv_modified = 'a b c'.

lv_diff = li_htmldiff->textdiff(
  iv_before = lv_original
  iv_after  = lv_modified ).

Result:

a <ins>b </ins>c

Example 2:

lv_original = 'a b c'.

lv_modified = 'a c'.

lv_diff = li_htmldiff->textdiff(
  iv_before = lv_original
  iv_after  = lv_modified ).

Result:

a <del>b </del>c

Styling

Here's an examle for styling the insertions and deletions using CSS.

/* CSS for <ins> and <del> tags */
ins { background-color: #ddffdd; }
ins img { border-color: #ddffdd; }

del { background-color: #ffdddd; }
del img { border-color: #ffdddd; }

With the CSS class option, use the following:

/* CSS for insert, delete, and modify classes */
.diffins { background-color: #ddffdd; }
.diffdel { background-color: #ffdddd; }
.diffmod { background-color: #ffffdd; }

Contributions

All contributions are welcome! Read our Contribution Guidelines, fork this repo, and create a pull request.

About

Made with ❤️ in Canada

Copyright 2021 Marc Bernard https://marcbernardtools.com/

Follow @marcfbe on Twitter

MBT Logo