2012-10-24 34 views
5

Mam listę list ciągów, które muszę sformatować przy użyciu programu Emps LISP. To był jedyny sposób, w jaki mogłem o tym pomyśleć:Jak sformatować listę ciągów znaków

(setq slist '("is there" "any" "way" "directed iteration"))  
(format "%s _%s_ %s to do %S in elisp?" 
     (elt slist 0) 
     (elt slist 1) 
     (elt slist 2) 
     (elt slist 3) 
     (elt slist 4)) 

Dając mi to, czego chcę.

is there _any_ way to do "directed iteration" in elisp? 

Musi istnieć bardziej elegancki sposób, ale po długim zastanowieniu, nie widzę go. Jestem nowy w emacs seplenienie i być może brakuje mi czegoś oczywistego.

Odpowiedz

4

Zastosowanie apply:

(apply 'format "%s _%s_ %s to do %S in elisp?" slist) 

Funkcja apply wykonuje funkcję (lub symbol) jako pierwszy argument, to liczby pojedynczych argumentów, kończąc na liście argumentów.

+0

Tak, właśnie dzięki. Było to oczywiste i brakowało mi charakteru wniosku. I wow, jaka to świetna funkcja! –

2

Postanowiłem zrobić z tego samodzielny projekt dodając kilka dodatkowych funkcji, naprawiając błędy i dodając kolejne błędy! yey :)

można znaleźć tutaj: http://code.google.com/p/formatting-el/source/browse/trunk/formatting.el projekt

Nie wiesz ile to jest wadliwy, ale na pierwszy rzut oka wydaje się działać:

(defun directive-end (c) 
    (member c "csdoxXeg%")) 

(defun pp-if-nil (spec) 
    (position ?\% spec)) 

(defun pp-list (spec args) 
    (let ((pos 0) (last 0) (fstring "% ") current seen-^) 
    (catch 't 
     (while t 
     (setq pos (1+ (or (position ?% spec :start pos) -1)) 
       current (aref spec pos)) 
     (unless (and seen-^ (char-equal current ?\}) (null args)) 
      (princ (substring spec last (1- pos)))) 
     (setq last pos pos (1+ pos)) 
     (cond 
     ((char-equal current ?^) 
      (incf last) 
      (setq seen-^ t)) 
     ((char-equal current ?\{) 
      (setq pos (+ pos (pp-list (substring spec pos) (car args))) 
       args (cdr args) 
       last pos 
       seen-^ nil)) 
     ((char-equal current ?\}) 
      (if args (setq pos 0 last 0) 
      (throw 't nil))) 
     ((char-equal current ?%) 
      (setq seen-^ nil last (1+ last)) 
      (write-char ?%)) 
     (t (unless args (error "Not enough argumens for list iteration")) 
      (setf (aref fstring 1) current) 
      (princ (format fstring (car args))) 
      (setq args (cdr args) 
        seen-^ nil 
        last 
        (or (position-if #'directive-end spec :start pos) 
         pos)))))) pos)) 

(defun cl-format (spec &rest args) 
    (with-output-to-string 
    (let ((pos 0) (last 0) (fstring "% ") current) 
     (catch 't 
     (while t 
      (setq pos (1+ (or (position ?\% spec :start pos) -1)) 
       current (aref spec pos)) 
      (when (= pos 0) (throw 't nil)) 
      (princ (substring spec last (1- pos))) 
      (setq last pos pos (1+ pos)) 
      (cond 
      ((char-equal current ?^) 
      (unless args 
       (setq last (pp-if-nil spec) 
        pos last))) 
      ((char-equal current ?\{) 
      (setq pos (+ pos (pp-list (substring spec pos) (car args))) 
        args (cdr args) 
        last pos)) 
      ((char-equal current ?\}) 
      (error "Unmatched list iteration termination directive")) 
      ((char-equal current ?%) 
      (write-char ?%) 
      (incf last)) 
      (t (unless args (error "Not enough argumens")) 
       (setf (aref fstring 1) current) 
       (princ (format fstring (car args))) 
       (setq args (cdr args) 
        last 
        (or (position-if #'directive-end spec :start pos) 
         pos)))) 
      (incf pos)))))) 

(cl-format "begin: %{%s = %d%^,%}; %% %c %% %{%{%s -> %d%^.%},%}" 
      '(a 1 b 2 c 3) ?\X '((a 2 b 4 c 6) (a 1 b 3 c 5))) 
"begin: a = 1,b = 2,c = 3; % X % a -> 2.b -> 4.c -> 6,a -> 1.b -> 3.c -> 5," 

Ten próbuje replikować niektóre (bardzo uproszczone) Typowe zachowanie drukowania w stylu Lisp w dyrektywach ~{ ... ~}.

Powiązane problemy