; -*- Scheme -*-
;
; $Id: string04.scm,v 1.1 1998/03/16 07:59:32 foner Exp $
;

;+doc
; procedure: substring:capitalize!
; arguments: string start end
; signature: string x int x int -> unspecified
; pre:       (<= 0 start end (string-length string))
;
; Modifies STRING such that for every word in STRING, the first
; character of the word, if case-modifiable, is uppercase and any
; other case modifiable characters in the word are lowercase.
; A word is defined here as a string consisting of alphanumeric
; characters or digits, delimited at each end either by a
; non-alphanumeric character or by the end of the string.
;
; The semantics are that of Common Lisp STRING-CAPITALIZE
;
; > (define foo "occlUDed cASEmenTs")
; > (substring:capitalize! foo 2 11)
; > foo
; "ocCluded CaSEmenTs"
;-doc

(define substring:capitalize!
  (lambda (st s e)
    (let loop ((cap? #t) (i s))
      (if (= i e)
	  st
	  (let* ((p (string-ref st i))
		 (nc (if cap? (char-upcase p) (char-downcase p))))
	    (string-set! st i nc)
	    (loop (not (or (char-alphabetic? p) (char-numeric? p)))
		  (+ 1 i)))))))

; Although the result is unspecified, this version returns the
; modified string to make SUB-STRING:CAPITALIZE slightly easier to
; write.

;------------

;+doc
; procedure: string:capitalize!
; arguments: string
; signature: string -> unspecified
;
; Equivalent to (SUB-STRING:CAPITALIZE! STRING 0 (STRING-LENGTH STRING))
;
; > (define foo "occlUDed cASEmenTs")
; > (string:capitalize! foo)
; > foo
; "Occluded Casements"
;-doc

(define string:capitalize!
  (lambda (string)
    (substring:capitalize! string 0 (string-length string))))


; eof
