Browse Source

Export: Implement macro replacement during export

A line: #+MARCO: name    replacement text

can be referenced by {{{name}}}.  As special cases, {{{title}}} will
reference #+TITLE, and similar with similar lines.
Carsten Dominik 16 years ago
parent
commit
3c06ae6000
4 changed files with 67 additions and 42 deletions
  1. 18 2
      doc/org.texi
  2. 36 7
      lisp/org-exp.el
  3. 10 33
      lisp/org-export-latex.el
  4. 3 0
      lisp/org.el

+ 18 - 2
doc/org.texi

@@ -315,6 +315,7 @@ Markup rules
 * TeX macros and LaTeX fragments::  Create special, rich export.
 * Horizontal rules::            A line across the page
 * Comment lines::               Some lines will not be exported
+* Macro replacement::           
 
 HTML export
 
@@ -372,7 +373,7 @@ Interaction with other packages
 
 Hacking
 
-* Hooks::                       How to reach into Org's internals
+* Hooks::                       Who to reach into Org's internals
 * Add-on packages::             Available extensions
 * Adding hyperlink types::      New custom link types
 * Context-sensitive commands::  How to add functioality to such commands
@@ -7580,6 +7581,7 @@ markup rule used in an Org mode buffer.
 * TeX macros and LaTeX fragments::  Create special, rich export.
 * Horizontal rules::            A line across the page
 * Comment lines::               Some lines will not be exported
+* Macro replacement::           Global replacement of place holdes
 @end menu
 
 @node Document title, Headings and sections, Markup rules, Markup rules
@@ -7926,7 +7928,7 @@ different lengths or a compact set of dots.
 A line consisting of only dashes, and at least 5 of them, will be
 exported as a horizontal line (@samp{<hr/>} in HTML).
 
-@node Comment lines,  , Horizontal rules, Markup rules
+@node Comment lines, Macro replacement, Horizontal rules, Markup rules
 @subheading Comment lines
 @cindex comment lines
 @cindex exporting, not
@@ -7942,6 +7944,20 @@ never be exported.  Also entire subtrees starting with the word
 Toggle the COMMENT keyword at the beginning of an entry.
 @end table
 
+@node Macro replacement,  , Comment lines, Markup rules
+@subheading Macro replacement
+
+You can define text snippets with
+
+@example
+#+MACRO: name   replacement text
+@end example
+
+@noindent which can be referenced anywhere in the document (even in
+code examples) with @code{@{@{@{name@}@}@}}.  In addition to defined macros,
+@code{@{@{@{title@}@}@}}, @code{@{@{@{author@}@}@}}, etc will reference
+information set by the @code{#+TITLE:}, @code{#+AUTHOR:}, and similar lines.
+
 @node Selective export, Export options, Markup rules, Exporting
 @section Selective export
 @cindex export, selective by tags

+ 36 - 7
lisp/org-exp.el

@@ -1043,6 +1043,14 @@ modified) list.")
 	  (setq p (plist-put p :latex-header-extra (substring latex-header 1))))
 	(when options
 	  (setq p (org-export-add-options-to-plist p options)))
+	;; Add macro definitions
+	(goto-char (point-min))
+	(while (re-search-forward
+		"^#\\+macro:[ \t]+\\([-a-zA-Z0-9_]+\\)[ \t]+\\(.*?[ \t]*$\\)"
+		nil t)
+	  (setq p (plist-put p (intern (concat ":macro-"
+					       (downcase (match-string 1))))
+			     (match-string 2))))
 	p))))
 
 (defun org-export-add-options-to-plist (p options)
@@ -1525,6 +1533,10 @@ on this string to produce the exported version."
       ;; Call the hook
       (run-hooks 'org-export-preprocess-hook)
 
+      ;; Process the macros
+      (org-export-preprocess-apply-macros)
+      (run-hooks 'org-export-preprocess-after-macros-hook)
+
       (untabify (point-min) (point-max))
 
       ;; Handle include files, and call a hook
@@ -2269,8 +2281,20 @@ TYPE must be a string, any of:
 	  (pop roman)))
       res)))
 
-(org-number-to-roman 1961)
+;;; Macros
 
+(defun org-export-preprocess-apply-macros ()
+  "Replace macro references."
+  (goto-char (point-min))
+  (let (sy val)
+    (while (re-search-forward "{{{\\([a-zA-Z][-a-zA-Z0-9_]*\\)}}}" nil t)
+      (setq key (downcase (match-string 1)))
+      (when (setq val (or (plist-get org-export-opt-plist
+				     (intern (concat ":macro-" key)))
+			  (plist-get org-export-opt-plist
+				     (intern (concat ":" key)))))
+	(and (stringp val)
+	     (replace-match val t t))))))
 
 ;;; Include files
 
@@ -2548,6 +2572,9 @@ Numbering lines works for all three major backends (html, latex, and ascii)."
 (defvar org-levels-open nil) ; dynamically scoped parameter
 (defvar org-ascii-current-indentation nil) ; For communication
 
+(defvar org-export-opt-plist nil
+  "Contains the current option plist.")
+
 ;;;###autoload
 (defun org-export-as-ascii (arg)
   "Export the outline as a pretty ASCII file.
@@ -2573,9 +2600,10 @@ underlined headlines.  The default is 3."
 			     (+ (funcall outline-level)
 				(if org-odd-levels-only 1 0)))
 			 0))
-	 (opt-plist (if subtree-p
-			(org-export-add-subtree-options opt-plist rbeg)
-		      opt-plist))
+	 (opt-plist (setq org-export-opt-plist
+			  (if subtree-p
+			      (org-export-add-subtree-options opt-plist rbeg)
+			    opt-plist)))
 	 (custom-times org-display-custom-times)
 	 (org-ascii-current-indentation '(0 . 0))
 	 (level 0) line txt
@@ -3249,9 +3277,10 @@ PUB-DIR is set, use this as the publishing directory."
 			     (+ (funcall outline-level)
 				(if org-odd-levels-only 1 0)))
 			 0))
-	 (opt-plist (if subtree-p
-			(org-export-add-subtree-options opt-plist rbeg)
-		      opt-plist))
+	 (opt-plist (setq org-export-opt-plist
+			  (if subtree-p
+			      (org-export-add-subtree-options opt-plist rbeg)
+			    opt-plist)))
 	 ;; The following two are dynamically scoped into other
 	 ;; routines below.
 	 (org-current-export-dir

+ 10 - 33
lisp/org-export-latex.el

@@ -404,9 +404,10 @@ when PUB-DIR is set, use this as the publishing directory."
 	      (goto-char rbeg)
 	      (and (org-at-heading-p)
 		   (>= (org-end-of-subtree t t) rend)))))
-	 (opt-plist (if subtree-p
-			(org-export-add-subtree-options opt-plist rbeg)
-		      opt-plist))
+	 (opt-plist (setq org-export-opt-plist
+			  (if subtree-p
+			      (org-export-add-subtree-options opt-plist rbeg)
+			    opt-plist)))
 	 ;; Make sure the variable contains the updated values.
 	 (org-export-latex-options-plist opt-plist)
 	 (title (or (and subtree-p (org-export-get-title-from-subtree))
@@ -416,8 +417,6 @@ when PUB-DIR is set, use this as the publishing directory."
 			 (org-export-grab-title-from-buffer))
 		    (file-name-sans-extension
 		     (file-name-nondirectory buffer-file-name))))
-	 (option-defs (and org-export-latex-import-inbuffer-stuff
-			   (org-export-latex-collect-header-macros title)))
 	 (filename (concat (file-name-as-directory
 			    (or pub-dir
 				(org-export-directory :LaTeX ext-plist)))
@@ -438,7 +437,7 @@ when PUB-DIR is set, use this as the publishing directory."
 		      (t (get-buffer-create to-buffer)))
 		   (find-file-noselect filename)))
 	 (odd org-odd-levels-only)
-	 (header (org-export-latex-make-header title opt-plist option-defs))
+	 (header (org-export-latex-make-header title opt-plist))
 	 (skip (cond (subtree-p nil)
 		     (region-p nil)
 		     (t (plist-get opt-plist :skip-before-1st-heading))))
@@ -725,7 +724,7 @@ LEVEL indicates the default depth for export."
 		  (sec-depth (length org-export-latex-sectioning)))
 	      (if (> hl-levels sec-depth) sec-depth hl-levels)))))
 
-(defun org-export-latex-make-header (title opt-plist &optional opt-defs)
+(defun org-export-latex-make-header (title opt-plist)
   "Make the LaTeX header and return it as a string.
 TITLE is the current title from the buffer or region.
 OPT-PLIST is the options plist for current buffer."
@@ -746,7 +745,6 @@ OPT-PLIST is the options plist for current buffer."
 			      (car p) (cadr p))))
 		  org-export-latex-packages-alist "\n"))
      ;; insert additional commands in the header
-     opt-defs
      (plist-get opt-plist :latex-header-extra)
      org-export-latex-append-header
      ;; insert the title
@@ -808,31 +806,10 @@ If BEG is non-nil, the is the beginning of he region."
 	 (add-text-properties pt (max pt (1- end))
 			      '(:org-license-to-kill t)))))))
 
-(defun org-export-latex-collect-header-macros (&optional title)
-  "Find the various definitions in #+... lines and define TeX macros for them."
-  (let ((re (org-make-options-regexp
-	     '("TITLE" "AUTHOR" "DATE" "EMAIL" "OPTIONS" "LANGUAGE"
-	       "LINK_UP" "LINK_HOME" "SETUPFILE" "STYLE"
-	       "EXPORT_SELECT_TAGS" "EXPORT_EXCLUDE_TAGS")))
-	out key val a)
-    (save-excursion
-      (save-restriction
-	(widen)
-	(goto-char (point-min))
-	(while (re-search-forward re nil t)
-	  (setq key (upcase (match-string 1))
-		val (match-string 2))
-	  (if (and title (equal key "TITLE"))
-	      (setq val title))
-	  (while (string-match "_" key)
-	    (setq key (replace-match "" t t key)))
-	  (if (setq a (assoc key out))
-	      (setcdr a (concat (cdr a) "\n" val))
-	    (push (cons key val) out))))
-      (mapconcat
-       (lambda (x) (concat "\\def\\org" (car x) "{" (cdr x) "}"))
-       out
-       "\n"))))
+(defvar org-export-latex-header-defs nil
+  "The header definitions that might be used in the LaTeX body.")
+(defvar org-export-latex-header-defs-re nil
+  "The header definitions that might be used in the LaTeX body.")
 
 (defun org-export-latex-content (content &optional exclude-list)
   "Convert CONTENT string to LaTeX.

+ 3 - 0
lisp/org.el

@@ -928,6 +928,9 @@ links in Org-mode buffers can have an optional tag after a double colon, e.g.
 
      [[linkkey:tag][description]]
 
+The 'linkkey' must be a word word, starting with a letter, followed
+by letters, numbers, '-' or '_'.
+
 If REPLACE is a string, the tag will simply be appended to create the link.
 If the string contains \"%s\", the tag will be inserted there.  Alternatively,
 the placeholder \"%h\" will cause a url-encoded version of the tag to