;;; sixel.el --- minor mode for processing sixel graphics ;; Copyright (C) 2019 Tim Vaughan ;; Author: Tim Vaughan ;; Created: 19 May 2019 ;; Version: 1.0.0 ;; Keywords: ;; Homepage: https://github.com/tgvaughan/sixel ;; Package-Requires: ((emacs "25")) ;;; Commentary: ;;; Code: (defvar test-string (concat "q" "#0;2;0;0;0#1;2;100;100;0#2;2;0;100;0" "#1~~@@vv@@~~@@~~$" "#2??GG????-" "#1!14@")) (defun sixel-get-params (string) "Retrieve the sixel parameters." (car (split-string string "q"))) (defun sixel-get-data (string) "Retrieve data string." (substring string (1+ (string-match "q" string)))) (defun sixel-tag-bits (sixel n tag) "Set bits of SIXEL corresponding to N with to the value TAG." (dotimes (i 6) (if (= (% n 2) 1) (aset sixel i tag)) (setq n (/ n 2)))) (defun sixel-tag-sixel-in-row (row index char tag) "Tag the bits of the sixel at INDEX in the list identified by the variable ROW-VARIABLE corresponding to input character CHAR with TAG." (while (not (< index (length row))) (push (make-vector 6 nil) row)) (let ((sixel (elt row (- (length row) 1 index)))) (sixel-tag-bits sixel (- char 63) tag)) row) (defun sixel-process-data (string) "Convert STRING into a list of lists representing individual sixels." (with-temp-buffer (insert string) (goto-char (point-min)) (let ((idx-out 0) this-row rows current-colour colour-map finished) (while (not finished) (cond ((looking-at "#\\([0-9]+\\);\\([0-9]+\\);\\([0-9]+\\);\\([0-9]+\\);\\([0-9]+\\)") (let ((tag (intern (match-string 1))) (mode (match-string 2)) (r (string-to-number (match-string 3))) (g (string-to-number (match-string 4))) (b (string-to-number (match-string 5)))) (push (list tag r g b) colour-map))) ((looking-at "#\\([0-9]+\\)") (let ((tag (intern (match-string 1)))) (setq current-colour tag))) ((looking-at "\\$") (setq idx-out 0)) ((looking-at "-") (push (reverse this-row) rows) (setq this-row nil) (setq idx-out 0)) ((looking-at "!\\([0-9]+\\)\\([?-~]\\)") (let ((repeat-count (string-to-number (match-string 1))) (char (elt (match-string 2) 0))) (dotimes (i repeat-count) (setq this-row (sixel-tag-sixel-in-row this-row idx-out char current-colour)) (setq idx-out (1+ idx-out))))) ((looking-at "\\([?-~]\\)") (let ((char (elt (match-string 1) 0))) (setq this-row (sixel-tag-sixel-in-row this-row idx-out char current-colour)) (setq idx-out (1+ idx-out)))) (t (setq finished t))) (goto-char (match-end 0))) (push (reverse this-row) rows) (list color-map (reverse rows))))) ;; sixel.el ends here