ca3306967cb067f6491945ac5395272d998fb634
1 (in-package :parenscript
)
3 (defun string-join (strings separator
)
4 (format nil
"~{~}" (format nil
"~~a~~^~a" separator
) strings
))
6 (defun val-to-string (val)
8 (string-downcase (symbol-name val
))
9 (princ-to-string val
)))
11 (defun string-split (string separators
&key
(keep-separators nil
) (remove-empty-subseqs nil
))
12 (do ((len (length string
))
17 (let ((split (if (> i last
)
18 (cons (subseq string last i
) res
)
20 (nreverse (if remove-empty-subseqs
21 (delete "" split
:test
#'string-equal
)
23 (when (member (char string i
) separators
)
24 (push (subseq string last i
) res
)
25 (when keep-separators
(push (string (char string i
)) res
))
28 (defun concat-constant-strings (list)
29 (reverse (reduce (lambda (optimized-list next-obj
)
30 (if (and (or (numberp next-obj
) (stringp next-obj
)) (stringp (car optimized-list
)))
31 (cons (format nil
"~a~a" (car optimized-list
) next-obj
) (cdr optimized-list
))
32 (cons next-obj optimized-list
)))
35 (defparameter *special-chars
*
46 ;;; Parenscript-style symbol -> Javascript-style symbol
48 (defun constant-string-p (string)
49 (let ((len (length string
))
50 (constant-chars '(#\
+ #\
*)))
52 (member (char string
0) constant-chars
)
53 (member (char string
(1- len
)) constant-chars
))))
55 (defun first-uppercase-p (string)
56 (and (> (length string
) 1)
57 (member (char string
0) '(#\
+ #\
*))))
59 (defun untouchable-string-p (string)
60 (and (> (length string
) 1)
61 (char= #\
: (char string
0))))
63 (defun symbol-to-js (symbol)
64 "Given a Lisp symbol or string, produces to a valid JavaScript
65 identifier by following transformation heuristics case conversion. For
66 example, paren-script becomes parenScript, *some-global* becomes
68 (when (symbolp symbol
)
69 (setf symbol
(symbol-name symbol
)))
70 (let ((symbols (string-split symbol
'(#\.
#\
[ #\
]) :keep-separators t
:remove-empty-subseqs t
)))
71 (cond ((null symbols
) "")
72 ((= (length symbols
) 1)
77 (cond ((constant-string-p symbol
)
79 symbol
(subseq symbol
1 (1- (length symbol
)))))
80 ((first-uppercase-p symbol
)
82 symbol
(subseq symbol
1)))
83 ((untouchable-string-p symbol
)
85 symbol
(subseq symbol
1))))
89 ((and lowercase
(not all-uppercase
))
94 (dotimes (i (length symbol
))
95 (let ((c (char symbol i
)))
98 (setf lowercase
(not lowercase
)))
99 ((assoc c
*special-chars
*)
100 (dolist (i (coerce (cdr (assoc c
*special-chars
*)) 'list
))
103 (coerce (nreverse res
) 'string
)))
104 (t (string-join (mapcar #'symbol-to-js symbols
) "")))))
106 (defun ordered-set-difference (list1 list2
&key
(test #'eql
)) ;; because the CL set-difference may not preserve order
107 (reduce (lambda (list el
) (remove el list
:test test
))