emacs-framebuffer

Emacs library to show images and documents in console using Linux framebuffer
Log | Files | Refs

commit 1d5f8baf63a127d3c0b98b4465f73141e096d583
parent 62e22ab9f310c2142327fc57dc9cf168ccc5d4da
Author: Tomas Hlavaty <tom@logand.com>
Date:   Sun,  5 Jul 2020 00:47:55 +0200

support abw, doc, docx, odt, rtf documents and p[bgnp]m and x[bp]m images

documents are converted via pdf to images

intermediate files are cached with sha256sum key

Diffstat:
Memacs-framebuffer.el | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 113 insertions(+), 23 deletions(-)

diff --git a/emacs-framebuffer.el b/emacs-framebuffer.el @@ -1,6 +1,6 @@ ;;; emacs-framebuffer.el ;;; -;;; Show images in console using Linux framebuffer. +;;; Show images and documents in console using Linux framebuffer. ;;; ;;; Copyright (C) 2020 Tomas Hlavaty <tom at logand dot com> ;;; @@ -12,6 +12,12 @@ ;;; ;;; - w3mimgdisplay from w3m terminal web browser ;;; +;;; Optional dependencies: +;;; +;;; - sha256sum from coreutils +;;; - pdftocairo and pdfinfo from poppler-utils to display pdf +;;; - abiword to display abw, doc, docx, odt, rtf +;;; ;;; Example configuration: ;;; ;;; (when (and (eq system-type 'gnu/linux) (not (display-graphic-p))) @@ -56,12 +62,25 @@ (defvar framebuffer-size nil) (defun framebuffer-file-format (file) - (let ((ext (file-name-extension file))) + (let ((name (file-name-sans-versions file))) (cond - ((equal ext "pbm") 'pbm) - ((equal ext "pdf") 'pdf) - ((equal ext "pgm") 'pgm) - ((equal ext "ppm") 'ppm) + ((string-match "\\.\\(abw\\|ABW\\)\\'" name) 'abw) + ((string-match "\\.\\(bmp\\|BMP\\)\\'" name) 'bmp) + ((string-match "\\.\\(doc\\|DOC\\)\\'" name) 'doc) + ((string-match "\\.\\(docx\\|DOCX\\)\\'" name) 'docx) + ((string-match "\\.\\(gif\\|GIF\\)\\'" name) 'gif) + ((string-match "\\.\\(jpe?g\\|JPE?G\\)\\'" name) 'jpeg) + ((string-match "\\.\\(odt\\|ODT\\)\\'" name) 'odt) + ((string-match "\\.\\(pbm\\|PBM\\)\\'" name) 'pbm) + ((string-match "\\.\\(pdf\\|PDF\\)\\'" name) 'pdf) + ((string-match "\\.\\(pgm\\|PGM\\)\\'" name) 'pgm) + ((string-match "\\.\\(png\\|PNG\\)\\'" name) 'png) + ((string-match "\\.\\(pnm\\|PNM\\)\\'" name) 'pnm) + ((string-match "\\.\\(ppm\\|PPM\\)\\'" name) 'ppm) + ((string-match "\\.\\(rtf\\|RTF\\)\\'" name) 'rtf) + ((string-match "\\.\\(tiff?\\|TIFF?\\)\\'" name) 'tiff) + ((string-match "\\.\\(xbm\\|XBM\\)\\'" name) 'xbm) + ((string-match "\\.\\(xpm\\|XPM\\)\\'" name) 'xpm) ))) (defun framebuffer-virtual-size () @@ -95,6 +114,16 @@ (call-process "sha256sum" nil t nil (expand-file-name file)) (buffer-substring (point-min) (+ (point-min) 64)))) +(defun framebuffer-cache-abiword (format ifile ofile) + (case format + ((abw odt rtf doc docx) + (unless (file-readable-p ofile) + (call-process "abiword" nil nil nil + "-t" (expand-file-name ofile) + (expand-file-name ifile))) + (when (file-readable-p ofile) + ofile)))) + (defun framebuffer-cache-to-pdf (format file) (framebuffer-cache-abiword format @@ -114,6 +143,10 @@ ofile)) (defun framebuffer-draw-now (x1 y1 w1 h1 x2 y2 w2 h2 file) + (let ((format (framebuffer-file-format file))) + (case format + ((abw odt rtf doc docx) + (setq file (framebuffer-cache-to-pdf format file))))) (case (framebuffer-file-format file) (pdf (setq file (framebuffer-cache-pdf-to-png @@ -248,14 +281,60 @@ (3 (setq h v))))))) (when (and w h) (cons w h)))))))) - (?P ;; ppm pnm + (?P ;; docx odt pbm pgm pnm ppm (case (framebuffer-next-u8 brook) - ((?3 ?6) + (?K + (case (framebuffer-file-format file) + (odt + (framebuffer-pdf-page-size + (framebuffer-cache-to-pdf 'odt file))) + (docx + (framebuffer-pdf-page-size + (framebuffer-cache-to-pdf 'docx file))))) + ((?1 ?2 ?3 ?4 ?5 ?6) (search-forward-regexp "^\\([0-9]+\\) \\([0-9]+\\)$") (cons (read (match-string 1)) (read (match-string 2)))))) - (t ;; xpm - (when (search-forward-regexp "\"[ ]*\\([0-9]+\\)[ ]+\\([0-9]+\\)[ ]+\\([0-9]+\\)[ ]+\\([0-9]+\\)[ ]*") - (cons (read (match-string 1)) (read (match-string 2))))) + (?< ;; abw + (case (framebuffer-next-u8 brook) + (?? + (case (framebuffer-next-u8 brook) + (?x + (case (framebuffer-next-u8 brook) + (?m + (case (framebuffer-next-u8 brook) + (?l + (case (framebuffer-next-u8 brook) + ((? ) + (let ((xml (xml-parse-file file))) + (ecase (caar xml) + (abiword + (framebuffer-pdf-page-size + (framebuffer-cache-to-pdf 'abw file)))))))))))))))) + (?{ ;; rtf + (case (framebuffer-next-u8 brook) + (?\\ + (case (framebuffer-next-u8 brook) + (?r + (case (framebuffer-next-u8 brook) + (?t + (case (framebuffer-next-u8 brook) + (?f + (framebuffer-pdf-page-size + (framebuffer-cache-to-pdf 'rtf file))))))))))) + (t ;; doc xbm xpm + (case (framebuffer-file-format file) + (doc + (framebuffer-pdf-page-size + (framebuffer-cache-to-pdf 'doc file))) + (xbm + (let (w) + (search-forward-regexp "_width[ ]+\\([0-9]+\\)") + (setq w (read (match-string 1))) + (search-forward-regexp "_height[ ]+\\([0-9]+\\)") + (cons w (read (match-string 1))))) + (xpm + (search-forward-regexp "\"[ ]*\\([0-9]+\\)[ ]+\\([0-9]+\\)[ ]+\\([0-9]+\\)[ ]+\\([0-9]+\\)[ ]*") + (cons (read (match-string 1)) (read (match-string 2)))))) )))) (defun framebuffer-image-file (file) @@ -281,9 +360,7 @@ (let ((f (dired-file-name-at-point))) (and f (not (file-directory-p f)) - (string-match - "jpe?g\\|JPE?G\\|png\\|PNG\\|bmp\\|BMP\\|gif\\|GIF\\|tiff?\\|TIFF?\\|ppm\\|PPM\\|pnm\\|PNM\\|xpm\\|XPM\\|pdf\\|PDF" - (or (file-name-extension f) ""))))) + (framebuffer-file-format f)))) (defun framebuffer-image-file-dired-next (arg) (interactive "^p") @@ -357,6 +434,8 @@ (case format (pdf (framebuffer-pdf-npages file)) + ((abw odt rtf doc docx) + (framebuffer-pdf-npages (framebuffer-cache-to-pdf format file))) (t 1)))) (defvar framebuffer-image-mode-hook nil) @@ -370,6 +449,14 @@ (setq framebuffer-image-mode-current-page 1) (setq framebuffer-image-mode-scale :fit-page) (setq framebuffer-image-mode-scroll 0) + (setq-local mode-line-position + '(" P" + (:eval (number-to-string framebuffer-image-mode-current-page)) + "/" + (:eval (typecase framebuffer-image-mode-npages + (number + (number-to-string framebuffer-image-mode-npages)) + (t "?"))))) (with-silent-modifications (erase-buffer) (insert "file: ") @@ -473,15 +560,18 @@ (defun framebuffer-install () (interactive) - (add-to-list 'auto-mode-alist '("\\.bmp\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.gif\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.jpe?g\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.pdf\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.png\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.pnm\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.ppm\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.tiff?\\'" . framebuffer-image-mode)) - (add-to-list 'auto-mode-alist '("\\.xpm\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(abw\\|ABW\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(bmp\\|BMP\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(docx?\\|DOCX?\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(gif\\|GIF\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(jpe?g\\|JPE?G\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(odt\\|ODT\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(p[bgnp]m\\|P[BGNP]M\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(pdf\\|PDF\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(png\\|PNG\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(rtf\\|RTF\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(tiff?\\|TIFF?\\)\\'" . framebuffer-image-mode)) + (add-to-list 'auto-mode-alist '("\\.\\(x[bp]m\\|X[BP]M\\)\\'" . framebuffer-image-mode)) (with-eval-after-load 'dired (define-key dired-mode-map "I" 'framebuffer-image-file-dired) (define-key dired-mode-map "N" 'framebuffer-image-file-dired-next)