You can write a printer function with a lambda expression taking one argument in two cases:
ses-define-local-printer
.
When doing so, please take care that the returned value is a string, or a list containing a string, even when the input argument has an unexpected value. Here is an example:
(lambda (val) (cond ((null val) "") ((and (numberp val) (>= val 0)) (format "%.1f" val)) (t (ses-center-span val ?# 'ses-prin1))))
This example will:
val
is nil
), print an
empty string ""
ses-prin1
), centered and surrounded by
#
filling.
Another precaution to take is to avoid stack overflow due to a
printer function calling itself indefinitely. This mistake can
happen when you use a local printer as a column printer,
and this local printer implicitly calls the current column printer, so it
will call itself recursively. Imagine for instance that you want to
create some local printer =fill
that would center the content
of a cell and surround it by equal signs =
, and you do it this
way:
(lambda (x) (cond ((null x) "") (t (ses-center x 0 ?=))))
Because =fill
uses the standard printer ses-center
without
explicitly passing any printer to it, ses-center
will call the
current column printer if any, or the spreadsheet default printer
otherwise. So using =fill
as a column printer will result in a
stack overflow in this column. SES does not check for that;
you just have to be careful. For instance, re-write =fill
like
this:
(lambda (x) (cond ((null x) "") ((stringp x) (ses-center x 0 ?= " %s ")) (t (ses-center-span x ?# 'ses-prin1))))
The code above applies the =
filling only to strings; it also
surrounds the string by one space on each side before filling with
=
signs. So the string ‘Foo’ will be displayed like ‘=== Foo ===’ in an 11 character wide column. Anything other than an empty cell
or a non-string is displayed as an error by using #
filling.