From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rasmus Subject: [patch] Question on resolving links? Date: Sat, 20 Sep 2014 22:49:04 +0200 Message-ID: <87d2aq6mrj.fsf@gmx.us> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:37933) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XVRb4-0006r2-EO for emacs-orgmode@gnu.org; Sat, 20 Sep 2014 16:49:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XVRay-0000zb-0T for emacs-orgmode@gnu.org; Sat, 20 Sep 2014 16:49:34 -0400 Received: from plane.gmane.org ([80.91.229.3]:42668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XVRax-0000yd-NA for emacs-orgmode@gnu.org; Sat, 20 Sep 2014 16:49:27 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1XVRao-0000gd-K9 for emacs-orgmode@gnu.org; Sat, 20 Sep 2014 22:49:18 +0200 Received: from 217.130.110.20 ([217.130.110.20]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 20 Sep 2014 22:49:18 +0200 Received: from rasmus by 217.130.110.20 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sat, 20 Sep 2014 22:49:18 +0200 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org --=-=-= Content-Type: text/plain 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 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-ox-Allow-headline-links-with-INCLUDE.patch >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 "\\