;;;; "chap.scm" Chapter ordering -*-scheme-*- ;;; Copyright 1992, 1993, 1994 Aubrey Jaffer. ; ;Permission to copy this software, to redistribute it, and to use it ;for any purpose is granted, subject to the following restrictions and ;understandings. ; ;1. Any copy made of this software must include this copyright notice ;in full. ; ;2. I have made no warrantee or representation that the operation of ;this software will be error-free, and I am under no obligation to ;provide any services, by way of maintenance, update, or otherwise. ; ;3. In conjunction with products arising from the use of this ;material, there shall be no use of my name in any advertising, ;promotional, or sales literature without prior written consent in ;each case. ;;; The CHAP: functions deal with strings which are ordered like ;;; chapters in a book. For instance, a_9 < a_10 and 4c < 4aa. Each ;;; section of the string consists of consecutive numeric or ;;; consecutive aphabetic characters. (define (chap:string= i l1) (not (>= i l2))) ((>= i l2) #f) (else (let ((c1 (string-ref s1 i)) (c2 (string-ref s2 i))) (cond ((char=? c1 c2) (if (ctypep c1) (match-so-far (+ 1 i) ctypep) (delimited i))) ((ctypep c1) (if (ctypep c2) (length-race (+ 1 i) ctypep (char= i l1) (if (>= i l2) def #t)) ((>= i l2) #f) (else (let ((c1 (string-ref s1 i)) (c2 (string-ref s2 i))) (cond ((ctypep c1) (if (ctypep c2) (length-race (+ 1 i) ctypep def) #f)) ((ctypep c2) #t) (else def)))))) (define (ctype c1) (cond ((char-numeric? c1) char-numeric?) ((char-lower-case? c1) char-lower-case?) ((char-upper-case? c1) char-upper-case?) (else #f))) (define (delimited i) (cond ((>= i l1) (not (>= i l2))) ((>= i l2) #f) (else (let* ((c1 (string-ref s1 i)) (c2 (string-ref s2 i)) (ctype1 (ctype c1))) (cond ((char=? c1 c2) (if ctype1 (match-so-far (+ i 1) ctype1) (delimited (+ i 1)))) ((and ctype1 (eq? ctype1 (ctype c2))) (length-race (+ 1 i) ctype1 (charinteger #\2) (char->integer #\1))) (define (chap:inc-string s p) (let ((c (string-ref s p))) (cond ((char=? c #\z) (string-set! s p #\a) (cond ((zero? p) (string-append "a" s)) ((char-lower-case? (string-ref s (+ -1 p))) (chap:inc-string s (+ -1 p))) (else (string-append (substring s 0 p) "a" (substring s p (string-length s)))))) ((char=? c #\Z) (string-set! s p #\A) (cond ((zero? p) (string-append "A" s)) ((char-upper-case? (string-ref s (+ -1 p))) (chap:inc-string s (+ -1 p))) (else (string-append (substring s 0 p) "A" (substring s p (string-length s)))))) ((char=? c #\9) (string-set! s p #\0) (cond ((zero? p) (string-append "1" s)) ((char-numeric? (string-ref s (+ -1 p))) (chap:inc-string s (+ -1 p))) (else (string-append (substring s 0 p) "1" (substring s p (string-length s)))))) ((or (char-alphabetic? c) (char-numeric? c)) (string-set! s p (integer->char (+ chap:char-incr (char->integer (string-ref s p))))) s) (else (slib:error "inc-string error" s p))))) (define (chap:next-string s) (do ((i (+ -1 (string-length s)) (+ -1 i))) ((or (negative? i) (char-numeric? (string-ref s i)) (char-alphabetic? (string-ref s i))) (if (negative? i) (string-append s "0") (chap:inc-string (string-copy s) i))))) ;;; testing utilities ;(define (ns s1) (chap:next-string s1)) ;(define (ts s1 s2) ; (let ((s< (chap:string (chap:string ; (display s1) ; (display " > ") ; (display s2) ; (newline))))) (define (chap:string>? s1 s2) (chap:string=? s1 s2) (not (chap:string