;;; ox-my-html.el --- HTML Derived Backend -*- lexical-binding: t; -*-
;; Copyright (C) 2023 Free Software Foundation, Inc.
;; Author: Carsten Dominik
;; Jambunathan K
;; Gerard Vermeulen
;; Maintainer: Gerard Vermeulen
;; Keywords: org, hypermedia
;; This file is NOT part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see .
;;; Commentary:
;; This library implements a HTML derived backend for Org export:
;; 1. The function org-my-html-link is an edited org-html-link copy.
;; 2. The Org ox-beamer library shows how to code derived backends.
;; 3. It borrows code from https://emacs.stackexchange.com/a/57433 to
;; embed SVG images in exported HTML files.
;;; Code:
(require 'org-macs)
(org-assert-version)
(require 'cl-lib)
(require 'ox-html)
;;; Define Backend
(org-export-define-derived-backend 'my-html 'html
:menu-entry
'(?h 1
((?M "As MY-HTML buffer" org-my-html-export-as-html)
(?m "As MY-HTML file" org-my-html-export-to-html)
(?O "As MY-HTML file and open"
(lambda (a s v b)
(if a (org-my-html-export-to-html t s v b)
(org-open-file (org-my-html-export-to-html nil s v b)))))))
:options-alist
'((:html-embed-svg-excludes "HTML_EMBED_SVG_EXCLUDES" nil
org-html-embed-svg-excludes split)
(:html-embed-svg-includes "HTML_EMBED_SVG_INCLUDES" nil
org-html-embed-svg-includes split)
(:with-html-svg-embedding nil "html-embed-svg" org-html-embed-svg))
:translate-alist
'((link . org-my-html-link)))
;;; User Configuration Variables
;;;; Links :: Embed SVG
(defcustom org-html-embed-svg nil
"Non-nil means embed SVG images into exported HTML pages,
otherwise link to SVG images from exported HTML pages.
This option can also be set in Org files with
#+OPTIONS: html-embed-svg:t
or
#+OPTIONS: html-embed-svg:nil
to enable or disable SVG embedding in exported HTML."
:group 'org-export-html
:version "30.0"
:type 'boolean)
(defcustom org-html-embed-svg-excludes nil
"List of SVG files to exclude from SVG embedding.
This option overrules an `org-html-embed-svg' non-nil value.
It can also be set with the HTML_EMBED_SVG_EXCLUDES keyword."
:group 'org-export-html
:version "30.0"
:type '(repeat string)
:safe (lambda (x) (and (listp x) (cl-every #'stringp x))))
(defcustom org-html-embed-svg-includes nil
"List of SVG files to include in SVG embedding.
This option overrules an `org-html-embed-svg' nil value.
It can also be set with the HTML_EMBED_SVG_INCLUDES keyword."
:group 'org-export-html
:version "30.0"
:type '(repeat string)
:safe (lambda (x) (and (listp x) (cl-every #'stringp x))))
;;; Internal Functions
(defun org-my-html--embed-svg-p (link path info)
"Check whether LINK and INFO specify to embed the SVG file named PATH.
LINK must have no contents and link to an SVG file. INFO may contain
lists of SVG files to include in and/or to exclude from embedding."
(and (not (org-element-contents link))
(let ((case-fold-search t))
(string-match-p ".svg\\'" (org-element-property :path link)))
(or (and (plist-get info :with-html-svg-embedding)
(not (member path (plist-get info :html-embed-svg-excludes))))
(and (not (plist-get info :with-html-svg-embedding))
(member path (plist-get info :html-embed-svg-includes))))))
(defun org-my-html-svg-contents (path)
"Return the SVG contents of the file named PATH."
(with-temp-buffer
(insert-file-contents path)
;; Delete text preceding something starting as an SVG root element.
;; The intent is to remove XML declarations (and XML comments).
;; This breaks in case of a preceding XML comment with