Explorar o código

Allow to capture plain templates into Org nodes

* lisp/org.el (org-end-of-meta-data-and-drawers): New function.
* lisp/org-capture.el (org-capture-place-plain-text): Implement adding
plain text templates to Org nodes.

This is something which came out of a discussion with Philip Rooke, in
the thread

Philip tried to use a capture template with template type plain, but
using a date tree as a target.  Plain templates where placed at the
end of the file, not at the end of the entry.  I complained first that
mixing headlined entries and plain snippets into the same capture
target is not possible, but I realized that there is a way to make
this work OK.  The headlined entries become children, and the plain
text snippets become part of the text before the first child.
Carsten Dominik %!s(int64=14) %!d(string=hai) anos
pai
achega
f1ffed8a6c
Modificáronse 2 ficheiros con 40 adicións e 5 borrados
  1. 19 5
      lisp/org-capture.el
  2. 21 0
      lisp/org.el

+ 19 - 5
lisp/org-capture.el

@@ -1012,13 +1012,27 @@ it.  When it is a variable, retrieve the value.  Return whatever we get."
     (org-table-align)))
 
 (defun org-capture-place-plain-text ()
-  "Place the template plainly."
+  "Place the template plainly.
+If the target locator points at an Org node, place the template into
+the text of the entry, before the first child.  If not, place the
+template at the beginning or end of the file.
+Of course, if exact position has been required, just put it at point."
   (let* ((txt (org-capture-get :template))
 	 beg end)
-    (goto-char (cond
-		((org-capture-get :exact-position))
-		((org-capture-get :prepend) (point-min))
-		(t (point-max))))
+    (cond
+     ((org-capture-get :exact-position))
+     ((and (org-capture-get :target-entry-p)
+	   (bolp)
+	   (looking-at org-outline-regexp))
+      ;; we should place the text into this entry
+      (if (org-capture-get :prepend)
+	  ;; Skip meta data and drawers
+	  (org-end-of-meta-data-and-drawers)
+	;; go to ent of the entry text, before the next headline
+	(outline-next-heading)))
+     (t
+      ;; beginning or end of file
+      (goto-char (if (org-capture-get :prepend) (point-min) (point-max)))))
     (or (bolp) (newline))
     (org-capture-empty-lines-before)
     (setq beg (point))

+ 21 - 0
lisp/org.el

@@ -19826,6 +19826,27 @@ If there is no such heading, return nil."
 	(unless (eobp) (backward-char 1)))
     ad-do-it))
 
+(defun org-end-of-meta-data-and-drawers ()
+  "Jump to the first text after meta data and drawers in the current entry.
+This will move over empty lines, lines with planning time stamps,
+clocking lines, and drawers."
+  (org-back-to-heading t)
+  (let ((end (save-excursion (outline-next-heading) (point)))
+	(re (concat "[ \t]*$"
+		    "\\|"
+		    "\\(" org-drawer-regexp "\\)" ; group 1 are drawers
+		    "\\|"
+		    "\\([ \t]*\\(" org-keyword-time-regexp "\\)\\)")))
+    (forward-line 1)
+    (while (looking-at (concat "[ \t]*\\(" org-keyword-time-regexp "\\)"))
+      (if (not (match-end 1))
+	  ;; empty or planning line
+	  (forward-line 1)
+	;; a drawer, find the end
+	(re-search-forward "^[ \t]*:END:" end 'move)
+	(forward-line 1)))
+    (point)))
+
 (defun org-forward-same-level (arg &optional invisible-ok)
   "Move forward to the arg'th subheading at same level as this one.
 Stop at the first and last subheadings of a superior heading.