Numbra
Numbra

Reputation: 642

Common Lisp: custom predicate for conditional formatting

I have a list consisting of two different kind of elements:

I would like this list to be printed with the following structure: all elements separated by commas, and each cons cell (a . b) is printed as a=b.

The real goal is to generate Tikz/LaTeX code using Common Lisp, and this specific part of the code is just there to generate "options" (to an environment, a package, a command ...)

Example:

>>> (format nil "<cool-format-string>" '(draw (color . red) dashed (fill . gray)))
[draw, color=red, dashed, fill=gray]

I know about iteration directives, conditional ones, etc, in format. The only problem is that I want to print my list elements differently according to their type, not according to their numerical value or their 'truth' (nil vs anything else)

Besides writing a custom directive with ~/, is there a way to use another construction which would do something akin to the conditional directive, but using a custom predicate ?

Upvotes: 0

Views: 230

Answers (1)

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 9865

(defun dotted-pair-p (x)
  (and (listp x) (not (listp (cdr x)))))

(defun print-fancy (lst)
  (let ((res (mapcar (lambda (x) (if (dotted-pair-p x)
                                     (format nil "~a=~a" (car x) (cdr x))
                                     (format nil "~a" x)))
                     lst)))
    ;; add the ', ' inbetween the strings
    ;; and put the result in between "[]"
    (format nil "[~{~a~^, ~}]" res)))
                                  

(print-fancy '(draw (color . red) dashed (fill . gray)))
;; "[DRAW, COLOR=RED, DASHED, FILL=GRAY]"

Upvotes: 3

Related Questions