Reputation: 17576
I wonder if it is possible to tell FORMAT to ignore undefined format directives. I have looked at the pages for FORMAT in the CLHS but I don't see anything.
What I am trying to do is to get FORMAT to ignore ~m
in a format string and just output ~m
instead of trying to replace it with something. My plan is that at that point I will call another function which knows what to do with with ~m
.
I guess a related question is then, is there a way to define a function to handle a format directive which is otherwise not defined?
In anticipation of some questions. (1) I guess a workaround would be to substitute a placeholder for ~m
, and then substitute it back in afterwards and keep going. I guess I'll do that if all else fails. (2) I guess another general strategy would be to call the other function first, to handle ~m
, then call FORMAT on the result. Unfortunately that other function recognizes some of the same directives, and barfs on others; it doesn't recognize only ~m
and ignore everything else.
Upvotes: 1
Views: 107
Reputation: 2282
From http://www.lispworks.com/documentation/lw50/CLHS/Body/22_c.htm
The control-string argument to format is actually a format control. That is, it can be either a format string or a function, for example a function returned by the formatter macro.
So you can do:
(defmacro frmt (control-string)
(let ((str (cl-ppcre:regex-replace-all "~m" control-string "~~m")))
`(formatter ,str)))
Now:
(format t (frmt "~m~A") 1)
outputs:
~m1
NIL
This way you don't have to modify the control string directly.
You do have to modify the call to format
to include frmt
.
Upvotes: 1
Reputation:
I don't think there is a way of doing that portably (implementations may let you do all sorts of magic). I'd write a quote-weird-tildes
and dequote-weird-tildes
pair of functions and then write code like:
(defun format/qw (control &rest args)
(declare (dynamic-extent args)
(type string control)) ;can't be a function
(dequote-weird-tildes
(apply #'format nil (quote-weird-tildes control) args)))
Now you have a function which looks like (format nil ...)
and is no harder to use than that. For extra value the quoting and dequoting functions should not cons a string if they don't have to.
Upvotes: 1
Reputation: 1934
You can define your own format directive with ~/name/, where name is the name of the function which is called. In your case you would have:
(format t "~/m/" 1)
(defun m (stream n colon-mod at-mod)
(format stream "~a" n)) ; or do something else with n
You still need to change the control string, but you can add a preprocessing step where "~m" is replaced by "~/m/".
Upvotes: 3