From 2ef369f0fd06b4eb48b9f539553835838daf621f Mon Sep 17 00:00:00 2001 From: Arun Isaac Date: Sun, 2 Aug 2020 22:21:24 +0530 Subject: Use closures instead of ennum-exp objects. The lexical environment of a closure can capture all inputs to an expression. Earlier we were capturing some of these inputs using the inputs slot of an ennum-exp object. Capturing dynamically scoped global variables is a different matter, and is not addressed by this commit. * ennum.el (ennum-exp): Delete type. (ennum--rewrite-inputs): Delete macro. (ennum-eval): Deal with closures not ennum-exp objects. (ennum-store-item-union, ennum-publish-post, ennum-publish-generic, ennum-publish-feed, ennum-publish-image, ennum-publish-copy): Pass inputs as lexically bound variables of a closure, rather than as ennum-exp inputs. --- ennum.el | 161 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 67 insertions(+), 94 deletions(-) diff --git a/ennum.el b/ennum.el index 86295f8..bfd3bc7 100644 --- a/ennum.el +++ b/ennum.el @@ -64,42 +64,16 @@ respectively by - and _, and the pad character = is optional." (t (chmod file file-mode)))) (ennum-directory-files directory t t))) -(cl-defstruct (ennum-exp (:constructor ennum-make-exp) - (:copier nil)) - inputs proc) - -(defun ennum--rewrite-inputs (exp) - (pcase exp - (`(ennum-input ,arg) - (let ((input-identifier (gensym "input"))) - (vector input-identifier (list arg) (list input-identifier)))) - (`(,parent . ,childern) - (seq-reduce (pcase-lambda (`[,result ,inputs ,input-identifiers] node) - (pcase (ennum--rewrite-inputs node) - (`[,modified-tree ,new-inputs ,new-input-identifiers] - (vector (append result (list modified-tree)) - (append inputs new-inputs) - (append input-identifiers new-input-identifiers))))) - exp - (vector nil nil nil))) - (leaf (vector exp nil nil)))) - (defmacro ennum-exp (&rest body) - (let ((raw-expression `(progn ,@body))) - (pcase (ennum--rewrite-inputs raw-expression) - (`[,rewritten-body ,inputs ,input-identifiers] - `(ennum-eval - (ennum-make-exp - :inputs (list ,@inputs) - :proc (lambda ,input-identifiers ,rewritten-body))))))) - -(defun ennum-eval (exp) + `(ennum-eval (lambda () ,@body))) + +(defun ennum-eval (closure) (let ((output (expand-file-name (with-temp-buffer (let ((print-length nil) (print-level nil)) - (print exp (current-buffer))) + (print closure (current-buffer))) (ennum--hash)) (ennum-setting :store)))) ;; Create store if it doesn't exist @@ -110,8 +84,7 @@ respectively by - and _, and the pad character = is optional." (message "Building %s" output) (ennum-with-temporary-directory temporary-directory (ennum-with-current-directory temporary-directory - (apply (ennum-exp-proc exp) - (ennum-exp-inputs exp))) + (funcall closure)) (rename-file temporary-directory output)) (ennum--set-file-modes-recursively output #o555 #o444 #o555)) output)) @@ -128,7 +101,7 @@ respectively by - and _, and the pad character = is optional." (make-directory destination) (copy-file source destination t))))) (reverse (ennum-directory-files item nil t)))) - (ennum-input items)))) + items))) (defmacro ennum-make-functional-setter (name copier accessor) `(defun ,name (object new-value) @@ -333,44 +306,43 @@ result as a string." (org-export-as 'ennum-html nil nil body-only ext-plist)))))) (defun ennum-publish-post (post) - (append - (list - (ennum-exp - (ennum-export-post post - (ennum-input (ennum-intern (ennum-post-filename post))) - (ennum--org-output-filename (ennum-post-filename post))))) - (when (ennum-post-tangle post) + (let ((interned-org-file (ennum-intern (ennum-post-filename post)))) + (append (list (ennum-exp - ;; TODO: Handle tangle outputs that are nested - ;; into directories, and when each tangle output - ;; is nested into a different directory. - (let* ((input-org-file (ennum-input (ennum-intern (ennum-post-filename post)))) - (post-file-copy - (expand-file-name - (file-name-nondirectory input-org-file) - (ennum-setting :static-directory)))) - (ennum-copy input-org-file post-file-copy) - (org-babel-tangle-file post-file-copy) - (delete-file post-file-copy))))) - (seq-mapcat 'ennum-publish-link (ennum-post-links post)))) + (ennum-export-post post + interned-org-file + (ennum--org-output-filename (ennum-post-filename post))))) + (when (ennum-post-tangle post) + (list + (ennum-exp + ;; TODO: Handle tangle outputs that are nested + ;; into directories, and when each tangle output + ;; is nested into a different directory. + (let* ((post-file-copy + (expand-file-name + (file-name-nondirectory interned-org-file) + (ennum-setting :static-directory)))) + (ennum-copy interned-org-file post-file-copy) + (org-babel-tangle-file post-file-copy) + (delete-file post-file-copy))))) + (seq-mapcat 'ennum-publish-link (ennum-post-links post))))) (defun ennum-publish-generic (other-files-directory file) - (ennum-exp - (let ((interned-file - (ennum-input (ennum-intern + (let ((interned-file (ennum-intern (ennum--file-join other-files-directory file)))) - (output-file - (pcase (file-name-extension file) - ("org" (ennum--org-output-filename file)) - (_ file)))) - (pcase (file-name-extension interned-file) - ("org" - (when (file-name-directory output-file) - (ennum-mkdir-p (file-name-directory output-file))) - (ennum-with-file-contents interned-file - (org-export-to-file 'html output-file))) - (_ (ennum-copy interned-file output-file)))))) + (ennum-exp + (let ((output-file + (pcase (file-name-extension file) + ("org" (ennum--org-output-filename file)) + (_ file)))) + (pcase (file-name-extension interned-file) + ("org" + (when (file-name-directory output-file) + (ennum-mkdir-p (file-name-directory output-file))) + (ennum-with-file-contents interned-file + (org-export-to-file 'html output-file))) + (_ (ennum-copy interned-file output-file))))))) (defun ennum-video-poster (video) (or (seq-find (lambda (file) @@ -471,28 +443,29 @@ result as a string." (format-time-string "%Y-%m-%dT%H:%M:%SZ" date)) (defun ennum-publish-feed (feed-file title rights posts) - (ennum-exp - ;; TODO: Create ennu-mkdir-p-for-file - (when (file-name-directory feed-file) - (ennum-mkdir-p (file-name-directory feed-file))) - (with-temp-file feed-file - (insert - (xmlgen - `(feed :xmlns "http://www.w3.org/2005/Atom" - (id ,(ennum--absolute-uri "")) - (title ,title) - (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 ennum %s" - emacs-major-version emacs-minor-version (org-version) ennum-version)) - (rights ,rights) - ,@(seq-mapn (lambda (post interned-post-file) - (ennum--feed-entry post interned-post-file)) - posts - (ennum-input (seq-map (lambda (post) - (ennum-intern (ennum-post-filename post))) - posts))))))))) + (let ((interned-post-files + (seq-map (lambda (post) + (ennum-intern (ennum-post-filename post))) + posts))) + (ennum-exp + ;; TODO: Create ennu-mkdir-p-for-file + (when (file-name-directory feed-file) + (ennum-mkdir-p (file-name-directory feed-file))) + (with-temp-file feed-file + (insert + (xmlgen + `(feed :xmlns "http://www.w3.org/2005/Atom" + (id ,(ennum--absolute-uri "")) + (title ,title) + (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 ennum %s" + emacs-major-version emacs-minor-version (org-version) ennum-version)) + (rights ,rights) + ,@(seq-mapn (lambda (post interned-post-file) + (ennum--feed-entry post interned-post-file)) + posts interned-post-files)))))))) (defun ennum--feed-entry (post interned-post-file) (let ((link (ennum--absolute-uri (ennum--org-output-filename @@ -551,21 +524,21 @@ result as a string." "/")) (defun ennum-publish-image (image width) - (ennum-exp - (let ((input-image (ennum-input (ennum-intern image)))) + (let ((interned-image (ennum-intern image))) + (ennum-exp (ennum-mkdir-p (ennum-setting :images-directory)) (ennum-image-optimize-image (ennum-image-resize-image - input-image + interned-image (ennum--file-join (ennum-setting :images-directory) (ennum-image-output-filename - (file-name-nondirectory input-image) width)) + (file-name-nondirectory interned-image) width)) width))))) (defun ennum-publish-copy (file) - (ennum-exp - (ennum-copy (ennum-input (ennum-intern file)) file))) + (let ((interned-file (ennum-intern file))) + (ennum-exp (ennum-copy interned-file file)))) (defun newest-file (files) (pcase files -- cgit v1.2.3