Discussion:
Common Lisp question
Jeffrey Massung
2014-07-20 22:21:01 UTC
Permalink
Okay, I feel like a dolt, but this is something that's always eluded me
in CL. How do I write unicode (well, specifically multibyte) characters
to a file?

For example:

(with-output-to-string (s)
(princ #\u+2022 s))

Error: Cannot write SIMPLE-CHAR into stream.

Makes sense. So...

(with-output-to-string (s nil :element-type 'character)
(princ #\u+2022 s))

"•"

Success. Let's try the same thing with a file, though:

(with-open-file (s #p"~/test.txt" :element-type 'character :direction
:output)
(princ #\u+2022 s))

Error: Cannot write SIMPLE-CHAR into stream.

I've never been able to use with-open-file to create a "character"
stream for any character class other than a base-char. How do I do this? :-)

Thanks!

Jeff M.

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-***@lispworks.com
http://www.lispworks.com/support/lisp-hug.html
Pierpaolo Bernardi
2014-07-21 03:24:24 UTC
Permalink
Post by Jeffrey Massung
(with-open-file (s #p"~/test.txt" :element-type 'character :direction
:output)
(princ #\u+2022 s))
Error: Cannot write SIMPLE-CHAR into stream.
I've never been able to use with-open-file to create a "character" stream
for any character class other than a base-char. How do I do this? :-)
You read the documentation of the CL function OPEN, supplemented by
the implementation specific details that the documentation for OPEN
directs you to look at.

(The documentation for WITH-OPEN-FILE directs you to OPEN.)

P.

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-***@lispworks.com
http://www.lispworks.com/support/lisp-hug.html
Camille Troillard
2014-07-21 07:24:38 UTC
Permalink
Hi Jeff,

Have you tried setting this:

(lw:set-default-character-element-type 'lw:simple-char)


http://www.lispworks.com/documentation/lw61/LW/html/lw-966.htm


I set the default character element type in my .lispworks file and at the beginning of every delivery script.


Best,
Cam
Okay, I feel like a dolt, but this is something that's always eluded me in CL. How do I write unicode (well, specifically multibyte) characters to a file?
(with-output-to-string (s)
(princ #\u+2022 s))
Error: Cannot write SIMPLE-CHAR into stream.
Makes sense. So...
(with-output-to-string (s nil :element-type 'character)
(princ #\u+2022 s))
"•"
(with-open-file (s #p"~/test.txt" :element-type 'character :direction :output)
(princ #\u+2022 s))
Error: Cannot write SIMPLE-CHAR into stream.
I've never been able to use with-open-file to create a "character" stream for any character class other than a base-char. How do I do this? :-)
Thanks!
Jeff M.
_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-***@lispworks.com
http://www.lispworks.com/support/lisp-hug.html
Tim Bradshaw
2014-07-21 10:33:26 UTC
Permalink
(with-open-file (s #p"~/test.txt" :element-type 'character :direction :output)
(princ #\u+2022 s))
1. You need to set the external format for the file so LW knows how to encode the Unicode. There is a mass of LW documentation on this, most of which I have not read, but :utf-8 will work as en external format. There is almost certainly a way of making that be the default external format.

2. You then need to make sure that the characters you write can be encoded in that format, and (at least for LW) this means they need to be LW:SIMPLE-CHARs not CHARACTERs. Camille mentioned how you can make this the default.

So:

(with-open-file (s #p"/tmp/ts.out"
:element-type 'lw:simple-char
:external-format ':utf-8
:direction ':output
:if-exists ':supersede)
(princ #\u+2022 s))

This is all described in the "Internationalization" chapter of the manual

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-***@lispworks.com
http://www.lispworks.com/support/lisp-hug.html
Jeffrey Massung
2014-07-21 13:47:57 UTC
Permalink
Thanks, everyone! I very much appreciate it.

Jeff M.
Monday, July 21, 2014 5:33 AM
1. You need to set the external format for the file so LW knows how to
encode the Unicode. There is a mass of LW documentation on this, most
of which I have not read, but :utf-8 will work as en external format.
There is almost certainly a way of making that be the default external
format.
2. You then need to make sure that the characters you write can be
encoded in that format, and (at least for LW) this means they need to
be LW:SIMPLE-CHARs not CHARACTERs. Camille mentioned how you can make
this the default.
(with-open-file (s #p"/tmp/ts.out"
:element-type 'lw:simple-char
:external-format ':utf-8
:direction ':output
:if-exists ':supersede)
(princ #\u+2022 s))
This is all described in the "Internationalization" chapter of the manual
Loading...