From: ey15
Subject: Re: backslashes in strings
Date: 
Message-ID: <7fhmrg$k7e$1@news.liv.ac.uk>
In article <··············@eho.eaglets.com>, ···@goems.com says...
>
>Is there away to make CL interpret `\n' in a string as an embedded
>newline?
>IIUC, this would break 2.1.4.6.1: (eq 'nbc '\nbc).
>Well, I can live with it (I can turn if off by
>(setq *readtable* (copy-readtable)) at any time).
>
>Unfortunately, the obvious trick:
>  (set-macro-character #\\ (lambda (stream char) 
>                             (setq char (read-char stream t nil t))
>                             (case char (#\n #\Newline) (t char)))
>                       nil)
>does no good:
>
>USER(2): (print "aaa\nccc")
>
>"aaa\\nccc" 
>"aaa\\nccc"
>
>while I want it to print
>"aaa
>ccc"
>
>Any suggestions?

I had a quick go at what you wanted.  This works for your example,
but probably needs some extra work.


(set-macro-character #\" #'(lambda (stream char)
   (declare (ignore char))
   (LOOP WITH char-to-add
         FOR this-char = (read-char stream t nil t)
         UNTIL (CHAR= this-char \")
         IF (AND (CHAR= this-char #\\) (CHAR= (PEEK-CHAR nil stream) \n))
         DO (SETQ char-to-add #\Newline)
         ELSE
         DO (SETQ char-to-add this-char)
         COLLECTING char-to-add INTO list-of-characters
         FINALLY RETURN (COERCE list-of-characters 'STRING))))

BTW, you didn't put a #' before the lambda.

I extended the double quote character.  It's probably not
that efficient, but who cares, it seams to work :-).

CL-USER 55 > "aaa\nccc"""
"aaa
nccc"


CL-USER 58 > "aaa\bnccc"
"aaa\\bnccc"