systemreboot git repos ennum / master ennum-gemini.el
master

Tree @master (Download .tar.gz)

ennum-gemini.el @masterraw · history · blame

;; -*- lexical-binding: t -*-

(require 'ox)
(require 'ox-gemini)
(require 'subr-x)
(require 'xmlgen)
(require 'ennum-lang)

(defun expand-file-name* (name base-directory)
  (expand-file-name name (concat "/" base-directory)))

(org-export-define-derived-backend 'ennum-gemini 'gemini
  :translate-alist
  '((inner-template . ennum-gemini-inner-template)
    (section . ennum-gemini-section)
    (paragraph . ennum-gemini-paragraph)
    (link . ennum-gemini-link))
  :options-alist
  '((:summary "SUMMARY" nil nil parse)
    (:thumbnail "THUMBNAIL" nil nil t)
    (:translation-group "TRANSLATION_GROUP" nil nil t)))

(defun ennum-gemini-inner-template (contents info)
  (concat
   ;; Date
   (org-export-get-date info "%B %d, %Y\n\n")
   ;; Interlanguage language links
   (mapconcat (pcase-lambda (`(,lang . ,slug))
                (ennum-link-export-post
                 slug
                 (map-elt ennum--iso-639-1-alist lang)
                 (org-export-backend-name (plist-get info :back-end))
                 info))
              (ennum-post-translations (plist-get info :ennum-post))
              "\n")
   "\n\n"
   ;; Body
   contents
   ;; Tags
   "\nTags:\n"
   (mapconcat (lambda (tag)
                (ennum-link-export-tag
                 (ennum-add-tongue-suffix tag (plist-get info :language))
                 tag
                 (org-export-backend-name (plist-get info :back-end))
                 info))
              (plist-get info :filetags)
              "\n")))

(defun ennum-gemini-section (section contents info)
  ;; Render links at the end of the section, but only if they are not
  ;; image, video or pdf links.
  (pcase (seq-remove (lambda (link)
                       (member (org-element-property :type link)
                               (list "image" "video" "pdf")))
                     (org-ascii--unique-links section info))
    ('()
     contents)
    (links
     (org-remove-indentation
      (concat (org-element-normalize-string contents)
              "\n\n"
              (org-gemini--describe-links
               links
               (org-ascii--current-text-width section info)
               info))))))

(defun ennum-gemini-paragraph (paragraph contents info)
  ;; If the paragraph contains an image or video link, then it is an
  ;; image paragraph; tag on the caption.
  (if (= (length (org-element-map paragraph '(link)
                   (lambda (link)
                     (and (member (org-element-property :type link)
                                  (list "image" "video"))
                          link))))
         1)
      (concat (string-trim contents)
              " "
              (org-export-data (org-export-get-caption paragraph)
                               info))
    ;; Else, fall back to the gemini backend.
    (org-gemini-paragraph paragraph contents info)))

(defun ennum-gemini-link (link desc info)
  ;; Try a custom link type before falling back to the gemini backend.
  (or (org-export-custom-protocol-maybe link desc 'ennum-gemini info)
      (org-gemini-link link desc info)))

(provide 'ennum-gemini)