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:
M | emacs-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)