From: Rasmus <rasmus@gmx.us>
To: emacs-orgmode@gnu.org
Subject: Re: [patch, ox] #+INCLUDE resolves links
Date: Sun, 21 Sep 2014 13:46:42 +0200 [thread overview]
Message-ID: <87lhpdurfh.fsf@gmx.us> (raw)
In-Reply-To: 87k34x6bjd.fsf@gmx.us
[-- Attachment #1: Type: text/plain, Size: 1120 bytes --]
Hi,
Rasmus <rasmus@gmx.us> writes:
> This patch allows INCLUDE to have intuitive links as resolved by
> `org-link'-search'. A couple of examples:
>
> #+INCLUDE: file.org::#custom_id :noheadline :lines "3-"
> #+INCLUDE: file.org::*headline :lines "-10"
>
> :noheading tries to get rid of the first headline, and immediately
> subsequent drawer and property-drawer, if present. :noheading is only
> interpret when a headline argument is present. :lines is interpreted
> relatively, if coupled with a headline link.
>
> I should work for other types of links as well though it could be
> limited to headlines only.
>
> Perhaps it would even make sense to let it take a no-file argument to
> locate things within the same buffer. This would be useful for
> including, say, tables in babel/code-appendices.
Ups, I think the previous patch had a paredit mistake.
The attached patch includes documentation, better error handling and
enforces consistency when using `org-link-search'. I used the patch
this morning and I think it makes INCLUDE more enjoyable to use.
Cheers,
Rasmus
--
It was you, Jezebel, it was you
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-Allow-file-links-with-INCLUDE-keyword.patch --]
[-- Type: text/x-diff, Size: 8716 bytes --]
From 6925403a72db7216b9deca56acc3f72f6d179f22 Mon Sep 17 00:00:00 2001
From: Rasmus <rasmus@gmx.us>
Date: Sun, 21 Sep 2014 13:35:11 +0200
Subject: [PATCH] ox: Allow file-links with #+INCLUDE-keyword
* org.el (org-edit-special): Handle file-links for INCLUDE.
* ox.el (org-export--prepare-file-contents): Handle links and
add option no-heading.
* ox.el (org-export-expand-include-keyword): Resolve headline
links and add option :only-contents.
* orgguide.texi (Include files): Updated.
* org.texi (Include files): Updated.
---
doc/org.texi | 18 ++++++++++++++++
doc/orgguide.texi | 9 ++++++--
lisp/org.el | 8 ++++---
lisp/ox.el | 63 +++++++++++++++++++++++++++++++++++++++++++------------
4 files changed, 80 insertions(+), 18 deletions(-)
diff --git a/doc/org.texi b/doc/org.texi
index 7d98d51..9414314 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -10008,6 +10008,24 @@ to use the obvious defaults.
#+INCLUDE: "~/.emacs" :lines "10-" @r{Include lines from 10 to EOF}
@end example
+Finally, you may use a file-link, see @ref{External links}, to extract an
+object as matched by @code{org-link-search}@footnote{Note that
+@code{org-link-search-must-match-exact-headline} is locally bound to non-nil.
+Therefore, @code{org-link-search} only matches headlines and named
+elements.}. If the keyword @code{:only-contents} is used, only the contents
+of the element in included. For headlines, drawers and properties
+immediately following the headline will not be included when using
+@code{:only-contents}. The @code{:lines} keyword is local to the
+element in question. Some examples:
+
+@example
+#+INCLUDE: "./paper.org::#theory" :only-contents
+ @r{Include the body of the heading with the custom id @code{theory}}
+#+INCLUDE: "./paper.org::mytable" @r{Include tabel with name and caption.}
+#+INCLUDE: "./paper.org::*conclusion" :lines 1-20
+ @r{Include the first 20 lines of the headline named conclusion.}
+@end example
+
@table @kbd
@kindex C-c '
@item C-c '
diff --git a/doc/orgguide.texi b/doc/orgguide.texi
index ca8e052..d3cee0c 100644
--- a/doc/orgguide.texi
+++ b/doc/orgguide.texi
@@ -2264,8 +2264,13 @@ include your @file{.emacs} file, you could use:
The optional second and third parameter are the markup (i.e., @samp{example}
or @samp{src}), and, if the markup is @samp{src}, the language for formatting
the contents. The markup is optional, if it is not given, the text will be
-assumed to be in Org mode format and will be processed normally. @kbd{C-c '}
-will visit the included file.
+assumed to be in Org mode format and will be processed normally. File-links
+will be interpret as well:
+@smallexample
+#+INCLUDE: "./otherfile.org::#my_custom_id" :no-contents
+@end smallexample
+@noindent
+@kbd{C-c '} will visit the included file.
@node Embedded @LaTeX{}, , Include files, Markup
@section Embedded @LaTeX{}
diff --git a/lisp/org.el b/lisp/org.el
index 4ffe1e8..86a1bf9 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -20520,9 +20520,11 @@ Otherwise, return a user error."
session params))))))
(keyword
(if (member (org-element-property :key element) '("INCLUDE" "SETUPFILE"))
- (find-file-other-window
- (org-remove-double-quotes
- (car (org-split-string (org-element-property :value element)))))
+ (org-open-link-from-string
+ (format "[[%s]]"
+ (expand-file-name
+ (org-remove-double-quotes
+ (car (org-split-string (org-element-property :value element)))))))
(user-error "No special environment to edit here")))
(table
(if (eq (org-element-property :type element) 'table.el)
diff --git a/lisp/ox.el b/lisp/ox.el
index f01f951..f5b8fcc 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -1,5 +1,4 @@
;;; ox.el --- Generic Export Engine for Org Mode
-
;; Copyright (C) 2012-2014 Free Software Foundation, Inc.
;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
@@ -3321,13 +3320,23 @@ paths."
;; Extract arguments from keyword's value.
(let* ((value (org-element-property :value element))
(ind (org-get-indentation))
+ location
(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 location (car-safe (cdr-safe matched)))
+ (prog1 (expand-file-name
+ (org-remove-double-quotes
+ (car matched))
+ dir)
+ (setq value (replace-match "" nil nil value))))))
+
+ (only-contents
+ (and (string-match
+ ":\\(only-?contents?[[:space:]]*\\(?:'t\\|true\\|yes\\)?\\)" value)
+ (prog1 t
+ (setq value (replace-match "" nil nil value)))))
(lines
(and (string-match
":lines +\"\\(\\(?:[0-9]+\\)?-\\(?:[0-9]+\\)?\\)\""
@@ -3370,18 +3379,18 @@ 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))))
+ (org-export--prepare-file-contents file location only-contents lines))))
(format "%s#+BEGIN_%s%s\n%s%s#+END_%s\n"
ind-str block arg-str contents ind-str block))))
((stringp block)
(insert
(let ((ind-str (make-string ind ? ))
(contents
- (org-export--prepare-file-contents file lines)))
+ (org-export--prepare-file-contents file location only-contents lines)))
(format "%s#+BEGIN_%s\n%s%s#+END_%s\n"
ind-str block contents ind-str block))))
(t
@@ -3390,7 +3399,7 @@ paths."
(let ((org-inhibit-startup t)) (org-mode))
(insert
(org-export--prepare-file-contents
- file lines ind minlevel
+ file location only-contents lines ind minlevel
(or (gethash file file-prefix)
(puthash file (incf current-prefix) file-prefix))))
(org-export-expand-include-keyword
@@ -3398,9 +3407,17 @@ paths."
(file-name-directory file))
(buffer-string)))))))))))))
-(defun org-export--prepare-file-contents (file &optional lines ind minlevel id)
+(defun org-export--prepare-file-contents (file &optional location only-contents lines ind minlevel id)
"Prepare the contents of FILE for inclusion and return them as a string.
+When optional argument LOCATION is a string the matching element
+identified using `org-link-search' is returned. Note that
+`org-link-search-must-match-exact-headline' is locally set to
+non-nil. When ONLY-CONTENTS is non-nil only the contents of the
+matched element in included. If LOCATION is a headline and
+ONLY-CONTENTS is non-nil, drawers and property-drawers
+immediately following the first headline are also removed.
+
When optional argument LINES is a string specifying a range of
lines, include only those lines.
@@ -3420,6 +3437,26 @@ This is useful to avoid conflicts when more than one Org file
with footnotes is included in a document."
(with-temp-buffer
(insert-file-contents file)
+ (org-mode)
+ (when location
+ (condition-case err
+ ;; enforce consistency in search.
+ (let ((org-link-search-must-match-exact-headline t))
+ (org-link-search location))
+ ;; helpful error messages
+ (error (error (format "%s for %s::%s"
+ (error-message-string err) file location))))
+ (narrow-to-region
+ (org-element-property
+ (if only-contents :contents-begin :begin) (org-element-at-point))
+ (org-element-property (if only-contents :contents-end :end) (org-element-at-point)))
+ ;; get rid of drawers and properties
+ (when only-contents
+ (let ((element (org-element-at-point)))
+ (while (member (org-element-type element) '(drawer property-drawer))
+ (delete-region (org-element-property :begin element)
+ (org-element-property :end element))
+ (setq element (org-element-at-point))))))
(when lines
(let* ((lines (split-string lines "-"))
(lbeg (string-to-number (car lines)))
@@ -3495,7 +3532,7 @@ with footnotes is included in a document."
(org-element-normalize-string (buffer-string))))
(defun org-export-execute-babel-code ()
- "Execute every Babel code in the visible part of current buffer."
+ "ExecUte every Babel code in the visible part of current buffer."
;; Get a pristine copy of current buffer so Babel references can be
;; properly resolved.
(let ((reference (org-export-copy-buffer)))
--
2.1.0
next prev parent reply other threads:[~2014-09-21 11:47 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-21 0:51 [patch, ox] #+INCLUDE resolves links Rasmus
2014-09-21 11:46 ` Rasmus [this message]
2014-09-21 13:53 ` Nicolas Goaziou
2014-09-21 14:46 ` Rasmus
2014-09-21 19:51 ` Nicolas Goaziou
2014-09-23 23:25 ` Rasmus
2014-09-24 21:22 ` Nicolas Goaziou
2014-09-28 19:32 ` Rasmus
2014-09-30 8:07 ` Nicolas Goaziou
2014-09-30 10:18 ` Rasmus
2014-09-30 14:29 ` Nicolas Goaziou
2014-09-30 21:48 ` Rasmus
2014-10-01 20:03 ` Nicolas Goaziou
2014-10-01 21:27 ` Rasmus
2014-10-02 7:29 ` Xavier Garrido
2014-10-02 8:55 ` Rasmus
2014-10-02 16:30 ` Aaron Ecay
2014-10-02 16:53 ` Nicolas Goaziou
2014-10-02 17:47 ` Rasmus
2014-10-02 19:11 ` Achim Gratz
2014-10-02 20:58 ` Rasmus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87lhpdurfh.fsf@gmx.us \
--to=rasmus@gmx.us \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).