;;; org-exp.el --- ASCII, HTML, XOXO and iCalendar export for Org-mode
-;; Copyright (C) 2004-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2012 Free Software Foundation, Inc.
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
-;; Version: 7.7
;;
;; This file is part of GNU Emacs.
;;
(declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ())
(declare-function org-table-cookie-line-p "org-table" (line))
(declare-function org-table-colgroup-line-p "org-table" (line))
+(declare-function org-pop-to-buffer-same-window "org-compat"
+ (&optional buffer-or-name norecord label))
(autoload 'org-export-generic "org-export-generic" "Export using the generic exporter" t)
(autoload 'org-export-as-odt "org-odt"
- "Export the outline to a OpenDocumentText file." t)
+ "Export the outline to a OpenDocument Text file." t)
(autoload 'org-export-as-odt-and-open "org-odt"
- "Export the outline to a OpenDocumentText file and open it." t)
+ "Export the outline to a OpenDocument Text file and open it." t)
(defgroup org-export nil
"Options for exporting org-listings."
This applied to the commands `org-export-as-html-and-open' and
`org-export-as-pdf-and-open'."
:group 'org-export-general
+ :version "24.1"
:type 'boolean)
(defcustom org-export-run-in-background nil
"The initial scope when exporting with `org-export'.
This variable can be either set to 'buffer or 'subtree."
:group 'org-export-general
+ :version "24.1"
:type '(choice
(const :tag "Export current buffer" 'buffer)
(const :tag "Export current subtree" 'subtree)))
:group 'org-export-general
:type 'string)
+(defcustom org-export-date-timestamp-format "%Y-%m-%d"
+ "Time string format for Org timestamps in the #+DATE option."
+ :group 'org-export-general
+ :version "24.1"
+ :type 'string)
+
(defvar org-export-page-description ""
"The page description, for the XHTML meta tag.
This is best set with the #+DESCRIPTION line in a file, it does not make
nil remove all tasks before export
list of TODO kwds keep only tasks with these keywords"
:group 'org-export-general
+ :version "24.1"
:type '(choice
(const :tag "All tasks" t)
(const :tag "No tasks" nil)
This option can also be set with the +OPTIONS line,
e.g. \"email:t\"."
:group 'org-export-general
+ :version "24.1"
:type 'boolean)
(defcustom org-export-creator-info t
This is the global equivalent of the :remove-nil-lines option
when locally sending a table with #+ORGTBL."
:group 'org-export-tables
+ :version "24.1"
:type 'boolean)
(defcustom org-export-prefer-native-exporter-for-tables nil
modified) list.")
;; FIXME: should we fold case here?
+
(defun org-infile-export-plist ()
"Return the property list with file-local settings for export."
(save-excursion
'("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE"
"MATHJAX"
"LINK_UP" "LINK_HOME" "SETUPFILE" "STYLE"
- "LATEX_HEADER" "LATEX_CLASS"
+ "LATEX_HEADER" "LATEX_CLASS" "LATEX_CLASS_OPTIONS"
"EXPORT_SELECT_TAGS" "EXPORT_EXCLUDE_TAGS"
"KEYWORDS" "DESCRIPTION" "MACRO" "BIND" "XSLT")
(mapcar 'car org-export-inbuffer-options-extra))))
(case-fold-search t)
p key val text options mathjax a pr style
- latex-header latex-class macros letbind
+ latex-header latex-class latex-class-options macros letbind
ext-setup-or-nil setup-file setup-dir setup-contents (start 0))
(while (or (and ext-setup-or-nil
(string-match re ext-setup-or-nil start)
((string-equal key "TITLE") (setq p (plist-put p :title val)))
((string-equal key "AUTHOR")(setq p (plist-put p :author val)))
((string-equal key "EMAIL") (setq p (plist-put p :email val)))
- ((string-equal key "DATE") (setq p (plist-put p :date val)))
+ ((string-equal key "DATE")
+ ;; If date is an Org timestamp, convert it to a time
+ ;; string using `org-export-date-timestamp-format'
+ (when (string-match org-ts-regexp3 val)
+ (setq val (format-time-string
+ org-export-date-timestamp-format
+ (apply 'encode-time (org-parse-time-string
+ (match-string 0 val))))))
+ (setq p (plist-put p :date val)))
((string-equal key "KEYWORDS") (setq p (plist-put p :keywords val)))
((string-equal key "DESCRIPTION")
(setq p (plist-put p :description val)))
(setq latex-header (concat latex-header "\n" val)))
((string-equal key "LATEX_CLASS")
(setq latex-class val))
+ ((string-equal key "LATEX_CLASS_OPTIONS")
+ (setq latex-class-options val))
((string-equal key "TEXT")
(setq text (if text (concat text "\n" val) val)))
((string-equal key "OPTIONS")
(setq p (plist-put p :latex-header-extra (substring latex-header 1))))
(when latex-class
(setq p (plist-put p :latex-class latex-class)))
+ (when latex-class-options
+ (setq p (plist-put p :latex-class-options latex-class-options)))
(when options
(setq p (org-export-add-options-to-plist p options)))
(when mathjax
\[D] export as DocBook [V] export as DocBook, process to PDF, and open
-\[o] export as OpenDocumentText [O] ... and open
+\[o] export as OpenDocument Text [O] ... and open
\[j] export as TaskJuggler [J] ... and open
(message "Export buffer: "))
((not subtree-p)
(setq subtree-p t)
+ (setq bpos (point))
(message "Export subtree: "))))
(when (eq r1 ?\ )
(let ((case-fold-search t)
(setq r1 (read-char-exclusive)))
(error "No enclosing node with LaTeX_CLASS or EXPORT_TITLE or EXPORT_FILE_NAME")
)))))
- (redisplay)
+ (if (fboundp 'redisplay) (redisplay)) ;; XEmacs does not have/need (redisplay)
(and bpos (goto-char bpos))
(setq r2 (if (< r1 27) (+ r1 96) r1))
(unless (setq ass (assq r2 cmds))
;; Remove #+TBLFM and #+TBLNAME lines
(org-export-handle-table-metalines)
+ ;; Remove #+results and #+name lines
+ (org-export-res/src-name-cleanup)
+
;; Run the final hook
(run-hooks 'org-export-preprocess-final-hook)
(setq found (condition-case nil (org-link-search link)
(error nil)))
(when (and found
- (or (org-on-heading-p)
+ (or (org-at-heading-p)
(not (eq found 'dedicated))))
(or (get-text-property (point) 'target)
(get-text-property
(defvar org-export-format-drawer-function nil
"Function to be called to format the contents of a drawer.
-The function must accept three parameters:
+The function must accept two parameters:
NAME the drawer name, like \"PROPERTIES\"
CONTENT the content of the drawer.
You can check the export backend through `org-export-current-backend'.
(setq beg (point))
(put-text-property beg (point-max) :org-delete t)
(while (re-search-forward re-sel nil t)
- (when (org-on-heading-p)
+ (when (org-at-heading-p)
(org-back-to-heading)
(remove-text-properties
(max (1- (point)) (point-min))
(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))
+ (if (not (org-at-heading-p t))
(goto-char (point-at-eol))
(beginning-of-line 1)
(setq a (if export-archived-trees
(org-if-unprotected
(replace-match "")))))
+(defvar org-heading-keyword-regexp-format) ; defined in org.el
(defun org-export-protect-quoted-subtrees ()
"Mark quoted subtrees with the protection property."
- (let ((org-re-quote (concat "^\\*+[ \t]+" org-quote-string "\\>")))
+ (let ((org-re-quote (format org-heading-keyword-regexp-format
+ org-quote-string)))
(goto-char (point-min))
(while (re-search-forward org-re-quote nil t)
(goto-char (match-beginning 0))
":[ \t]*\\(.*\\)") nil t)
(if (not (eq backend org-export-current-backend))
(delete-region (point-at-bol) (min (1+ (point-at-eol)) (point-max)))
- (replace-match "\\1\\2" t)
- (add-text-properties
- (point-at-bol) (min (1+ (point-at-eol)) (point-max))
- `(org-protected t original-indentation ,ind org-native-text t))))
+ (let ((ind (get-text-property (point-at-bol) 'original-indentation)))
+ (replace-match "\\1\\2" t)
+ (add-text-properties
+ (point-at-bol) (min (1+ (point-at-eol)) (point-max))
+ `(org-protected t original-indentation ,ind org-native-text t)))))
;; Delete #+ATTR_BACKEND: stuff of another backend. Those
;; matching the current backend will be taken care of by
;; `org-export-attach-captions-and-attributes'
(while (re-search-forward (concat "^[ \t]*#\\+BEGIN_" backend-name "\\>.*\n?")
nil t)
(setq beg (match-beginning 0) beg-content (match-end 0))
- (setq ind (save-excursion (goto-char beg) (org-get-indentation)))
+ (setq ind (or (get-text-property beg 'original-indentation)
+ (save-excursion (goto-char beg) (org-get-indentation))))
(when (re-search-forward (concat "^[ \t]*#\\+END_" backend-name "\\>.*\n?")
nil t)
(setq end (match-end 0) end-content (match-beginning 0))
beg-content end-content
`(org-protected t original-indentation ,ind org-native-text t))
;; strip protective commas
- (save-excursion
- (save-match-data
- (goto-char beg-content)
- (while (re-search-forward "^[ \t]*\\(,\\)" end-content t)
- (replace-match "" nil nil nil 1))))
+ (org-strip-protective-commas beg-content end-content)
(delete-region (match-beginning 0) (match-end 0))
(save-excursion
(goto-char beg)
(top (point-at-bol))
(top-ind (org-list-get-ind top struct)))
(goto-char bottom)
- (when (and (not (eq org-list-ending-method 'indent))
- (not (looking-at "[ \t]*$"))
+ (when (and (not (looking-at "[ \t]*$"))
(looking-at org-list-end-re))
(replace-match ""))
(unless (bolp) (insert "\n"))
;; useful to line processing exporters.
(goto-char bottom)
(when (or (looking-at "^ORG-LIST-END-MARKER\n")
- (and (not (eq org-list-ending-method 'indent))
- (not (looking-at "[ \t]*$"))
+ (and (not (looking-at "[ \t]*$"))
(looking-at org-list-end-re)))
(replace-match ""))
(unless (bolp) (insert "\n"))
(defun org-export-remove-comment-blocks-and-subtrees ()
"Remove the comment environment, and also commented subtrees."
- (let ((re-commented (concat "^\\*+[ \t]+" org-comment-string "\\>"))
+ (let ((re-commented (format org-heading-keyword-regexp-format
+ org-comment-string))
case-fold-search)
;; Remove comment environment
(goto-char (point-min))
(replace-match "")
(goto-char (max (point-min) (1- pos)))))))
+(defun org-export-res/src-name-cleanup ()
+ "Clean up #+results and #+name lines for export.
+This function should only be called after all block processing
+has taken place."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((case-fold-search t))
+ (while (org-re-search-forward-unprotected
+ "#\\+\\(name\\|results\\(\\[[a-z0-9]+\\]\\)?\\):" nil t)
+ (delete-region (match-beginning 0) (progn (forward-line) (point)))))))
+
(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
(defun org-store-forced-table-alignment ()
"Find table lines which force alignment, store the results in properties."
- (let (line cnt aligns)
+ (let (line cnt cookies)
(goto-char (point-min))
- (while (re-search-forward "|[ \t]*<[lrc][0-9]*>[ \t]*|" nil t)
+ (while (re-search-forward "|[ \t]*<\\([lrc]?[0-9]+\\|[lrc]\\)>[ \t]*|"
+ nil t)
;; OK, this looks like a table line with an alignment cookie
(org-if-unprotected
(setq line (buffer-substring (point-at-bol) (point-at-eol)))
(when (and (org-at-table-p)
(org-table-cookie-line-p line))
- (setq cnt 0 aligns nil)
+ (setq cnt 0 cookies nil)
(mapc
(lambda (x)
(setq cnt (1+ cnt))
- (if (string-match "\\`<\\([lrc]\\)" x)
- (push (cons cnt (downcase (match-string 1 x))) aligns)))
+ (when (string-match "\\`<\\([lrc]\\)?\\([0-9]+\\)?>\\'" x)
+ (let ((align (and (match-end 1)
+ (downcase (match-string 1 x))))
+ (width (and (match-end 2)
+ (string-to-number (match-string 2 x)))))
+ (push (cons cnt (list align width)) cookies))))
(org-split-string line "[ \t]*|[ \t]*"))
(add-text-properties (org-table-begin) (org-table-end)
- (list 'org-forced-aligns aligns))))
+ (list 'org-col-cookies cookies))))
(goto-char (point-at-eol)))))
(defun org-export-remove-special-table-lines ()
(re-angle-link (concat "\\([^[]\\)" org-angle-link-re))
nodesc)
(goto-char (point-min))
+ (while (re-search-forward org-bracket-link-regexp nil t)
+ (put-text-property (match-beginning 0) (match-end 0) 'org-normalized-link t))
+ (goto-char (point-min))
(while (re-search-forward re-plain-link nil t)
- (unless (org-string-match-p
- "\\[\\[\\S-+:\\S-*?\\<"
- (buffer-substring (point-at-bol) (match-beginning 0)))
+ (unless (get-text-property (match-beginning 0) 'org-normalized-link)
(goto-char (1- (match-end 0)))
(org-if-unprotected-at (1+ (match-beginning 0))
(let* ((s (concat (match-string 1)
(save-excursion (outline-next-heading) (point)))))
(when (re-search-forward "^[ \t]*[^|# \t\r\n].*\n" end t)
;; Mark the line so that it will not be exported as normal text.
- (org-unmodified
- (add-text-properties (match-beginning 0) (match-end 0)
- (list :org-license-to-kill t)))
+ (unless (org-in-block-p org-list-forbidden-blocks)
+ (org-unmodified
+ (add-text-properties (match-beginning 0) (match-end 0)
+ (list :org-license-to-kill t))))
;; Return the title string
(org-trim (match-string 0)))))))
(defun org-export-get-title-from-subtree ()
"Return subtree title and exclude it from export."
(let ((rbeg (region-beginning)) (rend (region-end))
- (inhibit-read-only t) title)
+ (inhibit-read-only t)
+ (tags (plist-get (org-infile-export-plist) :tags))
+ title)
(save-excursion
(goto-char rbeg)
(when (and (org-at-heading-p)
(>= (org-end-of-subtree t t) rend))
+ (when (plist-member org-export-opt-plist :tags)
+ (setq tags (or (plist-get org-export-opt-plist :tags) tags)))
;; This is a subtree, we take the title from the first heading
(goto-char rbeg)
- (looking-at org-todo-line-regexp)
- (setq title (match-string 3))
+ (looking-at org-todo-line-tags-regexp)
+ (setq title (if (and (eq tags t) (match-string 4))
+ (format "%s\t%s" (match-string 3) (match-string 4))
+ (match-string 3)))
(org-unmodified
(add-text-properties (point) (1+ (point-at-eol))
(list :org-license-to-kill t)))
(plist-get org-export-opt-plist
(intern (concat ":" key)))))
(save-match-data
- ;; If arguments are provided, first retreive them properly
+ ;; If arguments are provided, first retrieve them properly
;; (in ARGS, as a list), then replace them in VAL.
(when args
(setq args (org-split-string args ",") args2 nil)
(format "\\begin{%s}\n%s\\end{%s}\n"
custom-environment rtn custom-environment))
(listings-p
- (format "\\begin{%s}\n%s\\end{%s}\n"
+ (format "\\begin{%s}\n%s\\end{%s}"
"lstlisting" rtn "lstlisting"))
(minted-p
(format
- "\\begin{minted}[%s]{%s}\n%s\\end{minted}\n"
+ "\\begin{minted}[%s]{%s}\n%s\\end{minted}"
(mapconcat #'make-option-string
org-export-latex-minted-options ",")
backend-lang rtn)))))))
"\n#+BEGIN_" backend-name "\n"
(org-add-props rtn
'(org-protected t org-example t org-native-text t))
- "\n#+END_" backend-name "\n\n"))
+ "\n#+END_" backend-name "\n"))
(org-add-props rtn nil 'original-indentation indent))))
(defun org-export-number-lines (text &optional skip1 skip2 number cont
- replace-labels label-format)
+ replace-labels label-format preprocess)
+ "Apply line numbers to literal examples and handle code references.
+Handle user-specified options under info node `(org)Literal
+examples' and return the modified source block.
+
+TEXT contains the source or example block.
+
+SKIP1 and SKIP2 are the number of lines that are to be skipped at
+the beginning and end of TEXT. Use these to skip over
+backend-specific lines pre-pended or appended to the original
+source block.
+
+NUMBER is non-nil if the literal example specifies \"+n\" or
+\"-n\" switch. If NUMBER is non-nil add line numbers.
+
+CONT is non-nil if the literal example specifies \"+n\" switch.
+If CONT is nil, start numbering this block from 1. Otherwise
+continue numbering from the last numbered block.
+
+REPLACE-LABELS is dual-purpose.
+1. It controls the retention of labels in the exported block.
+2. It specifies in what manner the links (or references) to a
+ labeled line be formatted.
+
+REPLACE-LABELS is the symbol `keep' if the literal example
+specifies \"-k\" option, is numeric if the literal example
+specifies \"-r\" option and is nil otherwise.
+
+Handle REPLACE-LABELS as below:
+- If nil, retain labels in the exported block and use
+ user-provided labels for referencing the labeled lines.
+- If it is a number, remove labels in the exported block and use
+ one of line numbers or labels for referencing labeled lines based
+ on NUMBER option.
+- If it is a keep, retain labels in the exported block and use
+ one of line numbers or labels for referencing labeled lines
+ based on NUMBER option.
+
+LABEL-FORMAT is the value of \"-l\" switch associated with
+literal example. See `org-coderef-label-format'.
+
+PREPROCESS is intended for backend-agnostic handling of source
+block numbering. When non-nil do the following:
+- do not number the lines
+- always strip the labels from exported block
+- do not make the labeled line a target of an incoming link.
+ Instead mark the labeled line with `org-coderef' property and
+ store the label in it."
(setq skip1 (or skip1 0) skip2 (or skip2 0))
- (if (not cont) (setq org-export-last-code-line-counter-value 0))
+ (if (and number (not cont)) (setq org-export-last-code-line-counter-value 0))
(with-temp-buffer
(insert text)
(goto-char (point-max))
(org-goto-line (1+ skip1))
(while (and (re-search-forward "^" nil t) (not (eobp)) (< n nmax))
- (if number
- (insert (format fm (incf n)))
- (forward-char 1))
+ (when number (incf n))
+ (if (or preprocess (not number))
+ (forward-char 1)
+ (insert (format fm n)))
(when (looking-at lbl-re)
(setq ref (match-string 3))
(cond ((numberp replace-labels)
;; lines are numbered, use labels otherwise
(goto-char (match-beginning 2))
(delete-region (match-beginning 2) (match-end 2))
- (insert "(" ref ")")
+ (unless preprocess
+ (insert "(" ref ")"))
(push (cons ref (if (> n 0) n (concat "(" ref ")")))
org-export-code-refs))
(t
;; references
(goto-char (match-beginning 2))
(delete-region (match-beginning 2) (match-end 2))
- (insert "(" ref ")")
+ (unless preprocess
+ (insert "(" ref ")"))
(push (cons ref (concat "(" ref ")")) org-export-code-refs)))
- (when (eq org-export-current-backend 'html)
+ (when (and (eq org-export-current-backend 'html) (not preprocess))
(save-excursion
(beginning-of-line 1)
(insert (format "<span id=\"coderef-%s\" class=\"coderef-off\">"
ref))
(end-of-line 1)
- (insert "</span>")))))
+ (insert "</span>")))
+ (when preprocess
+ (add-text-properties
+ (point-at-bol) (point-at-eol) (list 'org-coderef ref)))))
(setq org-export-last-code-line-counter-value n)
(goto-char (point-max))
(newline)
(switch-to-buffer-other-window buffer)
(goto-char (point-min)))))
-(defun org-find-visible ()
- (let ((s (point)))
- (while (and (not (= (point-max) (setq s (next-overlay-change s))))
- (get-char-property s 'invisible)))
- s))
-(defun org-find-invisible ()
- (let ((s (point)))
- (while (and (not (= (point-max) (setq s (next-overlay-change s))))
- (not (get-char-property s 'invisible))))
- s))
-
(defvar org-export-htmlized-org-css-url) ;; defined in org-html.el
(defun org-export-string (string fmt &optional dir)
(org-load-modules-maybe)
(unless org-local-vars
(setq org-local-vars (org-get-local-variables)))
- (eval ;; convert to fmt -- mimicing `org-run-like-in-org-mode'
+ (eval ;; convert to fmt -- mimicking `org-run-like-in-org-mode'
(list 'let org-local-vars
(list (intern (format "org-export-as-%s" fmt))
nil nil nil ''string t))))
(region (buffer-string))
str-ret)
(save-excursion
- (switch-to-buffer buffer)
+ (org-pop-to-buffer-same-window buffer)
(erase-buffer)
(insert region)
(let ((org-inhibit-startup t)) (org-mode))
((org-table-cookie-line-p x)
;; This line contains formatting cookies, discard it
nil)
- ((string-match "^[ \t]*| *[!_^/] *|" x)
+ ((string-match "^[ \t]*| *\\([!_^/$]\\|\\\\\\$\\) *|" x)
;; ignore this line
nil)
((or (string-match "^\\([ \t]*\\)|-+\\+" x)
(defun org-export-push-to-kill-ring (format)
"Push buffer content to kill ring.
-The depends on the variable `org-export-copy-to-kill'."
+The depends on the variable `org-export-copy-to-kill-ring'."
(when org-export-copy-to-kill-ring
(org-kill-new (buffer-string))
(when (fboundp 'x-set-selection)
(provide 'org-exp)
-
-
;;; org-exp.el ends here