From f8dadcc363e4ad3fc102d1cbf200b6ff8344184d Mon Sep 17 00:00:00 2001 From: Rasmus 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 "\\" value) 'literal) ((string-match "\\