62

GitHub - progfolio/doct: DOCT: Declarative Org Capture Templates for Emacs

 4 years ago
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:

entry An Org node with a headline. The template becomes a child of the target entry or a top level entry. item A plain list item, placed in the first plain list at the target location. checkitem A checkbox item. This differs from the plain list item only in so far as it uses a different default template. table-line A new line in the first table at target location. plain Text inserted as is.

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.

:id “id of existing Org entry” File as child of this entry, or in the body of the entry (see org-id-get-create and the Org Mode Manual) :clock t File to the currently clocked entry :function (lambda () ;visit file and move point to desired location…) This keyword is exclusive when used without the :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.

:regexp “regexp describing location”

File to the entry matching regexp in target file

:function location-finding-function

If 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-hook

Runs 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-hook

Runs before the finalization starts. The capture buffer is current and narrowed.

:before-finalize org-capture-before-finalize-hook

Runs 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))
doct-sort-children-predicate nil A binary predicate function used to sort parent’s children. A nil value skips sorting. The list it sorts is of the form:
((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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK