; abbreviated sentences

(define (abbrev sentence)
  (with-output-to-string (lambda ()
    (define (word head len prev)
      (display head)
      (when (positive? len) (display (number->string len)))
      (when prev (display prev)))
    (let loop ((cs (string->list sentence))
               (head #f) (len -1) (prev #f))
      (cond ((null? cs) ; end of sentence
              (when head (word head len prev)))
            ((char-alphabetic? (car cs)) ; in a word
              (if head
                  (loop (cdr cs) head (+ len 1) (car cs))
                  (loop (cdr cs) (car cs) -1 #f)))
            (else ; not in a word
              (when head (word head len prev))
              (display (car cs))
              (loop (cdr cs) #f 0 #f)))))))

(display (abbrev "A is one; Programming Praxis hello-goodbye."))