(module scss-plus (scss-plus->scss) (import chicken scheme) (use srfi-1 data-structures extras) (define (maybe-symbol->list s) (if (symbol? s) (list s) s)) (define (combinator? c) (member c '(// > + &))) (define (normalize-selector selector) (if (and (pair? selector) (or (pair? (car selector)) (not (combinator? (car selector))))) selector (list selector))) (define (conc-last p s) (if (list? p) (append (butlast p) (list (conc-last (last p) s))) (string->symbol (conc p s)))) (define (prefix-selector selector prefixes) (append-map (lambda (p) (map (lambda (s) (append (butlast p) (if (eq? '& (car s)) (conc-last (last p) (last s)) (cons* (car s) (last p) (cdr s))))) selector)) prefixes)) (define (flatten-declarations selector declarations) (fold-right (lambda (declaration rules) (if (symbol? (car declaration)) (alist-update! selector (cons declaration (alist-ref selector rules equal? '())) rules equal?) (append (scss-plus->scss (list declaration) selector) rules))) '() declarations)) (define (scss-plus->scss styles #!optional (prefixes '())) (let ((prefixes (map normalize-selector (maybe-symbol->list prefixes)))) (fold (lambda (rule scss) (let* ((selector (normalize-selector (car rule))) (selector (if (null? prefixes) selector (prefix-selector selector prefixes)))) (append scss (flatten-declarations selector (cdr rule))))) '() styles))) )