Initial string processing function seems to work.
[sixel.git] / sixel.el
1 (defvar test-string
2   (concat "q"
3           "#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0"
4           "#1~~@@vv@@~~@@~~$"
5           "#2??GG????-"
6           "#1!14@"))
7
8
9 (defun sixel-get-params (string)
10   "Retrieve the sixel parameters."
11   (car (split-string string "q")))
12
13 (defun sixel-get-data (string)
14   "Retrieve data string."
15   (substring string (1+ (string-match "q" string))))
16
17 (defun sixel-compute-row-length (string)
18   (apply 'max
19          (mapcar
20           (lambda (substr)
21             (apply 'max (mapcar
22                          (lambda (subsubstr)
23                            (length (subsubstr)))
24                          (split-string substr "$"))))
25           (split-string string -))))
26
27 (defun sixel-tag-bits (sixel n tag)
28   "Set bits of SIXEL corresponding to N with to the value TAG."
29   (dotimes (i 6)
30     (if (= (% n 2) 1)
31         (aset sixel i tag))
32     (setq n (/ n 2))))
33
34 (defun sixel-tag-sixel-in-row (row index char tag)
35   "Tag the bits of the sixel at INDEX in the list identified by
36 the variable ROW-VARIABLE corresponding to input character CHAR
37 with TAG."
38   (while (not (< index (length row)))
39     (push (make-vector 6 nil) row))
40   (let ((sixel (elt row (- (length row) 1 index))))
41     (sixel-tag-bits sixel (- char 63) tag))
42   row)
43
44 (defun sixel-process-data (string)
45   "Convert STRING into a list of lists representing individual sixels."
46   (with-temp-buffer
47     (insert string)
48     (goto-char (point-min))
49     (let ((idx-out 0)
50           this-row rows
51           current-colour colour-map
52           finished)
53       (while  (not finished)
54         (cond
55          ((looking-at "#\\([0-9]+\\);\\([0-9]+\\);\\([0-9]+\\);\\([0-9]+\\);\\([0-9]+\\)")
56           (let ((tag (intern (match-string 1)))
57                 (mode (match-string 2))
58                 (r (string-to-number (match-string 3)))
59                 (g (string-to-number (match-string 4)))
60                 (b (string-to-number (match-string 5))))
61             (push (list tag r g b) colour-map)))
62
63          ((looking-at "#\\([0-9]+\\)")
64           (let ((tag (intern (match-string 1))))
65             (setq current-colour tag)))
66
67          ((looking-at "\\$")
68           (setq idx-out 0))
69
70          ((looking-at "-")
71           (push (reverse this-row) rows)
72           (setq this-row nil)
73           (setq idx-out 0))
74
75          ((looking-at "!\\([0-9]+\\)\\([?-~]\\)")
76           (let ((repeat-count (string-to-number (match-string 1)))
77                 (char (elt (match-string 2) 0)))
78             (dotimes (i repeat-count)
79               (setq this-row
80                     (sixel-tag-sixel-in-row this-row idx-out char current-colour))
81               (setq idx-out (1+ idx-out)))))
82
83          ((looking-at "\\([?-~]\\)")
84           (let ((char (elt (match-string 1) 0)))
85             (setq this-row
86                   (sixel-tag-sixel-in-row this-row idx-out char current-colour))
87             (setq idx-out (1+ idx-out))))
88
89          (t (setq finished t)))
90
91         (goto-char (match-end 0)))
92       (push (reverse this-row) rows)
93       (reverse rows))))