Erik Naggum <erik@naggum.no> wrote:
+---------------
| given that a syntax familiar to Emacs Lisp (and C) users is unavailable...
| #.(format nil "foo~Cbar" #\Newline)
| #.(concatenate 'string "foo" '(#\Newline) "bar")
+---------------
You realize, I assume, that this particular example can already be
done easily in CL, like so:
#.(format nil "foo~%bar")
And (if you don't mind tabs being expanded) for "foo\tbar\nbaz\tgorp\n\f"
you can use:
#.(format nil "foo~9,8Tbar~%baz~9,8Tgorp~%~|")
So back to the general case...
+---------------
| how would one accomplish the same goal: to embed a (named) control
| character in a literal string in source code that is likely to travel
| across all sorts of information-losing channels? ...
| I feel I must have overlooked something or think in the wrong terms.
+---------------
I suspect the latter. Look, Lisp is a language for building languages,
right? So design a "language" for expressing the kind of strings you
want, and build a mechanism for translating that into Lisp.
Oh? You say you already *have* the language you want, namely, good old
familiar C strings? Fine! Then simply write a function that takes C
strings as input (in the form of "control strings") and gives you Lisp
strings as output. Something like this:
(cstr->string "First line:\\ttext\\nSecond line:\\tmore text\\007\\n")
==> "First line: text
Second line: more text(*ding!*)
" [i.e. ^G ]
(Unfortunately, if you want the use "backslash" as your escape character,
you'd have to double them everywhere [as shown] to get them into your
control string. And if you want to use C strings in "format" calls, you
probably don't want to use "~", either. How about "%" or "^" or "&"?)
Then if you wanted to use these inside "format", perhaps to print lines
with fields prefixed by the tab character and suffixed by (say) <cntl-A>,
you could do something like this (let "c2s" be an alias for "cstr->string"):
(format nil #.(c2s "\\tfield1=~A\\001\\tfield2=~A\\001~%") 123 456)
==> " field1=123 field2=456
"
a.k.a. ==> "^Ifield1=123^A^Ifield2=456^A^J"
By the way, with some work (well, probably quite a bit more!), a similar
hack would enable one to rewrite C "printf" control strings into "format"
control strings (at least, for those things that map):
(pf2fmt "foo = %8.8x, bar = %d\\n")
==> "foo = ~8,'0X, bar = ~D~%"
so you could say:
(format nil #.(pf2fmt "foo = 0x%8.8x, bar = %d\\n") 123456 789)
==> "foo = 0x0001e240, bar = 789
"
+---------------
| (incidentally, my actual problem case involves lots of escape sequences for
| a form printer now written in Emacs Lisp with the `cl' package. it is
| trivially portable to Common Lisp except for the string literals.)
+---------------
So write yourself a "c2s" function, and with a little editing to double
the backslashes and wrap #.(c2s ...) around the strings, you're home.
-Rob
-----
Rob Warnock, 7L-551 rpw3@sgi.com
Silicon Graphics, Inc. http://reality.sgi.com/rpw3/
2011 N. Shoreline Blvd. Phone: 415-933-1673 FAX: 415-933-0979
Mountain View, CA 94043 PP-ASEL-IA