Time-stamp: <2021-03-11 14:34>
Emacs, Org-mode, and Gemini
There is some discussion on the gemini email list about rendering tables and such. Personally, I'm not in favor of adding especially this to the Gemini file syntax -- we all know what happened with tables in HTML. On the other hand, it would be nice to have a richer display of content including tables proper and e.g. source code with syntax highlighting.
I'm using Elpher in Emacs to browse Gemspace. I'm also using Germinal to serve my capsule, a Gemini server written in Common Lisp. It just so happens that a mime type for org-mode is predefined in Germinal. So why not just use Org for the fancy stuff?
By default, elpher displays Org files as plain text. Just switching to Org-mode kills the browsing session. Org files from unknown sources can pose a certain danger as well because they can contain code to be evaluated when the user set org-confirm-babel-evaluate to nil.
My Elpher configuration opens an org file in a new buffer, sets org-confirm-babel-evaluate to t for the buffer, regardless of system-wide setting, and uses a keymap that allows to go back to elpher or save the file to disk. The file is also opened read-only. That, I hope, makes it safe enough. Here's the configuration:
(use-package elpher
:ensure t
:config
(use-package elpher
:ensure t
:config
(defun elpher-render-org (data &optional _mime-type-string)
"Render DATA as Org by opening a new buffer and switching to Org mode"
(let ((buf (generate-new-buffer "elpher-org")))
(with-current-buffer buf
(if (not data)
t
(progn (switch-to-buffer buf)
(setq elpher-org-map (make-sparse-keymap))
(define-key elpher-org-map (kbd "b") (lambda () (interactive)
(kill-current-buffer)
(switch-to-buffer "*elpher*")
(elpher-back)))
(define-key elpher-org-map (kbd "W") (lambda () (interactive) (save-buffer default-directory t)))
(make-local-variable 'org-confirm-babel-evaluate)
(setq org-confirm-babel-evaluate t)
(org-mode)
(insert data)
(view-mode t)
(use-local-map elpher-org-map)
(message "Use W to save to file, b to return to elpher. View-mode keybindings apply."))))))
(defun elpher-render-gemini (body &optional mime-type-string)
"Render gemini response BODY with rendering MIME-TYPE-STRING."
(if (not body)
t
(let* ((mime-type-string* (if (or (not mime-type-string)
(string-empty-p mime-type-string))
"text/gemini; charset=utf-8"
mime-type-string))
(mime-type-split (split-string mime-type-string* ";" t))
(mime-type (string-trim (car mime-type-split)))
(parameters (mapcar (lambda (s)
(let ((key-val (split-string s "=")))
(list (downcase (string-trim (car key-val)))
(downcase (string-trim (cadr key-val))))))
(cdr mime-type-split))))
(when (string-prefix-p "text/" mime-type)
(setq body (decode-coding-string
body
(if (assoc "charset" parameters)
(intern (cadr (assoc "charset" parameters)))
'utf-8)))
(setq body (replace-regexp-in-string "\r" "" body)))
(pcase mime-type
((or "text/gemini" "")
(elpher-render-gemini-map body parameters))
("text/html"
(elpher-render-html body))
("text/org-mode"
(elpher-render-org body))
((pred (string-prefix-p "text/"))
(elpher-render-gemini-plain-text body parameters))
((pred (string-prefix-p "image/"))
(elpher-render-image body))
(_other
(elpher-render-download body)))))))
Prerequisite for this to work is that the server returns a mime type of "text/org-mode" for an Org file.
Try this with the above configuration:
----------
language: EN
tags: emacs lisp gemini org-mode