Hi, I would like to use #+INCLUDE keywords for inputting headlines from other files. Line-numbers are too volatile and I'm not willing to split up my file.
The attached patch does not, but I am not very happy about the elegance of the implementation and it relies on a mix of org.el functions and ox functions. Basically, the patch tries to interpret keywords like this: #+INCLUDE: "~/file.org::*foo" Is there not a function to interpret a link-string, say "~/file.org::*foo", particularly with ox? The closes thing I found was `org-element-parse-secondary-string` on [[~/file.org::*foo]] which gives me the correct element. Normally, `org-export-resolve-fuzzy-link' should then help me out, but in `org-export-expand-include-keyword' I don't have info! Also, `org-link-search' didn't seem to work across files. Am I missing something obvious or is there a function I can study to better understand how to resolve links? Thanks, Rasmus -- In theory, practice and theory are the same. In practice they are not
>From f8dadcc363e4ad3fc102d1cbf200b6ff8344184d Mon Sep 17 00:00:00 2001 From: Rasmus <ras...@gmx.us> Date: Sat, 20 Sep 2014 22:22:15 +0200 Subject: [PATCH 2/2] ox: Allow headline links with #+INCLUDE * ox.el (org-export-expand-include-keyword): Resolve headline links. Accept keywords like "#+INCLUDE: file1.org::head1". head1 must be a CUSTOM_ID or resolvable by `org-link-search'. --- lisp/ox.el | 55 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/lisp/ox.el b/lisp/ox.el index 55c02eb..bdcdc71 100644 --- a/lisp/ox.el +++ b/lisp/ox.el @@ -3322,19 +3322,46 @@ paths." ;; Extract arguments from keyword's value. (let* ((value (org-element-property :value element)) (ind (org-get-indentation)) + headline-id (file (and (string-match "^\\(\".+?\"\\|\\S-+\\)\\(?:\\s-+\\|$\\)" value) - (prog1 (expand-file-name - (org-remove-double-quotes - (match-string 1 value)) - dir) - (setq value (replace-match "" nil nil value))))) + (let ((matched (save-match-data + (org-split-string (match-string 1 value) "::")))) + (setq headline-id (car-safe (cdr-safe matched))) + (prog1 (expand-file-name + (org-remove-double-quotes + (car matched)) + dir) + (setq value (replace-match "" nil nil value)))))) (lines - (and (string-match - ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\"" - value) - (prog1 (match-string 1 value) - (setq value (replace-match "" nil nil value))))) + ;; (or + ;; (and (string-match ":headline" value) + ;; (error "#+INCLUDE can only have :lines /or/ :headline")) + (prog1 + (if (string-match + ":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\"" + value) + (if headline-id + (error "You have specified a headline and :lines in #+INCLUDE.") + (match-string 1 value) + (setq value (replace-match "" nil nil value))) + (save-window-excursion + (find-file file) + (let* ((data (org-element-parse-buffer)) + (headline + (or ;; FIXME: there *must* be a better way to do this + (org-element-map data 'headline + (lambda (head) (when (equal headline-id + (org-element-property :CUSTOM_ID head)) + head)) + nil 'first-match) + (and (org-link-search headline-id) (org-element-at-point))))) + (when (equal 'headline (org-element-type headline)) + (mapconcat 'number-to-string + (list + (line-number-at-pos (org-element-property :begin headline)) + (line-number-at-pos (org-element-property :end headline))) + "-"))))))) (env (cond ((string-match "\\<example\\>" value) 'literal) ((string-match "\\<src\\(?: +\\(.*\\)\\)?" value) @@ -3371,8 +3398,8 @@ paths." (insert (let ((ind-str (make-string ind ? )) (arg-str (if (stringp src-args) - (format " %s" src-args) - "")) + (format " %s" src-args) + "")) (contents (org-escape-code-in-string (org-export--prepare-file-contents file lines)))) @@ -3382,7 +3409,7 @@ paths." (insert (let ((ind-str (make-string ind ? )) (contents - (org-export--prepare-file-contents file lines))) + (org-export--prepare-file-contents file lines))) (format "%s#+BEGIN_%s\n%s%s#+END_%s\n" ind-str block contents ind-str block)))) (t @@ -3853,7 +3880,7 @@ INFO is a plist used as a communication channel." (unless (org-export-get-node-property :UNNUMBERED headline t) (let ((sec-num (plist-get info :section-numbers)) (level (org-export-get-relative-level headline info))) - (if (wholenump sec-num) (<= level sec-num) sec-num))))) + (if (wholenump sec-num) (<= level sec-num) sec-num)))) (defun org-export-number-to-roman (n) "Convert integer N into a roman numeral." -- 2.1.0