Split the export pre-processor into a zillion small functions.
This commit is contained in:
parent
18eba42709
commit
236396ebf8
|
@ -1,5 +1,25 @@
|
|||
2008-05-28 Carsten Dominik <dominik@science.uva.nl>
|
||||
|
||||
* org-exp.el (org-export-ascii-preprocess): Renamed from
|
||||
`org-export-ascii-clean-string'.
|
||||
(org-export-kill-licensed-text)
|
||||
(org-export-define-heading-targets)
|
||||
(org-export-handle-invisible-targets)
|
||||
(org-export-target-internal-links)
|
||||
(org-export-remove-or-extract-drawers)
|
||||
(org-export-remove-archived-trees)
|
||||
(org-export-protect-quoted-subtrees)
|
||||
(org-export-protect-verbatim, org-export-protect-examples)
|
||||
(org-export-select-backend-specific-text)
|
||||
(org-export-mark-blockquote-and-verse)
|
||||
(org-export-remove-comment-blocks-and-subtrees)
|
||||
(org-export-handle-comments, org-export-mark-radio-links)
|
||||
(org-export-remove-special-table-lines)
|
||||
(org-export-normalize-links)
|
||||
(org-export-concatenate-multiline-links)
|
||||
(org-export-concatenate-multiline-emphasis): New functions,
|
||||
obtained from spliiting the export preprocessor.
|
||||
|
||||
* org-table.el (org-table-recalculate): Improve error message if
|
||||
the row number is invalid.
|
||||
|
||||
|
|
328
lisp/org-exp.el
328
lisp/org-exp.el
|
@ -1239,18 +1239,14 @@ to export. It then creates a temporary buffer where it does its job.
|
|||
The result is then again returned as a string, and the exporter works
|
||||
on this string to produce the exported version."
|
||||
(interactive)
|
||||
(let* ((re-radio (and org-target-link-regexp
|
||||
(concat "\\([^<]\\)\\(" org-target-link-regexp "\\)")))
|
||||
(htmlp (plist-get parameters :for-html))
|
||||
(let* ((htmlp (plist-get parameters :for-html))
|
||||
(asciip (plist-get parameters :for-ascii))
|
||||
(latexp (plist-get parameters :for-LaTeX))
|
||||
(commentsp (plist-get parameters :comments))
|
||||
(archived-trees (plist-get parameters :archived-trees))
|
||||
(inhibit-read-only t)
|
||||
(drawers org-drawers)
|
||||
(outline-regexp "\\*+ ")
|
||||
target-alist tmp target level
|
||||
a b rtn p)
|
||||
target-alist rtn)
|
||||
|
||||
(with-current-buffer (get-buffer-create " org-mode-tmp")
|
||||
(erase-buffer)
|
||||
|
@ -1263,21 +1259,21 @@ on this string to produce the exported version."
|
|||
;; The caller markes some stuff fo killing, stuff that has been
|
||||
;; used to create the page title, for example.
|
||||
(org-export-kill-licensed-text)
|
||||
|
||||
|
||||
(let ((org-inhibit-startup t)) (org-mode))
|
||||
(setq case-fold-search t)
|
||||
(untabify (point-min) (point-max))
|
||||
|
||||
|
||||
;; Handle incude files
|
||||
(org-export-handle-include-files)
|
||||
|
||||
|
||||
;; Handle source code snippets
|
||||
(org-export-replace-src-segments)
|
||||
|
||||
|
||||
;; Get rid of drawers
|
||||
(org-export-remove-or-extract-drawers drawers
|
||||
(plist-get parameters :drawers))
|
||||
|
||||
|
||||
;; Get the correct stuff before the first headline
|
||||
(when (plist-get parameters :skip-before-1st-heading)
|
||||
(goto-char (point-min))
|
||||
|
@ -1288,77 +1284,23 @@ on this string to produce the exported version."
|
|||
(when (plist-get parameters :add-text)
|
||||
(goto-char (point-min))
|
||||
(insert (plist-get parameters :add-text) "\n"))
|
||||
|
||||
|
||||
;; Get rid of archived trees
|
||||
(org-export-remove-archived-trees archived-trees)
|
||||
|
||||
|
||||
;; Find all headings and compute the targets for them
|
||||
(goto-char (point-min))
|
||||
(org-init-section-numbers)
|
||||
(let ((re (concat "^" org-outline-regexp)))
|
||||
(while (re-search-forward re nil t)
|
||||
(setq level (org-reduced-level
|
||||
(save-excursion (goto-char (point-at-bol))
|
||||
(org-outline-level))))
|
||||
(setq target (org-solidify-link-text
|
||||
(format "sec-%s" (org-section-number level))))
|
||||
(push (cons target target) target-alist)
|
||||
(add-text-properties
|
||||
(point-at-bol) (point-at-eol)
|
||||
(list 'target target))))
|
||||
(setq target-alist (org-export-define-heading-targets target-alist))
|
||||
|
||||
;; Find targets in comments and move them out of comments,
|
||||
;; but mark them as targets that should be invisible
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^#.*?\\(<<<?\\([^>\r\n]+\\)>>>?\\).*" nil t)
|
||||
;; Check if the line before or after is a headline with a target
|
||||
(if (setq target (or (get-text-property (point-at-bol 0) 'target)
|
||||
(get-text-property (point-at-bol 2) 'target)))
|
||||
(progn
|
||||
;; use the existing target in a neighboring line
|
||||
(setq tmp (match-string 2))
|
||||
(replace-match "")
|
||||
(and (looking-at "\n") (delete-char 1))
|
||||
(push (cons (org-solidify-link-text tmp) target)
|
||||
target-alist))
|
||||
;; Make an invisible target
|
||||
(replace-match "\\1(INVISIBLE)")))
|
||||
(setq target-alist (org-export-handle-invisible-targets target-alist))
|
||||
|
||||
;; Protect examples
|
||||
(org-export-protect-examples)
|
||||
|
||||
;; Protect backend specific stuff, throw away the others.
|
||||
(let ((formatters
|
||||
`((,htmlp "HTML" "BEGIN_HTML" "END_HTML")
|
||||
(,asciip "ASCII" "BEGIN_ASCII" "END_ASCII")
|
||||
(,latexp "LaTeX" "BEGIN_LaTeX" "END_LaTeX")))
|
||||
fmt)
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^#\\+BEGIN_EXAMPLE[ \t]*\n" nil t)
|
||||
(goto-char (match-end 0))
|
||||
(while (not (looking-at "#\\+END_EXAMPLE"))
|
||||
(insert ": ")
|
||||
(beginning-of-line 2)))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^[ \t]*:.*\\(\n[ \t]*:.*\\)*" nil t)
|
||||
(add-text-properties (match-beginning 0) (match-end 0)
|
||||
'(org-protected t)))
|
||||
(while formatters
|
||||
(setq fmt (pop formatters))
|
||||
(when (car fmt)
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward (concat "^#\\+" (cadr fmt)
|
||||
":[ \t]*\\(.*\\)") nil t)
|
||||
(replace-match "\\1" t)
|
||||
(add-text-properties
|
||||
(point-at-bol) (min (1+ (point-at-eol)) (point-max))
|
||||
'(org-protected t))))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward
|
||||
(concat "^#\\+"
|
||||
(caddr fmt) "\\>.*\\(\\(\n.*\\)*?\n\\)#\\+"
|
||||
(cadddr fmt) "\\>.*\n?") nil t)
|
||||
(if (car fmt)
|
||||
(add-text-properties (match-beginning 1) (1+ (match-end 1))
|
||||
'(org-protected t))
|
||||
(delete-region (match-beginning 0) (match-end 0))))))
|
||||
(org-export-select-backend-specific-text
|
||||
(cond (htmlp 'html) (latexp 'latex) (asciip 'ascii)))
|
||||
|
||||
;; Protect quoted subtrees
|
||||
(org-export-protect-quoted-subtrees)
|
||||
|
@ -1381,40 +1323,19 @@ on this string to produce the exported version."
|
|||
(require 'org-export-latex nil)
|
||||
(org-export-latex-preprocess))
|
||||
|
||||
;; Specific ASCII stuff
|
||||
(when asciip
|
||||
(org-export-ascii-clean-string))
|
||||
(org-export-ascii-preprocess))
|
||||
|
||||
;; Specific HTML stuff
|
||||
(when htmlp
|
||||
;; Convert LaTeX fragments to images
|
||||
(when (plist-get parameters :LaTeX-fragments)
|
||||
(org-format-latex
|
||||
(concat "ltxpng/" (file-name-sans-extension
|
||||
(file-name-nondirectory
|
||||
org-current-export-file)))
|
||||
org-current-export-dir nil "Creating LaTeX image %s"))
|
||||
(message "Exporting..."))
|
||||
(org-export-html-preprocess parameters))
|
||||
|
||||
;; Remove or replace comments
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^#\\(.*\n?\\)" nil t)
|
||||
(setq pos (match-beginning 0))
|
||||
(if commentsp
|
||||
(progn (add-text-properties
|
||||
(match-beginning 0) (match-end 0) '(org-protected t))
|
||||
(replace-match (format commentsp (match-string 1)) t t))
|
||||
(goto-char (1+ pos))
|
||||
(org-if-unprotected
|
||||
(replace-match "")
|
||||
(goto-char (max (point-min) (1- pos))))
|
||||
(end-of-line 1)))
|
||||
(org-export-handle-comments (plist-get parameters :comments))
|
||||
|
||||
;; Find matches for radio targets and turn them into internal links
|
||||
(goto-char (point-min))
|
||||
(when re-radio
|
||||
(while (re-search-forward re-radio nil t)
|
||||
(org-if-unprotected
|
||||
(replace-match "\\1[[\\2]]"))))
|
||||
(org-export-mark-radio-links)
|
||||
|
||||
;; Find all links that contain a newline and put them into a single line
|
||||
(org-export-concatenate-multiline-links)
|
||||
|
@ -1422,42 +1343,10 @@ on this string to produce the exported version."
|
|||
;; Find all internal links. If they have a fuzzy match (i.e. not
|
||||
;; a *dedicated* target match, let the link point to the
|
||||
;; corresponding section.
|
||||
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward org-bracket-link-regexp nil t)
|
||||
(org-if-unprotected
|
||||
(let* ((md (match-data))
|
||||
(desc (match-end 2))
|
||||
(link (org-link-unescape (match-string 1)))
|
||||
(slink (org-solidify-link-text link))
|
||||
found props pos
|
||||
(target
|
||||
(or (cdr (assoc slink target-alist))
|
||||
(save-excursion
|
||||
(unless (string-match org-link-types-re link)
|
||||
(setq found (condition-case nil (org-link-search link)
|
||||
(error nil)))
|
||||
(when (and found
|
||||
(or (org-on-heading-p)
|
||||
(not (eq found 'dedicated))))
|
||||
(or (get-text-property (point) 'target)
|
||||
(get-text-property
|
||||
(max (point-min)
|
||||
(1- (previous-single-property-change
|
||||
(point) 'target)))
|
||||
'target))))))))
|
||||
(when target
|
||||
(set-match-data md)
|
||||
(goto-char (match-beginning 1))
|
||||
(setq props (text-properties-at (point)))
|
||||
(delete-region (match-beginning 1) (match-end 1))
|
||||
(setq pos (point))
|
||||
(insert target)
|
||||
(unless desc (insert "][" link))
|
||||
(add-text-properties pos (point) props)))))
|
||||
(org-export-target-internal-links target-alist)
|
||||
|
||||
;; Normalize links: Convert angle and plain links into bracket links
|
||||
;; Expand link abbreviations
|
||||
;; and expand link abbreviations
|
||||
(org-export-normalize-links)
|
||||
|
||||
;; Find multiline emphasis and put them into single line
|
||||
|
@ -1470,9 +1359,86 @@ on this string to produce the exported version."
|
|||
|
||||
(defun org-export-kill-licensed-text ()
|
||||
"Remove all text that is marked with a :org-license-to-kill property."
|
||||
(while (setq p (text-property-any (point-min) (point-max)
|
||||
:org-license-to-kill t))
|
||||
(delete-region p (next-single-property-change p :org-license-to-kill))))
|
||||
(let (p)
|
||||
(while (setq p (text-property-any (point-min) (point-max)
|
||||
:org-license-to-kill t))
|
||||
(delete-region p (next-single-property-change p :org-license-to-kill)))))
|
||||
|
||||
(defun org-export-define-heading-targets (target-alist)
|
||||
"Find all headings and define the targets for them.
|
||||
The new targets are added to TARGET-ALIST, which is also returned."
|
||||
(goto-char (point-min))
|
||||
(org-init-section-numbers)
|
||||
(let ((re (concat "^" org-outline-regexp))
|
||||
level target)
|
||||
(while (re-search-forward re nil t)
|
||||
(setq level (org-reduced-level
|
||||
(save-excursion (goto-char (point-at-bol))
|
||||
(org-outline-level))))
|
||||
(setq target (org-solidify-link-text
|
||||
(format "sec-%s" (org-section-number level))))
|
||||
(push (cons target target) target-alist)
|
||||
(add-text-properties
|
||||
(point-at-bol) (point-at-eol)
|
||||
(list 'target target))))
|
||||
target-alist)
|
||||
|
||||
(defun org-export-handle-invisible-targets (target-alist)
|
||||
"Find targets in comments and move them out of comments.
|
||||
Mark them as invisible targets."
|
||||
(let (target tmp)
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^#.*?\\(<<<?\\([^>\r\n]+\\)>>>?\\).*" nil t)
|
||||
;; Check if the line before or after is a headline with a target
|
||||
(if (setq target (or (get-text-property (point-at-bol 0) 'target)
|
||||
(get-text-property (point-at-bol 2) 'target)))
|
||||
(progn
|
||||
;; use the existing target in a neighboring line
|
||||
(setq tmp (match-string 2))
|
||||
(replace-match "")
|
||||
(and (looking-at "\n") (delete-char 1))
|
||||
(push (cons (org-solidify-link-text tmp) target)
|
||||
target-alist))
|
||||
;; Make an invisible target
|
||||
(replace-match "\\1(INVISIBLE)"))))
|
||||
target-alist)
|
||||
|
||||
(defun org-export-target-internal-links (target-alist)
|
||||
"Find all internal links and assign target to them.
|
||||
If a link has a fuzzy match (i.e. not a *dedicated* target match),
|
||||
let the link point to the corresponding section."
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward org-bracket-link-regexp nil t)
|
||||
(org-if-unprotected
|
||||
(let* ((md (match-data))
|
||||
(desc (match-end 2))
|
||||
(link (org-link-unescape (match-string 1)))
|
||||
(slink (org-solidify-link-text link))
|
||||
found props pos
|
||||
(target
|
||||
(or (cdr (assoc slink target-alist))
|
||||
(save-excursion
|
||||
(unless (string-match org-link-types-re link)
|
||||
(setq found (condition-case nil (org-link-search link)
|
||||
(error nil)))
|
||||
(when (and found
|
||||
(or (org-on-heading-p)
|
||||
(not (eq found 'dedicated))))
|
||||
(or (get-text-property (point) 'target)
|
||||
(get-text-property
|
||||
(max (point-min)
|
||||
(1- (previous-single-property-change
|
||||
(point) 'target)))
|
||||
'target))))))))
|
||||
(when target
|
||||
(set-match-data md)
|
||||
(goto-char (match-beginning 1))
|
||||
(setq props (text-properties-at (point)))
|
||||
(delete-region (match-beginning 1) (match-end 1))
|
||||
(setq pos (point))
|
||||
(insert target)
|
||||
(unless desc (insert "][" link))
|
||||
(add-text-properties pos (point) props))))))
|
||||
|
||||
(defun org-export-remove-or-extract-drawers (all-drawers exp-drawers)
|
||||
"Remove drawers, or extract the content.
|
||||
|
@ -1499,13 +1465,13 @@ When it is nil the entire tree including the headline will be removed
|
|||
from the buffer."
|
||||
(let ((re-archive (concat ":" org-archive-tag ":"))
|
||||
a b)
|
||||
(when (not (eq archived-trees t))
|
||||
(when (not (eq export-archived-trees t))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward re-archive nil t)
|
||||
(if (not (org-on-heading-p t))
|
||||
(org-end-of-subtree t)
|
||||
(beginning-of-line 1)
|
||||
(setq a (if archived-trees
|
||||
(setq a (if export-archived-trees
|
||||
(1+ (point-at-eol)) (point))
|
||||
b (org-end-of-subtree t))
|
||||
(if (> b a) (delete-region a b)))))))
|
||||
|
@ -1528,6 +1494,49 @@ from the buffer."
|
|||
'(org-protected t))
|
||||
(goto-char (1+ (match-end 4)))))
|
||||
|
||||
(defun org-export-protect-examples ()
|
||||
"Protect code that should be exported as monospaced examples."
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^#\\+BEGIN_EXAMPLE[ \t]*\n" nil t)
|
||||
(goto-char (match-end 0))
|
||||
(while (not (looking-at "#\\+END_EXAMPLE"))
|
||||
(insert ": ")
|
||||
(beginning-of-line 2)))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^[ \t]*:.*\\(\n[ \t]*:.*\\)*" nil t)
|
||||
(add-text-properties (match-beginning 0) (match-end 0)
|
||||
'(org-protected t))))
|
||||
|
||||
(defun org-export-select-backend-specific-text (backend)
|
||||
(let ((formatters
|
||||
'((html "HTML" "BEGIN_HTML" "END_HTML")
|
||||
(ascii "ASCII" "BEGIN_ASCII" "END_ASCII")
|
||||
(latex "LaTeX" "BEGIN_LaTeX" "END_LaTeX")))
|
||||
fmt)
|
||||
|
||||
(while formatters
|
||||
(setq fmt (pop formatters))
|
||||
(when (eq (car fmt) backend)
|
||||
;; This is selected code, put it into the file for real
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward (concat "^#\\+" (cadr fmt)
|
||||
":[ \t]*\\(.*\\)") nil t)
|
||||
(replace-match "\\1" t)
|
||||
(add-text-properties
|
||||
(point-at-bol) (min (1+ (point-at-eol)) (point-max))
|
||||
'(org-protected t))))
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward
|
||||
(concat "^#\\+"
|
||||
(caddr fmt) "\\>.*\\(\\(\n.*\\)*?\n\\)#\\+"
|
||||
(cadddr fmt) "\\>.*\n?") nil t)
|
||||
(if (eq (car fmt) backend)
|
||||
;; yes, keep this
|
||||
(add-text-properties (match-beginning 1) (1+ (match-end 1))
|
||||
'(org-protected t))
|
||||
;; No, this is for a different backend, kill it
|
||||
(delete-region (match-beginning 0) (match-end 0)))))))
|
||||
|
||||
(defun org-export-mark-blockquote-and-verse ()
|
||||
"Mark block quote and verse environments with special cookies.
|
||||
These special cookies will later be interpreted by the backend."
|
||||
|
@ -1559,6 +1568,34 @@ These special cookies will later be interpreted by the backend."
|
|||
(goto-char (match-beginning 0))
|
||||
(delete-region (point) (org-end-of-subtree t)))))
|
||||
|
||||
(defun org-export-handle-comments (commentsp)
|
||||
"Remove comments, or convert to backend-specific format.
|
||||
COMMENTSP can be a format string for publishing comments.
|
||||
When it is nit, all comments will be removed."
|
||||
(let (pos)
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward "^#\\(.*\n?\\)" nil t)
|
||||
(setq pos (match-beginning 0))
|
||||
(if commentsp
|
||||
(progn (add-text-properties
|
||||
(match-beginning 0) (match-end 0) '(org-protected t))
|
||||
(replace-match (format commentsp (match-string 1)) t t))
|
||||
(goto-char (1+ pos))
|
||||
(org-if-unprotected
|
||||
(replace-match "")
|
||||
(goto-char (max (point-min) (1- pos))))
|
||||
(end-of-line 1)))))
|
||||
|
||||
(defun org-export-mark-radio-links ()
|
||||
"Find all matches for radio targets and turn them into internal links."
|
||||
(let ((re-radio (and org-target-link-regexp
|
||||
(concat "\\([^<]\\)\\(" org-target-link-regexp "\\)"))))
|
||||
(goto-char (point-min))
|
||||
(when re-radio
|
||||
(while (re-search-forward re-radio nil t)
|
||||
(org-if-unprotected
|
||||
(replace-match "\\1[[\\2]]"))))))
|
||||
|
||||
(defun org-export-remove-special-table-lines ()
|
||||
"Remove tables lines that are used for internal purposes."
|
||||
(goto-char (point-min))
|
||||
|
@ -1616,7 +1653,6 @@ can work correctly."
|
|||
(replace-match "\\1 \\3")
|
||||
(goto-char (match-beginning 0)))))
|
||||
|
||||
|
||||
(defun org-export-concatenate-multiline-emphasis ()
|
||||
"Find multi-line emphasis and put it all into a single line.
|
||||
This is to make sure that the line-processing export backends
|
||||
|
@ -2097,7 +2133,7 @@ underlined headlines. The default is 3."
|
|||
(goto-char beg)))
|
||||
(goto-char (point-min))))
|
||||
|
||||
(defun org-export-ascii-clean-string ()
|
||||
(defun org-export-ascii-preprocess ()
|
||||
"Do extra work for ASCII export"
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward org-verbatim-re nil t)
|
||||
|
@ -2320,6 +2356,16 @@ Does include HTML export options as well as TODO and CATEGORY stuff."
|
|||
"org file:~/org/%s.org"
|
||||
))
|
||||
|
||||
(defun org-export-html-preprocess (parameters)
|
||||
;; Convert LaTeX fragments to images
|
||||
(when (plist-get parameters :LaTeX-fragments)
|
||||
(org-format-latex
|
||||
(concat "ltxpng/" (file-name-sans-extension
|
||||
(file-name-nondirectory
|
||||
org-current-export-file)))
|
||||
org-current-export-dir nil "Creating LaTeX image %s"))
|
||||
(message "Exporting..."))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-insert-export-options-template ()
|
||||
"Insert into the buffer a template with information for exporting."
|
||||
|
|
|
@ -5335,6 +5335,8 @@ If WITH-CASE is non-nil, the sorting will be case-sensitive."
|
|||
|
||||
(defvar org-exit-edit-mode-map (make-sparse-keymap))
|
||||
(define-key org-exit-edit-mode-map "\C-c'" 'org-edit-src-exit)
|
||||
(defvar org-edit-src-force-single-line nil)
|
||||
(defvar org-edit-src-from-org-mode nil)
|
||||
|
||||
(define-minor-mode org-exit-edit-mode
|
||||
"Minor mode installing a single key binding, \"C-c '\" to exit special edit.")
|
||||
|
@ -5351,7 +5353,7 @@ exit by killing the buffer with \\[org-edit-src-exit]."
|
|||
"Edit, then exit with C-c ' (C-c and single quote)"))
|
||||
(info (org-edit-src-find-region-and-lang))
|
||||
(org-mode-p (eq major-mode 'org-mode))
|
||||
beg end lang single)
|
||||
beg end lang lang-f single)
|
||||
(if (not info)
|
||||
nil
|
||||
(setq beg (nth 0 info)
|
||||
|
@ -5406,7 +5408,7 @@ the language, a switch telling of the content should be in a single line."
|
|||
("^#\\+ascii:" "\n" "ascii" single-line)
|
||||
))
|
||||
(pos (point))
|
||||
re beg end lang)
|
||||
re re1 re2 single beg end lang)
|
||||
(catch 'exit
|
||||
(while (setq entry (pop re-list))
|
||||
(setq re1 (car entry) re2 (nth 1 entry) lang (nth 2 entry)
|
||||
|
|
Loading…
Reference in New Issue