[proper escape sequences in strings henrik.hjelte@poboxes.com**20060202123912] { hunk ./src/js.lisp 383 - (declare (ignore start-pos)) + (declare (ignore start-pos) + (inline lisp-special-char-to-js)) hunk ./src/js.lisp 387 - initially (write-char #\' escaped) - for char across (value string) - if (char= #\' char) - do (write-string "\\'" escaped) - else - do (write-char char escaped) - finally (write-char #\' escaped))))) + initially (write-char #\' escaped) + for char across (value string) + for code = (char-code char) + for special = (lisp-special-char-to-js char) + do + (cond + (special + (write-char #\\ escaped) + (write-char special escaped)) + ((or (<= code #x1f) (>= code #x80)) + (format escaped "\\u~4,'0x" code)) + (t (write-char char escaped))) + finally (write-char #\' escaped))))) + +(defparameter *js-lisp-escaped-chars* + '((#\' . #\') + (#\\ . #\\) + (#\b . #\Backspace) + (#\f . #\Form) + (#\n . #\Newline) + (#\r . #\Return) + (#\t . #\Tab))) + +(defun lisp-special-char-to-js(lisp-char) + (car (rassoc lisp-char *js-lisp-escaped-chars*))) hunk ./t/test.lisp 137 +(test escape-sequences-in-string + (let ((escapes `((#\\ . #\\) + (#\b . #\Backspace) + (#\f . #\Form) + ("u000B" . ,(code-char #x000b));;Vertical tab, too uncommon to bother with + (#\n . #\Newline) + (#\r . #\Return) + (#\' . #\');;Double quote need not be quoted because parenscript strings are single quoted + (#\t . #\Tab) + ("u001F" . ,(code-char #x001f));; character below 32 + ("u0080" . ,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure. + ("uABCD" . ,(code-char #xabcd)))));; Really above ascii. + (loop for (js-escape . lisp-char) in escapes + for generated = (js-to-string `(let ((x , (format nil "hello~ahi" lisp-char))))) + for wanted = (format nil "{ + var x = 'hello\\~ahi'; +}" js-escape) + do (is (string= generated wanted))))) + }