Browse Source

Merge branch 'master' of orgmode.org:org-mode

Carsten Dominik 6 years ago
parent
commit
11dec73c0c

+ 2 - 2
contrib/lisp/org-elisp-symbol.el

@@ -104,8 +104,8 @@
 	     (stype (cond ((commandp sym-name) "Command")
 			  ((functionp sym-name) "Function")
 			  ((user-variable-p sym-name) "User variable")
-			  ((eq def "defvar") "Variable")
-			  ((eq def "defmacro") "Macro")
+			  ((string= def "defvar") "Variable")
+			  ((string= def "defmacro") "Macro")
 			  (t "Symbol")))
 	     (args (if (match-string 3)
 		       (mapconcat (lambda (a) (unless (string-match "^&" a) a))

+ 143 - 21
contrib/lisp/org-lparse.el

@@ -335,6 +335,7 @@ OPT-PLIST is the export options list."
      ,@body
      (when org-lparse-do-open-par
        (org-lparse-begin-paragraph))))
+(def-edebug-spec with-org-lparse-preserve-paragraph-state (body))
 
 (defvar org-lparse-native-backends nil
   "List of native backends registered with `org-lparse'.
@@ -693,12 +694,6 @@ and then converted to \"doc\" then org-lparse-backend is set to
 (defvar org-lparse-to-buffer nil
   "Bind this to TO-BUFFER arg of `org-lparse'.")
 
-(defvar org-lparse-current-paragraph-style nil
-  "Default paragraph style to use.
-Exporter sets or resets this as it enters and leaves special
-contexts.  Currently this is used for formatting of paragraphs
-that are part of table-cells created from list-tables.")
-
 (defun org-do-lparse (arg &optional hidden ext-plist
 			  to-buffer body-only pub-dir)
   "Export the outline to various formats.
@@ -728,11 +723,20 @@ version."
 					; collecting styles
 	 org-lparse-encode-pending
 	 org-lparse-par-open
-	 org-lparse-current-paragraph-style
-	 org-lparse-list-table-p
+
+	 ;; list related vars
 	 (org-lparse-list-level 0)	; list level starts at 1. A
 					; value of 0 implies we are
 					; outside of any list
+	 (org-lparse-list-item-count 0)
+	 org-lparse-list-stack
+
+	 ;; list-table related vars
+	 org-lparse-list-table-p
+	 org-lparse-list-table:table-cell-open
+	 org-lparse-list-table:table-row
+	 org-lparse-list-table:lines
+
 	 org-lparse-outline-text-open
 	 (org-lparse-latex-fragment-fallback ; currently used only by
 					; odt exporter
@@ -1363,7 +1367,7 @@ form (FIELD1 FIELD2 FIELD3 ...) as appropriate."
 	  (push (org-split-string line "[ \t]*|[ \t]*") lines-1))))))
     (nreverse lines-1)))
 
-(defun org-lparse-do-format-org-table (lines &optional splice)
+(defun org-lparse-insert-org-table (lines &optional splice)
   "Format a org-type table into backend-specific code.
 LINES is a list of lines.  Optional argument SPLICE means, do not
 insert header and surrounding <table> tags, just format the lines.
@@ -1390,12 +1394,14 @@ for formatting.  This is required for the DocBook exporter."
 			       (lambda (x) (string-match "^[ \t]*|-" x))
 			       (cdr lines))))))
     (setq lines (org-lparse-org-table-to-list-table lines splice))
-    (org-lparse-do-format-list-table
+    (org-lparse-insert-list-table
      lines splice caption label attributes head org-lparse-table-colalign-info)))
 
-(defun org-lparse-do-format-list-table (lines &optional splice
+(defun org-lparse-insert-list-table (lines &optional splice
 					      caption label attributes head
 					      org-lparse-table-colalign-info)
+  (or (featurep 'org-table)		; required for
+      (require 'org-table))		; `org-table-number-regexp'
   (let* ((org-lparse-table-rownum -1) org-lparse-table-ncols i (cnt 0)
 	 tbopen fields line
 	 org-lparse-table-cur-rowgrp-is-hdr
@@ -1427,15 +1433,15 @@ for formatting.  This is required for the DocBook exporter."
 
 (defun org-lparse-format-org-table (lines &optional splice)
   (with-temp-buffer
-    (org-lparse-do-format-org-table lines splice)
+    (org-lparse-insert-org-table lines splice)
     (buffer-substring-no-properties (point-min) (point-max))))
 
 (defun org-lparse-format-list-table (lines &optional splice)
   (with-temp-buffer
-    (org-lparse-do-format-list-table lines splice)
+    (org-lparse-insert-list-table lines splice)
     (buffer-substring-no-properties (point-min) (point-max))))
 
-(defun org-lparse-do-format-table-table (lines)
+(defun org-lparse-insert-table-table (lines)
   "Format a table generated by table.el into backend-specific code.
 This conversion does *not* use `table-generate-source' from table.el.
 This has the advantage that Org-mode's HTML conversions can be used.
@@ -1475,7 +1481,7 @@ But it has the disadvantage, that no cell- or row-spanning is allowed."
 
 (defun org-lparse-format-table-table (lines)
   (with-temp-buffer
-    (org-lparse-do-format-table-table lines)
+    (org-lparse-insert-table-table lines)
     (buffer-substring-no-properties (point-min) (point-max))))
 
 (defvar table-source-languages)		; defined in table.el
@@ -2044,7 +2050,12 @@ See `org-xhtml-entity-format-callbacks-alist' for more information."
   lines)
 
 (defun org-lparse-format-table-row (fields &optional text-for-empty-fields)
-  (unless org-lparse-table-ncols
+  (if org-lparse-table-ncols
+      ;; second and subsequent rows of the table
+      (when (and org-lparse-list-table-p
+		 (> (length fields) org-lparse-table-ncols))
+	(error "Table row has %d columns but header row claims %d columns"
+	       (length fields) org-lparse-table-ncols))
     ;; first row of the table
     (setq org-lparse-table-ncols (length fields))
     (when org-lparse-table-is-styled
@@ -2191,20 +2202,131 @@ When TITLE is nil, just close all open levels."
 		      ("u" . unordered)
 		      ("d" . description)))))
 
-(defvar org-lparse-list-level) ; dynamically bound in org-do-lparse
+;; following vars are bound during `org-do-lparse'
+(defvar org-lparse-list-level)
+(defvar org-lparse-list-item-count)
+(defvar org-lparse-list-stack)
+(defvar org-lparse-list-table:table-row)
+(defvar org-lparse-list-table:lines)
+
+;; Notes on LIST-TABLES
+;; ====================
+;; When `org-lparse-list-table-enable' is non-nil, the following list
+;;
+;; #+begin_list-table
+;; - Row 1
+;;   - 1.1
+;;   - 1.2
+;;   - 1.3
+;; - Row 2
+;;   - 2.1
+;;   - 2.2
+;;   - 2.3
+;; #+end_list-table
+;;
+;; will be exported as though it were a table as shown below.
+;;
+;; | Row 1 | 1.1 | 1.2 | 1.3 |
+;; | Row 2 | 2.1 | 2.2 | 2.3 |
+;;
+;; Note that org-tables are NOT multi-line and each line is mapped to
+;; a unique row in the exported document.  So if an exported table
+;; needs to contain a single paragraph (with copious text) it needs to
+;; be typed up in a single line. Editing such long lines using the
+;; table editor will be a cumbersome task.  Furthermore inclusion of
+;; multi-paragraph text in a table cell is well-nigh impossible.
+;;
+;; LIST-TABLEs are meant to circumvent the above problems with
+;; org-tables.
+;;
+;; Note that in the example above the list items could be paragraphs
+;; themselves and the list can be arbitrarily deep.
+;;
+;; Inspired by following thread:
+;; https://lists.gnu.org/archive/html/emacs-orgmode/2011-03/msg01101.html
+
 (defun org-lparse-begin-list (ltype)
   (incf org-lparse-list-level)
-  (org-lparse-begin 'LIST ltype))
+  (push org-lparse-list-item-count org-lparse-list-stack)
+  (setq org-lparse-list-item-count 0)
+  (cond
+   ((not org-lparse-list-table-p)
+    (org-lparse-begin 'LIST ltype))
+   ;; process LIST-TABLE
+   ((= 1 org-lparse-list-level)
+    ;; begin LIST-TABLE
+    (setq org-lparse-list-table:lines nil)
+    (setq org-lparse-list-table:table-row nil))
+   ((= 2 org-lparse-list-level)
+    (ignore))
+   (t
+    (org-lparse-begin 'LIST ltype))))
 
 (defun org-lparse-end-list (ltype)
+  (setq org-lparse-list-item-count (pop org-lparse-list-stack))
   (decf org-lparse-list-level)
-  (org-lparse-end 'LIST ltype))
+  (cond
+   ((not org-lparse-list-table-p)
+    (org-lparse-end 'LIST ltype))
+   ;; process LIST-TABLE
+   ((= 0 org-lparse-list-level)
+    ;; end LIST-TABLE
+    (insert (org-lparse-format-list-table
+	     (nreverse org-lparse-list-table:lines))))
+   ((= 1 org-lparse-list-level)
+    (ignore))
+   (t
+    (org-lparse-end 'LIST ltype))))
 
 (defun org-lparse-begin-list-item (ltype &optional arg headline)
-  (org-lparse-begin 'LIST-ITEM ltype arg headline))
+  (incf org-lparse-list-item-count)
+  (cond
+   ((not org-lparse-list-table-p)
+    (org-lparse-begin 'LIST-ITEM ltype arg headline))
+   ;; process LIST-TABLE
+   ((and (= 1 org-lparse-list-level)
+	 (= 1 org-lparse-list-item-count))
+    ;; begin TABLE-ROW for LIST-TABLE
+    (setq org-lparse-list-table:table-row nil)
+    (org-lparse-begin-list-table:table-cell))
+   ((and (= 2 org-lparse-list-level)
+	 (= 1 org-lparse-list-item-count))
+    ;; begin TABLE-CELL for LIST-TABLE
+    (org-lparse-begin-list-table:table-cell))
+   (t
+    (org-lparse-begin 'LIST-ITEM ltype arg headline))))
 
 (defun org-lparse-end-list-item (ltype)
-  (org-lparse-end 'LIST-ITEM ltype))
+  (decf org-lparse-list-item-count)
+  (cond
+   ((not org-lparse-list-table-p)
+    (org-lparse-end 'LIST-ITEM ltype))
+   ;; process LIST-TABLE
+   ((and (= 1 org-lparse-list-level)
+	 (= 0 org-lparse-list-item-count))
+    ;; end TABLE-ROW for LIST-TABLE
+    (org-lparse-end-list-table:table-cell)
+    (push (nreverse org-lparse-list-table:table-row)
+	  org-lparse-list-table:lines))
+   ((= 2 org-lparse-list-level)
+    ;; end TABLE-CELL for LIST-TABLE
+    (org-lparse-end-list-table:table-cell))
+   (t
+    (org-lparse-end 'LIST-ITEM ltype))))
+
+(defvar org-lparse-list-table:table-cell-open)
+(defun org-lparse-begin-list-table:table-cell ()
+  (org-lparse-end-list-table:table-cell)
+  (setq org-lparse-list-table:table-cell-open t)
+  (org-lparse-begin-collect)
+  (org-lparse-begin-paragraph))
+
+(defun org-lparse-end-list-table:table-cell ()
+  (when org-lparse-list-table:table-cell-open
+    (setq org-lparse-list-table:table-cell-open nil)
+    (org-lparse-end-paragraph)
+    (push (org-lparse-end-collect)
+	  org-lparse-list-table:table-row)))
 
 (defvar org-lparse-table-rowgrp-info)
 (defun org-lparse-begin-table-rowgroup (&optional is-header-row)

+ 311 - 282
contrib/lisp/org-odt.el

@@ -76,9 +76,9 @@
   "Directory that holds auxiliary files used by the ODT exporter.
 
 The 'styles' subdir contains the following xml files -
- 'OrgOdtStyles.xml' and 'OrgOdtAutomaticStyles.xml' - which are
+ 'OrgOdtStyles.xml' and 'OrgOdtContentTemplate.xml' - which are
  used as factory settings of `org-export-odt-styles-file' and
- `org-export-odt-automatic-styles-file'.
+ `org-export-odt-content-template-file'.
 
 The 'etc/schema' subdir contains rnc files for validating of
 OpenDocument xml files.")
@@ -148,9 +148,13 @@ OpenDocument xml files.")
 	       'org-export-odt-preprocess-latex-fragments)
   nil)
 
-(defcustom org-export-odt-automatic-styles-file nil
-  "Automatic styles for use with ODT exporter.
-If unspecified, the file under `org-odt-data-dir' is used."
+(defcustom org-export-odt-content-template-file nil
+  "Template file for \"content.xml\".
+The exporter embeds the exported content just before
+\"</office:text>\" element.
+
+If unspecified, the file named \"OrgOdtContentTemplate.xml\"
+under `org-odt-data-dir' is used."
   :type 'file
   :group 'org-export-odt)
 
@@ -383,8 +387,6 @@ PUB-DIR is set, use this as the publishing directory."
      . (org-odt-begin-table org-odt-end-table))
     (TABLE-ROWGROUP
      . (org-odt-begin-table-rowgroup org-odt-end-table-rowgroup))
-    (TABLE-CELL
-     . (org-odt-begin-table-cell org-odt-end-table-cell))
     (LIST
      . (org-odt-begin-list org-odt-end-list))
     (LIST-ITEM
@@ -430,16 +432,14 @@ PUB-DIR is set, use this as the publishing directory."
 ;;;_. control callbacks
 ;;;_ , document body
 (defun org-odt-begin-office-body ()
-  (insert "
-  <office:body>
-    <office:text>
-      <text:sequence-decls>
-	<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Illustration\"/>
-	<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Table\"/>
-	<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Text\"/>
-	<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Drawing\"/>
-	<text:sequence-decl text:display-outline-level=\"0\" text:name=\"Equation\"/>
-      </text:sequence-decls>"))
+  ;; automatic styles
+  (insert-file-contents
+   (or org-export-odt-content-template-file
+       (expand-file-name "styles/OrgOdtContentTemplate.xml"
+			 org-odt-data-dir)))
+  (goto-char (point-min))
+  (re-search-forward "</office:text>" nil nil)
+  (delete-region (match-beginning 0) (point-max)))
 
 ;; Following variable is let bound when `org-do-lparse' is in
 ;; progress. See org-html.el.
@@ -462,48 +462,8 @@ PUB-DIR is set, use this as the publishing directory."
     (org-lparse-insert-tag "</office:text>")
     (org-lparse-insert-tag "</office:body>")))
 
-(defconst org-odt-document-content-header
-  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-<office:document-content
-    xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"
-    xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"
-    xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"
-    xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"
-    xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"
-    xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"
-    xmlns:xlink=\"http://www.w3.org/1999/xlink\"
-    xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
-    xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"
-    xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"
-    xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"
-    xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"
-    xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"
-    xmlns:math=\"http://www.w3.org/1998/Math/MathML\"
-    xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"
-    xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"
-    xmlns:ooo=\"http://openoffice.org/2004/office\"
-    xmlns:ooow=\"http://openoffice.org/2004/writer\"
-    xmlns:oooc=\"http://openoffice.org/2004/calc\"
-    xmlns:dom=\"http://www.w3.org/2001/xml-events\"
-    xmlns:xforms=\"http://www.w3.org/2002/xforms\"
-    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
-    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
-    xmlns:rpt=\"http://openoffice.org/2005/report\"
-    xmlns:of=\"urn:oasis:names:tc:opendocument:xmlns:of:1.2\"
-    xmlns:xodt=\"http://www.w3.org/1999/xodt\"
-    xmlns:field=\"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0\"    office:version=\"1.2\">
-")
-
 (defun org-odt-begin-document-content (opt-plist)
-  ;; document header
-  (insert org-odt-document-content-header)
-
-  ;; automatic styles
-  (insert-file-contents
-   (or org-export-odt-automatic-styles-file
-       (expand-file-name "styles/OrgOdtAutomaticStyles.xml"
-			 org-odt-data-dir)))
-   (goto-char (point-max)))
+  (ignore))
 
 (defun org-odt-end-document-content ()
   (org-lparse-insert-tag "</office:document-content>"))
@@ -524,10 +484,7 @@ PUB-DIR is set, use this as the publishing directory."
 (defun org-odt-end-outline-text ()
   (ignore))
 
-(defvar org-lparse-current-paragraph-style) ; bound during
-					    ; `org-do-lparse'
 (defun org-odt-begin-paragraph (&optional style)
-  (setq style (or style org-lparse-current-paragraph-style))
   (org-lparse-insert-tag
    "<text:p%s>" (org-odt-get-extra-attrs-for-paragraph-style style)))
 
@@ -548,8 +505,7 @@ PUB-DIR is set, use this as the publishing directory."
 (defun org-odt-format-stylized-paragraph (style text)
   (org-odt-format-tags
    '("<text:p%s>" . "</text:p>") text
-   (org-odt-get-extra-attrs-for-paragraph-style
-    (or style org-lparse-current-paragraph-style))))
+   (org-odt-get-extra-attrs-for-paragraph-style style)))
 
 (defun org-odt-begin-environment (style)
   (case style
@@ -728,26 +684,17 @@ PUB-DIR is set, use this as the publishing directory."
   (when org-lparse-table-is-styled
     (format "@@table-cell:style-name@@%03d@@%03d@@" r c)))
 
-(defun org-odt-begin-table-cell (r c)
-  (setq org-lparse-current-paragraph-style
-	(org-odt-get-paragraph-style-cookie-for-table-cell r c))
-  (let* ((style-name-cookie
+(defun org-odt-format-table-cell (data r c)
+  (let* ((paragraph-style-cookie
+	  (org-odt-get-paragraph-style-cookie-for-table-cell r c))
+	 (style-name-cookie
 	  (org-odt-get-style-name-cookie-for-table-cell r c))
 	 (extra (if style-name-cookie
 		    (format " table:style-name=\"%s\""  style-name-cookie) "")))
-    (org-lparse-insert-tag "<table:table-cell%s>" extra)))
-
-(defun org-odt-end-table-cell ()
-  (org-lparse-insert-tag "</table:table-cell>")
-  (setq org-lparse-current-paragraph-style nil))
-
-(defun org-odt-format-table-cell (data r c)
-  (with-temp-buffer
-    (org-odt-begin-table-cell r c)
-    (insert (org-odt-format-stylized-paragraph
-	     org-lparse-current-paragraph-style data))
-    (org-odt-end-table-cell)
-    (buffer-string)))
+    (org-odt-format-tags
+     '("<table:table-cell%s>" . "</table:table-cell>")
+     (if org-lparse-list-table-p data
+       (org-odt-format-stylized-paragraph paragraph-style-cookie data)) extra)))
 
 (defun org-odt-begin-footnote-definition (n)
   (org-lparse-begin-paragraph 'footnote))
@@ -1070,6 +1017,98 @@ value of `org-export-odt-use-htmlfontify."
 	       (org-odt-copy-image-file thefile) thelink))))
     (org-export-odt-format-image thefile href)))
 
+(defun org-export-odt-do-format-numbered-formula (embed-as caption attr label
+							   width height href)
+  (with-temp-buffer
+    (let ((org-lparse-table-colalign-info '((0 "c" "8") (0 "c" "1"))))
+      (org-lparse-insert-list-table
+       `((,(org-export-odt-do-format-formula ; caption and label
+					     ; should be nil
+	    embed-as nil attr nil width height href)
+	  ,(org-odt-format-entity-caption label caption "Equation")))
+       nil nil nil nil nil org-lparse-table-colalign-info))
+    (buffer-substring-no-properties (point-min) (point-max))))
+
+(defun org-export-odt-do-format-formula (embed-as caption attr label
+						  width height href)
+  "Create image tag with source and attributes."
+  (save-match-data
+    (cond
+     ((and (not caption) (not label))
+      (let (style-name anchor-type)
+	(case embed-as
+	  (paragraph
+	   (setq style-name  "OrgSimpleGraphics" anchor-type "paragraph"))
+	  (character
+	   (setq style-name  "OrgInlineGraphics" anchor-type "as-char"))
+	  (t
+	   (error "Unknown value for embed-as %S" embed-as)))
+	(org-odt-format-frame href style-name width height nil anchor-type)))
+     (t
+      (concat
+       (org-odt-format-textbox
+	(org-odt-format-stylized-paragraph
+	 'illustration
+	 (concat
+	  (let ((extra ""))
+	    (org-odt-format-frame
+	     href "" width height extra "paragraph"))
+	  (org-odt-format-entity-caption label caption)))
+	"OrgCaptionFrame" width height))))))
+
+(defun org-export-odt-format-formula (src href &optional embed-as)
+  "Create image tag with source and attributes."
+  (save-match-data
+    (let* ((caption (org-find-text-property-in-string 'org-caption src))
+	   (caption (and caption (org-xml-format-desc caption)))
+	   (attr (org-find-text-property-in-string 'org-attributes src))
+	   (label (org-find-text-property-in-string 'org-label src))
+	   (embed-as (or embed-as
+			 (and (org-find-text-property-in-string
+			       'org-latex-src src)
+			      (org-find-text-property-in-string
+			       'org-latex-src-embed-type src))
+			 'paragraph))
+	   (attr-plist (when attr (read  attr)))
+	   (width (plist-get attr-plist :width))
+	   (height (plist-get attr-plist :height)))
+      (org-export-odt-do-format-formula
+       embed-as caption attr label width height href))))
+
+(defvar org-odt-embedded-formulas-count 0)
+(defun org-odt-copy-formula-file (path)
+  "Returns the internal name of the file"
+  (let* ((src-file (expand-file-name
+		    path (file-name-directory org-current-export-file)))
+	 (target-dir (format "Formula-%04d/"
+			     (incf org-odt-embedded-formulas-count)))
+	 (target-file (concat target-dir "content.xml")))
+    (when (not org-lparse-to-buffer)
+      (message "Embedding %s as %s ..."
+	       (substring-no-properties path) target-file)
+
+	(make-directory target-dir)
+	(org-odt-create-manifest-file-entry
+	 "application/vnd.oasis.opendocument.formula" target-dir "1.2")
+
+	(copy-file src-file target-file 'overwrite)
+	(org-odt-create-manifest-file-entry "text/xml" target-file))
+    target-file))
+
+(defun org-odt-format-inline-formula (thefile)
+  (let* ((thelink (if (file-name-absolute-p thefile) thefile
+		    (org-xml-format-href
+		     (org-odt-relocate-relative-path
+		      thefile org-current-export-file))))
+	 (href
+	  (org-odt-format-tags
+	   "<draw:object xlink:href=\"%s\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\"/>" ""
+	   (file-name-directory (org-odt-copy-formula-file thefile)))))
+    (org-export-odt-format-formula thefile href)))
+
+(defun org-odt-is-formula-link-p (file)
+  (member (downcase (file-name-extension file)) '("mathml")))
+
 (defun org-odt-format-org-link (opt-plist type-1 path fragment desc attr
 					  descp)
   "Make an HTML link.
@@ -1080,7 +1119,6 @@ FRAGMENT is the fragment part of the link, if any (foo.html#THIS)
 DESC is the link description, if any.
 ATTR is a string of other attributes of the a element.
 MAY-INLINE-P allows inlining it as an image."
-
   (declare (special org-lparse-par-open))
   (save-match-data
     (let* ((may-inline-p
@@ -1090,7 +1128,6 @@ MAY-INLINE-P allows inlining it as an image."
 	   (type (if (equal type-1 "id") "file" type-1))
 	   (filename path)
 	   (thefile path))
-
       (cond
        ;; check for inlined images
        ((and (member type '("file"))
@@ -1099,12 +1136,13 @@ MAY-INLINE-P allows inlining it as an image."
 	      filename org-odt-export-inline-image-extensions)
 	     (or (eq t org-odt-export-inline-images)
 		 (and org-odt-export-inline-images (not descp))))
-
-	;; (when (and (string= type "file") (file-name-absolute-p path))
-	;;   (setq thefile (concat "file://" (expand-file-name path))))
-	;; (setq thefile (org-xml-format-href thefile))
-	;; (org-export-html-format-image thefile)
 	(org-odt-format-inline-image thefile))
+       ;; check for embedded formulas
+       ((and (member type '("file"))
+	     (not fragment)
+	     (org-odt-is-formula-link-p filename)
+	     (or (not descp)))
+	(org-odt-format-inline-formula thefile))
        (t
 	(when (string= type "file")
 	  (setq thefile
@@ -1201,33 +1239,46 @@ MAY-INLINE-P allows inlining it as an image."
    (expand-file-name
     (concat (sha1 file-name) "." (file-name-extension file-name)) "Pictures")))
 
-(defun org-export-odt-format-image (src href)
+(defun org-export-odt-format-image (src href &optional embed-as)
   "Create image tag with source and attributes."
   (save-match-data
     (let* ((caption (org-find-text-property-in-string 'org-caption src))
 	   (caption (and caption (org-xml-format-desc caption)))
 	   (attr (org-find-text-property-in-string 'org-attributes src))
 	   (label (org-find-text-property-in-string 'org-label src))
-	   (embed-as (if (string-match "^ltxpng/" src) 'character 'paragraph))
+	   (embed-as (or embed-as
+			 (if (org-find-text-property-in-string
+			      'org-latex-src src)
+			     (or (org-find-text-property-in-string
+				  'org-latex-src-embed-type src) 'character)
+			   'paragraph)))
 	   (attr-plist (when attr (read  attr)))
 	   (size (org-odt-image-size-from-file
 		  src (plist-get attr-plist :width)
 		  (plist-get attr-plist :height)
 		  (plist-get attr-plist :scale) nil embed-as)))
       (org-export-odt-do-format-image
-       embed-as caption attr label size href))))
-
-(defun org-odt-format-textbox (text style)
-  (let ((draw-frame-pair
-	 '("<draw:frame draw:style-name=\"%s\"
-              text:anchor-type=\"paragraph\"
-              style:rel-width=\"100%%\"
-              draw:z-index=\"0\">" . "</draw:frame>")))
+       embed-as caption attr label (car size) (cdr size) href))))
+
+(defun org-odt-format-frame (text style &optional
+				  width height extra anchor-type)
+  (let ((frame-attrs
+	 (concat
+	  (if width (format " svg:width=\"%0.2fcm\"" width) "")
+	  (if height (format " svg:height=\"%0.2fcm\"" height) "")
+	  extra
+	  (format " text:anchor-type=\"%s\"" (or anchor-type "paragraph")))))
     (org-odt-format-tags
-     draw-frame-pair
-     (org-odt-format-tags
-      '("<draw:text-box fo:min-height=\"%dcm\">" . "</draw:text-box>")
-      text 0) style)))
+     '("<draw:frame draw:style-name=\"%s\"%s>" . "</draw:frame>")
+     text style frame-attrs)))
+
+(defun org-odt-format-textbox (text style &optional width height extra)
+  (org-odt-format-frame
+   (org-odt-format-tags
+    '("<draw:text-box %s>" . "</draw:text-box>")
+    text (concat (format " fo:min-height=\"%0.2fcm\"" (or height .2))
+		 (format " fo:min-width=\"%0.2fcm\"" (or width .2))))
+   style width nil extra))
 
 (defun org-odt-format-inlinetask (heading content
 					  &optional todo priority tags)
@@ -1238,103 +1289,56 @@ MAY-INLINE-P allows inlining it as an image."
 		 (org-lparse-format
 		  'HEADLINE (concat (org-lparse-format-todo todo) " " heading)
 		  nil tags))
-		content) "OrgInlineTaskFrame")))
-
+		content) "OrgInlineTaskFrame" nil nil " style:rel-width=\"100%\"")))
 (defun org-export-odt-do-format-image (embed-as caption attr label
-						size href)
+						width height href)
   "Create image tag with source and attributes."
   (save-match-data
-    (let ((width (car size)) (height (cdr size))
-	  (draw-frame-pair
-	   '("<draw:frame draw:style-name=\"%s\"
-              text:anchor-type=\"%s\"
-              draw:z-index=\"%d\" %s>" . "</draw:frame>")))
-      (cond
-       ((and (not caption) (not label))
-	(let (style-name anchor-type)
-	  (cond
-	   ((eq embed-as 'paragraph)
-	    (setq style-name  "OrgGraphicsParagraph" anchor-type "paragraph"))
-	   ((eq embed-as 'character)
-	    (setq style-name  "OrgGraphicsBaseline" anchor-type "as-char")))
-	  (org-odt-format-tags
-	   draw-frame-pair href style-name anchor-type 0
-	   (org-odt-image-attrs-from-size width height))))
-
-       (t
-	(concat
-	 ;; (when par-open (org-odt-close-par))
-	 (org-odt-format-tags
-	  draw-frame-pair
-	  (org-odt-format-tags
-	   '("<draw:text-box fo:min-height=\"%dcm\">" . "</draw:text-box>")
-	   (org-odt-format-stylized-paragraph
-	    'illustration
-	    (concat
-	     (let ((extra " style:rel-width=\"100%\" style:rel-height=\"scale\""))
-	       (org-odt-format-tags
-		draw-frame-pair href "OrgGraphicsParagraphContent" "paragraph" 2
-		(concat (org-odt-image-attrs-from-size width height) extra)))
-	     (org-odt-format-entity-caption label caption)))
-	   height)
-	  "OrgFrame" "paragraph" 1
-	  (org-odt-image-attrs-from-size width))
-
-	 ;; (when par-open (org-odt-open-par))
-	 ))))))
-
-;; xml files generated on-the-fly
-(defconst org-export-odt-save-list
-  '("mimetype" "META-INF/manifest.xml" "content.xml" "meta.xml" "styles.xml"))
-
-;; xml files that are copied
-(defconst org-export-odt-nosave-list '())
-
-;; xml files that contribute to the final odt file
-(defvar org-export-odt-file-list nil)
-
-(defconst org-export-odt-manifest-lines
-  '(("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-     "<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\" manifest:version=\"1.2\">"
-     "<manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.text\" manifest:version=\"1.2\" manifest:full-path=\"/\"/>"
-     "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/>"
-     "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"styles.xml\"/>"
-     "<manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"meta.xml\"/>"
-     "<manifest:file-entry manifest:media-type=\"\" manifest:full-path=\"Pictures/\"/>") . ("</manifest:manifest>")))
-
-(defconst org-export-odt-meta-lines
-  '(("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-     "<office:document-meta"
-     "    xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\""
-     "    xmlns:xlink=\"http://www.w3.org/1999/xlink\""
-     "    xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
-     "    xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\""
-     "    xmlns:ooo=\"http://openoffice.org/2004/office\" "
-     "    office:version=\"1.2\">"
-     "  <office:meta>") . ("  </office:meta>" "</office:document-meta>")))
-
-(defun org-odt-copy-image-file (path &optional target-file)
+    (cond
+     ((and (not caption) (not label))
+      (let (style-name anchor-type)
+	(case embed-as
+	  (paragraph
+	   (setq style-name  "OrgSimpleGraphics" anchor-type "paragraph"))
+	  (character
+	   (setq style-name  "OrgInlineGraphics" anchor-type "as-char"))
+	  (t
+	   (error "Unknown value for embed-as %S" embed-as)))
+	(org-odt-format-frame href style-name width height nil anchor-type)))
+     (t
+      (concat
+       (org-odt-format-textbox
+	(org-odt-format-stylized-paragraph
+	 'illustration
+	 (concat
+	  (let ((extra " style:rel-width=\"100%\" style:rel-height=\"scale\""))
+	    (org-odt-format-frame
+	     href "OrgCaptionedGraphics" width height extra "paragraph"))
+	  (org-odt-format-entity-caption label caption)))
+	"OrgCaptionFrame" width height))))))
+
+(defvar org-odt-embedded-images-count 0)
+(defun org-odt-copy-image-file (path)
   "Returns the internal name of the file"
   (let* ((image-type (file-name-extension path))
 	 (media-type (format "image/%s" image-type))
 	 (src-file (expand-file-name
 		    path (file-name-directory org-current-export-file)))
-	 (target-file (or target-file (org-odt-get-image-name src-file)))
-	 ;; FIXME
-	 (body-only nil))
-
+	 (target-dir "Images/")
+	 (target-file
+	  (format "%s%04d.%s" target-dir
+		  (incf org-odt-embedded-images-count) image-type)))
     (when (not org-lparse-to-buffer)
       (message "Embedding %s as %s ..."
 	       (substring-no-properties path) target-file)
-      (copy-file src-file target-file 'overwrite)
-      (org-odt-update-manifest-file media-type target-file)
-      (push target-file org-export-odt-file-list)) target-file))
 
-(defun org-odt-image-attrs-from-size (&optional width height)
-  (concat
-   (when width (format "svg:width=\"%0.2fcm\""  width))
-   " "
-   (when height (format "svg:height=\"%0.2fcm\""  height))))
+      (when (= 1 org-odt-embedded-images-count)
+	(make-directory target-dir)
+	(org-odt-create-manifest-file-entry "" target-dir))
+
+      (copy-file src-file target-file 'overwrite)
+      (org-odt-create-manifest-file-entry media-type target-file))
+    target-file))
 
 (defvar org-export-odt-image-size-probe-method
   '(emacs imagemagick force)
@@ -1422,57 +1426,20 @@ MAY-INLINE-P allows inlining it as an image."
 (defun org-odt-init-outfile (filename)
   (unless (executable-find "zip")
     ;; Not at all OSes ship with zip by default
-    (error "Executable \"zip\" needed for creating OpenDocument files. Aborting."))
+    (error "Executable \"zip\" needed for creating OpenDocument files"))
 
   (let* ((outdir (make-temp-file org-export-odt-tmpdir-prefix t))
-	 (mimetype-file (expand-file-name "mimetype" outdir))
-	 (content-file (expand-file-name "content.xml" outdir))
-	 (manifest-file (expand-file-name "META-INF/manifest.xml" outdir))
-	 (meta-file (expand-file-name "meta.xml" outdir))
-	 (styles-file (expand-file-name "styles.xml" outdir))
-	 (pictures-dir (expand-file-name "Pictures" outdir))
-	 (body-only nil))
-
-    ;; content file
-    (with-current-buffer (find-file-noselect content-file t)
-      (erase-buffer))
-
-    ;; FIXME: How to factor in body-only here
-    (unless body-only
-      ;; manifest file
-      (make-directory (file-name-directory manifest-file))
-      (with-current-buffer (find-file-noselect manifest-file t)
-	(erase-buffer)
-	(insert (mapconcat 'identity (car org-export-odt-manifest-lines) "\n"))
-	(insert "\n")
-	(save-excursion
-	  (insert (mapconcat 'identity (cdr org-export-odt-manifest-lines) "\n"))))
-
-    ;; meta file
-    (with-current-buffer (find-file-noselect meta-file t)
-      (erase-buffer)
-      (insert (mapconcat 'identity (car org-export-odt-meta-lines) "\n"))
-      (insert "\n")
-      (save-excursion
-	(insert (mapconcat 'identity (cdr org-export-odt-meta-lines) "\n"))))
-
-    ;; mimetype
-    (with-current-buffer (find-file-noselect mimetype-file t)
-      (insert "application/vnd.oasis.opendocument.text"))
-
-    ;; styles file
-    ;; (copy-file org-export-odt-styles-file styles-file t)
-
-    ;; Pictures dir
-    (make-directory pictures-dir)
-
-    ;; initialize list of files that contribute to the odt file
-    (setq org-export-odt-file-list
-	  (append org-export-odt-save-list org-export-odt-nosave-list)))
-    content-file))
+	 (content-file (expand-file-name "content.xml" outdir)))
 
-(defconst org-odt-manifest-file-entry-tag
-  "<manifest:file-entry manifest:media-type=\"%s\" manifest:full-path=\"%s\"/>")
+    ;; init conten.xml
+    (with-current-buffer (find-file-noselect content-file t))
+
+    ;; reset variables
+    (setq org-odt-manifest-file-entries nil
+	  org-odt-embedded-images-count 0
+	  org-odt-embedded-formulas-count 0)
+
+    content-file))
 
 (defcustom org-export-odt-prettify-xml nil
   "Specify whether or not the xml output should be prettified.
@@ -1485,6 +1452,10 @@ visually."
 
 (defvar hfy-user-sheet-assoc)		; bound during org-do-lparse
 (defun org-odt-save-as-outfile (target opt-plist)
+  ;; create mimetype file
+  (write-region "application/vnd.oasis.opendocument.text" nil
+		(expand-file-name "mimetype"))
+
   ;; write meta file
   (org-odt-update-meta-file opt-plist)
 
@@ -1517,7 +1488,18 @@ visually."
       (format " %s\n" (cddr style)))
     hfy-user-sheet-assoc ""))
 
-  (let ((zipdir default-directory))
+  ;; create a manifest entry for content.xml
+  (org-odt-create-manifest-file-entry
+   "application/vnd.oasis.opendocument.text" "/" "1.2")
+
+  (org-odt-create-manifest-file-entry "text/xml" "content.xml")
+
+  ;; write out the manifest entries before zipping
+  (org-odt-write-manifest-file)
+
+  (let ((xml-files '("mimetype" "META-INF/manifest.xml" "content.xml"
+		     "meta.xml" "styles.xml"))
+	(zipdir default-directory))
     (message "Switching to directory %s" (expand-file-name zipdir))
 
     ;; save all xml files
@@ -1527,8 +1509,8 @@ visually."
 	      ;; prettify output if needed
 	      (when org-export-odt-prettify-xml
 		(indent-region (point-min) (point-max)))
-	      (save-buffer)))
-	  org-export-odt-save-list)
+	      (save-buffer 0)))
+	  xml-files)
 
     (let* ((target-name (file-name-nondirectory target))
 	   (target-dir (file-name-directory target))
@@ -1556,7 +1538,7 @@ visually."
       (mapc (lambda (file)
 	      (kill-buffer
 	       (find-file-noselect (expand-file-name file zipdir) t)))
-	    org-export-odt-save-list)
+	    xml-files)
 
       (delete-directory zipdir)))
 
@@ -1587,39 +1569,75 @@ visually."
       date)
      (t
       ;; ISO 8601 format
-      (format-time-string "%Y-%m-%dT%T%:z")))))
+      (let ((stamp (format-time-string "%Y-%m-%dT%H:%M:%S%z")))
+	(format "%s:%s" (substring stamp 0 -2) (substring stamp -2)))))))
 
-(defun org-odt-update-meta-file (opt-plist)
-  (with-current-buffer
-      (find-file-noselect (expand-file-name "meta.xml") t)
-    (let ((date (org-odt-format-date (plist-get opt-plist :date)))
-	  (author (or (plist-get opt-plist :author) ""))
-	  (email (plist-get opt-plist :email))
-	  (keywords (plist-get opt-plist :keywords))
-	  (description (plist-get opt-plist :description))
-	  (title (plist-get opt-plist :title)))
+(defconst org-odt-manifest-file-entry-tag
+  "
+<manifest:file-entry manifest:media-type=\"%s\" manifest:full-path=\"%s\"%s/>")
+
+(defvar org-odt-manifest-file-entries nil)
+
+(defun org-odt-create-manifest-file-entry (&rest args)
+  (push args org-odt-manifest-file-entries))
+
+(defun org-odt-write-manifest-file ()
+  (make-directory "META-INF")
+  (let ((manifest-file (expand-file-name "META-INF/manifest.xml")))
+    (write-region
+     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+     <manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\" manifest:version=\"1.2\">\n"
+     nil manifest-file)
+    (mapc
+     (lambda (file-entry)
+       (let* ((version (nth 2 file-entry))
+	      (extra (if version
+			 (format  " manifest:version=\"%s\"" version)
+		       "")))
+	 (write-region
+	  (format org-odt-manifest-file-entry-tag
+		  (nth 0 file-entry) (nth 1 file-entry) extra)
+	  nil manifest-file t))) org-odt-manifest-file-entries)
+    (write-region "\n</manifest:manifest>" nil manifest-file t)))
 
-      (insert
-       "\n"
-       (org-odt-format-tags '("<dc:creator>" . "</dc:creator>") author)
-       (org-odt-format-tags
-	'("\n<meta:initial-creator>" . "</meta:initial-creator>") author)
-       (org-odt-format-tags '("\n<dc:date>" . "</dc:date>") date)
-       (org-odt-format-tags
-	'("\n<meta:creation-date>" . "</meta:creation-date>") date)
-       (org-odt-format-tags '("\n<meta:generator>" . "</meta:generator>")
-			     (when org-export-creator-info
-			       (format "Org-%s/Emacs-%s"
-				       org-version emacs-version)))
-       (org-odt-format-tags '("\n<meta:keyword>" . "</meta:keyword>") keywords)
-       (org-odt-format-tags '("\n<dc:subject>" . "</dc:subject>") description)
-       (org-odt-format-tags '("\n<dc:title>" . "</dc:title>") title)
-       "\n"))))
-
-(defun org-odt-update-manifest-file (media-type full-path)
-  (with-current-buffer
-      (find-file-noselect (expand-file-name "META-INF/manifest.xml") t)
-    (insert (format org-odt-manifest-file-entry-tag media-type full-path))))
+(defun org-odt-update-meta-file (opt-plist)
+  (let ((date (org-odt-format-date (plist-get opt-plist :date)))
+	(author (or (plist-get opt-plist :author) ""))
+	(email (plist-get opt-plist :email))
+	(keywords (plist-get opt-plist :keywords))
+	(description (plist-get opt-plist :description))
+	(title (plist-get opt-plist :title)))
+
+    (write-region
+     (concat
+      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+     <office:document-meta
+         xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"
+         xmlns:xlink=\"http://www.w3.org/1999/xlink\"
+         xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
+         xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"
+         xmlns:ooo=\"http://openoffice.org/2004/office\"
+         office:version=\"1.2\">
+       <office:meta>" "\n"
+      (org-odt-format-tags '("<dc:creator>" . "</dc:creator>") author)
+      (org-odt-format-tags
+       '("\n<meta:initial-creator>" . "</meta:initial-creator>") author)
+      (org-odt-format-tags '("\n<dc:date>" . "</dc:date>") date)
+      (org-odt-format-tags
+       '("\n<meta:creation-date>" . "</meta:creation-date>") date)
+      (org-odt-format-tags '("\n<meta:generator>" . "</meta:generator>")
+			   (when org-export-creator-info
+			     (format "Org-%s/Emacs-%s"
+				     org-version emacs-version)))
+      (org-odt-format-tags '("\n<meta:keyword>" . "</meta:keyword>") keywords)
+      (org-odt-format-tags '("\n<dc:subject>" . "</dc:subject>") description)
+      (org-odt-format-tags '("\n<dc:title>" . "</dc:title>") title)
+      "\n"
+      "  </office:meta>" "</office:document-meta>")
+     nil (expand-file-name "meta.xml")))
+
+  ;; create a manifest entry for meta.xml
+  (org-odt-create-manifest-file-entry "text/xml" "meta.xml"))
 
 (defun org-odt-finalize-outfile ()
   (org-odt-delete-empty-paragraphs))
@@ -1668,24 +1686,32 @@ visually."
 (defun org-export-odt-do-preprocess-latex-fragments ()
   "Convert LaTeX fragments to images."
   (let* ((latex-frag-opt (plist-get org-lparse-opt-plist :LaTeX-fragments))
-	 (latex-frag-opt-1		;  massage the options
+	 (latex-frag-opt		;  massage the options
 	  (or (and (member latex-frag-opt '(mathjax t))
+		   (not (and (fboundp 'org-format-latex-mathml-available-p)
+			     (org-format-latex-mathml-available-p)))
 		   (prog1 org-lparse-latex-fragment-fallback
 		     (org-lparse-warn
 		      (concat
-		       "Use of MathJax is incompatible with ODT exporter. "
+		       "LaTeX to MathML converter not available. "
 		       (format "Using %S instead."
 			       org-lparse-latex-fragment-fallback)))))
-	      latex-frag-opt)))
-    (when (and org-current-export-file latex-frag-opt-1)
-      ;; Investigate MathToWeb for converting TeX equations to MathML
-      ;; http://lists.gnu.org/archive/html/emacs-orgmode/2011-03/msg01755.html
+	      latex-frag-opt))
+	 cache-dir display-msg)
+    (cond
+     ((eq latex-frag-opt 'dvipng)
+      (setq cache-dir "ltxpng/")
+      (setq display-msg "Creating LaTeX image %s"))
+     ((member latex-frag-opt '(mathjax t))
+      (setq latex-frag-opt 'mathml)
+      (setq cache-dir "ltxmathml/")
+      (setq display-msg "Creating MathML formula %s")))
+    (when (and org-current-export-file)
       (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"
-       nil nil latex-frag-opt-1))))
+       (concat cache-dir (file-name-sans-extension
+			  (file-name-nondirectory org-current-export-file)))
+       org-current-export-dir nil display-msg
+       nil nil latex-frag-opt))))
 
 (defun org-export-odt-preprocess-latex-fragments ()
   (when (equal org-export-current-backend 'odt)
@@ -1760,7 +1786,7 @@ visually."
 	 (when (org-file-image-p member)
 	   (let* ((image-type (file-name-extension member))
 		  (media-type (format "image/%s" image-type)))
-	     (org-odt-update-manifest-file media-type member))))
+	     (org-odt-create-manifest-file-entry media-type member))))
        members)))
    ((and (stringp styles-file) (file-exists-p styles-file))
     (let ((styles-file-type (file-name-extension styles-file)))
@@ -1771,7 +1797,10 @@ visually."
 	(org-odt-zip-extract styles-file "styles.xml")))))
    (t
     (error (format "Invalid specification of styles.xml file: %S"
-		   org-export-odt-styles-file)))))
+		   org-export-odt-styles-file))))
+
+  ;; create a manifest entry for styles.xml
+  (org-odt-create-manifest-file-entry "text/xml" "styles.xml"))
 
 (defvar org-export-odt-factory-settings
   "d4328fb9d1b6cb211d4320ff546829f26700dc5e"

+ 5 - 3
contrib/lisp/org-xhtml.el

@@ -1524,7 +1524,8 @@ lang=\"%s\" xml:lang=\"%s\">
 	     "")
 
 	   (let* ((align (aref org-lparse-table-colalign-vector c))
-		  (alignspec (if org-xhtml-format-table-no-css
+		  (alignspec (if (and (boundp 'org-xhtml-format-table-no-css)
+				      org-xhtml-format-table-no-css)
 				 " align=\"%s\"" " class=\"%s\""))
 		  (extra (format alignspec  align)))
 	     (format "<col%s />" extra))
@@ -1541,8 +1542,9 @@ lang=\"%s\" xml:lang=\"%s\">
       (let ((c (string-to-number (match-string 1))))
 	(replace-match
 	 (if org-export-xhtml-table-align-individual-fields
-	     (format (if org-xhtml-format-table-no-css " align=\"%s\""
-		       " class=\"%s\"")
+	     (format (if (and (boundp 'org-xhtml-format-table-no-css)
+			      org-xhtml-format-table-no-css)
+			 " align=\"%s\"" " class=\"%s\"")
 		     (or (aref org-lparse-table-colalign-vector c) "left")) "")
 	 t t)))
     (goto-char (point-max)))

+ 64 - 103
contrib/odt/styles/OrgOdtAutomaticStyles.xml

@@ -1,3 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document-content
+    xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
+    xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
+    xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
+    xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
+    xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
+    xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
+    xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
+    xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
+    xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
+    xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
+    xmlns:math="http://www.w3.org/1998/Math/MathML"
+    xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
+    xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
+    xmlns:ooo="http://openoffice.org/2004/office"
+    xmlns:ooow="http://openoffice.org/2004/writer"
+    xmlns:oooc="http://openoffice.org/2004/calc"
+    xmlns:dom="http://www.w3.org/2001/xml-events"
+    xmlns:xforms="http://www.w3.org/2002/xforms"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:rpt="http://openoffice.org/2005/report"
+    xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"
+    xmlns:xodt="http://www.w3.org/1999/xodt"
+    xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"    office:version="1.2">
   <!-- scripts -->
   <office:scripts/>
 
@@ -16,142 +45,74 @@
 
   <!-- automatic styles -->
   <office:automatic-styles>
-  <style:style style:name="OrgTable" style:family="table">
-   <style:table-properties style:rel-width="90%" table:align="center"/>
-  </style:style>
+    <style:style style:name="OrgTable" style:family="table">
+      <style:table-properties style:rel-width="90%" table:align="center"/>
+    </style:style>
 
-  <style:style style:name="OrgTableColumn" style:family="table-column">
-   <style:table-column-properties style:rel-column-width="1*"/>
-  </style:style>
+    <style:style style:name="OrgTableColumn" style:family="table-column">
+      <style:table-column-properties style:rel-column-width="1*"/>
+    </style:style>
 
-  <style:style style:name="OrgTblCell" style:family="table-cell">
+    <style:style style:name="OrgTblCell" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="none" fo:border-left="none" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellL" style:family="table-cell">
+    <style:style style:name="OrgTblCellL" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="none" fo:border-left="0.035cm solid #808080" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellR" style:family="table-cell">
+    <style:style style:name="OrgTblCellR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="none" fo:border-left="none" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-  <style:style style:name="OrgTblCellLR" style:family="table-cell">
+    <style:style style:name="OrgTblCellLR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="none" fo:border-left="0.035cm solid #808080" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-  <style:style style:name="OrgTblCellT" style:family="table-cell">
+    <style:style style:name="OrgTblCellT" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="none" fo:border-left="none" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellTL" style:family="table-cell">
+    <style:style style:name="OrgTblCellTL" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="none" fo:border-left="0.035cm solid #808080" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellTR" style:family="table-cell">
+    <style:style style:name="OrgTblCellTR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="none" fo:border-left="none" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-  <style:style style:name="OrgTblCellTLR" style:family="table-cell">
+    <style:style style:name="OrgTblCellTLR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="none" fo:border-left="0.035cm solid #808080" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-  <style:style style:name="OrgTblCellB" style:family="table-cell">
+    <style:style style:name="OrgTblCellB" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.035cm solid #808080" fo:border-left="none" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellBL" style:family="table-cell">
+    <style:style style:name="OrgTblCellBL" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.035cm solid #808080" fo:border-left="0.035cm solid #808080" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellBR" style:family="table-cell">
+    <style:style style:name="OrgTblCellBR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.035cm solid #808080" fo:border-left="none" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-  <style:style style:name="OrgTblCellBLR" style:family="table-cell">
+    <style:style style:name="OrgTblCellBLR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.035cm solid #808080" fo:border-left="0.035cm solid #808080" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-  <style:style style:name="OrgTblCellTB" style:family="table-cell">
+    <style:style style:name="OrgTblCellTB" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="0.035cm solid #808080" fo:border-left="none" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellTBL" style:family="table-cell">
+    <style:style style:name="OrgTblCellTBL" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="0.035cm solid #808080" fo:border-left="0.035cm solid #808080" fo:border-right="none"/>
     </style:style>
-  <style:style style:name="OrgTblCellTBR" style:family="table-cell">
+    <style:style style:name="OrgTblCellTBR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="0.035cm solid #808080" fo:border-left="none" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-  <style:style style:name="OrgTblCellTBLR" style:family="table-cell">
+    <style:style style:name="OrgTblCellTBLR" style:family="table-cell">
       <style:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.035cm solid #808080" fo:border-bottom="0.035cm solid #808080" fo:border-left="0.035cm solid #808080" fo:border-right="0.035cm solid #808080"/>
     </style:style>
-    <style:style style:name="OrgFrame" 
-		 style:family="graphic" 
-		 style:parent-style-name="Frame">
-      <style:graphic-properties fo:margin-left="0cm" 
-				fo:margin-right="0cm" 
-				fo:margin-top="0cm" 
-				fo:margin-bottom="0cm" 
-				style:run-through="foreground" 
-				style:wrap="none" 
-				style:vertical-pos="top" 
-				style:vertical-rel="paragraph" 
-				style:horizontal-pos="center" 
-				style:horizontal-rel="paragraph" 
-				fo:padding="0cm" fo:border="none" 
-				style:shadow="none"/>
-    </style:style>
-
-    <style:style style:name="OrgGraphicsParagraphContent" 
-		 style:family="graphic" 
-		 style:parent-style-name="Graphics">
-      <style:graphic-properties fo:margin-left="0cm" 
-				fo:margin-right="0cm" 
-				fo:margin-top="0cm" 
-				fo:margin-bottom="0cm" 
-				style:run-through="foreground" 
-				style:wrap="none" 
-				style:vertical-pos="from-top" 
-				style:vertical-rel="paragraph-content" 
-				style:horizontal-pos="from-left" 
-				style:horizontal-rel="paragraph-content" 
-				fo:padding="0cm" 
-				fo:border="none" 
-				style:shadow="none" 
-				style:mirror="none" 
-				fo:clip="rect(0cm, 0cm, 0cm, 0cm)" 
-				draw:luminance="0%" 
-				draw:contrast="0%" 
-				draw:red="0%" 
-				draw:green="0%" 
-				draw:blue="0%" 
-				draw:gamma="100%" 
-				draw:color-inversion="false" 
-				draw:image-opacity="100%" 
-				draw:color-mode="standard"/>
-    </style:style>
+  </office:automatic-styles>
 
-    <style:style style:name="OrgGraphicsBaseline" 
-		 style:family="graphic" 
-		 style:parent-style-name="Graphics">
-      <style:graphic-properties style:vertical-pos="top" 
-				style:vertical-rel="baseline" 
-				style:mirror="none" 
-				fo:clip="rect(0cm, 0cm, 0cm, 0cm)" 
-				draw:luminance="0%" 
-				draw:contrast="0%" 
-				draw:red="0%" 
-				draw:green="0%" 
-				draw:blue="0%" 
-				draw:gamma="100%" 
-				draw:color-inversion="false" 
-				draw:image-opacity="100%" 
-				draw:color-mode="standard"/>
-    </style:style>
+  <office:body>
+    <office:text>
+      <text:sequence-decls>
+	<text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
+	<text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+	<text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+	<text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+	<text:sequence-decl text:display-outline-level="0" text:name="Equation"/>
+      </text:sequence-decls>
 
-    <style:style style:name="OrgGraphicsParagraph" 
-		 style:family="graphic" 
-		 style:parent-style-name="Graphics">
-      <style:graphic-properties style:horizontal-pos="center" 
-				style:horizontal-rel="paragraph" 
-				style:mirror="none" 
-				fo:clip="rect(0cm, 0cm, 0cm, 0cm)" 
-				draw:luminance="0%" 
-				draw:contrast="0%" 
-				draw:red="0%" 
-				draw:green="0%" 
-				draw:blue="0%" 
-				draw:gamma="100%" 
-				draw:color-inversion="false" 
-				draw:image-opacity="100%" 
-				draw:color-mode="standard"/>
-    </style:style>
-
-  </office:automatic-styles>
+    </office:text>
+  </office:body>
+</office:document-content>

+ 24 - 0
contrib/odt/styles/OrgOdtStyles.xml

@@ -362,6 +362,30 @@
    <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" fo:margin-left="0.201cm" fo:margin-right="0.201cm" fo:margin-top="0.201cm" fo:margin-bottom="0.201cm" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" fo:padding="0.15cm" fo:border="0.002cm solid #000000"/>
   </style:style>
 
+  <!-- Simple Images   -->
+  <style:style style:name="OrgSimpleGraphics" style:family="graphic" style:parent-style-name="Graphics">
+   <style:graphic-properties text:anchor-type="paragraph" style:wrap="none" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph"/>
+  </style:style>
+
+  <!-- Captioned Images  -->
+  <style:style style:name="OrgCaptionedGraphics" style:family="graphic" style:parent-style-name="Graphics">
+   <style:graphic-properties style:rel-width="100%" text:anchor-type="paragraph" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:run-through="foreground" style:wrap="none" style:vertical-pos="from-top" style:vertical-rel="paragraph-content" style:horizontal-pos="from-left" style:horizontal-rel="paragraph-content" fo:padding="0cm" fo:border="none" style:shadow="none"/>
+  </style:style>
+
+  <style:style style:name="OrgCaptionFrame" style:family="graphic" style:parent-style-name="Frame">
+   <style:graphic-properties text:anchor-type="paragraph" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:wrap="none" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph" fo:padding="0cm" fo:border="none"/>
+  </style:style>
+
+  <!-- Inlined Images -->
+  <style:style style:name="OrgInlineGraphics" style:family="graphic" style:parent-style-name="Graphics">
+   <style:graphic-properties text:anchor-type="as-char" style:vertical-pos="top" style:vertical-rel="baseline" style:horizontal-pos="center" style:horizontal-rel="paragraph"/>
+  </style:style>
+
+  <!-- Inline Formula -->
+  <style:style style:name="OrgInlineFormula" style:family="graphic" style:parent-style-name="Formula">
+    <style:graphic-properties text:anchor-type="as-char" fo:margin-left="0.201cm" fo:margin-right="0.201cm" style:vertical-pos="middle" style:vertical-rel="text"/>
+  </style:style>
+
   <!-- Inline Tasks -->
   <style:style style:name="OrgInlineTaskHeading" style:family="paragraph" style:parent-style-name="Caption" style:next-style-name="Text_20_body">
    <style:text-properties style:font-name="Arial1" fo:font-style="normal" fo:font-weight="bold"/>

+ 1 - 1
lisp/ob-R.el

@@ -294,7 +294,7 @@ last statement in BODY, as elisp."
 	      (mapcar
 	       (lambda (line) ;; cleanup extra prompts left in output
 		 (if (string-match
-		      "^\\([ ]*[>+][ ]?\\)+\\([[0-9]+\\|[ ]\\)" line)
+		      "^\\([ ]*[>+\\.][ ]?\\)+\\([[0-9]+\\|[ ]\\)" line)
 		     (substring line (match-end 1))
 		   line))
 	       (org-babel-comint-with-output (session org-babel-R-eoe-output)

+ 64 - 23
lisp/ob.el

@@ -159,6 +159,39 @@ not match KEY should be returned."
 	 (lambda (p) (when (funcall (if others #'not #'identity) (eq (car p) key)) p))
 	 params)))
 
+(defun org-babel-get-inline-src-block-matches()
+  "Set match data if within body of an inline source block.
+Returns non-nil if match-data set"
+  (let ((src-at-0-p (save-excursion
+		      (beginning-of-line 1)
+		      (string= "src" (thing-at-point 'word))))
+	(first-line-p (= 1 (line-number-at-pos)))
+	(orig (point)))
+    (let ((search-for (cond ((and src-at-0-p first-line-p  "src_"))
+			    (first-line-p "[ \t]src_")
+			    (t "[ \f\t\n\r\v]src_")))
+	  (lower-limit (if first-line-p
+			   nil
+			 (- (point-at-bol) 1))))
+      (save-excursion
+	(when (or (and src-at-0-p (bobp))
+		  (and (re-search-forward "}" (point-at-eol) t)
+		       (re-search-backward search-for lower-limit t)
+		       (> orig (point))))
+	  (when (looking-at org-babel-inline-src-block-regexp)
+	    t ))))))
+
+(defun org-babel-get-lob-one-liner-matches()
+  "Set match data if on line of an lob one liner.
+Returns non-nil if match-data set"
+
+  (save-excursion
+    (unless (= (point) (point-at-bol)) ;; move before inline block
+      (re-search-backward "[ \f\t\n\r\v]" nil t))
+    (if (looking-at org-babel-inline-lob-one-liner-regexp)
+	t
+      nil)))
+
 (defun org-babel-get-src-block-info (&optional light)
   "Get information on the current source block.
 
@@ -191,8 +224,7 @@ Returns a list
 			     (org-babel-ref-split-args (match-string 6)))
 		     (nth 2 info))))))
       ;; inline source block
-      (when (save-excursion (re-search-backward "[ \f\t\n\r\v]" nil t)
-			    (looking-at org-babel-inline-src-block-regexp))
+      (when (org-babel-get-inline-src-block-matches)
 	(setq info (org-babel-parse-inline-src-block-match))))
     ;; resolve variable references and add summary parameters
     (when (and info (not light))
@@ -989,9 +1021,10 @@ may be specified in the current buffer."
          (body (org-babel-clean-text-properties
 		(let* ((body (match-string 5))
 		       (sub-length (- (length body) 1)))
-		  (if (string= "\n" (substring body sub-length))
+		  (if (and (> sub-length 0)
+			   (string= "\n" (substring body sub-length)))
 		      (substring body 0 sub-length)
-		    body))))
+		    (or body "")))))
 	 (preserve-indentation (or org-src-preserve-indentation
 				   (string-match "-i\\>" switches))))
     (list lang
@@ -1334,6 +1367,8 @@ is created.  In both cases if the region is demarcated and if the
 region is not active then the point is demarcated."
   (interactive "P")
   (let ((info (org-babel-get-src-block-info 'light))
+	(headers (progn (org-babel-where-is-src-block-head)
+			(match-string 4)))
 	(stars (concat (make-string (or (org-current-level) 1) ?*) " ")))
     (if info
         (mapc
@@ -1346,11 +1381,16 @@ region is not active then the point is demarcated."
 				   (buffer-substring (point-at-bol)
 						     (point-at-eol)))
 		 (delete-region (point-at-bol) (point-at-eol)))
-               (insert (concat (if (looking-at "^") "" "\n")
-                               indent "#+end_src\n"
-                               (if arg stars indent) "\n"
-                               indent "#+begin_src " lang
-                               (if (looking-at "[\n\r]") "" "\n")))))
+               (insert (concat
+			(if (looking-at "^") "" "\n")
+			indent "#+end_src\n"
+			(if arg stars indent) "\n"
+			indent "#+begin_src " lang
+			(if (> (length headers) 1)
+			    (concat " " headers) headers)
+			(if (looking-at "[\n\r]")
+			    ""
+			  (concat "\n" (make-string (current-column) ? )))))))
 	   (move-end-of-line 2))
          (sort (if (region-active-p) (list (mark) (point)) (list (point))) #'>))
       (let ((start (point))
@@ -1380,10 +1420,8 @@ following the source block."
     (let* ((on-lob-line (save-excursion
 			  (beginning-of-line 1)
 			  (looking-at org-babel-lob-one-liner-regexp)))
-	   (inlinep (save-excursion
-		      (re-search-backward "[ \f\t\n\r\v]" nil t)
-		      (when (looking-at org-babel-inline-src-block-regexp)
-			(match-end 0))))
+	   (inlinep (when (org-babel-get-inline-src-block-matches)
+			(match-end 0)))
 	   (name (if on-lob-line
 		     (nth 0 (org-babel-lob-get-info))
 		   (nth 4 (or info (org-babel-get-src-block-info 'light)))))
@@ -1571,10 +1609,8 @@ code ---- the results are extracted in the syntax of the source
     (save-excursion
       (let* ((inlinep
 	      (save-excursion
-		(unless (= (point) (point-at-bol)) ;; move before inline block
-		  (re-search-backward "[ \f\t\n\r\v]" nil t))
-		(when (or (looking-at org-babel-inline-src-block-regexp)
-			  (looking-at org-babel-inline-lob-one-liner-regexp))
+		(when (or (org-babel-get-inline-src-block-matches)
+			  (org-babel-get-lob-one-liner-matches))
 		  (goto-char (match-end 0))
 		  (insert (if (listp result) "\n" " "))
 		  (point))))
@@ -1632,6 +1668,7 @@ code ---- the results are extracted in the syntax of the source
 			   '(:fmt (lambda (cell) (format "%s" cell)))) "\n"))
 	  (goto-char beg) (when (org-at-table-p) (org-table-align)))
 	 ((member "file" result-params)
+	  (when inlinep (goto-char inlinep))
 	  (insert result))
 	 (t (goto-char beg) (insert result)))
 	(when (listp result) (goto-char (org-table-end)))
@@ -1807,12 +1844,16 @@ parameters when merging lists."
 				       vars))
 			      vars)
 			    (list (cons name pair))))
-		   ;; if no name is given, then assign to variables in order
-		   (prog1 (setf (cddr (nth variable-index vars))
-				(concat (symbol-name
-					 (car (nth variable-index vars)))
-					"=" (cdr pair)))
-		     (incf variable-index)))))
+		   ;; if no name is given and we already have named variables
+		   ;; then assign to named variables in order
+		   (if (and vars (nth variable-index vars))
+		       (prog1 (setf (cddr (nth variable-index vars))
+				    (concat (symbol-name
+					     (car (nth variable-index vars)))
+					    "=" (cdr pair)))
+			 (incf variable-index))
+		     (error "variable \"%s\" must be assigned a default value"
+			    (cdr pair))))))
 	      (:results
 	       (setq results (e-merge results-exclusive-groups
 				      results

+ 1 - 1
lisp/org-compat.el

@@ -438,7 +438,7 @@ With two arguments, return floor and remainder of their quotient."
   "Pop to buffer specified by BUFFER-OR-NAME in the selected window."
   (if (fboundp 'pop-to-buffer-same-window)
       (funcall
-       'pop-to-buffer-same-window buffer-or-name norecord label)
+       'pop-to-buffer-same-window buffer-or-name norecord)
     (funcall 'switch-to-buffer buffer-or-name norecord)))
 
 (provide 'org-compat)

+ 8 - 2
lisp/org-exp.el

@@ -1739,8 +1739,14 @@ from the buffer."
 		(save-excursion
 		  (save-match-data
 		    (goto-char beg-content)
-		    (while (re-search-forward "^[ \t]*\\(,\\)" end-content t)
-		      (replace-match "" nil nil nil 1))))
+		    (let ((front-line (save-excursion
+					(re-search-forward
+					 "[^[:space:]]" end-content t)
+					(goto-char (match-beginning 0))
+					(current-column))))
+		      (while (re-search-forward "^[ \t]*\\(,\\)" end-content t)
+			(when (= (current-column) front-line)
+			  (replace-match "" nil nil nil 1))))))
 		(delete-region (match-beginning 0) (match-end 0))
 		(save-excursion
 		  (goto-char beg)

+ 2 - 0
lisp/org-footnote.el

@@ -52,6 +52,7 @@
 (declare-function org-in-indented-comment-line "org" ())
 (declare-function org-in-regexp "org" (re &optional nlines visually))
 (declare-function org-in-verbatim-emphasis "org" ())
+(declare-function org-inside-LaTeX-fragment-p "org" ())
 (declare-function org-inside-latex-macro-p "org" ())
 (declare-function org-mark-ring-push "org" (&optional pos buffer))
 (declare-function org-show-context "org" (&optional key))
@@ -178,6 +179,7 @@ extracted will be filled again."
   (save-match-data
     (not (or (org-in-commented-line)
 	     (org-in-indented-comment-line)
+	     (org-inside-LaTeX-fragment-p)
 	     ;; Avoid protected environments (LaTeX export)
 	     (get-text-property (point) 'org-protected)
 	     ;; Avoid literal example.

+ 17 - 17
lisp/org-html.el

@@ -33,7 +33,7 @@
 
 (declare-function org-id-find-id-file "org-id" (id))
 (declare-function htmlize-region "ext:htmlize" (beg end))
-(declare-function org-pop-to-buffer-same-window 
+(declare-function org-pop-to-buffer-same-window
 		  "org-compat" (&optional buffer-or-name norecord label))
 
 (defgroup org-export-html nil
@@ -906,7 +906,7 @@ OPT-PLIST is the export options list."
 			 (string-match "^\\.\\.?/" path)))
 		   "file")
 		  (t "internal")))
-      (setq path (org-extract-attributes (org-link-unescape path)))
+      (setq path (org-extract-attributes path))
       (setq attr (get-text-property 0 'org-attributes path))
       (setq desc1 (if (match-end 5) (match-string 5 line))
 	    desc2 (if (match-end 2) (concat type ":" path) path)
@@ -919,7 +919,7 @@ OPT-PLIST is the export options list."
 	  (if (string-match "^file:" desc)
 	      (setq desc (substring desc (match-end 0)))))
 	(setq desc (org-add-props
-		       (concat "<img src=\"" desc "\" alt=\"" 
+		       (concat "<img src=\"" desc "\" alt=\""
 			       (file-name-nondirectory desc) "\"/>")
 		       '(org-protected t))))
       (cond
@@ -1356,9 +1356,9 @@ lang=\"%s\" xml:lang=\"%s\">
 	    (insert "\n</div>\n")))
 
 	;; begin wrap around body
-	(insert (format "\n<div id=\"%s\">" 
+	(insert (format "\n<div id=\"%s\">"
 			;; FIXME org-export-html-content-div is obsolete since 7.7
-			(or org-export-html-content-div 
+			(or org-export-html-content-div
 			    (nth 1 org-export-html-divs)))
 		;; FIXME this should go in the preamble but is here so
 		;; that org-infojs can still find it
@@ -1375,7 +1375,7 @@ lang=\"%s\" xml:lang=\"%s\">
 	    (push "<div id=\"text-table-of-contents\">\n" thetoc)
 	    (push "<ul>\n<li>" thetoc)
 	    (setq lines
-		  (mapcar 
+		  (mapcar
 		   #'(lambda (line)
 		       (if (and (string-match org-todo-line-regexp line)
 				(not (get-text-property 0 'org-protected line)))
@@ -1401,7 +1401,7 @@ lang=\"%s\" xml:lang=\"%s\">
 					     line lines level))))
 			     (if (string-match
 				  (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt)
-				 (setq txt (replace-match  
+				 (setq txt (replace-match
 					    "&nbsp;&nbsp;&nbsp;<span class=\"tag\"> \\1</span>" t nil txt)))
 			     (if (string-match quote-re0 txt)
 				 (setq txt (replace-match "" t t txt)))
@@ -1429,7 +1429,7 @@ lang=\"%s\" xml:lang=\"%s\">
 				   ;; Check for targets
 				   (while (string-match org-any-target-regexp line)
 				     (setq line (replace-match
-						 (concat "@<span class=\"target\">" 
+						 (concat "@<span class=\"target\">"
 							 (match-string 1 line) "@</span> ")
 						 t t line)))
 				   (while (string-match "&lt;\\(&lt;\\)+\\|&gt;\\(&gt;\\)+" txt)
@@ -1437,8 +1437,8 @@ lang=\"%s\" xml:lang=\"%s\">
 				   (setq href
 					 (replace-regexp-in-string
 					  "\\." "-" (format "sec-%s" snumber)))
-				   (setq href (org-solidify-link-text 
-					       (or (cdr (assoc href 
+				   (setq href (org-solidify-link-text
+					       (or (cdr (assoc href
 							       org-export-preferred-target-alist)) href)))
 				   (push
 				    (format
@@ -1446,7 +1446,7 @@ lang=\"%s\" xml:lang=\"%s\">
 					 "</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>"
 				       "</li>\n<li><a href=\"#%s\">%s</a>")
 				     href txt) thetoc)
-				   
+
 				   (setq org-last-level level)))))
 		       line)
 		   lines))
@@ -1455,15 +1455,15 @@ lang=\"%s\" xml:lang=\"%s\">
 	      (push "</li>\n</ul>\n" thetoc))
 	    (push "</div>\n" thetoc)
 	    (setq thetoc (if have-headings (nreverse thetoc) nil))))
-      
+
       (setq head-count 0)
       (org-init-section-numbers)
-      
+
       (org-open-par)
-      
+
       (while (setq line (pop lines) origline line)
 	(catch 'nextline
-	  
+
 	  ;; end of quote section?
 	  (when (and inquote (string-match org-outline-regexp-bol line))
 	    (insert "</pre>\n")
@@ -1818,7 +1818,7 @@ lang=\"%s\" xml:lang=\"%s\">
 			      (?d . ,date)   (?c . ,creator-info)
 			      (?v . ,html-validation-link))))))
 	    (insert "\n</div>"))))
-      
+
       ;; FIXME `org-export-html-with-timestamp' has been declared
       ;; obsolete since Org 7.7 -- don't forget to remove this.
       (if org-export-html-with-timestamp
@@ -1951,7 +1951,7 @@ NO-CSS is passed to the exporter."
   (if (string-match "^[ \t]*|" (car lines))
       ;; A normal org table
       (org-format-org-table-html lines nil no-css)
-    ;; Table made by table.el 
+    ;; Table made by table.el
     (or (org-format-table-table-html-using-table-generate-source
 	 olines (not org-export-prefer-native-exporter-for-tables))
 	;; We are here only when table.el table has NO col or row

+ 2 - 0
lisp/org-taskjuggler.el

@@ -277,6 +277,7 @@ defined in `org-export-taskjuggler-default-reports'."
 		      (file-name-nondirectory buffer-file-name))
 		     org-export-taskjuggler-extension)))
 	 (buffer (find-file-noselect filename))
+	 (old-buffer (current-buffer))
 	 (org-export-taskjuggler-old-level 0)
 	 task resource)
     (unless tasks
@@ -304,6 +305,7 @@ defined in `org-export-taskjuggler-default-reports'."
 	(setcar tasks (push (cons "version" version) task))))
     (with-current-buffer buffer
       (erase-buffer)
+      (org-clone-local-variables old-buffer "^org-")
       (org-taskjuggler-open-project (car tasks))
       (insert org-export-taskjuggler-default-global-properties)
       (insert "\n")

+ 20 - 39
lisp/org.el

@@ -365,10 +365,10 @@ In Emacs 23, when `shift-select-mode' is on, shifted cursor keys
 start selecting a region, or enlarge regions started in this way.
 In Org-mode, in special contexts, these same keys are used for
 other purposes, important enough to compete with shift selection.
-Org tries to balance these needs by supporting `shift-select-mode' 
+Org tries to balance these needs by supporting `shift-select-mode'
 outside these special contexts, under control of this variable.
 
-The default of this variable is nil, to avoid confusing behavior.  Shifted 
+The default of this variable is nil, to avoid confusing behavior.  Shifted
 cursor keys will then execute Org commands in the following contexts:
 - on a headline, changing TODO state (left/right) and priority (up/down)
 - on a time stamp, changing the time
@@ -7346,39 +7346,20 @@ After top level, it switches back to sibling level."
 However, if any line in the current entry has no indentation, or if it
 would end up with no indentation after the change, nothing at all is done."
   (save-excursion
-    (let* ((end (save-excursion (outline-next-heading)
-				(point-marker)))
-	   ;; FIXME we should use `org-end-of-meta-data-and-drawers'
-	   ;; here but it matches misplaced :END:...
-	   (drawer-end (save-excursion
-			 (and (re-search-forward
-			       org-property-end-re end t)
-			      (match-end 0))))
-	   (prohibit (if (> diff 0)
-			 "^\\S-"
-		       (concat "^ \\{0," (int-to-string (- diff)) "\\}\\S-")))
-	   col)
-      (while (re-search-forward
-	      (concat "\\(" (regexp-opt org-all-time-keywords)
-		      "\\|" "^[ \t]*" org-tsr-regexp-both "*$"
-		      "\\|" "^[ \t]*:[a-zA-Z][a-zA-Z0-9_]*:.*$"
-		      "\\)") (or drawer-end end) t)
-	(beginning-of-line)
-	(when (looking-at "^[ \t]+")
+    (let ((end (save-excursion (outline-next-heading)
+			       (point-marker)))
+	  (prohibit (if (> diff 0)
+			"^\\S-"
+		      (concat "^ \\{0," (int-to-string (- diff)) "\\}\\S-")))
+	  col)
+      (unless (save-excursion (end-of-line 1)
+			      (re-search-forward prohibit end t))
+	(while (and (< (point) end)
+		    (re-search-forward "^[ \t]+" end t))
 	  (goto-char (match-end 0))
 	  (setq col (current-column))
 	  (if (< diff 0) (replace-match ""))
-	  (org-indent-to-column (+ diff col))
-	  (if drawer-end (setq drawer-end (+ diff drawer-end))))
-	(end-of-line))
-      (unless (save-excursion (end-of-line 1)
-      			      (re-search-forward prohibit end t))
-      	(while (and (< (point) end)
-      		    (re-search-forward "^[ \t]+" end t))
-      	  (goto-char (match-end 0))
-      	  (setq col (current-column))
-      	  (if (< diff 0) (replace-match ""))
-      	  (org-indent-to-column (+ diff col))))
+	  (org-indent-to-column (+ diff col))))
       (move-marker end nil))))
 
 (defun org-convert-to-odd-levels ()
@@ -9411,7 +9392,8 @@ application the system uses for this file type."
 	(save-excursion
 	  (when (or (org-in-regexp org-angle-link-re)
 		    (org-in-regexp org-plain-link-re))
-	    (setq type (match-string 1) path (match-string 2))
+	    (setq type (match-string 1)
+		  path (org-link-unescape (match-string 2)))
 	    (throw 'match t)))
 	(save-excursion
 	  (when (org-in-regexp (org-re "\\(:[[:alnum:]_@#%:]+\\):[ \t]*$"))
@@ -10018,8 +10000,8 @@ If the file does not exist, an error is thrown."
 				 match)
 			(progn (setq in-emacs (or in-emacs line search))
 			       nil))) ; if we have no match in apps-dlink,
-		                      ; always open the file in emacs if line or search
-		                      ; is given (for backwards compatibility)
+				      ; always open the file in emacs if line or search
+				      ; is given (for backwards compatibility)
 		    (assoc-default dfile (org-apps-regexp-alist apps a-m-a-p)
 				   'string-match)
 		    (cdr (assoc ext apps))
@@ -13707,7 +13689,7 @@ Being in this list makes sure that they are offered for completion.")
 
 (defsubst org-re-property (property)
   "Return a regexp matching PROPERTY.
-Match group 1 will be set to the value of the property."
+Match group 1 will be set to the value "
   (concat "^[ \t]*:" (regexp-quote property) ":[ \t]*\\(\\S-.*\\)"))
 
 (defun org-property-action ()
@@ -17108,7 +17090,7 @@ If not, return to the original position and throw an error."
 
 (defun org-speed-command-default-hook (keys)
   "Hook for activating single-letter speed commands.
-`org-speed-commands-default' specifies a minimal command set.  
+`org-speed-commands-default' specifies a minimal command set.
 Use `org-speed-commands-user' for further customization."
   (when (or (and (bolp) (looking-at org-outline-regexp))
 	    (and (functionp org-use-speed-commands)
@@ -20335,7 +20317,6 @@ If there is no such heading, return nil."
 	(unless (eobp) (backward-char 1)))
     ad-do-it))
 
-;; FIXME This should not match :END: for custom drawers?
 (defun org-end-of-meta-data-and-drawers ()
   "Jump to the first text after meta data and drawers in the current entry.
 This will move over empty lines, lines with planning time stamps,
@@ -20524,7 +20505,7 @@ if no description is present"
       (progn (org-remove-from-invisibility-spec '(org-link))
 	     (org-restart-font-lock)
 	     (setq org-descriptive-links nil))
-    (progn (add-to-invisibility-spec '(org-link)) 
+    (progn (add-to-invisibility-spec '(org-link))
 	   (org-restart-font-lock)
 	   (setq org-descriptive-links t))))
 

+ 10 - 0
testing/examples/babel.org

@@ -279,3 +279,13 @@ this is simple
    :ID:       d4faa7b3-072b-4dcf-813c-dd7141c633f3
    :END:
 has length 14
+
+* org-babel-get-inline-src-block-matches
+  :PROPERTIES:  
+  :results:  silent
+  :ID:       0D0983D4-DE33-400A-8A05-A225A567BC74
+  :END:
+src_sh{echo "One"} block at start of line
+ One spaced block in  src_sh{ echo "middle" } of line 
+src_sh{echo 2} blocks on the src_emacs-lisp{"same"} line
+ Inline block with src_sh[:results silent]{ echo "parameters" }.

+ 14 - 0
testing/examples/org-exp.org

@@ -0,0 +1,14 @@
+#+Title: a collection of examples for export tests
+#+OPTIONS: ^:nil
+
+* stripping commas from within blocks on export
+  :PROPERTIES:
+  :ID:       76d3a083-67fa-4506-a41d-837cc48158b5
+  :END:
+The following commas should not be removed.
+
+#+begin_src r
+  a <- c(1
+         , 2
+         , 3)
+#+end_src

+ 16 - 0
testing/lisp/test-ob-awk.el

@@ -1,3 +1,18 @@
+;;; test-ob-awk.el --- tests for ob-awk.el
+
+;; Copyright (c) 2010 Sergey Litvinov
+;; Authors: Sergey Litvinov
+
+;; Released under the GNU General Public License version 3
+;; see: http://www.gnu.org/licenses/gpl-3.0.html
+
+(let ((load-path (cons (expand-file-name
+			".." (file-name-directory
+			      (or load-file-name buffer-file-name)))
+		       load-path)))
+  (require 'org-test)
+  (require 'org-test-ob-consts))
+
 (require 'ob-awk)
 
 (ert-deftest ob-awk/input-none ()
@@ -17,3 +32,4 @@
   (org-test-at-id "9e998b2a-3581-43fe-b26d-07d3c507b86a"
     (org-babel-next-src-block 3)
     (should (= 150 (org-babel-execute-src-block)))))
+

+ 1 - 1
testing/lisp/test-ob-exp.el

@@ -50,7 +50,7 @@
 			  (buffer-string))))
   (when (get-buffer "*Org HTML Export*") (kill-buffer "*Org HTML Export*")))
 
-(ert-deftest test-ob-exp/org-babel-exp-src-blocks/w-no-headers ()
+(ert-deftest test-ob-exp/org-babel-exp-src-blocks/w-no-headers2 ()
   "Testing export without any headlines in the org-mode file."
   (let ((html-file (concat (file-name-sans-extension
 			    org-test-link-in-heading-file)

+ 37 - 7
testing/lisp/test-ob-fortran.el

@@ -1,5 +1,34 @@
-(require 'ob-fortran)
- 
+;;; test-ob-fortran.el --- tests for ob-fortran.el
+
+;; Copyright (c) 2010 Sergey Litvinov
+;; Authors: Sergey Litvinov
+
+;; Released under the GNU General Public License version 3
+;; see: http://www.gnu.org/licenses/gpl-3.0.html
+
+(let ((load-path (cons (expand-file-name
+			".." (file-name-directory
+			      (or load-file-name buffer-file-name)))
+		       load-path)))
+  (require 'org-test)
+  (require 'org-test-ob-consts))
+
+(let ((load-path (cons (expand-file-name
+			"langs"
+			(expand-file-name
+			 "babel"
+			 (expand-file-name
+			  "contrib"
+			  (expand-file-name
+			   ".."
+			   (expand-file-name
+			    ".."
+			    (file-name-directory
+			     (or load-file-name buffer-file-name)))))))
+		       load-path)))
+
+  (require 'ob-fortran))
+
 (ert-deftest ob-fortran/assert ()
   (should t))
 
@@ -29,11 +58,12 @@
     (org-babel-next-src-block 2)
     (should (= 42 (org-babel-execute-src-block)))))
 
-(ert-deftest ob-fortran/character-var ()
-  "Test string input"
-  (org-test-at-id "d8d1dfd3-5f0c-48fe-b55d-777997e02242"
-    (org-babel-next-src-block 3)
-    (should (equal "word" (org-babel-execute-src-block)))))
+;; ;; TODO: test fails
+;; (ert-deftest ob-fortran/character-var ()
+;;   "Test string input"
+;;   (org-test-at-id "d8d1dfd3-5f0c-48fe-b55d-777997e02242"
+;;     (org-babel-next-src-block 3)
+;;     (should (equal "word" (org-babel-execute-src-block)))))
 
 (ert-deftest ob-fortran/list-var ()
   "Test real array input"

+ 17 - 2
testing/lisp/test-ob-lilypond.el

@@ -1,11 +1,26 @@
+;;; test-ob-lilypond.el --- tests for ob-lilypond.el
+
+;; Copyright (c) 2010 Martyn Jago
+;; Authors: Martyn Jago
+
+;; Released under the GNU General Public License version 3
+;; see: http://www.gnu.org/licenses/gpl-3.0.html
+
+(let ((load-path (cons (expand-file-name
+			".." (file-name-directory
+			      (or load-file-name buffer-file-name)))
+		       load-path)))
+  (require 'org-test)
+  (require 'org-test-ob-consts))
+
+(require 'ob-lilypond)
+
 (save-excursion
   (set-buffer (get-buffer-create "test-ob-lilypond.el"))
   (setq ly-here
         (file-name-directory
          (or load-file-name (buffer-file-name)))))
 
-(require 'ob-lilypond)
- 
 (ert-deftest ob-lilypond/assert ()
   (should t))
  

+ 14 - 11
testing/lisp/test-ob-lob.el

@@ -8,19 +8,22 @@
 
 ;;;; Comments:
 
-;; Template test file for Org-mode tests
-
-
-;;; Code:
-(let ((load-path (cons (expand-file-name
-			".." (file-name-directory
-			      (or load-file-name buffer-file-name)))
-		       load-path)))
-  (require 'org-test)
-  (require 'org-test-ob-consts))
-
 
 ;;; Tests
+(org-babel-lob-ingest
+ (expand-file-name
+  "library-of-babel.org"
+  (expand-file-name
+   "babel"
+   (expand-file-name
+    "contrib"
+    (expand-file-name
+     ".."
+     (expand-file-name
+      ".."
+      (file-name-directory
+       (or load-file-name buffer-file-name))))))))
+
 (ert-deftest test-ob-lob/ingest ()
   "Test the ingestion of an org-mode file."
   (should (< 0 (org-babel-lob-ingest

+ 206 - 20
testing/lisp/test-ob.el

@@ -12,7 +12,6 @@
 		       load-path)))
   (require 'org-test)
   (require 'org-test-ob-consts))
-  (require 'org-test)
 
 (ert-deftest test-org-babel/src-name-regexp ()
   (should(equal "^[ \t]*#\\+\\(srcname\\|source\\|function\\):[ \t]*"
@@ -106,17 +105,6 @@
 	     org-babel-src-block-regexp
 	     (replace-regexp-in-string body "" test-block)))))
 
-
-(ert-deftest test-org-babel/inline-src-block-regexp ()
-  (should(equal (concat "[^-[:alnum:]]\\(src_\\([^ \f\t\n\r\v]+\\)"
-			"\\(\\|\\[\\(.*?\\)\\]\\)"
-			"{\\([^\f\n\r\v]+?\\)}\\)")
-		org-babel-inline-src-block-regexp))
-  ;; (should (org-test-string-exact-match
-  ;; 	   org-babel-inline-src-block-regexp
-  ;; 	   "src_lang[:testing1 yes :testing2 no]{ echo This is a test }\n"))
-  )
-
 (ert-deftest test-org-babel/get-header ()
   (should (not (org-babel-get-header
 		org-babel-default-header-args :doesnt-exist)))
@@ -206,7 +194,7 @@
       (should(equal '(:result-type . output) (assoc :result-type params)))
       (should(equal '(num . 9) (cdr (assoc :var params)))))))
 
-(ert-deftest test-org-babel/parse-header-args ()
+(ert-deftest test-org-babel/parse-header-args2 ()
   (org-test-at-id "2409e8ba-7b5f-4678-8888-e48aa02d8cb4"
     (should (string-match (regexp-quote "this is simple")
 			  (org-babel-ref-resolve "simple-subtree")))
@@ -215,13 +203,211 @@
 
 (ert-deftest test-org-babel/inline-src-blocks ()
   (org-test-at-id "54cb8dc3-298c-4883-a933-029b3c9d4b18"
-    (flet ((next ()
-		 (move-end-of-line 1)
-		 (re-search-forward org-babel-inline-src-block-regexp nil t)
-		 (goto-char (match-beginning 1))))
-      (next) (should (equal 1 (org-babel-execute-src-block)))
-      (next) (should (equal 2 (org-babel-execute-src-block)))
-      (next) (should (equal 3 (org-babel-execute-src-block))))))
+    (macrolet ((at-next (&rest body)
+		 `(progn
+		    (move-end-of-line 1)
+		    (re-search-forward org-babel-inline-src-block-regexp nil t)
+		    (goto-char (match-beginning 1))
+		    (save-match-data ,@body))))
+      (at-next (should (equal 1 (org-babel-execute-src-block))))
+      (at-next (should (equal 2 (org-babel-execute-src-block))))
+      (at-next (should (equal 3 (org-babel-execute-src-block)))))))
+
+(ert-deftest test-org-babel/org-babel-get-inline-src-block-matches ()
+  (org-test-at-id "0D0983D4-DE33-400A-8A05-A225A567BC74"
+    (let ((test-point (point)))
+      (should (fboundp 'org-babel-get-inline-src-block-matches))
+      (should (re-search-forward "src_" nil t)) ;; 1
+      (should (= (+ test-point 140) (match-end 0)))
+      (should (org-babel-get-inline-src-block-matches))
+      (should (re-search-forward "}" nil (point-at-bol))) ;; 1
+      (should-not (org-babel-get-inline-src-block-matches))
+      (should (re-search-forward "in" nil t)) ;; 2
+      (should-not (org-babel-get-inline-src-block-matches))
+      (should (re-search-forward "echo" nil t)) ;; 2
+      (should (org-babel-get-inline-src-block-matches))
+      (should (re-search-forward "blocks" nil t)) ;; 3
+      (backward-char 8) ;; 3
+      (should (org-babel-get-inline-src-block-matches))
+      (forward-char 1) ;;3
+      (should-not (org-babel-get-inline-src-block-matches))
+      (should (re-search-forward ":results" nil t)) ;; 4
+      (should (org-babel-get-inline-src-block-matches))
+      (end-of-line)
+      (should-not (org-babel-get-inline-src-block-matches))
+    )))
+
+(ert-deftest test-org-babel/inline-src_blk-default-results-replace-line-1 ()
+  (with-temp-buffer
+
+    ;; src_ at bol line 1...
+    (let ((test-line "src_sh{echo 1}"))
+      (insert test-line)
+      (should-error (org-ctrl-c-ctrl-c))
+      (goto-char (point-min)) (org-ctrl-c-ctrl-c)
+      (should (string=
+       	       (concat test-line " =1=")
+       	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (forward-char) (org-ctrl-c-ctrl-c)
+      (should (string=
+       	       (concat test-line " =1= =1=")
+       	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (re-search-forward "1}")
+      (should-error (org-ctrl-c-ctrl-c))
+      (backward-char) ;; last char of block body
+      (org-ctrl-c-ctrl-c)
+      (should (string=
+       	       (concat test-line " =1= =1= =1=")
+       	       (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))
+
+    ;; src_ follows space line 1...
+    (let ((test-line " src_emacs-lisp{ 1 }"))
+      (beginning-of-line)
+      (insert (concat test-line "\n"))
+      (goto-char (point-min))
+      (should-error (org-ctrl-c-ctrl-c))
+      (forward-char) (org-ctrl-c-ctrl-c) 
+      (should (string=
+	       (concat test-line " =1=")
+	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (re-search-forward "{ 1 ") (org-ctrl-c-ctrl-c)
+      (should (string=
+	       (concat test-line " =1= =1=")
+	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (forward-char)
+      (should-error (org-ctrl-c-ctrl-c))
+      )))
+
+(ert-deftest test-org-babel/inline-src_blk-default-results-replace-line-2 ()
+  (with-temp-buffer
+
+    ;; src_ at bol line 2...
+    (let ((test-line " src_emacs-lisp{ \"x\" }"))
+      (insert (concat "\n" test-line))
+      (should-error (org-ctrl-c-ctrl-c))
+      (goto-char (point-min))
+      (should-error (org-ctrl-c-ctrl-c))
+      (forward-line)
+      (should-error (org-ctrl-c-ctrl-c))
+      (forward-char) (org-ctrl-c-ctrl-c)
+      (should (string=
+	       (concat test-line " =x=")
+	       (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))
+
+    (let ((test-line "Some text prior to block src_emacs-lisp{ \"y\" }"))
+      (goto-char (point-max))
+      (insert (concat "\n" test-line " end"))
+      (re-search-backward "src") (org-ctrl-c-ctrl-c)
+      (should (string=
+       	       (concat test-line " =y= end")
+       	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (re-search-forward "\" ") (org-ctrl-c-ctrl-c)
+      (should (string=
+	       (concat test-line " =y= =y= end")
+       	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (forward-char)
+      (should-error (org-ctrl-c-ctrl-c))
+      )))
+
+(ert-deftest test-org-babel/inline-src_blk-manual-results-replace ()
+  (with-temp-buffer
+
+    (let ((test-line " src_emacs-lisp[:results replace]{ \"x\" }"))
+      (insert (concat "\n" test-line))
+      (should-error (org-ctrl-c-ctrl-c))
+      (goto-char (point-min))
+      (should-error (org-ctrl-c-ctrl-c))
+      (forward-line)
+      (should-error (org-ctrl-c-ctrl-c))
+      (forward-char) (org-ctrl-c-ctrl-c)
+      (should (string=
+      	       (concat test-line " =x=")
+      	       (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))
+    
+    (let ((test-line " Some text prior to block src_emacs-lisp[:results replace]{ \"y\" }"))
+      (goto-char (point-max))
+      (insert (concat "\n" test-line " end"))
+      (re-search-backward "src") (org-ctrl-c-ctrl-c)
+      (should (string=
+    	       (concat test-line " =y= end")
+    	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (re-search-forward "\" ") (org-ctrl-c-ctrl-c)
+      (should (string=
+    	       (concat test-line " =y= =y= end")
+    	       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (forward-char)
+      (should-error (org-ctrl-c-ctrl-c)))
+    ))
+
+(ert-deftest test-org-babel/inline-src_blk-results-silent ()
+  (with-temp-buffer
+
+    (let ((test-line "src_emacs-lisp[ :results silent ]{ \"x\" }"))
+      (insert test-line)
+      (should-error (org-ctrl-c-ctrl-c))
+      (goto-char (point-min)) (org-ctrl-c-ctrl-c)
+      (should (string= test-line
+		       (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))
+    (let ((test-line " Some text prior to block src_emacs-lisp[ :results silent ]{ \"y\" }"))
+      (goto-char (point-max))
+      (insert (concat "\n" test-line " end"))
+      (re-search-backward "src_") (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line " end")
+		       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (re-search-forward "\" ") (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line " end")
+		       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (forward-char)
+      (should-error (org-ctrl-c-ctrl-c)))
+      ))
+
+(ert-deftest test-org-babel/inline-src_blk-results-raw ()
+  (with-temp-buffer
+
+    (let ((test-line "src_emacs-lisp[ :results raw ]{ \"x\" }"))
+      (insert test-line)
+      (goto-char (point-min)) (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line " x")
+		       (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))
+    (let ((test-line " Some text prior to block src_emacs-lisp[ :results raw ]{ \"the\" }"))
+      (goto-char (point-max))
+      (insert (concat "\n" test-line " end"))
+      (re-search-backward "src_") (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line " the end")
+		       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (re-search-forward "\" ") (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line " the the end")
+		       (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
+      (forward-char)
+      (should-error (org-ctrl-c-ctrl-c)))
+      ))
+
+(ert-deftest test-org-babel/inline-src_blk-results-file ()
+  (with-temp-buffer
+
+    (let ((test-line "src_emacs-lisp[ :results file ]{ \"~/test-file\"  }"))
+      (insert test-line)
+      (goto-char (point-min)) (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line " [[file:~/test-file]]")
+		       (buffer-substring-no-properties (point-min) (point-max)))))))
+
+(ert-deftest test-org-babel/inline-src_blk-results-scalar ()
+  (with-temp-buffer
+
+    (let ((test-line "src_emacs-lisp[ :results scalar ]{ \"x\"  }"))
+      (insert test-line)
+      (goto-char (point-min)) (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line  " =\"x\"=")
+		       (buffer-substring-no-properties (point-min) (point-max)))))))
+
+(ert-deftest test-org-babel/inline-src_blk-results-verbatim ()
+  (with-temp-buffer
+
+    (let ((test-line "src_emacs-lisp[ :results verbatim ]{ \"x\"  }"))
+      (insert test-line)
+      (goto-char (point-min)) (org-ctrl-c-ctrl-c)
+      (should (string= (concat test-line " =\"x\"=")
+		       (buffer-substring-no-properties (point-min) (point-max)))))))
 
 (provide 'test-ob)
 

+ 23 - 0
testing/lisp/test-org-exp.el

@@ -0,0 +1,23 @@
+;;; test-org-exp.el --- tests for org-exp.el
+
+;; Copyright (c) 2010 Eric Schulte
+;; Authors: Eric Schulte
+
+;; Released under the GNU General Public License version 3
+;; see: http://www.gnu.org/licenses/gpl-3.0.html
+
+(let ((load-path (cons (expand-file-name
+			".." (file-name-directory
+			      (or load-file-name buffer-file-name)))
+		       load-path)))
+  (require 'org-test)
+  (require 'org-test-ob-consts))
+
+(ert-deftest test-org-exp/stripping-commas ()
+  "Test the stripping of commas from within blocks during export."
+  (org-test-at-id "76d3a083-67fa-4506-a41d-837cc48158b5"
+    ;; don't strip internal commas
+    (org-narrow-to-subtree)
+    (should (string-match
+	     ", 2"
+	     (org-export-as-ascii nil nil nil 'string)))))

+ 6 - 6
testing/lisp/test-org.el

@@ -12,12 +12,12 @@
 
 
 ;;; Code:
-(let ((load-path (cons (expand-file-name
-			".." (file-name-directory
-			      (or load-file-name buffer-file-name)))
-		       load-path)))
-  (require 'org-test)
-  (require 'org-test-ob-consts))
+(let* ((testing-lisp-dir (file-name-directory
+			  (or load-file-name buffer-file-name)))
+       (load-path (cons testing-lisp-dir load-path)))
+  (dolist (file (directory-files testing-lisp-dir 'full
+				 "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*\\.org$"))
+    (require (intern (substring file 0 (- (length file) 3))))))
 
 
 ;;; Tests

+ 38 - 18
testing/org-test.el

@@ -16,27 +16,38 @@
 ;; called while in a `defun' all ert tests with names matching the
 ;; name of the function are run.
 
-;;; Prerequisites:
-
-;; ERT and jump.el are both included as git submodules, install with
-;;   $ git submodule init
-;;   $ git submodule update
+;;; Test Development
+;; For test development purposes a number of navigation and test
+;; function construction routines are available as a git submodule
+;; (jump.el)
+;; Install with...
+;; $ git submodule init
+;; $ git submodule update
 
 
 ;;;; Code:
-(let* ((org-test-dir (expand-file-name
+(let ((org-test-dir (expand-file-name
 		      (file-name-directory
-		       (or load-file-name buffer-file-name))))
-       (load-path (cons
-		   (expand-file-name "ert" org-test-dir)
-		   (cons
-		    (expand-file-name "jump" org-test-dir)
-		    load-path))))
-  (require 'ert)
-  (require 'ert-x)
-  (require 'jump)
-  (require 'which-func)
-  (require 'org))
+		       (or load-file-name buffer-file-name)))))
+   (let ((org-lisp-dir (expand-file-name
+   		       (concat org-test-dir "../lisp"))))
+     (unless (member 'features "org")
+       (setq load-path (cons org-lisp-dir load-path))
+       (org-babel-do-load-languages
+	'org-babel-load-languages '((sh . t)))))
+   (let* ((load-path (cons
+		     (expand-file-name "ert" org-test-dir)
+		     (cons
+		      (expand-file-name "jump" org-test-dir)
+		      load-path))))
+    (require 'cl)
+    (require 'ert)
+    (require 'ert-x)
+    (when (file-exists-p
+	   (expand-file-name "jump/jump.el" org-test-dir))
+      (require 'jump)
+      (require 'which-func))
+    (require 'org)))
 
 (defconst org-test-default-test-file-name "tests.el"
   "For each defun a separate file with tests may be defined.
@@ -129,6 +140,7 @@ files."
 
 
 ;;; Navigation Functions
+(when (featurep 'jump)
 (defjump org-test-jump
   (("lisp/\\1.el" . "testing/lisp/test-\\1.el")
    ("lisp/\\1.el" . "testing/lisp/\\1.el/test.*.el")
@@ -171,7 +183,7 @@ files."
        "  (should-error (error \"errr...\")))\n\n\n"
        "(provide '" name ")\n\n"
        ";;; " file-name " ends here\n") full-path))
-  (lambda () ((lambda (res) (if (listp res) (car res) res)) (which-function))))
+  (lambda () ((lambda (res) (if (listp res) (car res) res)) (which-function)))))
 
 (define-key emacs-lisp-mode-map "\M-\C-j" 'org-test-jump)
 
@@ -228,6 +240,14 @@ files."
 		 "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*\\.org$"))
     (find-file file)))
 
+(defun org-test-run-batch-tests ()
+  "Run all defined tests matching \"\\(org\\|ob\\)\".
+Load all test files first."
+  (interactive)
+  (org-test-touch-all-examples)
+  (org-test-load)
+  (ert-run-tests-batch-and-exit "\\(org\\|ob\\)"))
+
 (defun org-test-run-all-tests ()
   "Run all defined tests matching \"\\(org\\|ob\\)\".
 Load all test files first."