(define-module (language python string) #:use-module (oop goops) #:use-module (oop pf-objects) #:use-module (ice-9 match) #:use-module (language python list) #:use-module (parser stis-parser) #:export (py-format py-capitalize py-center py-endswith py-expandtabs py-find py-rfind py-isalnum py-isalpha py-isdigit py-islower py-isspace py-isupper py-istitle py-join py-ljust py-rljust py-lower py-upper py-lstrip py-rstrip py-partition py-replace py-strip py-title)) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) (define-syntax-rule (define-py (f n o . u) code ...) (begin (define-method (f (o ) . u) code ...) (define-method (f (o

) . l) (apply (ref o 'n) l)))) (define-py (py-capitalize capitalize o) (string-capitalize o)) (define-py (py-center center o w . l) (let* ((ws (if (pair? l) (car (string->list (car l))) #\space)) (n (string-length o)) (w (if (< w n) n w)) (d (- w n)) (e (floor-quotient (- w n) 2)) (s (make-string w #\space))) (let lp ((i 0) (j e)) (if (< i n) (begin (string-set! s j (string-ref o i)) (lp (+ i 1) (+ j 1))))) s)) ;;;py-decode ;;;py-encode (define-py (py-endswith endswith o (suff ) . l) (let* ((n (string-length o)) (ns (string-length suff)) (f (lambda (x) (< x 0) (+ n x) x))) (call-with-values (lambda () (match l (() (values 0 n )) ((x) (values (f x) n )) ((x y) (values (f x) (f y))))) (lambda (start end) (string-suffix? suff o 0 ns start end))))) (define-py (py-expandtabs expandtabs s . l) (let* ((tabsize (match l (() 8) ((x) x))) (u (string->list (make-string tabsize #\space))) (n (string-length s))) (let lp ((l (string->list s)) (r '())) (if (pair? l) (let ((x (car l))) (if (eq? x #\tab) (lp (cdr l) (append u r)) (lp (cdr l) (cons x r)))) (list->string (reverse r)))))) (define-py (py-find find s sub . l) (let* ((n (string-length s)) (f (lambda (x) (< x 0) (+ n x) x))) (call-with-values (lambda () (match l (() (values 0 n )) ((x) (values (f x) n )) ((x y) (values (f x) (f y))))) (lambda (start end) (aif it (string-contains s sub start end) it -1))))) (define-py (py-rfind rfind s sub . l) (let* ((n (string-length s)) (s (string-reverse s)) (sub (string-reverse sub)) (f (lambda (x) (< x 0) (+ n x) x))) (call-with-values (lambda () (match l (() (values 0 n )) ((x) (values (f x) n )) ((x y) (values (f x) (f y))))) (lambda (start end) (aif it (string-contains s sub start end) (- n it (len sub)) -1))))) (define i (f-list #:i (mk-token (f+ (f-reg! "[0-9]"))))) (define s (f-list #:s (mk-token (f+ (f-not! (f-tag "}")))))) (define e (f-list #:e (f-and (f-tag "}") f-true))) (define tagbody (f-or! e i s)) (define tag (f-seq "{" tagbody "}")) (define nontag (f-list #:str (mk-token (f+ (f-or! (f-tag "{{") (f-not! tag)))))) (define e (ff* (f-or! tag nontag))) (define (compile x args kwargs) (let lp ((l x) (r '()) (u '()) (i 0)) (match l (((#:str x) . l) (lp l (cons x r) u i)) (((#:i x) . l) (lp l (cons "~a" r) (cons (list-ref args (string->number x)) u) i)) (((#:s x) . l) (lp l (cons "~a" r) (cons (hash-ref kwargs x 'None) u) i)) (((#:e) . l) (lp l (cons "~a" r) (cons (list-ref args i) u) (+ i 1))) (() (apply format #f (string-join (reverse r) "") (reverse u)))))) (define-py (py-format format s . l) (call-with-values (lambda () (let lp ((l l) (args '()) (kwargs (make-hash-table))) (match l (((? keyword? key) x . l) (hash-set! kwargs (symbol->string (keyword->symbol key)) x) (lp l args kwargs)) ((x . l) (lp l (cons x args) kwargs)) (() (values (reverse args) kwargs))))) (lambda (args kwargs) (compile (parse s e) args kwargs)))) (define-syntax-rule (mk-is py-isalnum isalnum x ...) (define-py (py-isalnum isalnum s) (and (> (len s) 0) (string-fold (lambda (ch s) (if (or (x ch) ...) s #f)) #t s)))) (mk-is py-isalnum isalnum char-alphabetic? char-numeric?) (mk-is py-isalpha isalpha char-alphabetic?) (mk-is py-isdigit isdigit char-numeric?) (mk-is py-islower islower char-lower-case?) (mk-is py-isspace isspace char-whitespace?) (mk-is py-isupper isupper char-upper-case?) (define-py (py-istitle istitle s) (let ((n (len s))) (if ((> n 0)) (let lp ((i 0) (space? #t)) (if (< i n) (let ((ch (string-ref s i))) (if space? (cond ((char-whitespace? ch) (lp (+ i 1) #t)) ((char-upper-case? ch) (lp (+ i 1) #f)) (else #f)) (cond ((char-whitespace? ch) (lp (+ i 1) #t)) ((char-upper-case? ch) #f) ((char-lower-case? ch) (lp (+ i 1) #f)) (else #f)))) #t)) #f))) (define-py (py-join join s iterator) (string-join (to-list iterator) s)) (define-py (py-ljust ljust s width . l) (let* ((n (len s)) (ch (match l ((x . l) (if (string? x) (string-ref x 0) x)) (() #\space)))) (if (< width n) (pylist-slice s 0 width) (let ((ret (make-string width ch))) (let lp ((i 0)) (if (< i n) (string-set! ret i (string-ref s i)) ret)))))) (define-py (py-rjust rjust s width . l) (let* ((n (len s)) (ch (match l ((x . l) (if (string? x) (string-ref x 0) x)) (() #\space)))) (if (< width n) (pylist-slice s (- width) (len s)) (let ((ret (make-string width ch))) (let lp ((i 0) (j (- width n))) (if (< i n) (string-set! ret j (string-ref s i)) ret)))))) (define-py (py-lower lower s) (string-downcase s)) (define-py (py-upper upper s) (string-upcase s)) (define-py (py-lstrip lstrip s . l) (match l (() (string-trim s)) ((x . _) (let ((l (map (lambda (x) (if (string? x) (string-ref x 0) x)) x))) (string-trim s (lambda (ch) (member ch l))))))) (define-py (py-rstrip rstrip s . l) (match l (() (string-trim-right s)) ((x . _) (let ((l (map (lambda (x) (if (string? x) (string-ref x 0) x)) x))) (string-trim-right s (lambda (ch) (member ch l))))))) (define-py (py-partition partition s (sep )) (let ((n (len s)) (m (len sep))) (define (test i) (let lp ((i i) (j 0)) (if (< i n) (if (< j m) (if (eq? (string-ref s i) (string-ref sep j)) (lp (+ i 1) (+ j 1)) #f) #t) #f))) (let lp ((i 0)) (if (< i n) (if (test i) (list (pylist-slice s 0 i) sep (pylist-slice s (+ i m) n)) (lp (+ i 1))) (list s "" ""))))) (define-py (py-replace replace s old new . l) (let ((n (match l (() #f) ((n . _) n)))) (string-join (reverse (let lp ((s s) (r '())) (let ((l (py-partition s old))) (if (equal? (cadr l) "") (cons s r) (lp (list-ref l 2) (cons (car l) r)))))) new))) (define-py (py-strip strip s . l) (apply py-rstrip (apply py-lstrip s l) l)) (define-py (py-title title s) (string-titlecase s)) #| py-rindex py-rpartition py-rsplit py-split py-splitlines py-startswith py-swapcase py-translate py-zfill |#