text.diff
- Calculate difference of text streams ¶This module calculates the difference of two text streams or strings,
using util.lcs
(see util.lcs
- The longest common subsequence).
{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")))
{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
{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 util.lcs
- 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.
{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 gauche.test
- Unit Testing).