Add string-inflection library
This commit is contained in:
parent
0ecb40253a
commit
6c147feb09
|
@ -0,0 +1,63 @@
|
|||
;; Copyright 2020 Lassi Kortela
|
||||
;; SPDX-License-Identifier: ISC
|
||||
|
||||
(import (scheme base) (srfi 64) (lassik string-inflection))
|
||||
|
||||
(test-begin "string-inflection")
|
||||
|
||||
(test-equal "command-output-to-string"
|
||||
(string-inflection-lisp "command_output_to_string"))
|
||||
|
||||
(test-equal "command_output_to_string"
|
||||
(string-inflection-underscore "command--output_to-string"))
|
||||
|
||||
(test-equal "a_single_line"
|
||||
(string-inflection-underscore "ASingleLine"))
|
||||
|
||||
(test-equal '("PHP" "Mode")
|
||||
(string-inflection-split "PHPMode"))
|
||||
|
||||
(test-equal '("Ends" "With" "PHP")
|
||||
(string-inflection-split "EndsWithPHP"))
|
||||
|
||||
(test-equal '("PHP" "And" "XML" "Too")
|
||||
(string-inflection-split "PHPAndXMLToo"))
|
||||
|
||||
(test-equal '("php" "And" "Xml" "Too")
|
||||
(string-inflection-split "phpAndXmlToo"))
|
||||
|
||||
;; This one does not have the expected split.
|
||||
(test-equal '("PH" "Pand" "XM" "Ltoo")
|
||||
(string-inflection-split "PHPandXMLtoo"))
|
||||
|
||||
(test-equal '("list" "take" "right")
|
||||
(string-inflection-split "list-take-right"))
|
||||
|
||||
(test-equal '("list" "null" "?")
|
||||
(string-inflection-split "list-null?"))
|
||||
|
||||
(test-equal '("string" "=" "?")
|
||||
(string-inflection-split "string=?"))
|
||||
|
||||
(test-equal '("string" "ci" "<=" "?")
|
||||
(string-inflection-split "string-ci<=?"))
|
||||
|
||||
(test-equal '("what" "happened" "?" "!")
|
||||
(string-inflection-split "what-happened?!"))
|
||||
|
||||
(test-equal '()
|
||||
(string-inflection-split ""))
|
||||
|
||||
(test-equal ""
|
||||
(string-inflection-caps-upper ""))
|
||||
|
||||
(test-equal "FooBarBaz"
|
||||
(string-inflection-caps-upper "foo-bar-baz"))
|
||||
|
||||
(test-equal "fooBarBaz"
|
||||
(string-inflection-caps-lower "foo-bar-baz"))
|
||||
|
||||
(test-equal "XmlToJson"
|
||||
(string-inflection-caps-upper "XML-to-JSON"))
|
||||
|
||||
(test-end "string-inflection")
|
|
@ -0,0 +1,71 @@
|
|||
;; Copyright 2020 Lassi Kortela
|
||||
;; SPDX-License-Identifier: ISC
|
||||
|
||||
;; The algorithm is based on the Emacs Lisp string-inflection package
|
||||
;; by akicho8, but rewritten to use recursion instead of regular
|
||||
;; expressions and expanded to recognize special characters in Lisp.
|
||||
|
||||
(define-library (lassik string-inflection)
|
||||
(export string-inflection-split
|
||||
string-inflection-lisp
|
||||
string-inflection-underscore
|
||||
string-inflection-caps-upper
|
||||
string-inflection-caps-lower)
|
||||
(import (scheme base) (scheme char))
|
||||
(begin
|
||||
|
||||
(define (string-inflection-split str)
|
||||
(define (char-alphanumeric? char)
|
||||
(or (char-alphabetic? char) (char-numeric? char)))
|
||||
(define (split-off run runs)
|
||||
(if (null? run) runs (cons (list->string (reverse run)) runs)))
|
||||
(let loop ((runs '()) (run '()) (chars (string->list str)))
|
||||
(if (null? chars) (reverse (split-off run runs))
|
||||
(let ((char (car chars)))
|
||||
(cond ((or (char=? #\- char) (char=? #\_ char))
|
||||
(loop (split-off run runs) '() (cdr chars)))
|
||||
((or (char=? #\! char) (char=? #\? char))
|
||||
(loop (cons (string char) (split-off run runs))
|
||||
'() (cdr chars)))
|
||||
((and (not (null? run))
|
||||
(or (and (char-upper-case? char)
|
||||
(not (char-upper-case? (car run))))
|
||||
(not (eqv? (char-alphanumeric? char)
|
||||
(char-alphanumeric? (car run))))))
|
||||
(loop (split-off run runs) (list char) (cdr chars)))
|
||||
((and (not (char-upper-case? char))
|
||||
(not (null? run))
|
||||
(not (null? (cdr run)))
|
||||
(char-upper-case? (car run))
|
||||
(char-upper-case? (cadr run)))
|
||||
(loop (split-off (cdr run) runs)
|
||||
(list char (car run))
|
||||
(cdr chars)))
|
||||
(else
|
||||
(loop runs (cons char run) (cdr chars))))))))
|
||||
|
||||
(define (string-titlecase str)
|
||||
(string-append (string (char-upcase (string-ref str 0)))
|
||||
(string-downcase (substring str 1 (string-length str)))))
|
||||
|
||||
(define (join-between between runs)
|
||||
(if (null? runs) ""
|
||||
(let loop ((so-far (car runs)) (runs (cdr runs)))
|
||||
(if (null? runs) so-far
|
||||
(loop (string-append so-far between (car runs))
|
||||
(cdr runs))))))
|
||||
|
||||
(define (string-inflection-lisp str)
|
||||
(join-between "-" (string-inflection-split str)))
|
||||
|
||||
(define (string-inflection-underscore str)
|
||||
(string-downcase (join-between "_" (string-inflection-split str))))
|
||||
|
||||
(define (string-inflection-caps-upper str)
|
||||
(apply string-append
|
||||
(map string-titlecase (string-inflection-split str))))
|
||||
|
||||
(define (string-inflection-caps-lower str)
|
||||
(let ((runs (string-inflection-split str)))
|
||||
(apply string-append (cons (string-downcase (car runs))
|
||||
(map string-titlecase (cdr runs))))))))
|
Loading…
Reference in New Issue