3e34737c4a7e

Fix wrapping for indented lines of multiline strings inside lists
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sun, 17 Nov 2019 18:24:52 -0500
parents a9ab8d792a4d
children 1625b5eda50f
branches/tags (none)
files bobbin.asd docs/03-changelog.markdown src/main.lisp test/tests.lisp

Changes

--- a/bobbin.asd	Thu Mar 07 12:44:55 2019 -0500
+++ b/bobbin.asd	Sun Nov 17 18:24:52 2019 -0500
@@ -4,7 +4,7 @@
   :homepage "https://sjl.bitbucket.io/bobbin/"
 
   :license "MIT"
-  :version "1.0.0"
+  :version "1.0.1"
 
   :depends-on (:split-sequence)
 
--- a/docs/03-changelog.markdown	Thu Mar 07 12:44:55 2019 -0500
+++ b/docs/03-changelog.markdown	Sun Nov 17 18:24:52 2019 -0500
@@ -5,6 +5,12 @@
 
 [TOC]
 
+v1.0.1
+------
+
+Fixed a bug that caused indented lines inside of multiline strings to be
+incorrectly wrapped.
+
 v1.0.0
 ------
 
--- a/src/main.lisp	Thu Mar 07 12:44:55 2019 -0500
+++ b/src/main.lisp	Sun Nov 17 18:24:52 2019 -0500
@@ -50,9 +50,18 @@
 
 (defun wrap-lines (strings width)
   "Wrap a list of `strings` to `width`, returning a list of strings."
-  (mapcan (lambda (string)
-            (split-sequence:split-sequence #\newline (wrap-line string width)))
-          strings))
+  ;; This is mildly tricky because we want to correctly handle indented lines
+  ;; inside of multiline strings inside the list.
+  (let ((lines (mapcan
+                 ;; Split and flatten any multiline strings in the list first.
+                 (lambda (string)
+                   (split-sequence:split-sequence #\newline string))
+                 strings)))
+    (mapcan
+      ;; Then wrap each string in the list and flatten the results.
+      (lambda (line)
+        (split-sequence:split-sequence #\newline (wrap-line line width)))
+      lines)))
 
 (defun wrap-string (string width)
   "Wrap a multi-line string, returning a multi-line string."
--- a/test/tests.lisp	Thu Mar 07 12:44:55 2019 -0500
+++ b/test/tests.lisp	Sun Nov 17 18:24:52 2019 -0500
@@ -11,11 +11,14 @@
 (defun run-tests ()
   (1am:run))
 
+(defun f (&rest args)
+  (apply #'format nil args))
+
 (defmacro check (input width result)
   (if (stringp input)
     `(is (string= (format nil ,result)
-                  (bobbin:wrap (format nil ,input) ,width)))
-    `(is (equal ',result (bobbin:wrap ',input ,width)))))
+                  (bobbin:wrap (f ,input) ,width)))
+    `(is (equal ',result (bobbin:wrap (mapcar #'f ',input) ,width)))))
 
 
 ;;;; Tests --------------------------------------------------------------------
@@ -62,7 +65,9 @@
 
 (define-test indentation
   (check "   foo~% bar" 50 "   foo~% bar")
-  (check "            foo          bar" 3 "foo~%bar"))
+  (check "            foo          bar" 3 "foo~%bar")
+  (check "  foo~%  bar" 5 "  foo~%  bar")
+  (check ("  foo~%  bar") 5 ("  foo" "  bar")))
 
 (define-test lists
   (check ("foo bar baz")