Browse Source

Implement setup inclusion from external file.

The #+STARTUP etc lines that define settings on a per-file
basis can now be collected in a separate file and included
with a line:

#+SETUPFILE: "/path/to/setup.org"

This has been a frequent request in the past, now it is
finally possible.
Carsten Dominik 17 years ago
parent
commit
9cad371bc4
5 changed files with 99 additions and 20 deletions
  1. 9 0
      ChangeLog
  2. 17 5
      ORGWEBPAGE/Changes.org
  3. 7 0
      doc/org.texi
  4. 25 8
      lisp/org-exp.el
  5. 41 7
      lisp/org.el

+ 9 - 0
ChangeLog

@@ -1,5 +1,14 @@
 2008-05-07  Carsten Dominik  <dominik@science.uva.nl>
 
+	* lisp/org.el (org-remove-double-quotes, org-file-contents): New
+	functions.
+
+	* lisp/org-exp.el (org-infile-export-plist): Also parse the
+	contents of #+SETUPFILE files, recursively.
+
+	* lisp/org.el (org-set-regexps-and-options): Also parse the
+	contents of #+SETUPFILE files, recursively.
+
 	* lisp/org-exp.el (org-export-handle-include-files): New function.
 	(org-export-preprocess-string): Call
 	`org-export-handle-include-files'.

+ 17 - 5
ORGWEBPAGE/Changes.org

@@ -14,11 +14,6 @@
 
 ** Incompatible changes
 
-*** The in-buffer settings keywords may now be upper or lower case
-    
-    From now on, it makes no difference is you write =#+STARTUP=
-    or =#+startup=, similarly for all the in-buffer keywords.
-
 *** The text before the first headline is now exported by default
 
     Previously, the default was to not include this text, but for
@@ -31,6 +26,23 @@
 
 ** Details
 
+*** In-buffer options may now be included from an external file.
+
+    If you would like to share the Org setup between a number of
+    files, you can now store in-buffer setup in a file and simply
+    point to that file from each buffer that should read it.  If
+    you write in a buffer
+
+    : #+SETUPFILE: "path/to/setup.org"
+
+    then this file will be scanned as well for in-buffer options
+    like =#+STARTUP=, =#+TITLE=, or =#+OPTIONS=.
+
+*** The in-buffer settings keywords may now be upper or lower case
+    
+    From now on, it makes no difference is you write =#+STARTUP=
+    or =#+startup=, similarly for all the in-buffer keywords.
+
 *** Description lists are now supported natively
 
     A plain list will be exported as a description list if the

+ 7 - 0
doc/org.texi

@@ -7872,6 +7872,13 @@ have a lower ASCII number that the lowest priority.
 @item #+PROPERTY: Property_Name Value
 This line sets a default inheritance value for entries in the current
 buffer, most useful for specifying the allowed values of a property.
+@item #+SETUPFILE: file
+This line defines a file that holds more in-buffer setup.  Normally this is
+entirely ignored.  Only when the buffer is parsed for option-setting lines
+(i.e. when starting Org mode for a file, when pressing @kbd{C-c C-c} in a
+settings line, or when exporting), then the contents of this file are parsed
+as if they had been included in the buffer.  In particlar, the file can be
+any other Org mode file with internal setup.
 @item #+STARTUP:
 This line sets options to be used at startup of Org mode, when an
 Org file is being visited.  The first set of options deals with the

+ 25 - 8
lisp/org-exp.el

@@ -699,16 +699,21 @@ modified) list.")
   (save-excursion
     (save-restriction
       (widen)
-      (goto-char 0)
+      (goto-char (point-min))
       (let ((re (org-make-options-regexp
 		 (append
 		  '("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE"
-		    "LINK_UP" "LINK_HOME")
+		    "LINK_UP" "LINK_HOME" "SETUPFILE")
 		  (mapcar 'car org-export-inbuffer-options-extra))))
-	    p key val text options js-up js-main js-css js-opt a pr)
-	(while (re-search-forward re nil t)
-	  (setq key (upcase (org-match-string-no-properties 1))
-		val (org-match-string-no-properties 2))
+	    p key val text options js-up js-main js-css js-opt a pr
+	    ext-setup-or-nil setup-contents (start 0))
+	(while (or (and ext-setup-or-nil
+			(string-match re ext-setup-or-nil start)
+			(setq start (match-end 0)))
+		   (and (setq ext-setup-or-nil nil start 0)
+			(re-search-forward re nil t)))
+	  (setq key (upcase (org-match-string-no-properties 1 ext-setup-or-nil))
+		val (org-match-string-no-properties 2 ext-setup-or-nil))
 	  (cond
 	   ((setq a (assoc key org-export-inbuffer-options-extra))
 	    (setq pr (nth 1 a))
@@ -721,11 +726,23 @@ modified) list.")
 	   ((string-equal key "TEXT")
 	    (setq text (if text (concat text "\n" val) val)))
 	   ((string-equal key "OPTIONS")
-	    (setq options (concat options " " val)))
+	    (setq options (concat val " " options)))
 	   ((string-equal key "LINK_UP")
 	    (setq p (plist-put p :link-up val)))
 	   ((string-equal key "LINK_HOME")
-	    (setq p (plist-put p :link-home val)))))
+	    (setq p (plist-put p :link-home val)))
+	   ((equal key "SETUPFILE")
+	    (setq setup-contents (org-file-contents
+				  (expand-file-name
+				   (org-remove-double-quotes
+				    (org-trim val)))
+				  'noerror))
+	    (if (not ext-setup-or-nil)
+		(setq ext-setup-or-nil setup-contents start 0)
+	      (setq ext-setup-or-nil
+		    (concat (substring ext-setup-or-nil 0 start)
+			    "\n" setup-contents "\n"
+			    (substring ext-setup-or-nil start)))))))
 	(setq p (plist-put p :text text))
 	(when options
 	  (let ((op '(("H"     . :headline-levels)

+ 41 - 7
lisp/org.el

@@ -2703,17 +2703,22 @@ means to push this value onto the list in the variable.")
     (let ((re (org-make-options-regexp
 	       '("CATEGORY" "SEQ_TODO" "TYP_TODO" "TODO" "COLUMNS"
 		 "STARTUP" "ARCHIVE" "TAGS" "LINK" "PRIORITIES"
-		 "CONSTANTS" "PROPERTY" "DRAWERS")))
+		 "CONSTANTS" "PROPERTY" "DRAWERS" "SETUPFILE")))
 	  (splitre "[ \t]+")
 	  kwds kws0 kwsa key log value cat arch tags const links hw dws
-	  tail sep kws1 prio props drawers)
+	  tail sep kws1 prio props drawers
+	  ext-setup-or-nil setup-contents (start 0))
       (save-excursion
 	(save-restriction
 	  (widen)
 	  (goto-char (point-min))
-	  (while (re-search-forward re nil t)
-	    (setq key (upcase (match-string 1))
-		  value (org-match-string-no-properties 2))
+	  (while (or (and ext-setup-or-nil
+			  (string-match re ext-setup-or-nil start)
+			  (setq start (match-end 0)))
+		     (and (setq ext-setup-or-nil nil start 0)
+			  (re-search-forward re nil t)))
+	    (setq key (upcase (match-string 1 ext-setup-or-nil))
+		  value (org-match-string-no-properties 2 ext-setup-or-nil))
 	    (cond
 	     ((equal key "CATEGORY")
 	      (if (string-match "[ \t]+$" value)
@@ -2758,8 +2763,19 @@ means to push this value onto the list in the variable.")
 	      (string-match " *$" value)
 	      (setq arch (replace-match "" t t value))
 	      (remove-text-properties 0 (length arch)
-				      '(face t fontified t) arch)))
-	    )))
+				      '(face t fontified t) arch))
+	     ((equal key "SETUPFILE")
+	      (setq setup-contents (org-file-contents
+				    (expand-file-name
+				     (org-remove-double-quotes value))
+				    'noerror))
+	      (if (not ext-setup-or-nil)
+		  (setq ext-setup-or-nil setup-contents start 0)
+		(setq ext-setup-or-nil
+		      (concat (substring ext-setup-or-nil 0 start)
+			      "\n" setup-contents "\n"
+			      (substring ext-setup-or-nil start)))))
+	     ))))
       (when cat
 	(org-set-local 'org-category (intern cat))
 	(push (cons "CATEGORY" cat) props))
@@ -2922,6 +2938,20 @@ means to push this value onto the list in the variable.")
     (org-compute-latex-and-specials-regexp)
     (org-set-font-lock-defaults)))
 
+(defun org-file-contents (file &optional noerror)
+  "Return the contents of FILE, as a string."
+  (if (or (not file)
+	  (not (file-readable-p file)))
+      (if noerror
+	  (progn
+	    (message "Cannot read file %s" file)
+	    (ding) (sit-for 2)
+	    "")
+	(error "Cannot read file %s" file))
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-string))))
+
 (defun org-extract-log-state-settings (x)
   "Extract the log state setting from a TODO keyword string.
 This will extract info from a string like \"WAIT(w@/!)\"."
@@ -7142,6 +7172,10 @@ onto the ring."
   (if (equal (substring s 0 1) "<") nil (setq s (concat "<" s)))
   (if (equal (substring s -1) ">") nil (setq s (concat s ">")))
   s)
+(defun org-remove-double-quotes (s)
+  (if (equal (substring s 0 1) "\"") (setq s (substring s 1)))
+  (if (equal (substring s -1) "\"") (setq s (substring s 0 -1)))
+  s)
 
 ;;; Following specific links