Skip to content

Commit

Permalink
refine workbook and project definitions, relate options - create docs
Browse files Browse the repository at this point in the history
  • Loading branch information
balddotcat committed Jun 8, 2019
1 parent 408cf3b commit 161b2e6
Show file tree
Hide file tree
Showing 3 changed files with 480 additions and 197 deletions.
128 changes: 120 additions & 8 deletions README.md
@@ -1,23 +1,135 @@


# org-publish-workbook

**WIP** an `org-publish` pipeline utilizing [ox-slimhtml](https://github.com/balddotcat/ox-slimhtml).
`org-export` can easily generate multiple versions of the
same org data; an **org-publish-workbook** binds an export
backend with an `org-publish` project, to help with the
process of iteratively customizing output.

A **workbook** consists of an entry in `org-publish-workbook
-alist`, a set of entries in `org-publish-project-alist` and
an `org-export-derived-backend`.

As an example, the initial outline of publishing this
project's `README.md` consisted of the following setup.

(org-publish-workbook-add
'documentation
'(md ;; workbook derived from markdown exporter (ox-md.el)
:filters-alist ;; word wrap paragraphs, with hyphens
((:filter-paragraph (lambda (content backend info)
(with-temp-buffer
(insert content)
(modify-category-entry ?- ?|)
(set-fill-column 60)
(fill-region (point-min) (point-max) 'full t nil)
(buffer-string)))))
:exclude ".*"
:base-extension ".md"))

(org-publish-workbook-add-project
'documentation
'("org-publish-workbook"
:base-directory "~/workbook/lib"
:include ["org-publish-workbook.org"]
:publishing-directory "~/workbook/lib/org-publish-workbook"
:decorators ((:before-processing ;; insert title as md export is body only
(lambda ()
(org-map-entries (lambda () (org-demote-subtree)) "LEVEL=1")
(org-insert-heading)
(insert "org-publish-workbook"))))))


## adding a workbook

Workbooks are initialized with `org-publish-workbook-
add`. This function adds an entry to `org-publish-workbook-
alist`, based on the first argument, **label**.

The second argument, **backend**, can be either a symbol, or
a list starting with a symbol and an alist of options. The
symbol should reference an **org-export backend**; the
provided options are used to create an `org-export-derived-
backend`.

Publish project specific options `:base-directory`, `:base-
extension`, `:exclude`, `:publishing-directory`, `:template`
and `:template-directory` can be also be specified, to set
the workbook's projects' default values.

The rest of the arguments are used to create **projects**
with `org-publish-workbook-add-project`.


### org-export backend

Each workbook creates a reusable (further extendable)
derived backend based on the original exporter, for use with
all of it's projects. For a list of options and settings,
please see the doc string of `org-export-define-derived-
backend`.


### org-publish projects

When a project is added to a workbook, it is added to `org-
publish-project-alist` labelled as `[workbook`-`project]`.

When not set directly, options default to values set in each
respective **workbook**, or their equivalent environment
variables; root-directory is set to the Emacs server's
initial working directory.

- :template-directory; `.etc/export-template`
- :output-directory; `.var`

Commonly used options are `:include`, `:exclude` and
`:recursive` - the custom properties `:template` and
`:decorate` create export hooks through **output
decorators**.


## output decorators

By adding **decorators** to a publishing project's export
pipeline, the `:final-output`, or the contents of each
buffer `:before-processing`, can be directly edited.

When editing the `:final-output`, the function supplied to
`workbook-decorate` is called with **contents** and optional
**args**. The function's output becomes the result of this
export action.

`:before-processing` hooks are expanded within the context
of each current-buffer, allowing for direct editing.

Each hook is activated during a project's `:preparation-
function`, and deactivated in it's `:completion-function`.

## paths

### template decorator

## workbook
When a project's `:template` property is set, by default, a
hook is run during publishing to insert or update the
current buffer's `#+SETUPFILE` property before any
processing takes place.

Alternately, the `insert-template-fn` variable can be
updated to specify a function which will be called with the
resolved path of the project's template file.

## publishing

## rendering

## workbook projects
The `org-publish-workbook-render` function publishes a
workbook's projects. Optional arguments are `force`, `async`
and projects - to publish only the ones specified.


## decorate
## tests

emacs -batch \
-l ert \
-l org-publish-workbook-tests.el \
-f ert-run-tests-batch-and-exit

### add template
140 changes: 77 additions & 63 deletions org-publish-workbook-tests.el
@@ -1,82 +1,96 @@
(and (require 'package) (package-initialize))
(load-file "org-publish-workbook.el")

(defmacro workbook-test (name &rest body)
`(ert-deftest ,name ()
(setq org-export-registered-backends
(delete [cl-struct-org-export-backend test slimhtml nil nil nil nil nil]
(delete [cl-struct-org-export-backend test html nil nil nil nil nil]
org-export-registered-backends))
(setq org-publish-project-alist nil)
(should (eq nil (org-export-get-backend 'test)))
(should (eq nil org-publish-project-alist))
(setq org-publish-workbook-alist nil)
,@body))


(workbook-test workbook-init
(org-publish-workbook-init 'test '() '("test"))
(should (equal 'test (org-publish-workbook-backend 'test)))
(should (assoc "test-test" org-publish-project-alist))
(let ((project-properties (cdr (assoc "test-test" org-publish-project-alist))))
(should (string= (format "%s/test" org-publish-workbook--path-root)
(plist-get project-properties :base-directory)))))
(org-publish-workbook-add 'test 'html '("project"))
(should (assoc 'test org-publish-workbook-alist))
(should (seq-filter (lambda (backend)
(equal backend [cl-struct-org-export-backend test html nil nil nil nil nil]))
org-export-registered-backends))
(should (assoc "test-project" org-publish-project-alist)))

(workbook-test project-properties
(let ((project-properties (cdr (org-publish-workbook-project
(org-publish-workbook-backend 'test '())))))
(should (string= (format "%s/test" org-publish-workbook--path-root)
(plist-get project-properties :base-directory)))
(should (string= (format "%s/.var/test" org-publish-workbook--path-root)
(plist-get project-properties :publishing-directory)))
(should (equal nil (plist-get project-properties :recursive)))
(should (equal nil (plist-get project-properties :preparation-function)))
(should (equal nil (plist-get project-properties :completion-function)))))

(workbook-test add-project
(org-publish-workbook-backend 'test '())
(let ((project-properties (cdr (assoc (org-publish-workbook-add-project
(org-publish-workbook-backend 'test) '("test"))
org-publish-project-alist))))
(should (string= (format "%s/test" org-publish-workbook--path-root)
(plist-get project-properties :base-directory)))
(should (string= (format "%s/.var/test" org-publish-workbook--path-root)
(plist-get project-properties :publishing-directory)))
(should (equal nil (plist-get project-properties :recursive)))
(should (equal nil (plist-get project-properties :preparation-function)))))
(org-publish-workbook-add 'test 'html)
(org-publish-workbook-add-project
(org-export-backend-name (org-publish-workbook-backend 'test))
'("project"))
(should (assoc "test-project" org-publish-project-alist)))


(workbook-test project-properties
(org-publish-workbook-add 'test 'html '("project"))
(let ((properties (cdr (assoc "test-project" org-publish-project-alist))))
(should (string= (plist-get properties :base-directory)
(format "%s" org-publish-workbook-root-directory)))
(should (string= (plist-get properties :publishing-directory)
(format "%s.var" org-publish-workbook-root-directory)))
(should (equal nil (plist-get properties :recursive)))
(should (equal nil (plist-get properties :preparation-function)))
(should (equal nil (plist-get properties :completion-function)))))


(workbook-test workbook-remove
(org-publish-workbook-add 'test 'html '("project"))
(org-publish-workbook-remove 'test)
(should (eq nil (org-export-get-backend 'test)))
(should (eq nil (assoc 'test org-publish-workbook-alist)))
(should (eq nil (assoc "test-project" org-publish-project-alist))))

(workbook-test redefine-project
(org-publish-workbook-backend 'test '())
(org-publish-workbook-add-project (org-publish-workbook-backend 'test) '("test"))
(org-publish-workbook-add-project (org-publish-workbook-backend 'test)
'("test"
:publishing-directory "hello"
:base-directory "hello"))
(should (equal 1 (length org-publish-project-alist)))
(let ((project (cdr (assoc "test-test" org-publish-project-alist))))
(should (string= (format "%s/.var/hello" org-publish-workbook--path-root)
(plist-get project :publishing-directory)))
(should (string= (format "%s/hello" org-publish-workbook--path-root)
(plist-get project :base-directory)))))
(workbook-test project-template-property
(let* ((project (org-publish-workbook-project 'test '("project" :template PATH)))
(project-properties (cdr project))
(preparation-function (plist-get project-properties :preparation-function))
(completion-function (plist-get project-properties :completion-function)))
(should (equal (cadr (cdar (cddr (car preparation-function))))
'(lambda (backend) (funcall (quote org-publish-workbook-insert-setupfile) nil))))
(should (equal (cadr (cadr (cdar (cddr (car completion-function)))))
'(lambda (backend) (funcall (quote org-publish-workbook-insert-setupfile) nil))))))

(workbook-test project-decorate-property
(let* ((project (org-publish-workbook-project 'test '("project" :decorate '(identity))))
(project-properties (cdr project))
(preparation-function (plist-get project-properties :preparation-function))
(completion-function (plist-get project-properties :completion-function)))
(should (equal (cadr (cdar (cddr (car preparation-function))))
'(lambda (content backend info) (apply (quote quote) content (quote ((identity)))))))
(should (equal (cadr (cadr (cdar (cddr (car completion-function)))))
'(lambda (content backend info) (apply (quote quote) content (quote ((identity)))))))))

(workbook-test before-processing-hooks
(org-publish-workbook-add 'test 'html '("project"))
(let* ((project (assoc "test-project" org-publish-project-alist))
(project-properties (cdr project)))
(should (not (plist-get project-properties :preparation-function)))
(should (not (plist-get project-properties :completion-function)))
(let* ((updated-project (org-publish-workbook-decorate-project project :before-processing 'identity))
(preparation-function (plist-get (cdr updated-project) :preparation-function))
(completion-function (plist-get (cdr updated-project) :completion-function)))
(should (equal (cadr (cdar (cddr (car preparation-function))))
'(lambda (backend) (funcall (quote identity)))))
(should (equal (cadr (cadr (cdar (cddr (car completion-function)))))
'(lambda (backend) (funcall (quote identity))))))))

(workbook-test decorate
(org-publish-workbook-init 'test '() '("test"))
(let* ((project (assoc "test-test" org-publish-project-alist))
(workbook-test final-output-hooks
(org-publish-workbook-add 'test 'html '("project"))
(let* ((project (assoc "test-project" org-publish-project-alist))
(project-properties (cdr project)))
(should (not (plist-get project-properties :preparation-function)))
(should (not (plist-get project-properties :completion-function)))
(let ((updated-project (org-publish-workbook-decorate :before-processing project 'identity)))
(should (equal (nth 3 (car (plist-get (cdr updated-project) :preparation-function)))
'(add-hook (quote org-export-before-processing-hook)
(function (lambda (backend)
(apply fn args))))))
(should (equal (nth 3 (car (plist-get (cdr updated-project) :completion-function)))
'(remove-hook (quote org-export-before-processing-hook) fn))))
(let ((updated-project (org-publish-workbook-decorate :final-output project 'identity)))
(should (equal (nth 3 (car (plist-get (cdr updated-project) :preparation-function)))
'(add-to-list (quote org-export-filter-final-output-functions)
(function (lambda (content backend info)
(apply fn content info args))))))
(should (equal (nth 3 (car (plist-get (cdr updated-project) :completion-function)))
'(setq org-export-filter-final-output-functions
(seq-filter (function
(lambda (filter)
(and (not (eq filter fn)) filter)))
org-export-filter-final-output-functions)))))))
(let* ((updated-project (org-publish-workbook-decorate-project project :final-output 'identity))
(preparation-function (plist-get (cdr updated-project) :preparation-function))
(completion-function (plist-get (cdr updated-project) :completion-function)))
(should (equal (cadr (cdar (cddr (car preparation-function))))
'(lambda (content backend info) (apply (quote identity) content (quote nil)))))
(should (equal (cadr (cadr (cdar (cddr (car completion-function)))))
'(lambda (content backend info) (apply (quote identity) content (quote nil))))))))

0 comments on commit 161b2e6

Please sign in to comment.