s

  1. s
    1. Description
    2. Author
    3. Requirements
    4. Repository
    5. Documentation
      1. s-trim
      2. s-trim-left
      3. s-trim-right
      4. s-chomp
      5. s-collapse-whitespace
      6. s-center
      7. s-truncate
      8. s-left
      9. s-right
      10. s-chop-suffix
      11. s-chop-suffixes
      12. s-chop-prefix
      13. s-chop-prefixes
      14. s-shared-start
      15. s-shared-end
      16. s-repeat
      17. s-concat
      18. s-prepend
      19. s-append
      20. s-lines
      21. s-match
      22. s-match-multiple
      23. s-split
      24. s-join
      25. s-chop
      26. s-equals?
      27. s-matches?
      28. s-blank?
      29. s-ends-with?
      30. s-starts-with?
      31. s-contains?
      32. s-lowercase?
      33. s-uppercase?
      34. s-mixedcase?
      35. s-capitalized?
      36. s-titleized?
      37. s-numeric?
      38. s-replace
      39. s-downcase
      40. s-upcase
      41. s-capitalize
      42. s-titleize
      43. s-index-of
      44. s-reverse
      45. s-split-words
      46. s-lower-camel-case
      47. s-upper-camel-case
      48. s-snake-case
      49. s-dashed-words
      50. s-capitalized-words
      51. s-titleized-words
      52. s-unique-words
    6. Examples
    7. Changelog
    8. License
      1. s-append
      2. s-dashed-words
      3. s-unique-words

Description

String manipulation egg for chicken scheme.

The s egg aims to provide many convenient procedures for working with strings. Some of these functions are simply wrappers around existing scheme procedures. In the spirit of s.el, such wrappers exist to provide users with a consistent API for quickly and easily manipulating strings in Chicken Scheme without searching documentation across multiple modules.

An attempt has been made to organize procedures according to their categorical behavior. Available procedures are listed by category below, followed by documentation and examples.

Many of the functions defined here were inspired by the Emacs lisp string manipulation library "s.el" created by Magnar Sveen (and others) at https://github.com/magnars/s.el.

Author

Nicholas Van Horn

Requirements

The following units are required:

data-structures srfi-1 srfi-13

Repository

The git repository for the s source code is hosted by github: https://github.com/n3mo/s.

Documentation

s-trim

[procedure] (s-trim s)

Remove whitespace at the beginning and end of s.

(s-trim "trim ") ;; => "trim"
(s-trim " this") ;; => "this"
(s-trim " only  trims beg and end  ") ;; => "only  trims beg and end"

s-trim-left

[procedure] (s-trim-left s)

Remove whitespace at the beginning of s.

(s-trim-left "trim ") ;; => "trim "
(s-trim-left " this") ;; => "this"

s-trim-right

[procedure] (s-trim-right s)

Remove whitespace at the end of s.

(s-trim-right "trim ") ;; => "trim"
(s-trim-right " this") ;; => " this"

s-chomp

[procedure] (s-chomp s)

Remove one trailing \n, \r or \r\n from s.

(s-chomp "no newlines\n") ;; => "no newlines"
(s-chomp "no newlines\r\n") ;; => "no newlines"
(s-chomp "some newlines\n\n") ;; => "some newlines\n"

s-collapse-whitespace

[procedure] (s-collapse-whitespace s)

Convert all adjacent whitespace characters in s to a single space.

(s-collapse-whitespace "only   one space   please") ;; => "only one space please"
(s-collapse-whitespace "collapse \n all \t sorts of \r whitespace") ;; => "collapse all sorts of whitespace"

s-center

[procedure] (s-center len s)

If s is shorter than len, pad it with spaces so it is centered.

(s-center 5 "a") ;; => "  a  "
(s-center 5 "ab") ;; => "  ab "
(s-center 1 "abc") ;; => "abc"

s-truncate

[procedure] (s-truncate len s)

If s is longer than len, cut it down and add ... at the end.

(s-truncate 6 "This is too long") ;; => "Thi..."
(s-truncate 16 "This is also too long") ;; => "This is also ..."
(s-truncate 16 "But this is not!") ;; => "But this is not!"

s-left

[procedure] (s-left len s)

Returns up to the len first chars of s.

(s-left 3 "lib/file.js") ;; => "lib"
(s-left 3 "li") ;; => "li"

s-right

[procedure] (s-right len s)

Returns up to the len last chars of s.

(s-right 3 "lib/file.js") ;; => ".js"
(s-right 3 "li") ;; => "li"

s-chop-suffix

[procedure] (s-chop-suffix suffix s)

Remove suffix if it is at end of s.

(s-chop-suffix "-test.js" "penguin-test.js") ;; => "penguin"
(s-chop-suffix "\n" "no newlines\n") ;; => "no newlines"
(s-chop-suffix "\n" "some newlines\n\n") ;; => "some newlines\n"

s-chop-suffixes

[procedure] (s-chop-suffixes suffixes s)

Remove suffixes one by one in order, if they are at the end of s.

(s-chop-suffixes '("_test.js" "-test.js" "Test.js") "penguin-test.js") ;; => "penguin"
(s-chop-suffixes '("\r" "\n") "penguin\r\n") ;; => "penguin\r"
(s-chop-suffixes '("\n" "\r") "penguin\r\n") ;; => "penguin"

s-chop-prefix

[procedure] (s-chop-prefix prefix s)

Remove prefix if it is at the start of s.

(s-chop-prefix "/tmp" "/tmp/file.js") ;; => "/file.js"
(s-chop-prefix "/tmp" "/tmp/tmp/file.js") ;; => "/tmp/file.js"

s-chop-prefixes

[procedure] (s-chop-prefixes prefixes s)

Remove prefixes one by one in order, if they are at the start of s.

(s-chop-prefixes '("/tmp" "/my") "/tmp/my/file.js") ;; => "/file.js"
(s-chop-prefixes '("/my" "/tmp") "/tmp/my/file.js") ;; => "/my/file.js"

s-shared-start

[procedure] (s-shared-start s1 s2)

Returns the longest prefix s1 and s2 have in common.

(s-shared-start "bar" "baz") ;; => "ba"
(s-shared-start "foobar" "foo") ;; => "foo"
(s-shared-start "bar" "foo") ;; => ""

s-shared-end

[procedure] (s-shared-end s1 s2)

Returns the longest suffix s1 and s2 have in common.

(s-shared-end "bar" "var") ;; => "ar"
(s-shared-end "foo" "foo") ;; => "foo"
(s-shared-end "bar" "foo") ;; => ""

s-repeat

[procedure] (s-repeat num s)

Make a string of s repeated num times.

(s-repeat 10 " ") ;; => "          "
(s-concat (s-repeat 8 "Na") " Batman!") ;; => "NaNaNaNaNaNaNaNa Batman!"

s-concat

[procedure] (s-concat s ...)

Join all the string arguments into one string.

(s-concat "abc" "def" "ghi") ;; => "abcdefghi"

s-prepend

[procedure] (s-prepend prefix s)

Concatenate prefix and s.

(s-prepend "abc" "def") ;; => "abcdef"

s-append

[procedure] (s-append suffix s)

Concatenate s and suffix.

(s-append "abc" "def") ;; => "defabc"

s-lines

[procedure] (s-lines s)

Splits s into a list of strings on newline characters.

(s-lines "abc\ndef\nghi") ;; => '("abc" "def" "ghi")
(s-lines "abc\rdef\rghi") ;; => '("abc" "def" "ghi")
(s-lines "abc\r\ndef\r\nghi") ;; => '("abc" "def" "ghi")

s-match

[procedure] (s-match regexp s)

When the given expression matches the string, this function returns a list of the whole matching string and a string for each matched subexpression. If it did not match the returned value is an empty list '().

(s-match "^def" "abcdefg") ;; => '()
(s-match "^abc" "abcdefg") ;; => '("abc")
(s-match "^.*/([a-z]+).([a-z]+)" "/some/weird/file.html") ;; => '("/some/weird/file.html" "file" "html")

s-match-multiple

[procedure] (s-match-multiple regexp s)

Returns a list of all matches to regexp in s.

(s-match-multiple "[[:digit:]]{4}" "Grab (1234) four-digit (4321) numbers (4567)") ;; => ("1234" "4321" "4567")
(s-match-multiple "<.+?>" "<html> <body> Some text </body> </html>") ;; => ("<html>" "<body>" "</body>" "</html>")
(s-match-multiple "foo-[0-9]{2}" "foo-10 foo-11 foo-1 foo-2 foo-100 foo-21") ;; => ("foo-10" "foo-11" "foo-10" "foo-21")

s-split

[procedure] (s-split separators s [keepempty])

Splits s into substrings bounded by matches for separators. If keepempty is #t, zero-length substrings are returned.

(s-split " " "one  two  three") ;; => ("one" "two" "three")
(s-split ":" "foo:bar::baz" #t) ;; => ("foo" "bar" "" "baz")
(s-split ":," "foo:bar:baz,quux,zot") ;; => ("foo" "bar" "baz" "quux" "zot")

s-join

[procedure] (s-join separator strings)

Join all the strings in strings with separator in between.

(s-join "+" '("abc" "def" "ghi")) ;; => "abc+def+ghi"
(s-join "\n" '("abc" "def" "ghi")) ;; => "abc\ndef\nghi"

s-chop

[procedure] (s-chop len s)

Return a list of substrings taken by chopping s every len characters.

(s-chop 4 "1234567890") ;; => ("1234" "5678" "90")
(s-chop 3 "i-1i-2i-3i-4i-5") ;; => ("i-1" "i-2" "i-3" "i-4" "i-5")

s-equals?

[procedure] (s-equals? s1 s2)

Is s1 equal to s2?

This is a simple wrapper around the built-in string=.

(s-equals? "abc" "ABC") ;; => #f
(s-equals? "abc" "abc") ;; => #t

s-matches?

[procedure] (s-matches? regexp s)

Does regexp match s?

(s-matches? "^[0-9]+$" "123") ;; => #t
(s-matches? "^[0-9]+$" "a123") ;; => #f

s-blank?

[procedure] (s-blank? s)

Is s the empty string?

(s-blank? "") ;; => #t
(s-blank? " ") ;; => #f

s-ends-with?

[procedure] (s-ends-with? suffix s [ignore-case])

Does s end with suffix?

If ignore-case is non-#f, the comparison is done without paying attention to case differences.

Alias: s-suffix?

(s-ends-with? ".md" "readme.md") ;; => #t
(s-ends-with? ".MD" "readme.md") ;; => #f
(s-ends-with? ".MD" "readme.md" #t) ;; => #t

s-starts-with?

[procedure] (s-starts-with? prefix s [ignore-case])

Does s start with prefix?

If ignore-case is non-#f, the comparison is done without paying attention to case differences.

(s-starts-with? "lib/" "lib/file.js") ;; => #t
(s-starts-with? "LIB/" "lib/file.js") ;; => #f
(s-starts-with? "LIB/" "lib/file.js" #t) ;; => #t

s-contains?

[procedure] (s-contains? needle s [ignore-case])

Does s contain needle?

If ignore-case is non-#f, the comparison is done without paying attention to case differences.

(s-contains? "file" "lib/file.js") ;; => #t
(s-contains? "nope" "lib/file.js") ;; => #f
(s-contains? "^a" "it's not ^a regexp") ;; => #t

s-lowercase?

[procedure] (s-lowercase? s)

Are all the letters in s in lower case?

(s-lowercase? "file") ;; => #t
(s-lowercase? "File") ;; => #f
(s-lowercase? "123?") ;; => #t

s-uppercase?

[procedure] (s-uppercase? s)

Are all the letters in s in upper case?

(s-uppercase? "HULK SMASH") ;; => #t
(s-uppercase? "Bruce no smash") ;; => #f
(s-uppercase? "123?") ;; => #t

s-mixedcase?

[procedure] (s-mixedcase? s)

Are there both lower case and upper case letters in s?

(s-mixedcase? "HULK SMASH") ;; => #f
(s-mixedcase? "Bruce no smash") ;; => #t
(s-mixedcase? "123?") ;; => #f

s-capitalized?

[procedure] (s-capitalized? s)

In s, is the first letter upper case, and all other letters lower case?

(s-capitalized? "Capitalized") ;; => #t
(s-capitalized? "I am capitalized") ;; => #t
(s-capitalized? "I Am Titleized") ;; => #f

s-titleized?

[procedure] (s-titleized? s)

In s, is the first letter of each word upper case, and all other letters lower case?

(s-titleized? "Titleized") ;; => #t
(s-titleized? "I Am Titleized") ;; => #t
(s-titleized? "I am only capitalized") ;; => #f

s-numeric?

[procedure] (s-numeric? s)

Is s a number?

(s-numeric? "123") ;; => #t
(s-numeric? "onetwothree") ;; => #f

s-replace

[procedure] (s-replace old new s)

Replaces old with new in s.

(s-replace "file" "nope" "lib/file.js") ;; => "lib/nope.js"
(s-replace "^a" "---" "it's not ^a regexp") ;; => "it's not --- regexp"

s-downcase

[procedure] (s-downcase s)

Convert s to lower case.

This is a simple wrapper around string-downcase.

(s-downcase "ABC") ;; => "abc"

s-upcase

[procedure] (s-upcase s)

Convert s to upper case.

This is a simple wrapper around string-upcase.

(s-upcase "abc") ;; => "ABC"

s-capitalize

[procedure] (s-capitalize s)

Convert the first word's first character to upper case and the rest to lower case in s.

(s-capitalize "abc DEF") ;; => "Abc def"
(s-capitalize "abc.DEF") ;; => "Abc.def"

s-titleize

[procedure] (s-titleize s)

Convert each word's first character to upper case and the rest to lower case in s.

This is a simple wrapper around string-titlecase.

(s-titleize "abc DEF") ;; => "Abc Def"
(s-titleize "abc.DEF") ;; => "Abc.Def"

s-index-of

[procedure] (s-index-of needle s [ignore-case])

Returns first index of needle in s, or #f.

If ignore-case is non-#f, the comparison is done without paying attention to case differences.

(s-index-of "abc" "abcdef") ;; => 0
(s-index-of "CDE" "abcdef" #t) ;; => 2
(s-index-of "n.t" "not a regexp") ;; => #f

s-reverse

[procedure] (s-reverse s)

Return the reverse of s.

(s-reverse "abc") ;; => "cba"
(s-reverse "ab xyz") ;; => "zyx ba"
(s-reverse "") ;; => ""

s-split-words

[procedure] (s-split-words s)

Split s into list of words.

(s-split-words "under_score") ;; => '("under" "score")
(s-split-words "some-dashed-words") ;; => '("some" "dashed" "words")
(s-split-words "evenCamelCase") ;; => '("even" "Camel" "Case")

s-lower-camel-case

[procedure] (s-lower-camel-case s)

Convert s to lowerCamelCase.

(s-lower-camel-case "some words") ;; => "someWords"
(s-lower-camel-case "dashed-words") ;; => "dashedWords"
(s-lower-camel-case "under_scored_words") ;; => "underScoredWords"

s-upper-camel-case

[procedure] (s-upper-camel-case s)

Convert s to UpperCamelCase.

(s-upper-camel-case "some words") ;; => "SomeWords"
(s-upper-camel-case "dashed-words") ;; => "DashedWords"
(s-upper-camel-case "under_scored_words") ;; => "UnderScoredWords"

s-snake-case

[procedure] (s-snake-case s)

Convert s to snake_case.

(s-snake-case "some words") ;; => "some_words"
(s-snake-case "dashed-words") ;; => "dashed_words"
(s-snake-case "camelCasedWords") ;; => "camel_cased_words"

s-dashed-words

[procedure] (s-dashed-words s)

Convert s to dashed-words.

(s-dashed-words "some words") ;; => "some-words"
(s-dashed-words "under_scored_words") ;; => "under-scored-words"
(s-dashed-words "camelCasedWords") ;; => "camel-cased-words"

s-capitalized-words

[procedure] (s-capitalized-words s)

Convert s to Capitalized Words.

(s-capitalized-words "some words") ;; => "Some words"
(s-capitalized-words "under_scored_words") ;; => "Under scored words"
(s-capitalized-words "camelCasedWords") ;; => "Camel cased words"

s-titleized-words

[procedure] (s-titleized-words s)

Convert s to Titleized Words.

(s-titleized-words "some words") ;; => "Some Words"
(s-titleized-words "under_scored_words") ;; => "Under Scored Words"
(s-titleized-words "camelCasedWords") ;; => "Camel Cased Words"

s-unique-words

[procedure] (s-unique-words s)

Return list of unique words in s.

(s-unique-words "Forget redundancy about about redundancy") ;; => ("Forget" "about" "redundancy")
(s-unique-words "unique-dashed-words-dashed-words-too") ;; => ("unique" "dashed" "words" "too")
(s-unique-words "camelCase_words and_and underscore_words_too") ;; => ("camel" "Case" "and" "underscore" "words" "too")

Examples

Multiple examples for each procedure are given above.

Changelog

License

Copyright (C) 2013 Nicholas M. Van Horn

Original Elisp Library Copyright (C) 2012 Magnar Sveen

Author: Nicholas M. Van Horn Keywords: chicken, scheme, string

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. s.el thisonly one space please

 ab  ) ;; =

Returns up to the len first chars of s.

/procedure (s-chop-suffix (s-chop-suffixes '(/tmp/procedure/tmp/my/file.jsbar (s-shared-end s1 s2)foo) ;; =

s-append

(s-lines s)abc /procedure) ;; =   Some text body enscript highlight= i-1

(s-equals? scheme.md/procedure) ;; =enscript highlight= fileHULK SMASHHULK SMASH/enscript/enscript (s-titleized? (s-numeric? nope (s-downcase s)) ;; = enscript highlight=) (s-split-words /enscriptsome words (s-lower-camel-case SomeWords

s-dashed-words

/procedureCamel cased wordsscheme

s-unique-words

) ;; =underscore/enscript