summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ennum-html.el (renamed from ennu-html.el)110
-rw-r--r--ennum-image.el (renamed from ennu-image.el)20
-rw-r--r--ennum.el (renamed from ennu.el)336
3 files changed, 238 insertions, 228 deletions
diff --git a/ennu-html.el b/ennum-html.el
index 10025bc..1475927 100644
--- a/ennu-html.el
+++ b/ennum-html.el
@@ -4,7 +4,7 @@
(require 'subr-x)
(require 'xmlgen)
-(defconst ennu--iso-639-1-alist
+(defconst ennum--iso-639-1-alist
'(("ab" . "аҧсуа бызшәа, аҧсшәа")
("aa" . "Afaraf")
("af" . "Afrikaans")
@@ -193,16 +193,16 @@
(defun expand-file-name* (name default-directory)
(expand-file-name name (concat "/" default-directory)))
-(org-export-define-derived-backend 'ennu-html 'html
+(org-export-define-derived-backend 'ennum-html 'html
:translate-alist
- '((inner-template . ennu-html-inner-template)
- (link . ennu-html-link))
+ '((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 ennu-html-inner-template (contents info)
+(defun ennum-html-inner-template (contents info)
(concat
;; Table of contents
(let ((depth (plist-get info :with-toc)))
@@ -222,7 +222,7 @@
,@(when author
`(" by "
(a :class "p-author h-card"
- :href ,(ennu--absolute-uri "")
+ :href ,(ennum--absolute-uri "")
,(car (plist-get info :author)))))
,@(when date
`(" on "
@@ -234,12 +234,12 @@
(format "<p>In other languages: %s</p>"
(mapconcat
(lambda (translation)
- (let ((lang (ennu-post-language translation))
- (slug (ennu-post-slug translation)))
+ (let ((lang (ennum-post-language translation))
+ (slug (ennum-post-slug translation)))
(replace-regexp-in-string
"<a " (format "<a hreflang=\"%s\" " lang)
- (ennu-export-post slug
- (map-elt ennu--iso-639-1-alist lang nil 'string=)
+ (ennum-export-post slug
+ (map-elt ennum--iso-639-1-alist lang nil 'string=)
(org-export-backend-name
(plist-get info :back-end))))))
translations
@@ -251,7 +251,7 @@
(lambda (tag)
(replace-regexp-in-string
"<a " "<a class=\"p-category\" "
- (ennu-export-tag (ennu-add-tongue-suffix tag (plist-get info :language))
+ (ennum-export-tag (ennum-add-tongue-suffix tag (plist-get info :language))
tag (org-export-backend-name (plist-get info :back-end)))))
tags
", ")))
@@ -264,7 +264,7 @@
(org-html-footnote-section info)
"</article>"))
-(defun ennu-html-link (link desc info)
+(defun ennum-html-link (link desc info)
;; We override the html link transcoder to handle image links
;; differently. We cannot use the `:export' property of
;; `org-link-parameters' since those functions cannot access the
@@ -278,9 +278,9 @@
;; larger image as specified by the :image-link-width setting.
(format "<a href=\"%s\">%s</a>"
(expand-file-name*
- (ennu-image-output-filename
- path (ennu-setting :image-link-width))
- (ennu-setting :images-directory))
+ (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
@@ -288,96 +288,96 @@
(org-element-put-property
link :path (url-encode-url
(expand-file-name*
- (ennu-image-output-filename
- path (ennu-setting :default-image-width))
- (ennu-setting :images-directory))))
+ (ennum-image-output-filename
+ path (ennum-setting :default-image-width))
+ (ennum-setting :images-directory))))
:type "file")
desc info))))
;; Pass other link types to org-html-link
(_ (org-html-link link desc info)))))
-(defmacro ennu-follow (path)
- `(ennu-with-current-directory (ennu-setting :working-directory)
+(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 ennu-export-post (path desc backend)
+(defun ennum-export-post (path desc backend)
(pcase backend
- ((or 'ennu-html 'html)
- (let ((filename (concat (expand-file-name path (ennu-setting :posts-directory))
+ ((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 (ennu-setting :posts-directory)))
- ,(or desc (ennu-post-title (ennu-read-post filename)))))))))
+ (expand-file-name* path (ennum-setting :posts-directory)))
+ ,(or desc (ennum-post-title (ennum-read-post filename)))))))))
-(defun ennu-follow-post (path)
- (ennu-follow (expand-file-name (concat path ".org")
- (ennu-setting :posts-directory))))
+(defun ennum-follow-post (path)
+ (ennum-follow (expand-file-name (concat path ".org")
+ (ennum-setting :posts-directory))))
(org-link-set-parameters
"post"
- :export 'ennu-export-post
- :follow 'ennu-follow-post)
+ :export 'ennum-export-post
+ :follow 'ennum-follow-post)
-(defun ennu-follow-image (path)
- (ennu-follow (expand-file-name path (ennu-setting :images-directory))))
+(defun ennum-follow-image (path)
+ (ennum-follow (expand-file-name path (ennum-setting :images-directory))))
(org-link-set-parameters
- "image" :follow 'ennu-follow-image)
+ "image" :follow 'ennum-follow-image)
-(defun ennu-export-thumbnail (path desc backend)
+(defun ennum-export-thumbnail (path desc backend)
(pcase backend
- ((or 'ennu-html 'html)
+ ((or 'ennum-html 'html)
(xmlgen
`(img :src ,(url-encode-url
(expand-file-name*
- (ennu-image-output-filename
- path (ennu-setting :thumbnail-image-width))
- (ennu-setting :images-directory))))))))
+ (ennum-image-output-filename
+ path (ennum-setting :thumbnail-image-width))
+ (ennum-setting :images-directory))))))))
(org-link-set-parameters
"thumbnail"
- :export 'ennu-export-thumbnail
- :follow 'ennu-follow-image)
+ :export 'ennum-export-thumbnail
+ :follow 'ennum-follow-image)
-(defun ennu-export-video (path desc backend)
+(defun ennum-export-video (path desc backend)
(pcase backend
- ((or 'ennu-html 'html)
- (let ((video-directory (ennu-setting :video-directory)))
+ ((or 'ennum-html 'html)
+ (let ((video-directory (ennum-setting :video-directory)))
(xmlgen
`(video :src ,(url-encode-url (expand-file-name* path video-directory))
:poster ,(url-encode-url
- (expand-file-name* (ennu-video-poster path) video-directory))
+ (expand-file-name* (ennum-video-poster path) video-directory))
:preload "none"
:controls ""))))))
(org-link-set-parameters
- "video" :export 'ennu-export-video)
+ "video" :export 'ennum-export-video)
-(defun ennu-export-static (path desc backend)
+(defun ennum-export-static (path desc backend)
(pcase backend
- ((or 'ennu-html 'html)
+ ((or 'ennum-html 'html)
(xmlgen
`(a :href ,(url-encode-url
- (expand-file-name* path (ennu-setting :static-directory)))
+ (expand-file-name* path (ennum-setting :static-directory)))
,desc)))))
(org-link-set-parameters
- "static" :export 'ennu-export-static)
+ "static" :export 'ennum-export-static)
(org-link-set-parameters
- "tangle" :export 'ennu-export-static)
+ "tangle" :export 'ennum-export-static)
-(defun ennu-export-tag (tag desc backend)
+(defun ennum-export-tag (tag desc backend)
(pcase backend
- ((or 'ennu-html 'html)
+ ((or 'ennum-html 'html)
(xmlgen
`(a :href ,(url-encode-url
- (expand-file-name* tag (ennu-setting :tag-directory)))
+ (expand-file-name* tag (ennum-setting :tag-directory)))
,(or desc tag))))))
(org-link-set-parameters
- "tag" :export 'ennu-export-tag)
+ "tag" :export 'ennum-export-tag)
-(provide 'ennu-html)
+(provide 'ennum-html)
diff --git a/ennu-image.el b/ennum-image.el
index 34c3e7e..3a8aa23 100644
--- a/ennu-image.el
+++ b/ennum-image.el
@@ -6,18 +6,18 @@
;; Check if all necessary image types are supported
(seq-do (lambda (image-type)
(unless (image-type-available-p image-type)
- (lwarn '(ennu) :error "`%s' image type not supported" image-type)))
+ (lwarn '(ennum) :error "`%s' image type not supported" image-type)))
'(jpeg png svg))
;; Check for existence of external image processing utilities
(seq-do (lambda (external-program)
(unless (executable-find external-program)
- (lwarn '(ennu) :error "`%s' not found" external-program)))
+ (lwarn '(ennum) :error "`%s' not found" external-program)))
'("convert" "identify" "jpegtran" "optipng"))
-(defun ennu-image-resize-image (infile-path outfile-path width)
+(defun ennum-image-resize-image (infile-path outfile-path width)
"A simple shell wrapper around ImageMagick's convert"
- (ennu-image--assert-file-exists infile-path)
+ (ennum-image--assert-file-exists infile-path)
(cl-case (image-type infile-path)
(svg
(copy-file infile-path outfile-path t))
@@ -26,9 +26,9 @@
infile-path "-resize" (format "%d>" width) outfile-path)))
outfile-path)
-(defun ennu-image-optimize-image (image-path)
+(defun ennum-image-optimize-image (image-path)
"A simple shell wrapper around jpegtran and optipng"
- (ennu-image--assert-file-exists image-path)
+ (ennum-image--assert-file-exists image-path)
(cl-case (image-type image-path)
(jpeg
(call-process "jpegtran" nil nil nil "-optimize"
@@ -38,8 +38,8 @@
(call-process "optipng" nil nil nil image-path)))
image-path)
-(defun ennu-image-get-width (image-path)
- (ennu-image--assert-file-exists image-path)
+(defun ennum-image-get-width (image-path)
+ (ennum-image--assert-file-exists image-path)
(cl-case (image-type image-path)
(svg 1e+INF)
(otherwise
@@ -48,8 +48,8 @@
"-format" "%w" image-path)
(string-to-number (buffer-string))))))
-(defun ennu-image--assert-file-exists (path)
+(defun ennum-image--assert-file-exists (path)
(unless (file-exists-p path)
(error "File %s does not exist" path)))
-(provide 'ennu-image)
+(provide 'ennum-image)
diff --git a/ennu.el b/ennum.el
index 439e1d9..69a7b5b 100644
--- a/ennu.el
+++ b/ennum.el
@@ -1,7 +1,7 @@
;; -*- lexical-binding: t -*-
-(require 'ennu-html)
-(require 'ennu-image)
+(require 'ennum-html)
+(require 'ennum-image)
(require 'ox)
(require 'seq)
(require 'cl)
@@ -9,43 +9,43 @@
(require 'memoize)
(require 'simple-httpd)
-(defvar ennu-version "0.1.0"
- "Ennu version string")
+(defvar ennum-version "0.1.0"
+ "Ennum version string")
-(cl-defstruct (ennu-post (:constructor ennu-make-post)
+(cl-defstruct (ennum-post (:constructor ennum-make-post)
(:copier nil))
filename slug author date language links tangle
summary tags thumbnail title translation-group)
-(cl-defstruct (ennu-operation (:constructor ennu-make-operation)
+(cl-defstruct (ennum-operation (:constructor ennum-make-operation)
(:copier nil))
inputs outputs publish)
-(defun ennu-posts (posts-directory)
- (sort (seq-map 'ennu-read-post
+(defun ennum-posts (posts-directory)
+ (sort (seq-map 'ennum-read-post
(file-expand-wildcards
(concat (file-name-as-directory
- (ennu-setting :posts-directory))
+ (ennum-setting :posts-directory))
"*.org")))
- 'ennu-later-post-p))
+ 'ennum-later-post-p))
-(defun ennu-later-post-p (post1 post2)
- (time-less-p (ennu-post-date post2)
- (ennu-post-date post1)))
+(defun ennum-later-post-p (post1 post2)
+ (time-less-p (ennum-post-date post2)
+ (ennum-post-date post1)))
-(defun ennu-read-post (filename)
- (ennu--read-post
+(defun ennum-read-post (filename)
+ (ennum--read-post
filename (file-attribute-modification-time
(file-attributes filename))))
-(defmemoize ennu--read-post (filename last-modified)
- (ennu-with-file-contents filename
- (let ((metadata (org-export-get-environment 'ennu-html))
- (export (apply-partially 'org-export-with-backend 'ennu-html)))
+(defmemoize ennum--read-post (filename last-modified)
+ (ennum-with-file-contents filename
+ (let ((metadata (org-export-get-environment 'ennum-html))
+ (export (apply-partially 'org-export-with-backend 'ennum-html)))
(seq-do (lambda (key)
(unless (plist-member metadata key)
(user-error "Metadata %s not specified" key)))
- ennu-mandatory-metadata)
+ ennum-mandatory-metadata)
(let* ((tree (org-element-parse-buffer))
(links (org-element-map tree 'link
(lambda (link)
@@ -54,7 +54,7 @@
(let ((link-type (org-element-property :type link)))
(when (member link-type (list "image" "static" "video"))
(cons link-type (org-element-property :path link))))))))))
- (ennu-make-post
+ (ennum-make-post
:filename filename
:slug (file-name-base filename)
:author (when-let (author (plist-get metadata :author))
@@ -79,16 +79,16 @@
(seq-some (lambda (link)
(pcase link
(`("image" . ,path) path)
- (`("video" . ,path) (ennu-video-poster path))))
+ (`("video" . ,path) (ennum-video-poster path))))
links))
:title (funcall export (first (plist-get metadata :title)))
:translation-group (or (plist-get metadata :translation-group)
(file-name-base filename)))))))
-(defvar ennu-mandatory-metadata
+(defvar ennum-mandatory-metadata
(list :title :date))
-(defmacro ennu-with-file-contents (file &rest body)
+(defmacro ennum-with-file-contents (file &rest body)
"Create a temporary buffer, insert contents of FILE into that
buffer and evaluate BODY. The value returned is the value of the
last form in BODY."
@@ -97,76 +97,76 @@ last form in BODY."
(insert-file-contents ,file)
,@body))
-(defun ennu--org-output-filename (filename)
+(defun ennum--org-output-filename (filename)
(concat (file-name-sans-extension filename) ".html"))
-(defun ennu-publish-post (posts)
+(defun ennum-publish-post (posts)
(let ((link-publish-operations
- (seq-mapcat 'ennu-publish-link (seq-mapcat 'ennu-post-links posts)))
- (input-post-files (seq-map 'ennu-post-filename posts)))
+ (seq-mapcat 'ennum-publish-link (seq-mapcat 'ennum-post-links posts)))
+ (input-post-files (seq-map 'ennum-post-filename posts)))
(append
(list
- (ennu-make-operation
+ (ennum-make-operation
:inputs (append input-post-files
- (seq-mapcat 'ennu-operation-inputs link-publish-operations))
- :outputs (seq-map 'ennu--org-output-filename input-post-files)
+ (seq-mapcat 'ennum-operation-inputs link-publish-operations))
+ :outputs (seq-map 'ennum--org-output-filename input-post-files)
:publish
(lambda (&rest output-files)
(seq-mapn
(lambda (post output-file)
- (let ((system-time-locale (map-elt (ennu-setting :locale-alist)
- (ennu-post-language post) nil 'string=)))
- (ennu-with-file-contents (ennu-post-filename post)
+ (let ((system-time-locale (map-elt (ennum-setting :locale-alist)
+ (ennum-post-language post) nil 'string=)))
+ (ennum-with-file-contents (ennum-post-filename post)
(org-export-to-file
- 'ennu-html output-file nil nil nil nil
+ 'ennum-html output-file nil nil nil nil
(list :translations (seq-remove (apply-partially 'equal post) posts))))))
posts
output-files))))
- (ennu--filter-map
+ (ennum--filter-map
(lambda (post)
- (when (ennu-post-tangle post)
- (ennu-make-operation
- :inputs (list (ennu-post-filename post))
+ (when (ennum-post-tangle post)
+ (ennum-make-operation
+ :inputs (list (ennum-post-filename post))
:outputs (seq-map (lambda (tangle-output)
- (ennu--expand-relative tangle-output
- (ennu-setting :static-directory)))
- (ennu-post-tangle post))
+ (ennum--expand-relative tangle-output
+ (ennum-setting :static-directory)))
+ (ennum-post-tangle post))
:publish (lambda (&rest output-files)
;; TODO: Handle tangle outputs that are nested
;; into directories, and when each tangle output
;; is nested into a different directory.
(let ((post-file-copy (concat
(file-name-directory (first output-files))
- (file-name-nondirectory (ennu-post-filename post)))))
- (copy-file (ennu-post-filename post) post-file-copy)
+ (file-name-nondirectory (ennum-post-filename post)))))
+ (copy-file (ennum-post-filename post) post-file-copy)
(org-babel-tangle-file post-file-copy)
(delete-file post-file-copy))))))
posts)
link-publish-operations)))
-(defun ennu-publish-generic (other-files-directory file)
- (ennu-make-operation
+(defun ennum-publish-generic (other-files-directory file)
+ (ennum-make-operation
:inputs (list file)
:outputs
(list (string-remove-prefix
(file-name-as-directory other-files-directory)
(pcase (file-name-extension file)
- ("org" (ennu--org-output-filename file))
+ ("org" (ennum--org-output-filename file))
(_ file))))
:publish (lambda (output-file)
(pcase (file-name-extension file)
- ("org" (ennu-with-file-contents file
+ ("org" (ennum-with-file-contents file
(org-export-to-file 'html output-file)))
- (_ (ennu-copy file output-file))))))
+ (_ (ennum-copy file output-file))))))
-(defun ennu-video-poster (video)
- (pcase (directory-files (ennu-setting :images-directory) nil
+(defun ennum-video-poster (video)
+ (pcase (directory-files (ennum-setting :images-directory) nil
(concat (file-name-sans-extension video)
"\\.\\(jpg\\|png\\)$"))
(`(,poster . ,_) poster)
(`() (user-error "Poster for %s not found" video))))
-(defun ennu-add-tongue-suffix (filename tongue)
+(defun ennum-add-tongue-suffix (filename tongue)
(pcase tongue
("en" filename)
(_ (format "%s.%s%s"
@@ -174,26 +174,26 @@ last form in BODY."
tongue
(file-name-extension filename t)))))
-(defun ennu-index-filename (filename-prefix tongue &optional extension page-number)
+(defun ennum-index-filename (filename-prefix tongue &optional extension page-number)
(let ((extension (if extension (concat "." extension) "")))
- (ennu-add-tongue-suffix
+ (ennum-add-tongue-suffix
(if page-number
(format "%s-%s%s" filename-prefix page-number extension)
(concat filename-prefix extension))
tongue)))
-(defun ennu-publish-index (filename-prefix title posts-per-page posts)
- (let* ((tongue (ennu-post-language (first posts)))
+(defun ennum-publish-index (filename-prefix title posts-per-page posts)
+ (let* ((tongue (ennum-post-language (first posts)))
(number-of-pages (ceiling (length posts) posts-per-page))
(page-numbers (number-sequence 1 number-of-pages)))
- (ennu-make-operation
- :inputs (seq-map 'ennu-post-filename posts)
- :outputs (cons (ennu-add-tongue-suffix (format "%s.html" filename-prefix) tongue)
- (seq-map (apply-partially 'ennu-index-filename filename-prefix tongue "html")
+ (ennum-make-operation
+ :inputs (seq-map 'ennum-post-filename posts)
+ :outputs (cons (ennum-add-tongue-suffix (format "%s.html" filename-prefix) tongue)
+ (seq-map (apply-partially 'ennum-index-filename filename-prefix tongue "html")
page-numbers))
:publish
(lambda (home-page &rest output-files)
- (let ((system-time-locale (map-elt (ennu-setting :locale-alist) tongue nil 'string=)))
+ (let ((system-time-locale (map-elt (ennum-setting :locale-alist) tongue nil 'string=)))
(seq-mapn
(lambda (posts page-number output-file)
(with-temp-buffer
@@ -201,30 +201,30 @@ last form in BODY."
(insert (format "#+LANGUAGE: %s\n" tongue))
(insert "#+OPTIONS: num:nil toc:nil\n\n")
(seq-do (lambda (post)
- (insert (format "* [[post:%s]]\n" (ennu-post-slug post)))
- (insert (format-time-string "/%b %e, %Y/\n\n" (ennu-post-date post)))
- (when-let ((thumbnail (ennu-post-thumbnail post)))
+ (insert (format "* [[post:%s]]\n" (ennum-post-slug post)))
+ (insert (format-time-string "/%b %e, %Y/\n\n" (ennum-post-date post)))
+ (when-let ((thumbnail (ennum-post-thumbnail post)))
(insert (format "[[thumbnail:%s]]\n\n" thumbnail)))
- (when-let ((summary (ennu-post-summary post)))
+ (when-let ((summary (ennum-post-summary post)))
(insert summary)
(insert "\n\n"))
- (when-let ((tags (ennu-post-tags post)))
+ (when-let ((tags (ennum-post-tags post)))
(insert "Tags: ")
(insert
(string-join
(seq-map (lambda (tag)
- (format "[[tag:%s][%s]]" (ennu-add-tongue-suffix tag tongue) tag))
+ (format "[[tag:%s][%s]]" (ennum-add-tongue-suffix tag tongue) tag))
tags)
", "))
(insert "\n\n")))
posts)
(unless (= page-number 1)
- (insert (format "[[./%s][Newer posts]]\n"
- (ennu-index-filename (file-name-nondirectory filename-prefix)
+ (insert (format "[[./%s][Newer posts]]\n\n"
+ (ennum-index-filename (file-name-nondirectory filename-prefix)
tongue nil (1- page-number)))))
(unless (= page-number number-of-pages)
(insert (format "[[./%s][Older posts]]\n"
- (ennu-index-filename (file-name-nondirectory filename-prefix)
+ (ennum-index-filename (file-name-nondirectory filename-prefix)
tongue nil (1+ page-number)))))
(org-export-to-file 'html output-file)))
(seq-partition posts posts-per-page)
@@ -232,18 +232,18 @@ last form in BODY."
output-files))
(copy-file (first output-files) home-page)))))
-(defun ennu--absolute-uri (path)
+(defun ennum--absolute-uri (path)
(format "%s://%s/%s"
- (ennu-setting :blog-scheme)
- (ennu-setting :blog-domain)
+ (ennum-setting :blog-scheme)
+ (ennum-setting :blog-domain)
path))
-(defun ennu--atom-date (date)
+(defun ennum--atom-date (date)
(format-time-string "%Y-%m-%dT%H:%M:%SZ" date))
-(defun ennu-publish-feed (feed-file title rights posts)
- (ennu-make-operation
- :inputs (seq-map 'ennu-post-filename posts)
+(defun ennum-publish-feed (feed-file title rights posts)
+ (ennum-make-operation
+ :inputs (seq-map 'ennum-post-filename posts)
:outputs (list feed-file)
:publish
(lambda (output-file)
@@ -251,40 +251,40 @@ last form in BODY."
(insert
(xmlgen
`(feed :xmlns "http://www.w3.org/2005/Atom"
- (id ,(ennu--absolute-uri ""))
+ (id ,(ennum--absolute-uri ""))
(title ,title)
- (updated ,(ennu--atom-date (ennu-post-date (first posts))))
- (link :rel "self" :href ,(ennu--absolute-uri feed-file))
+ (updated ,(ennum--atom-date (ennum-post-date (first posts))))
+ (link :rel "self" :href ,(ennum--absolute-uri feed-file))
(generator
- ,(format "Emacs %d.%d Org-mode %s ennu %s"
- emacs-major-version emacs-minor-version (org-version) ennu-version))
+ ,(format "Emacs %d.%d Org-mode %s ennum %s"
+ emacs-major-version emacs-minor-version (org-version) ennum-version))
(rights ,rights)
- ,@(seq-map 'ennu--feed-entry posts))))))))
+ ,@(seq-map 'ennum--feed-entry posts))))))))
-(defun ennu--feed-entry (post)
- (let ((link (ennu--absolute-uri (ennu--org-output-filename
- (ennu-post-filename post)))))
+(defun ennum--feed-entry (post)
+ (let ((link (ennum--absolute-uri (ennum--org-output-filename
+ (ennum-post-filename post)))))
`(entry (id ,link)
- (title :xml:lang ,(ennu-post-language post) ,(ennu-post-title post))
- (updated ,(ennu--atom-date (ennu-post-date post)))
+ (title :xml:lang ,(ennum-post-language post) ,(ennum-post-title post))
+ (updated ,(ennum--atom-date (ennum-post-date post)))
,@(when org-export-with-author
`((author
- (name ,(ennu-post-author post))
+ (name ,(ennum-post-author post))
(email ,user-mail-address))))
- (content :type "html" :xml:lang ,(ennu-post-language post)
- ,(ennu-with-file-contents (ennu-post-filename post)
- (org-export-as 'ennu-html nil nil t)))
+ (content :type "html" :xml:lang ,(ennum-post-language post)
+ ,(ennum-with-file-contents (ennum-post-filename post)
+ (org-export-as 'ennum-html nil nil t)))
(link :rel "alternate" :href ,link)
,@(seq-map (lambda (tag) `(category :term ,tag))
- (ennu-post-tags post)))))
+ (ennum-post-tags post)))))
-(defun ennu-setting (property)
+(defun ennum-setting (property)
(pcase property
((or :blog-domain :blog-license :blog-title
:images-directory :output-directory :posts-directory
:static-directory :tag-directory :video-directory
:working-directory)
- (or (plist-get ennu-blog property)
+ (or (plist-get ennum-blog property)
(user-error "Property %s not defined" property)))
((or :atom-feed-number-of-posts :atom-feed-file
:blog-scheme :default-image-width
@@ -301,35 +301,35 @@ last form in BODY."
:locale-alist '(("en" . "C"))
:tag-directory "tag"
:thumbnail-image-width 320)
- ennu-blog)
+ ennum-blog)
property))
(_ (error "Unknown property %s" property))))
-(defun ennu-image-output-filename (image width)
+(defun ennum-image-output-filename (image width)
(format "%s-%spx.%s"
(file-name-sans-extension image)
width (file-name-extension image)))
-(defun ennu--expand-relative (name directory)
+(defun ennum--expand-relative (name directory)
(concat (file-name-as-directory directory) name))
-(defun ennu-publish-image (widths image)
- (ennu-make-operation
+(defun ennum-publish-image (widths image)
+ (ennum-make-operation
:inputs (list image)
- :outputs (seq-map (apply-partially 'ennu-image-output-filename image)
+ :outputs (seq-map (apply-partially 'ennum-image-output-filename image)
widths)
:publish
(lambda (&rest output-files)
(seq-mapn (lambda (output-file width)
- (ennu-image-optimize-image
- (ennu-image-resize-image image output-file width)))
+ (ennum-image-optimize-image
+ (ennum-image-resize-image image output-file width)))
output-files widths))))
-(defun ennu-publish-copy (file)
- (ennu-make-operation
+(defun ennum-publish-copy (file)
+ (ennum-make-operation
:inputs (list file)
:outputs (list file)
- :publish (apply-partially 'ennu-copy file)))
+ :publish (apply-partially 'ennum-copy file)))
(defun newest-file (files)
(pcase files
@@ -339,10 +339,10 @@ last form in BODY."
file1 file2))
tail head))))
-(defun ennu-mkdir-p (directory)
+(defun ennum-mkdir-p (directory)
(make-directory directory t))
-(defun ennu-copy (source destination)
+(defun ennum-copy (source destination)
"Copy file or directory from SOURCE to DESTINATION. Overwrite
if DESTINATION already exists."
(if (file-directory-p source)
@@ -350,56 +350,65 @@ if DESTINATION already exists."
(make-directory (file-name-directory destination) t)
(copy-file source destination t)))
-(defun ennu--filter-map (function sequence)
+(defun ennum--filter-map (function sequence)
(seq-filter 'identity (seq-map function sequence)))
-(defun ennu--do-operation (temporary-directory operation)
+;; TODO: What if a file was removed from the inputs? Detect that
+;; change as well.
+
+;; Two separate problems
+;; - tracking of list of inputs
+;; - depending on a function of inputs, or equivalently intermediate files
+
+;; Solve both problems with an "ennum store"
+(defun ennum--do-operation (temporary-directory operation)
+ ;; TODO: Check all outputs were created correctly.
(let* ((expand (lambda (directory file)
(expand-file-name file directory)))
- (inputs (ennu-operation-inputs operation))
- (outputs (ennu-operation-outputs operation))
+ (inputs (ennum-operation-inputs operation))
+ (outputs (ennum-operation-outputs operation))
(absolute-outputs
(seq-map (apply-partially expand temporary-directory)
outputs))
(previous-outputs
- (seq-map (apply-partially expand (ennu-setting :output-directory))
+ (seq-map (apply-partially expand (ennum-setting :output-directory))
outputs)))
(cond
((and (seq-every-p 'file-exists-p previous-outputs)
(file-newer-than-file-p (newest-file previous-outputs)
(newest-file inputs)))
(message "Skipping publishing %s to %s" inputs outputs)
- (seq-mapn 'ennu-copy previous-outputs absolute-outputs))
+ (seq-mapn 'ennum-copy previous-outputs absolute-outputs))
(t (message "Publishing %s to %s" inputs outputs)
- (seq-do 'ennu-mkdir-p
+ (seq-do 'ennum-mkdir-p
(seq-uniq
(seq-map 'file-name-directory absolute-outputs)))
- (apply (ennu-operation-publish operation) absolute-outputs)))))
+ (apply (ennum-operation-publish operation) absolute-outputs)))))
-(defun ennu-publish-static-file (file)
- (ennu-make-operation
+(defun ennum-publish-static-file (file)
+ (ennum-make-operation
:inputs (list file)
:outputs (list file)
- :publish (apply-partially 'ennu-copy file)))
+ :publish (apply-partially 'ennum-copy file)))
-(defun ennu-publish-link (link)
+(defun ennum-publish-link (link)
(pcase link
(`("image" . ,path)
(list
- (ennu-publish-image
- (list (ennu-setting :default-image-width)
- (ennu-setting :image-link-width))
- (ennu--expand-relative path (ennu-setting :images-directory)))))
+ (ennum-publish-image
+ (list (ennum-setting :default-image-width)
+ (ennum-setting :image-link-width))
+ (ennum--expand-relative path (ennum-setting :images-directory)))))
(`("static" . ,path)
(list
- (ennu-publish-copy (ennu--expand-relative path (ennu-setting :static-directory)))))
+ (ennum-publish-copy (ennum--expand-relative path (ennum-setting :static-directory)))))
(`("video" . ,path)
(list
- (ennu-publish-copy (ennu--expand-relative path (ennu-setting :video-directory)))
- (ennu-publish-copy (ennu--expand-relative (ennu-video-poster path)
- (ennu-setting :images-directory)))))))
+ (ennum-publish-copy (ennum--expand-relative path (ennum-setting :video-directory)))
+ (ennum-publish-copy (ennum--expand-relative (ennum-video-poster path)
+ (ennum-setting :images-directory)))))))
-(defmacro ennu-with-current-directory (directory &rest body)
+(defmacro ennum-with-current-directory (directory &rest body)
"Change to DIRECTORY, evaluate BODY and restore the current
working directory. The value returned is the value of the last
form in BODY."
@@ -409,19 +418,19 @@ form in BODY."
(unwind-protect (progn (cd ,directory) ,@body)
(cd ,current-directory-symbol)))))
-(defmacro ennu-with-temporary-directory (temporary-directory &rest body)
+(defmacro ennum-with-temporary-directory (temporary-directory &rest body)
"Create temporary directory, evaluate BODY with the absolute
path of that directory assigned to TEMPORARY-DIRECTORY and
finally delete the temporary directory. The value returned is the
value of the last form in BODY."
(declare (indent defun))
- `(let ((,temporary-directory (make-temp-file "ennu" t)))
+ `(let ((,temporary-directory (make-temp-file "ennum" t)))
(chmod ,temporary-directory #o755)
(unwind-protect
(progn ,@body)
(delete-directory ,temporary-directory t))))
-(defun ennu-many-to-many-group-by (function sequence)
+(defun ennum-many-to-many-group-by (function sequence)
"Apply FUNCTION to each element of SEQUENCE.
Separate the elements of SEQUENCE into an alist using the results
as keys. Keys are compared using `equal'."
@@ -437,55 +446,55 @@ as keys. Keys are compared using `equal'."
(seq-reverse sequence)
nil))
-(defun ennu-publish ()
+(defun ennum-publish ()
(interactive)
(let ((make-backup-files nil)
- (blog-title (ennu-setting :blog-title))
- (posts-per-page (ennu-setting :index-posts-per-page)))
- (ennu-with-current-directory (ennu-setting :working-directory)
- (ennu-with-temporary-directory temporary-directory
+ (blog-title (ennum-setting :blog-title))
+ (posts-per-page (ennum-setting :index-posts-per-page)))
+ (ennum-with-current-directory (ennum-setting :working-directory)
+ (ennum-with-temporary-directory temporary-directory
(seq-do
- (apply-partially 'ennu--do-operation temporary-directory)
+ (apply-partially 'ennum--do-operation temporary-directory)
(append
- (let ((posts (ennu-posts (ennu-setting :posts-directory))))
+ (let ((posts (ennum-posts (ennum-setting :posts-directory))))
(append
;; Publish posts
(seq-mapcat (pcase-lambda (`(,translation-group . ,posts))
- (ennu-publish-post posts))
- (seq-group-by 'ennu-post-translation-group posts))
+ (ennum-publish-post posts))
+ (seq-group-by 'ennum-post-translation-group posts))
;; Publish feed
- (list (ennu-publish-feed (ennu-setting :atom-feed-file)
+ (list (ennum-publish-feed (ennum-setting :atom-feed-file)
blog-title
- (ennu-setting :blog-license)
- (seq-take posts (ennu-setting :atom-feed-number-of-posts))))
+ (ennum-setting :blog-license)
+ (seq-take posts (ennum-setting :atom-feed-number-of-posts))))
;; Publish indices
(seq-map
(pcase-lambda (`(,tongue . ,posts))
- (ennu-publish-index "index" blog-title posts-per-page posts))
- (seq-group-by 'ennu-post-language posts))
+ (ennum-publish-index "index" blog-title posts-per-page posts))
+ (seq-group-by 'ennum-post-language posts))
(seq-mapcat
(pcase-lambda (`(,tag . ,posts))
(seq-map
(pcase-lambda (`(,tongue . ,posts))
- (ennu-publish-index
- (ennu--expand-relative tag (ennu-setting :tag-directory))
+ (ennum-publish-index
+ (ennum--expand-relative tag (ennum-setting :tag-directory))
tag posts-per-page posts))
- (seq-group-by 'ennu-post-language posts)))
- (ennu-many-to-many-group-by 'ennu-post-tags posts))
+ (seq-group-by 'ennum-post-language posts)))
+ (ennum-many-to-many-group-by 'ennum-post-tags posts))
;; Publish thumbnails
(seq-map
- (apply-partially 'ennu-publish-image (list (ennu-setting :thumbnail-image-width)))
+ (apply-partially 'ennum-publish-image (list (ennum-setting :thumbnail-image-width)))
(seq-map (lambda (image)
- (ennu--expand-relative image (ennu-setting :images-directory)))
- (seq-uniq (ennu--filter-map 'ennu-post-thumbnail posts))))))
+ (ennum--expand-relative image (ennum-setting :images-directory)))
+ (seq-uniq (ennum--filter-map 'ennum-post-thumbnail posts))))))
;; Publish other files
- (when-let ((other-files-directory (ennu-setting :other-files-directory)))
- (seq-map (apply-partially 'ennu-publish-generic other-files-directory)
+ (when-let ((other-files-directory (ennum-setting :other-files-directory)))
+ (seq-map (apply-partially 'ennum-publish-generic other-files-directory)
(seq-map (apply-partially 'string-remove-prefix
(file-name-as-directory (expand-file-name default-directory)))
(directory-files-recursively other-files-directory "."))))))
;; Replace old output directory
- (let ((output (ennu-setting :output-directory)))
+ (let ((output (ennum-setting :output-directory)))
(delete-directory output t)
(rename-file temporary-directory output t))))))
@@ -493,10 +502,11 @@ as keys. Keys are compared using `equal'."
;;;
;;; Test HTTP server to serve the blog locally
-(defun ennu-server-start ()
+;; TODO: Why can't simple-httpd itself handle the unhexing?
+(defun ennum-server-start ()
(interactive)
- (setq httpd-root (expand-file-name (ennu-setting :output-directory)
- (ennu-setting :working-directory)))
+ (setq httpd-root (expand-file-name (ennum-setting :output-directory)
+ (ennum-setting :working-directory)))
(defun httpd/ (proc uri-path query request)
(let* ((uri-path (httpd-unhex uri-path))
(file-path (httpd-gen-path uri-path)))
@@ -514,11 +524,11 @@ as keys. Keys are compared using `equal'."
;; appended.
(t (httpd-serve-root proc httpd-root (concat uri-path ".html") request)))))
(httpd-start)
- (message "Ennu web server listening at http://localhost:%d" httpd-port))
+ (message "Ennum web server listening at http://localhost:%d" httpd-port))
-(defun ennu-server-stop ()
+(defun ennum-server-stop ()
(interactive)
(httpd-stop)
- (message "Ennu web server stopped"))
+ (message "Ennum web server stopped"))
-(provide 'ennu)
+(provide 'ennum)