GitHub - progfolio/doct: DOCT: Declarative Org Capture Templates for Emacs
source link: https://github.com/progfolio/doct
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.org
DOCT: Declarative Org Capture Templates
doct
is a function that provides an alternative, declarative syntax for describing Org capture templates.
tl;dr
'(("p" "Parent") ("pc" "Child" entry (file+headline "~/example.org" "Example") "* %^{Description} \n:PROPERTIES:\n:Created: %U\n:END:%?" :prepend t))
becomes:
(doct '(("Parent" :keys "p" :children ("Child" :keys "c" :file "~/example.org" :headline "Example" :prepend t :template ("* %^{Description}" ":PROPERTIES:" ":Created: %U" ":END:" "%?")))))
Installation
Still bug testing, and working on the code. I’ll be submitting to MELPA soon.
Until then, if interested in testing, clone the doct
repo and add it to your
load-path:
(use-package doct :load-path "lisp/")
Documentation
doct
(doct declarations)
doct
expects a list of declarations. Each declaration is either a parent, or child template declaration.
A parent declaration consists of:
- a name
- a
:keys
string - a list of
:children
A child declaration consists of:
- a name
- a
:keys
string - a template type
- a target
- an item template
- hook functions defined with the hook keywords
- additional arguments
Name & Keys
Each declaration must define, at a minimum, a name and keys. The name is the first
value in the declaration. The :keys
keyword defines the keys to access the template
from the capture menu.
(doct '(("example" :keys "e")))
returns:
(("e" "example"))
Type
The :type
keyword defines the entry type and accepts the following symbols:
doct-default-entry-type
defines the entry type when the :type
keyword is not provided.
For example, with doct-default-entry-type
set to entry
(the default):
(doct '(("example" :keys "e" :type entry :file "")))
And
(doct '(("example" :keys "e" :file "")))
Both return:
(("e" "example" entry (file "")))
Target
The :target
keyword defines the location of the inserted template text.
(doct ... :target (file "/path/to/target.org"))
The first keyword declared in the following group exclusively sets the target.
The :file
keyword is not necessary for these.
:file
keyword. It is
responsible for finding the proper file and location to insert the capture
item. If :file
defines a target file, then the function is only
responsible for moving point to the desired location within that file.
(doct '(("example" :keys "e" :type entry :clock t ;;ignored because clock is first :function (lambda () (ignore)) ;;also ignored :id "1")))
returns:
(("e" "example" entry (clock)))
The :file
keyword defines the target file for the capture template.
(doct ... :file "/path/to/target.org")
The following keywords refine the target file location:
:headline “node headline” File under unique heading in target file. :olp (“Level 1 heading” “Level 2 heading”…)Define the full outline in the target file.
If :+datetree
has a non-nil value, create a date tree for today’s date.
Use a non-nil :time-prompt
property to prompt for a different date.
Use a non-nil :tree-type
property to create a week-tree.
File to the entry matching regexp in target file
:function location-finding-functionIf used in addition to the :file
keyword, the value should be a function
that finds the desired location in that file. If used as an exclusive
keyword (see above), the function must locate both the target file and move
point to the desired location.
Template
The :template
keyword defines the template for creating the capture item.
It may be either a string or a list of strings. doct
joins the list with new lines.
(doct '((... :template ("Test" "One" "Two"))))
returns:
((... "Test\nOne\nTwo"))
The :template-file
keyword defines a file containing the text of the template.
The :template-function
keyword defines a function which returns the template.
The first keyword declared overrides any additional template declarations.
Additional options
Key Value pairs define additional options.
doct
does not include keywords with a nil
value in the returned template.
(doct '((...:immediate-finish nil)))
returns:
((...))
see the Org Mode Manual for a full list of additional options.
Children
A parent declaration may contain a list of :children
declarations.
The parent’s :keys
prefix each child’s :keys
.
(doct '(("parent" :keys "p" :children (("child" :keys "c" :children (("grandchild" :keys "g" :file "" :type plain :template "test")))))))
returns:
(("p" "parent") ("pc" "child") ("pcg" "grandchild" plain (file "") "test"))
Hooks
Adding one of the following hook keywords in an entry will generate a function of the form:
doct--hook/<hook-variable-abbreviation>/KEYS
which wraps the user’s function in a conditional check for the current template’s keys and adds it to the appropriate hook.
:hook org-capture-mode-hookRuns when entering the org-capture-mode minor mode. Useful for running a function immediately after filling the template out.
:prepare-finalize org-capture-prepare-finalize-hookRuns before the finalization starts. The capture buffer is current and narrowed.
:before-finalize org-capture-before-finalize-hookRuns right before a capture process finalizes. The capture buffer is still current and widened to the entire buffer.
:after-finalize org-capture-after-finalize-hook Runs right after a capture process finalizes. Suitable for window cleanup.For example:
(doct '(("example" :keys "e" :hook (lambda () ;;when selecting the "example" template ;;doct--hook/mode/e executes ;;during the org-capture-mode-hook. (ignore)))))
See doct-remove-hooks
to remove and unintern generated functions.
custom variables
doct supports the following variables for customization:
doct-default-entry-type ‘entry The default template entry type. It can be overridden by using the:type
keyword in an entry.
doct-sort-parents-predicate nil
A binary predicate function which sorts sets of parents/children.
A nil value skips sorting.
The list it sorts is of the form:
(((parent) (child)...)...)
For example:
(let ((doct-sort-parents-predicate (lambda (a b) (string< (caar a) (caar b))))) (doct '(("b-parent" :keys "b" :children (("b-child" :keys "b") ("a-child" :keys "a"))) ("a-parent" :keys "a" :children (("b-child" :keys "b") ("a-child" :keys "a"))))))
returns a list with the parents sorted. The children are still in declaration order:
(("a" "a-parent") ("ab" "b-child entry") ("aa" "a-child" entry) ("b" "b-parent") ("bb" "b-child" entry) ("ba" "a-child" entry))
((child)...)
For example:
(let ((doct-sort-children-predicate (lambda (a b) ;;sort childern alphabetically by their keys (string< (car a) (car b))))) (doct '(("b-parent" :keys "b" :children (("b-child" :keys "b") ("a-child" :keys "a"))) ("a-parent" :keys "a" :children (("b-child" :keys "b") ("a-child" :keys "a"))))))
returns a list with each parent’s children sorted alphabetically by their :keys
.
(("b" "b-parent") ("ba" "a-child" entry) ("bb" "b-child" entry) ("a" "a-parent") ("aa" "a-child" entry) ("ab" "b-child" entry))
Contributing
Pull/feature requests, code review, angry comments are all welcome.
Please add a test to the test suite if you introduce any changes.
Thanks, nv
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK