Hello,
there are situations in which I find myself frequently using the same format "pattern", which I'd like to abstract away. A concrete example is from my Declt package[1] which prints a lot in Texinfo format.
Since Texinfo has a couple of special characters (e.g. @), I have an ESCAPE function which takes a string and returns another one with all special characters escaped. In the Declt code, I hence have very frequent calls which look like this:
(format stream "... ~A ..." #|...|# (escape str) #|...|#)
This is frustrating because I would like to abstract away the relation "~A <-> #'escape". Of course there are solutions (I could provide my own wrapper around FORMAT in some way) but none of them seem satisfactory.
I'm aware of the ~// construct, which I find extremely cumbersome. Does anybody actually use it? It seems to me that the package handling part, specifically, makes it totally unusable. Just imagine that I would need to do something like that if I were to use it:
(format stream "... ~/com.dvlsoft.declt:escape/ ..." #|...|# str #|...|#)
and you get the idea! :-)
No, in fact, the problem is that FORMAT control sequences are not extensible. This reminds me of something that we have in the Gnus mail/newsreader. It's called "user format functions". Gnus Group and Summary buffer lines, for example, are define by a format string with a set of predefined %<char> constructs. One of them, %u<char> lets you define and use your own function, called gnus-user-format-function-<char>.
So what I would like to do is more or less define a function FORMAT-FUNCTION-E, just like a standard formatter, and then be able to write something like that:
(format stream "... ~\e\ ..." #|...|# str #|...|#)
Of course, there are package issues. Maybe we would need a centralized mapping between function names (what goes in ~\) and actual symbols denoting the actual function? Possibly with the possibility to override the mapping by providing a package prefix in the ~\ construct?
In fact, the more I think about it, the more it sounds like having a format-table facility, much like what a readtable is, with a similar API. You could do (in-format-table :my-table-name) at the beginning of a file and have a totally customized set of format control sequences, possibly inheriting the standard ones.
WDYT? Does something like that already exists[2]?
Footnotes: [1] http://www.lrde.epita.fr/~didier/software/lisp/misc.php#declt
[2] I've heard of something called fmt for scheme, but don't know much about it.
Yes, it is indeed quite revolting, and lacking in aesthetics. But I find that I am using it, for some of my dynamic menu building. Oh vile hack!
- nick
- Didier Verna qvqvre@yeqr.rcvgn.se [2011-01-25 18:05:11 +0100]:
I'm aware of the ~// construct, which I find extremely cumbersome. It seems to me that the package handling part, specifically, makes it totally unusable.
exactly.
Does anybody actually use it?
yes.
WDYT? Does something like that already exists[2]?
clisp has "~!"
http://clisp.sourceforge.net/impnotes/print-formatted.html
The additional FORMAT instruction ~! is similar to ~/, but avoids putting a function name into a string, thus, you might not need to specify the package explicitly.
(FORMAT stream "~arguments!" function object)
is equivalent to
(FUNCALL function stream object colon-modifier-p atsign-modifier-p arguments)
Sam Steingold sds@gnu.org wrote:
clisp has "~!"
http://clisp.sourceforge.net/impnotes/print-formatted.html
The additional FORMAT instruction ~! is similar to ~/, but avoids putting a function name into a string, thus, you might not need to specify the package explicitly.
(FORMAT stream "~arguments!" function object)
is equivalent to
(FUNCALL function stream object colon-modifier-p atsign-modifier-p arguments)
That's nice. Thanks for the pointer.