INITIAL (March 14, 2014): First rough draft.
EDIT (March 15, 2014): Created and revised the function named example
. The path of the let-bound variable org-file
must coincide with an existing org-mode file. The let-bound variables main-heading
and sub-heading
are not being used at this time due to an apparent limitation with using variables in a list that begins with '(
-- i.e., those two variables are not recognized under this circumstance. The function org-capture
from org-capture.el
has been modified to include the contents of the function org-capture-set-plist
, which in turn has been modified to eliminate the first two elements of org-capture-entry
(aka org-capture-templates
) -- both entries (i.e., :key
and :description
) are for manually selecting a template from the user-interface, and are not needed when generating an org buffer programmatically as is being done with this example
. In addition, the portions of the function org-capture
relating to manually selecting a template have been removed.
EDIT (March 16, 2014): Revised variables and list handling based upon lessons provided by @sds and @lunaryorn in the following thread: https://stackoverflow.com/a/22440518/2112489 Added four optional incoming variables -- (1) main-heading
; (2) sub-heading-headline
; (3) sub-heading-complete
; and (4) plain-list
. The example now work either interactively, or by evaluating the function using the following format: (org-generate "PROJECT" "Thesis" "** Thesis\n:PROPERTIES:\n:END:" '("a" "b" "c"))
EDIT (March 19, 2014): org-generate
is now a non-interactive function that requires incoming variables -- the doc-string has been updated. Created a function named example
that utilizes the new format for org-generate
.
;; EXAMPLES:
;; (org-generate 'entry "/Users/HOME/Desktop/myproject.org" "PROJECT" "Thesis" "** Thesis\n :PROPERTIES:\n :END:")
;; (org-generate 'item "/Users/HOME/Desktop/myproject.org" "PROJECT" "Thesis" nil '("a" "b" "c"))
(defun example ()
(interactive)
(let* (
(org-file "/Users/HOME/Desktop/myproject.org")
(level-one "TASKS")
(level-two
"Active [\#A] Generate Org-mode objects programmatically.")
(full-level-two (concat
"** Active [\#A] Generate Org-mode objects programmatically.\n"
" DEADLINE: <%<%Y-%m-%d %a>>\n"
" :PROPERTIES:\n"
" :ToodledoFolder: TASKS\n"
" :END:"))
(plain-list '("foo" "bar" "baz")) )
(org-generate 'entry org-file level-one level-two full-level-two)
(org-generate 'item org-file level-one level-two nil plain-list) ))
(defun org-generate (type org-file level-one
&optional level-two full-level-two plain-list)
"Formating options for `org-capture-entry` are similar to `org-capture-templates`.
However, the first two elements (i.e., `:key` and `:description`) are NOT used.
Please see the doc-string of the variable `org-capture-templates` for more info.
(1) `type`: required -- 'entry | 'item
(2) `org-file`: required -- path to the org-mode file.
(3) `level-one`: required -- main heading.
(4) `level-two`: optional -- sub-heading headline (only).
(5) `full-level-two`: optional -- complete sub-heading.
(6) `plain-list`: optional -- a list.
EXAMPLES:
`(org-generate 'entry org-file level-one level-two full-level-two)`
`(org-generate 'item org-file level-one level-two nil plain-list)` "
(require 'org-capture)
(let (org-capture-entry)
(cond
((eq type 'entry)
(setq org-capture-entry
`(entry
(file+headline ,org-file ,level-one)
,full-level-two :empty-lines 1 :immediate-finish t))
(lawlist-org-capture))
((eq type 'item)
(setq org-capture-entry
`(item
(file+olp ,org-file ,level-one ,level-two)
nil :empty-lines 1 :immediate-finish t))
(mapcar (lambda (x)
(progn
(setcar (nthcdr 2 org-capture-entry) x)
(lawlist-org-capture) ))
plain-list)))))
(defun lawlist-org-capture ()
(let* ((orig-buf (current-buffer))
(annotation (if (and (boundp 'org-capture-link-is-already-stored)
org-capture-link-is-already-stored)
(plist-get org-store-link-plist :annotation)
(ignore-errors (org-store-link nil))))
(entry org-capture-entry)
initial)
(setq initial (or org-capture-initial
(and (org-region-active-p)
(buffer-substring (point) (mark)))))
(when (stringp initial)
(remove-text-properties 0 (length initial) '(read-only t) initial))
(when (stringp annotation)
(remove-text-properties 0 (length annotation)
'(read-only t) annotation))
(setq org-capture-plist (copy-sequence (nthcdr 3 entry)))
(org-capture-put :target (nth 1 entry))
(let ((txt (nth 2 entry)) (type (or (nth 0 entry) 'entry)))
(when (or (not txt) (and (stringp txt) (not (string-match "\\S-" txt))))
(cond
((eq type 'item) (setq txt "- %?"))
((eq type 'checkitem) (setq txt "- [ ] %?"))
((eq type 'table-line) (setq txt "| %? |"))
((member type '(nil entry)) (setq txt "* %?\n %a"))))
(org-capture-put :template txt :type type))
(org-capture-get-template)
(org-capture-put :original-buffer orig-buf
:original-file (or (buffer-file-name orig-buf)
(and (featurep 'dired)
(car (rassq orig-buf
dired-buffers))))
:original-file-nondirectory
(and (buffer-file-name orig-buf)
(file-name-nondirectory
(buffer-file-name orig-buf)))
:annotation annotation
:initial initial
:return-to-wconf (current-window-configuration)
:default-time
(or org-overriding-default-time
(org-current-time)))
(org-capture-set-target-location)
(condition-case error
(org-capture-put :template (org-capture-fill-template))
((error quit)
(if (get-buffer "*Capture*") (kill-buffer "*Capture*"))
(error "Capture abort: %s" error)))
(setq org-capture-clock-keep (org-capture-get :clock-keep))
(condition-case error
(org-capture-place-template
(equal (car (org-capture-get :target)) 'function))
((error quit)
(if (and (buffer-base-buffer (current-buffer))
(string-match "\\`CAPTURE-" (buffer-name)))
(kill-buffer (current-buffer)))
(set-window-configuration (org-capture-get :return-to-wconf))
(error "Error.")))
(if (and (derived-mode-p 'org-mode)
(org-capture-get :clock-in))
(condition-case nil
(progn
(if (org-clock-is-active)
(org-capture-put :interrupted-clock
(copy-marker org-clock-marker)))
(org-clock-in)
(org-set-local 'org-capture-clock-was-started t))
(error
"Could not start the clock in this capture buffer")))
(if (org-capture-get :immediate-finish)
(org-capture-finalize))))

(source: lawlist.com)
org-capture-templates
, because it seems very similar to what you want to todo. – lawlistorg-element-interpret-data
could probably be yourorg-generate
, but the data seems to need a lot of details about positions, levels, bullets etc. soorg-generate-heading
and friends would still need to be written and would be nontrivial. – Michał Politowski