For Development HEAD DRAFTSearch (procedure/syntax/module):

Next: , Previous: , Up: Library modules - Utilities   [Contents][Index]

12.61 text.diff - Calculate difference of text streams

Module: text.diff

This module calculates the difference of two text streams or strings, using util.lcs (see The longest common subsequence).

Function: diff src-a src-b :key reader eq-fn

{text.diff} Generates an "edit list" from text sources src-a and src-b.

Each of text sources, src-a and src-b, can be either an input port or a string. If it is a string, it is converted to a string input port internally. Then, the text streams from both sources are converted to sequences by calling reader repeatedly on them; the default of reader is read-line, and those sequences are passed to lcs-edit-list to calculate the edit list. The equality function eq-fn is also passed to lcs-edit-list.

An edit list is a set of commands that turn the text sequence from src-a to the one from src-b. See the description of lcs-edit-list for the detailed explanation of the edit list.

(diff "a\nb\nc\nd\n" "b\ne\nd\nf\n")
⇒
  (((- 0 "a"))
   ((- 2 "c") (+ 1 "e"))
   ((+ 3 "f")))
Function: diff-report src-a src-b :key reader eq-fn writer

{text.diff} A convenience procedure to take the diff of two text sources and display the result nicely. This procedure calls lcs-fold to calculate the difference of two text sources. The meanings of src-a, src-b, reader and eq-fn are the same as diff’s.

Writer is a procedure that takes two arguments, the text element and a type, which is either a symbol +, a symbol -, or #f. If the text element is only in src-a, writer is called with the element and -. If the text element is only in src-b, it is called with the element and +. If the text element is in both sources, it is called with the element and #f. The default procedure of writer prints the passed text element to the current output port in unified-diff-like format:

(diff-report "a\nb\nc\nd\n" "b\ne\nd\nf\n")

displays:

- a
  b
- c
+ e
  d
+ f
Function: diff-report/context src-a src-b :key reader eq-fn writer context-size

{text.diff} Produce a human-friendly difference of two text sources like diff-report, but in the “context diff” format.

(diff-report/context "a\nb\nc\nd\n" "b\ne\nd\nf\n")

displays:

***************
*** 1,4 ****
- a
  b
! c
  d
--- 1,4 ----
  b
! e
  d
+ f

This calls lcs-edit-list/context to get a context diff of lines, then format it in the same way as diff -c output. (See The longest common subsequence, for the details of lcs-edit-list/context.)

Each “hunk” (a chunk containing difference) is preceded by a separater ***************, followed by the excerpt from src-a, then the excerpt form src-b, each preceded by the header showing the line number of that excerpts (start and end line, inclusive, 1-based).

In the excerpts, the line that’s deleted from src-a is prefixed with -, the line that’s inserted into src-b is prefixed with +, and the line changed is prefixed with !.

If the hunk only consists of either insertions or deletions, the other side of excerpt is omitted.

(diff-report/context "a\nb\nc\n" "a\nc\n")
 prints:
***************
*** 1,3 ****
  a
- b
  c
--- 1,2 ----

As a special case, if one of the source is empty, its header is shown as zero-th line:

(diff-report/context "" "a\nb\nc\n")
 prints:
***************
*** 0 ****
--- 1,3 ----
+ a
+ b
+ c

The reader, writer and eq-fn keyword arguments are the same as diff-report. The context-size keyword argument specifies the maximum unchanged lines attached to each hunk to show the context.

Function: diff-report/unified src-a src-b :key reader eq-fn writer context-size

{text.diff} Like diff-report/context, but use “unified diff” format, same as diff -u.

(diff-report/unified "a\nb\nc\nd\n" "a\nx\nd\n")
 prints:
@@ -1,4 +1,3 @@
 a
-b
-c
+x
 d

Each “hunk” begins with the header:

@@ -p,q +r,s @@

where p is the start line number in src-a, q is the length of the hunk in src-a, r is the start line number in src-b, and s is the length of the hunk in src-b.

The line-number is 1-based. If the length of the hunk is 1, it is omitted.

The lines deleted from src-a has - prefix, the ones inserted into src-b has + prefix, and unchanged lines has a space prefix.

As a special case, if either of sources is empty, both of its start index and length are shown as 0.

(diff-report/unified "a\nb\nc\n" "")
 prints:
@@ -1,3 +0,0 @@
-a
-b
-c

The reader, eq-fn, writer, and context-size keyword arguments are the same as diff-report/context.

This is used to show the difference of test results in test*/diff (see Unit testing).


Next: , Previous: , Up: Library modules - Utilities   [Contents][Index]


For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT