;; -*- lexical-binding: t -*- (require 'ox) (require 'subr-x) (require 'xmlgen) (defconst ennum--iso-639-1-alist '(("ab" . "аҧсуа бызшәа, аҧсшәа") ("aa" . "Afaraf") ("af" . "Afrikaans") ("ak" . "Akan") ("sq" . "Shqip") ("am" . "አማርኛ") ("ar" . "العربية") ("an" . "aragonés") ("hy" . "Հայերեն") ("as" . "অসমীয়া") ("av" . "авар мацӀ, магӀарул мацӀ") ("ae" . "avesta") ("ay" . "aymar aru") ("az" . "azərbaycan dili") ("bm" . "bamanankan") ("ba" . "башҡорт теле") ("eu" . "euskara, euskera") ("be" . "беларуская мова") ("bn" . "বাংলা") ("bh" . "भोजपुरी") ("bi" . "Bislama") ("bs" . "bosanski jezik") ("br" . "brezhoneg") ("bg" . "български език") ("my" . "ဗမာစာ") ("ca" . "català") ("ch" . "Chamoru") ("ce" . "нохчийн мотт") ("ny" . "chiCheŵa, chinyanja") ("zh" . "中文 (Zhōngwén), 汉语, 漢語") ("cv" . "чӑваш чӗлхи") ("kw" . "Kernewek") ("co" . "corsu, lingua corsa") ("cr" . "ᓀᐦᐃᔭᐍᐏᐣ") ("hr" . "hrvatski jezik") ("cs" . "čeština, český jazyk") ("da" . "dansk") ("dv" . "ދިވެހި") ("nl" . "Nederlands, Vlaams") ("dz" . "རྫོང་ཁ") ("en" . "English") ("eo" . "Esperanto") ("et" . "eesti, eesti keel") ("ee" . "Eʋegbe") ("fo" . "føroyskt") ("fj" . "vosa Vakaviti") ("fi" . "suomi, suomen kieli") ("fr" . "français, langue française") ("ff" . "Fulfulde, Pulaar, Pular") ("gl" . "galego") ("ka" . "ქართული") ("de" . "Deutsch") ("el" . "ελληνικά") ("gn" . "Avañe'ẽ") ("gu" . "ગુજરાતી") ("ht" . "Kreyòl ayisyen") ("ha" . "(Hausa) هَوُسَ") ("he" . "עברית") ("hz" . "Otjiherero") ("hi" . "हिन्दी, हिंदी") ("ho" . "Hiri Motu") ("hu" . "magyar") ("ia" . "Interlingua") ("id" . "Bahasa Indonesia") ("ie" . "Originally called Occidental; then Interlingue after WWII") ("ga" . "Gaeilge") ("ig" . "Asụsụ Igbo") ("ik" . "Iñupiaq, Iñupiatun") ("io" . "Ido") ("is" . "Íslenska") ("it" . "Italiano") ("iu" . "ᐃᓄᒃᑎᑐᑦ") ("ja" . "日本語 (にほんご)") ("jv" . "ꦧꦱꦗꦮ, Basa Jawa") ("kl" . "kalaallisut, kalaallit oqaasii") ("kn" . "ಕನ್ನಡ") ("kr" . "Kanuri") ("ks" . "कश्मीरी, كشميري‎") ("kk" . "қазақ тілі") ("km" . "ខ្មែរ, ខេមរភាសា, ភាសាខ្មែរ") ("ki" . "Gĩkũyũ") ("rw" . "Ikinyarwanda") ("ky" . "Кыргызча, Кыргыз тили") ("kv" . "коми кыв") ("kg" . "Kikongo") ("ko" . "한국어") ("ku" . "Kurdî, كوردی‎") ("kj" . "Kuanyama") ("la" . "latine, lingua latina") ("lb" . "Lëtzebuergesch") ("lg" . "Luganda") ("li" . "Limburgs") ("ln" . "Lingála") ("lo" . "ພາສາລາວ") ("lt" . "lietuvių kalba") ("lu" . "Tshiluba") ("lv" . "latviešu valoda") ("gv" . "Gaelg, Gailck") ("mk" . "македонски јазик") ("mg" . "fiteny malagasy") ("ms" . "bahasa Melayu, بهاس ملايو‎") ("ml" . "മലയാളം") ("mt" . "Malti") ("mi" . "te reo Māori") ("mr" . "मराठी") ("mh" . "Kajin M̧ajeļ") ("mn" . "Монгол хэл") ("na" . "Dorerin Naoero") ("nv" . "Diné bizaad") ("nd" . "isiNdebele") ("ne" . "नेपाली") ("ng" . "Owambo") ("nb" . "Norsk bokmål") ("nn" . "Norsk nynorsk") ("no" . "Norsk") ("ii" . "ꆈꌠ꒿ Nuosuhxop") ("nr" . "isiNdebele") ("oc" . "occitan, lenga d'òc") ("oj" . "ᐊᓂᔑᓈᐯᒧᐎᓐ") ("cu" . "ѩзыкъ словѣньскъ") ("om" . "Afaan Oromoo") ("or" . "ଓଡ଼ିଆ") ("os" . "ирон æвзаг") ("pa" . "ਪੰਜਾਬੀ") ("pi" . "पाऴि") ("fa" . "فارسی") ("pl" . "język polski, polszczyzna") ("ps" . "پښتو") ("pt" . "Português") ("qu" . "Runa Simi, Kichwa") ("rm" . "rumantsch grischun") ("rn" . "Ikirundi") ("ro" . "Română") ("ru" . "Русский") ("sa" . "संस्कृतम्") ("sc" . "sardu") ("sd" . "सिन्धी, سنڌي، سندھی‎") ("se" . "Davvisámegiella") ("sm" . "gagana fa'a Samoa") ("sg" . "yângâ tî sängö") ("sr" . "српски језик") ("gd" . "Gàidhlig") ("sn" . "chiShona") ("si" . "සිංහල") ("sk" . "slovenčina, slovenský jazyk") ("sl" . "slovenski jezik, slovenščina") ("so" . "Soomaaliga, af Soomaali") ("st" . "Sesotho") ("es" . "Español") ("su" . "Basa Sunda") ("sw" . "Kiswahili") ("ss" . "SiSwati") ("sv" . "svenska") ("ta" . "தமிழ்") ("te" . "తెలుగు") ("tg" . "тоҷикӣ, toçikī, تاجیکی‎") ("th" . "ไทย") ("ti" . "ትግርኛ") ("bo" . "བོད་ཡིག") ("tk" . "Türkmen, Түркмен") ("tl" . "Wikang Tagalog") ("tn" . "Setswana") ("to" . "faka Tonga") ("tr" . "Türkçe") ("ts" . "Xitsonga") ("tt" . "татар теле, tatar tele") ("tw" . "Twi") ("ty" . "Reo Tahiti") ("ug" . "ئۇيغۇرچە‎, Uyghurche") ("uk" . "Українська") ("ur" . "اردو") ("uz" . "Oʻzbek, Ўзбек, أۇزبېك‎") ("ve" . "Tshivenḓa") ("vi" . "Tiếng Việt") ("vo" . "Volapük") ("wa" . "walon") ("cy" . "Cymraeg") ("wo" . "Wollof") ("fy" . "Frysk") ("xh" . "isiXhosa") ("yi" . "ייִדיש") ("yo" . "Yorùbá") ("za" . "Saɯ cueŋƅ, Saw cuengh") ("zu" . "isiZulu"))) (defun expand-file-name* (name default-directory) (expand-file-name name (concat "/" default-directory))) (org-export-define-derived-backend 'ennum-html 'html :translate-alist '((inner-template . ennum-html-inner-template) (link . ennum-html-link)) :options-alist '((:summary "SUMMARY" nil nil parse) (:thumbnail "THUMBNAIL" nil nil t) (:translation-group "TRANSLATION_GROUP" nil nil t))) (defun ennum-html-inner-template (contents info) (concat ;; Table of contents (let ((depth (plist-get info :with-toc))) (when depth (org-html-toc depth info))) ;; Beginning of h-entry "
" ;; Title (format "

%s

\n" (org-export-data (plist-get info :title) info)) ;; Author and date (let ((author (when (plist-get info :with-author) (plist-get info :author))) (date (when (plist-get info :with-date) (org-export-get-date info)))) (when (or author date) (xmlgen `(p "Published" ,@(when author `(" by " (a :class "p-author h-card" :href ,(ennum--absolute-uri "") ,(car (plist-get info :author))))) ,@(when date `(" on " (time :class "dt-published" :datetime ,(org-export-get-date info "%Y-%m-%d 12:00:00") ,(org-export-get-date info "%B %d, %Y")))))))) ;; Interlanguage language links (when-let (translations (plist-get info :ennum-translations)) (format "

In other languages: %s

" (mapconcat (lambda (translation) (let ((lang (ennum-post-language translation)) (slug (ennum-post-slug translation))) (replace-regexp-in-string "Tags: %s

" (mapconcat (lambda (tag) (replace-regexp-in-string "
%s" (org-export-data (plist-get info :summary) info)) ;; Document contents (format "
%s
" contents) ;; Footnotes section (org-html-footnote-section info) "
")) (defun ennum-html-link (link desc info) ;; We override the html link transcoder to handle image and video ;; links differently. We cannot use the `:export' property of ;; `org-link-parameters' since those functions cannot access the ;; `info' communication channel. (let ((path (org-element-property :path link))) (pcase (org-element-property :type link) ("image" ;; Convert image links to file links, get them transcoded by ;; `org-html-link' and then remove the file:// scheme from the ;; URI. Finally insert the transcoded image link in a link to a ;; larger image as specified by the :image-link-width setting. (format "%s" (expand-file-name* (ennum-image-output-filename path (ennum-setting :image-link-width)) (ennum-setting :images-directory)) (replace-regexp-in-string (rx (group (or "src" "data")) "=\"file://") "\\1=\"" (org-html-link (org-element-put-property (org-element-put-property link :path (url-encode-url (expand-file-name* (ennum-image-output-filename path (ennum-setting :default-image-width)) (ennum-setting :images-directory)))) :type "file") desc info)))) ("video" (let ((video-directory (ennum-setting :video-directory))) (message "%s" (plist-get info :ennum-video-posters)) (xmlgen `(video :src ,(url-encode-url (expand-file-name* path video-directory)) :poster ,(url-encode-url (expand-file-name* (map-elt (plist-get info :ennum-video-posters) path nil 'string=) video-directory)) :preload "none" :controls "")))) ;; Pass other link types to org-html-link (_ (org-html-link link desc info))))) (defmacro ennum-follow (path) `(ennum-with-current-directory (ennum-setting :working-directory) (find-file ,path))) ;; TODO: Pass title through org-export-data-with-backend or something ;; similar in order to export org syntax in title (defun ennum-export-post (path desc backend) (pcase backend ((or 'ennum-html 'html) (let ((filename (concat (expand-file-name path (ennum-setting :posts-directory)) ".org"))) (xmlgen `(a :href ,(url-encode-url (expand-file-name* path (ennum-setting :posts-directory))) ,(or desc (ennum-post-title (ennum-read-post filename))))))))) (defun ennum-follow-post (path) (ennum-follow (expand-file-name (concat path ".org") (ennum-setting :posts-directory)))) (org-link-set-parameters "post" :export 'ennum-export-post :follow 'ennum-follow-post) (defun ennum-follow-image (path) (ennum-follow (expand-file-name path (ennum-setting :images-directory)))) (org-link-set-parameters "image" :follow 'ennum-follow-image) (defun ennum-export-thumbnail (path desc backend) (pcase backend ((or 'ennum-html 'html) (xmlgen `(img :src ,(url-encode-url (expand-file-name* (ennum-image-output-filename path (ennum-setting :thumbnail-image-width)) (ennum-setting :images-directory)))))))) (org-link-set-parameters "thumbnail" :export 'ennum-export-thumbnail :follow 'ennum-follow-image) (defun ennum-export-static (path desc backend) (pcase backend ((or 'ennum-html 'html) (xmlgen `(a :href ,(url-encode-url (expand-file-name* path (ennum-setting :static-directory))) ,desc))))) (org-link-set-parameters "static" :export 'ennum-export-static) (org-link-set-parameters "tangle" :export 'ennum-export-static) (defun ennum-export-tag (tag desc backend) (pcase backend ((or 'ennum-html 'html) (xmlgen `(a :href ,(url-encode-url (expand-file-name* tag (ennum-setting :tag-directory))) ,(or desc tag)))))) (org-link-set-parameters "tag" :export 'ennum-export-tag) (provide 'ennum-html)