Skip to content

Commit

Permalink
Add pad (left, right, center)
Browse files Browse the repository at this point in the history
fixes #33

(str:pad 10 "foo")
"foo       "
  • Loading branch information
vindarel committed Dec 16, 2019
1 parent d721c07 commit ac7e6bc
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 2 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The only dependency is `cl-ppcre`.
- [insert `(string/char index s)`](#insert-stringchar-index-s)
- [repeat `(count s)`](#repeat-count-s)
- [add-prefix, add-suffix `(items s)`](#add-prefix-add-suffix-items-s)
- [pad `(len s &key (pad-side :right) (pad-char #\Space))`, pad-left, pad-right, pad-center (new in 0.16, 2019/12)](#pad-len-s-key-pad-side-right-pad-char-space-pad-left-pad-right-pad-center-new-in-016-201912)
- [To shorter strings](#to-shorter-strings)
- [substring `(start end s)`](#substring-start-end-s)
- [s-first `(s)`](#s-first-s)
Expand Down Expand Up @@ -196,6 +197,34 @@ Make a string of `s` repeated `count` times.
Respectively prepend or append `s` to the front of each item.


#### pad `(len s &key (pad-side :right) (pad-char #\Space))`, pad-left, pad-right, pad-center (new in 0.16, 2019/12)

Fill `s` with characters until it is of the given length. By default,
add spaces on the right:

~~~lisp
(str:pad 10 "foo")
"foo "
~~~

* `pad-side`: one of `:right` (the default), `:left` or `:center`. See `*pad-side*`.
* `pad-char`: the padding character (or string of one character). Defaults to a space. See `*pad-char*`.

~~~lisp
(str:pad 10 "foo" :pad-side :center :pad-char "+")
"+++foo++++"
~~~

If the given length is smaller than the length o `s`, return `s`.

Filling with spaces can easily be done with format:

~~~lisp
(format nil "~va" len s) ;; => "foo "
(format nil "~v@a" 10 "foo") ;; => " foo" (with @)
~~~


### To shorter strings

#### substring `(start end s)`
Expand Down Expand Up @@ -609,6 +638,7 @@ Now:
("a" "b" "c" "")
~~~

* 0.16, november 2019: added `pad`, `pad-[left, right, center]`.
* 0.15, october 2019: added functions to change case (based on cl-change-case).
added remove-punctuation.
* august, 2019: deprecated `prune`, renamed to `shorten`.
Expand Down
2 changes: 1 addition & 1 deletion str.asd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
:author "vindarel <vindarel@mailz.org>"
:maintainer "vindarel <vindarel@mailz.org>"
:license "MIT"
:version "0.15"
:version "0.16"
:homepage "https://github.com/vindarel/cl-str"
:bug-tracker "https://github.com/vindarel/cl-str/issues"
:source-control (:git "git@github.com:vindarel/cl-str.git")
Expand Down
62 changes: 61 additions & 1 deletion str.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
:suffixp
:add-prefix
:add-suffix
:pad
:pad-left
:pad-right
:pad-center
:unlines
:from-file
:to-file
Expand Down Expand Up @@ -105,6 +109,8 @@
:*ignore-case*
:*omit-nulls*
:*ellipsis*
:*pad-char*
:*pad-side*
:version
:+version+
:?))
Expand All @@ -114,11 +120,15 @@

(defparameter *ignore-case* nil)
(defparameter *omit-nulls* nil)
(defparameter *pad-char* #\Space
"Padding character to use with `pad'. It can be a string of one character.")
(defparameter *pad-side* :right
"The side of the string to add padding characters to. Can be one of :right, :left and :center.")

(defvar *whitespaces* '(#\Space #\Newline #\Backspace #\Tab
#\Linefeed #\Page #\Return #\Rubout))

(defvar +version+ "0.15")
(defvar +version+ "0.16")

(defun version ()
(print +version+))
Expand Down Expand Up @@ -391,6 +401,56 @@ A simple call to the built-in `search` (which returns the position of the substr
"Append s to the end of eahc items."
(mapcar #'(lambda (item) (concat item s)) items))

(defun pad (len s &key (pad-side *pad-side*) (pad-char *pad-char*))
"Fill `s' with characters until it is of the given length. By default, add spaces on the right.
Filling with spaces can be done with format:
(format nil \"~v@a\" len s) ;; with or without the @ directive
`pad-side': to pad `:right' (the default), `:left' or `:center'.
`pad-char': padding character (or string of one character). Defaults to a space."
(if (< len (length s))
s
(flet ((pad-left (len s &key (pad-char *pad-char*))
(concatenate 'string
(make-string (- len (length s)) :initial-element pad-char)
s))
(pad-right (len s &key (pad-char *pad-char*))
(concatenate 'string
s
(make-string (- len (length s)) :initial-element pad-char)))
(pad-center (len s &key (pad-char *pad-char*))
(multiple-value-bind (q r)
(floor (- len (length s)) 2)
(concatenate 'string
(make-string q :initial-element pad-char)
s
(make-string (+ q r) :initial-element pad-char)))))

(unless (characterp pad-char)
(if (>= (length pad-char) 2)
(error "pad-char must be a character or a string of one character.")
(setf pad-char (coerce pad-char 'character))))
(case pad-side
(:right
(pad-right len s :pad-char pad-char))
(:left
(pad-left len s :pad-char pad-char))
(:center
(pad-center len s :pad-char pad-char))
(t
(error "str:pad: unknown padding side with ~a" pad-side))))))

(defun pad-left (len s &key (pad-char *pad-char*))
(pad len s :pad-side :left :pad-char pad-char))

(defun pad-right (len s &key (pad-char *pad-char*))
(pad len s :pad-side :right :pad-char pad-char))

(defun pad-center (len s &key (pad-char *pad-char*))
(pad len s :pad-side :center :pad-char pad-char))

(defun from-file (pathname &rest keys)
"Read the file and return its content as a string.
Expand Down
16 changes: 16 additions & 0 deletions test/test-str.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,22 @@
(is (add-suffix '("foo" nil) "bar") '("foobar" "bar") "with a nil")
(is (add-suffix '() "foo") '() "with void list"))

(subtest "pad left, right, center"
(is (pad 10 "foo") "foo "
"pad adds spaces on the right by default.")
(is (pad-right 10 "foo") (pad 10 "foo")
"pad-right is equivalent to pad")
(is (pad 10 "foo" :pad-side :left) " foo"
"pad-left")
(is (pad 10 "foo" :pad-side :center) " foo "
"pad with pad-side :center")
(is (pad-center 10 "foo") (pad 10 "foo" :pad-side :center)
"pad-center")
(is (pad 10 "foo" :pad-char #\+) "foo+++++++"
"pad with a custom padding character.")
(is (pad -1 "foo") "foo"
"pad with a short length returns the string."))

(subtest "contains?"
(ok (contains? "foo" "blafoobar") "default")
(ok (not (contains? "foo" "")) "with no string")
Expand Down

0 comments on commit ac7e6bc

Please sign in to comment.