emacs - Generar objetos de modo Org programáticamente
elisp org-mode (1)
Quiero generar cadenas que contengan texto Org-mode sin codificar realmente la sintaxis. Por ejemplo, quiero ejecutar una función como (org-generate (org-generate-heading "heading" (org-generate-plain-list ''("foo" "bar" "baz")))
y devolverá:
* heading
- foo
- bar
- baz
En otras palabras, quiero crear documentos en modo Org de complejidad arbitraria sin necesidad de microgenerizar características sintácticas como asteriscos e indentaciones, solo a través de funciones de llamada con parámetros, que devuelven algunos objetos Org. ¿Es posible hacer eso? ¿Tal vez a través de org-element
?
INICIAL (14 de marzo de 2014): primer borrador.
EDITAR (15 de marzo de 2014): creó y revisó la función denominada example
. La ruta del org-file
variable let-bound debe coincidir con un archivo org-mode existente. El main-heading
variables vinculadas no se utilizan en este momento debido a una aparente limitación con el uso de variables en una lista que comienza con ''(
- es decir, esas dos variables no se reconocen bajo esta circunstancia. La función org-capture
de org-capture.el
ha sido modificada para incluir los contenidos de la función org-capture-set-plist
, que a su vez ha sido modificada para eliminar los dos primeros elementos de org-capture-entry
(aka org-capture-templates
): ambas entradas (es decir :key
y :description
) son para seleccionar manualmente una plantilla de la interfaz de usuario, y no son necesarias cuando se genera un búfer orgánico programáticamente como se hace con este example
. las partes de la función org-capture
relacionadas con la selección manual de una plantilla han sido eliminadas.
EDITAR (16 de marzo de 2014): variables revisadas y manejo de listas basadas en las lecciones proporcionadas por @sd y @lunaryorn en el siguiente hilo: https://.com/a/22440518/2112489 Se agregaron cuatro variables entrantes opcionales - (1 ) main-heading
; (2) sub-heading-headline
; (3) sub-heading-complete
; y (4) plain-list
. El ejemplo ahora funciona interactivamente o mediante la evaluación de la función usando el siguiente formato: (org-generate "PROJECT" "Thesis" "** Thesis/n:PROPERTIES:/n:END:" ''("a" "b" "c"))
EDITAR (19 de marzo de 2014): org-generate
es ahora una función no interactiva que requiere variables entrantes: la cadena de documentación se ha actualizado. Creó una función llamada example
que utiliza el nuevo formato para 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))))
Ejemplo http://www.lawlist.com/images/programmatic_org_file.png