summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/guile/skribilo/package/diff.scm35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/guile/skribilo/package/diff.scm b/src/guile/skribilo/package/diff.scm
index 3aeed08..12eedb3 100644
--- a/src/guile/skribilo/package/diff.scm
+++ b/src/guile/skribilo/package/diff.scm
@@ -21,6 +21,7 @@
 (define-module (skribilo package diff)
   :use-module (differ)
   :use-module (srfi srfi-1)
+  :use-module (srfi srfi-14)
   :use-module (srfi srfi-39)
   :use-module (ice-9 optargs)
 
@@ -197,19 +198,45 @@
   ;; Return a list (actually an AST) denoting the differences between STR1
   ;; and STR2.  The returned text is actually that of STR2 augmented with
   ;; `insertion', `deletion', `replacement', and `unchanged' markup.
+
+  (define (space-preserving-substring str start end)
+    ;; Return the substring of STR, possibly inserting unbreakable spaces at
+    ;; the beginning/end if STR starts/ends in whitespaces.
+    (let ((len (- end start)))
+      (if (> len 0)
+          (let* ((lead (string-ref str start))
+                 (lead* (if (char-set-contains? char-set:whitespace
+                                                lead)
+                            (~)
+                            (string lead))))
+            (if (> len 1)
+                (let* ((trail (string-ref str (- end 1)))
+                       (trail* (if (char-set-contains? char-set:whitespace
+                                                       trail)
+                                   (~)
+                                   (string trail))))
+                  (list lead* (substring str (+ start 1) (- end 1))
+                        trail*))
+                (list lead* (substring str (+ start 1) end))))
+          "")))
+
   (reverse!
    (fold (lambda (edit result)
            (let ((start (cadr edit))
                  (end   (+ 1 (caddr edit))))
              (cons (case (car edit)
                      ((insertion)
-                      (insertion (substring str2 start end)))
+                      (insertion (space-preserving-substring str2 start
+                                                             end)))
                      ((deletion)
-                      (deletion  (substring str1 start end)))
+                      (deletion  (space-preserving-substring str1 start
+                                                             end)))
                      ((replacement)
-                      (replacement (substring str2 start end)))
+                      (replacement (space-preserving-substring str2 start
+                                                               end)))
                      ((unchanged)
-                      (unchanged (substring str2 start end))))
+                      (unchanged (space-preserving-substring str2 start
+                                                             end))))
                    result)))
          '()
          (string-diff-sequences str1 str2))))