Generate Org-mode objects programmatically

佐手、 提交于 2019-12-03 02:55:54
lawlist

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)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!