#lang racket/base (require racket/promise "util.rkt") (provide (all-defined-out)) ;; mapped-chars : (listof (list nat nat bool)) (define mapped-chars (make-known-char-range-list)) ;; get-chars-for-x : (nat -> bool) (listof (list nat nat bool)) -> (listof (cons nat nat)) (define (get-chars-for char-x? mapped-chars) (cond [(null? mapped-chars) null] [else (define range (car mapped-chars)) (define low (car range)) (define high (cadr range)) (define x (char-x? low)) (cond [(caddr range) (if x (cons (cons low high) (get-chars-for char-x? (cdr mapped-chars))) (get-chars-for char-x? (cdr mapped-chars)))] [else (let loop ([range-start low] [i (car range)] [parity x]) (cond [(> i high) (if parity (cons (cons range-start high) (get-chars-for char-x? (cdr mapped-chars))) (get-chars-for char-x? (cdr mapped-chars)))] [(eq? parity (char-x? i)) (loop range-start (add1 i) parity)] [parity (cons (cons range-start (sub1 i)) (loop i (add1 i) #f))] [else (loop i (add1 i) #t)]))])])) (define (compute-ranges x?) (delay (get-chars-for (λ (x) (x? (integer->char x))) mapped-chars))) (define alphabetic-ranges (compute-ranges char-alphabetic?)) ;; 325 (define lower-case-ranges (compute-ranges char-lower-case?)) ;; 405 (define upper-case-ranges (compute-ranges char-upper-case?)) ;; 380 (define title-case-ranges (compute-ranges char-title-case?)) ;; 10 (define numeric-ranges (compute-ranges char-numeric?)) ;; 47 (define symbolic-ranges (compute-ranges char-symbolic?)) ;; 153 (define punctuation-ranges (compute-ranges char-punctuation?)) ;; 86 (define graphic-ranges (compute-ranges char-graphic?)) ;; 401 (define whitespace-ranges (compute-ranges char-whitespace?)) ;; 10 (define blank-ranges (compute-ranges char-blank?)) ;; 9 #;(define hexadecimal-ranges (compute-ranges char-hexadecimal?)) (define iso-control-ranges (compute-ranges char-iso-control?)) ;; 2 (module+ test (require rackunit) (check-equal? (get-chars-for odd? '()) '()) (check-equal? (get-chars-for odd? '((1 4 #f) (8 13 #f))) '((1 . 1) (3 . 3) (9 . 9) (11 . 11) (13 . 13))) (check-equal? (get-chars-for (λ (x) (odd? (quotient x 10))) '((1 5 #t) (17 19 #t) (21 51 #f))) '((17 . 19) (30 . 39) (50 . 51))))