浏览代码

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

Carsten Dominik 13 年之前
父节点
当前提交
a7d89a80fb

+ 1 - 1
contrib/babel/langs/ob-fortran.el

@@ -139,7 +139,7 @@ of the same value."
       (format "integer, parameter  ::  %S = %S\n" var val))
      ((floatp val)
       (format "real, parameter ::  %S = %S\n" var val))
-     ((or (characterp val))
+     ((or (integerp val))
       (format "character, parameter :: %S = '%S'\n" var val))
      ((stringp val)
       (format "character(len=%d), parameter ::  %S = '%s'\n"

+ 355 - 145
contrib/lisp/org-odt.el

@@ -31,6 +31,8 @@
 (require 'org-lparse)
 
 (defun org-odt-end-export ()
+  (org-odt-fixup-label-references)
+
   ;; remove empty paragraphs
   (goto-char (point-min))
   (while (re-search-forward
@@ -598,15 +600,107 @@ PUB-DIR is set, use this as the publishing directory."
 (defvar org-lparse-table-is-styled)
 (defvar org-lparse-table-rowgrp-info)
 (defvar org-lparse-table-colalign-vector)
+
+(defvar org-odt-table-style nil
+  "Table style specified by \"#+ATTR_ODT: <style-name>\" line.
+This is set during `org-odt-begin-table'.")
+
+(defvar org-odt-table-style-spec nil
+  "Entry for `org-odt-table-style' in `org-export-odt-table-styles'.")
+
+(defcustom org-export-odt-table-styles nil
+  "Specify how Table Styles should be derived from a Table Template.
+This is a list where each element is of the
+form (TABLE-STYLE-NAME TABLE-TEMPLATE-NAME TABLE-CELL-OPTIONS).
+
+TABLE-STYLE-NAME is the style associated with the table through
+`org-odt-table-style'.
+
+TABLE-TEMPLATE-NAME is a set of - upto 9 - automatic
+TABLE-CELL-STYLE-NAMEs and PARAGRAPH-STYLE-NAMEs (as defined
+below) that is included in
+`org-export-odt-content-template-file'.
+
+TABLE-CELL-STYLE-NAME := TABLE-TEMPLATE-NAME + TABLE-CELL-TYPE +
+                         \"TableCell\"
+PARAGRAPH-STYLE-NAME  := TABLE-TEMPLATE-NAME + TABLE-CELL-TYPE +
+                         \"TableParagraph\"
+TABLE-CELL-TYPE       := \"FirstRow\"   | \"LastColumn\" |
+                         \"FirstRow\"   | \"LastRow\"    |
+                         \"EvenRow\"    | \"OddRow\"     |
+                         \"EvenColumn\" | \"OddColumn\"  | \"\"
+where \"+\" above denotes string concatenation.
+
+TABLE-CELL-OPTIONS is an alist where each element is of the
+form (TABLE-CELL-STYLE-SELECTOR . ON-OR-OFF).
+TABLE-CELL-STYLE-SELECTOR := `use-first-row-styles'       |
+                             `use-last-row-styles'        |
+                             `use-first-column-styles'    |
+                             `use-last-column-styles'     |
+                             `use-banding-rows-styles'    |
+                             `use-banding-columns-styles' |
+                             `use-first-row-styles'
+ON-OR-OFF                 := `t' | `nil'
+
+For example, with the following configuration
+
+\(setq org-export-odt-table-styles
+      '\(\(\"TableWithHeaderRowsAndColumns\" \"Custom\"
+         \(\(use-first-row-styles . t\)
+          \(use-first-column-styles . t\)\)\)
+        \(\"TableWithHeaderColumns\" \"Custom\"
+         \(\(use-first-column-styles . t\)\)\)\)\)
+
+1. A table associated with \"TableWithHeaderRowsAndColumns\"
+   style will use the following table-cell styles -
+   \"CustomFirstRowTableCell\", \"CustomFirstColumnTableCell\",
+   \"CustomTableCell\" and the following paragraph styles
+   \"CustomFirstRowTableParagraph\",
+   \"CustomFirstColumnTableParagraph\", \"CustomTableParagraph\"
+   as appropriate.
+
+2. A table associated with \"TableWithHeaderColumns\" style will
+   use the following table-cell styles -
+   \"CustomFirstColumnTableCell\", \"CustomTableCell\" and the
+   following paragraph styles
+   \"CustomFirstColumnTableParagraph\", \"CustomTableParagraph\"
+   as appropriate..
+
+Note that TABLE-TEMPLATE-NAME corresponds to the
+\"<table:table-template>\" elements contained within
+\"<office:styles>\".  The entries (TABLE-STYLE-NAME
+TABLE-TEMPLATE-NAME TABLE-CELL-OPTIONS) correspond to
+\"table:template-name\" and \"table:use-first-row-styles\" etc
+attributes of \"<table:table>\" element.  Refer ODF-1.2
+specification for more information.  Also consult the
+implementation filed under `org-odt-get-table-cell-styles'."
+  :group 'org-export-odt
+  :type '(choice
+          (const :tag "None" nil)
+          (repeat :tag "Table Styles"
+                  (list :tag "Table Style Specification"
+                   (string :tag "Table Style Name")
+                   (string  :tag "Table Template Name")
+                   (alist :options (use-first-row-styles
+                                    use-last-row-styles
+                                    use-first-column-styles
+                                    use-last-column-styles
+                                    use-banding-rows-styles
+                                    use-banding-columns-styles)
+                          :key-type symbol
+                          :value-type (const :tag "True" t))))))
+
 (defun org-odt-begin-table (caption label attributes)
+  (setq org-odt-table-style attributes)
+  (setq org-odt-table-style-spec
+	(assoc org-odt-table-style org-export-odt-table-styles))
   (when label
     (insert
      (org-odt-format-stylized-paragraph
       'table (org-odt-format-entity-caption label caption "Table"))))
-
   (org-lparse-insert-tag
    "<table:table table:name=\"%s\" table:style-name=\"%s\">"
-   (or label "") "OrgTable")
+   (or label "") (or (nth 1 org-odt-table-style-spec) "OrgTable"))
   (setq org-lparse-table-begin-marker (point)))
 
 (defun org-odt-end-table ()
@@ -614,22 +708,24 @@ PUB-DIR is set, use this as the publishing directory."
   (loop for level from 0 below org-lparse-table-ncols
 	do (insert
 	    (org-odt-format-tags
-	     "<table:table-column table:style-name=\"OrgTableColumn\"/>"  "")))
+	     "<table:table-column table:style-name=\"%sColumn\"/>"
+	     "" (or (nth 1 org-odt-table-style-spec) "OrgTable"))))
 
   ;; fill style attributes for table cells
   (when org-lparse-table-is-styled
     (while (re-search-forward "@@\\(table-cell:p\\|table-cell:style-name\\)@@\\([0-9]+\\)@@\\([0-9]+\\)@@" nil t)
-      (let ((spec (match-string 1))
-	    (r (string-to-number (match-string 2)))
-	    (c (string-to-number (match-string 3))))
+      (let* ((spec (match-string 1))
+	     (r (string-to-number (match-string 2)))
+	     (c (string-to-number (match-string 3)))
+	     (cell-styles (org-odt-get-table-cell-styles
+			   r c org-odt-table-style-spec))
+	     (table-cell-style (car cell-styles))
+	     (table-cell-paragraph-style (cdr cell-styles)))
 	(cond
 	 ((equal spec "table-cell:p")
-	  (let ((style-name (org-odt-get-paragraph-style-for-table-cell r c)))
-	    (replace-match style-name t t)))
+	  (replace-match table-cell-paragraph-style t t))
 	 ((equal spec "table-cell:style-name")
-	  (let ((style-name (org-odt-get-style-name-for-table-cell r c)))
-	    (replace-match style-name t t)))))))
-
+	  (replace-match table-cell-style t t))))))
   (goto-char (point-max))
   (org-lparse-insert-tag "</table:table>"))
 
@@ -653,30 +749,87 @@ PUB-DIR is set, use this as the publishing directory."
   (org-odt-format-tags
    '("<table:table-row>" . "</table:table-row>") row))
 
-(defun org-odt-get-style-name-for-table-cell (r c)
-  (concat
-   "OrgTblCell"
-   (cond
-    ((= r 0) "T")
-    ((eq (cdr (assoc r org-lparse-table-rowgrp-info))  :start) "T")
-    (t ""))
-   (when (= r org-lparse-table-rownum) "B")
-   (cond
-    ((= c 0) "")
-    ((or (memq (nth c org-table-colgroup-info) '(:start :startend))
-	 (memq (nth (1- c) org-table-colgroup-info) '(:end :startend))) "L")
-    (t ""))))
-
-(defun org-odt-get-paragraph-style-for-table-cell (r c)
-  (capitalize (aref org-lparse-table-colalign-vector c)))
+(defun org-odt-get-table-cell-styles (r c &optional style-spec)
+  "Retrieve styles applicable to a table cell.
+R and C are (zero-based) row and column numbers of the table
+cell.  STYLE-SPEC is an entry in `org-export-odt-table-styles'
+applicable to the current table.  It is `nil' if the table is not
+associated with any style attributes.
+
+Return a cons of (TABLE-CELL-STYLE-NAME . PARAGRAPH-STYLE-NAME).
+
+When STYLE-SPEC is nil, style the table cell the conventional way
+- choose cell borders based on row and column groupings and
+choose paragraph alignment based on `org-col-cookies' text
+property.  See also
+`org-odt-get-paragraph-style-cookie-for-table-cell'.
+
+When STYLE-SPEC is non-nil, ignore the above cookie and return
+styles congruent with the ODF-1.2 specification."
+  (cond
+   (style-spec
+
+    ;; LibreOffice - particularly the Writer - honors neither table
+    ;; templates nor custom table-cell styles.  Inorder to retain
+    ;; inter-operability with LibreOffice, only automatic styles are
+    ;; used for styling of table-cells.  The current implementation is
+    ;; congruent with ODF-1.2 specification and hence is
+    ;; future-compatible.
+
+    ;; Additional Note: LibreOffice's AutoFormat facility for tables -
+    ;; which recognizes as many as 16 different cell types - is much
+    ;; richer. Unfortunately it is NOT amenable to easy configuration
+    ;; by hand.
+
+    (let* ((template-name (nth 1 style-spec))
+	   (cell-style-selectors (nth 2 style-spec))
+	   (cell-type
+	    (cond
+	     ((and (cdr (assoc 'use-first-column-styles cell-style-selectors))
+		   (= c 0)) "FirstColumn")
+	     ((and (cdr (assoc 'use-last-column-styles cell-style-selectors))
+		   (= c (1- org-lparse-table-ncols))) "LastColumn")
+	     ((and (cdr (assoc 'use-first-row-styles cell-style-selectors))
+		   (= r 0)) "FirstRow")
+	     ((and (cdr (assoc 'use-last-row-styles cell-style-selectors))
+		   (= r org-lparse-table-rownum))
+	      "LastRow")
+	     ((and (cdr (assoc 'use-banding-rows-styles cell-style-selectors))
+		   (= (% r 2) 1)) "EvenRow")
+	     ((and (cdr (assoc 'use-banding-rows-styles cell-style-selectors))
+		   (= (% r 2) 0)) "OddRow")
+	     ((and (cdr (assoc 'use-banding-columns-styles cell-style-selectors))
+		   (= (% c 2) 1)) "EvenColumn")
+	     ((and (cdr (assoc 'use-banding-columns-styles cell-style-selectors))
+		   (= (% c 2) 0)) "OddColumn")
+	     (t ""))))
+      (cons
+       (concat template-name cell-type "TableCell")
+       (concat template-name cell-type "TableParagraph"))))
+   (t
+    (cons
+     (concat
+      "OrgTblCell"
+      (cond
+       ((= r 0) "T")
+       ((eq (cdr (assoc r org-lparse-table-rowgrp-info))  :start) "T")
+       (t ""))
+      (when (= r org-lparse-table-rownum) "B")
+      (cond
+       ((= c 0) "")
+       ((or (memq (nth c org-table-colgroup-info) '(:start :startend))
+	    (memq (nth (1- c) org-table-colgroup-info) '(:end :startend))) "L")
+       (t "")))
+     (capitalize (aref org-lparse-table-colalign-vector c))))))
 
 (defun org-odt-get-paragraph-style-cookie-for-table-cell (r c)
   (concat
-   (cond
-    (org-lparse-table-cur-rowgrp-is-hdr "OrgTableHeading")
-    ((and (= c 0) (org-lparse-get 'TABLE-FIRST-COLUMN-AS-LABELS))
-     "OrgTableHeading")
-    (t "OrgTableContents"))
+   (and (not org-odt-table-style-spec)
+	(cond
+	 (org-lparse-table-cur-rowgrp-is-hdr "OrgTableHeading")
+	 ((and (= c 0) (org-lparse-get 'TABLE-FIRST-COLUMN-AS-LABELS))
+	  "OrgTableHeading")
+	 (t "OrgTableContents")))
    (and org-lparse-table-is-styled
 	(format "@@table-cell:p@@%03d@@%03d@@" r c))))
 
@@ -1017,51 +1170,11 @@ 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
@@ -1069,11 +1182,20 @@ value of `org-export-odt-use-htmlfontify."
 			      (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))))
+	   width height)
+      (cond
+       ((eq embed-as 'character)
+	(org-odt-format-entity "InlineFormula" href width height))
+       (t
+	(org-lparse-end-paragraph)
+	(org-lparse-insert-list-table
+	 `((,(org-odt-format-entity
+	      (if caption "CaptionedDisplayFormula" "DisplayFormula")
+	      href width height caption nil)
+	    ,(if (not label) ""
+	       (org-odt-format-entity-caption label nil "Equation"))))
+	 nil nil nil "OrgEquation" nil '((1 "c" 8) (2 "c" 1)))
+	(throw 'nextline nil))))))
 
 (defvar org-odt-embedded-formulas-count 0)
 (defun org-odt-copy-formula-file (path)
@@ -1256,12 +1378,20 @@ MAY-INLINE-P allows inlining it as an image."
 	   (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 (car size) (cdr size) href))))
+		  (plist-get attr-plist :scale) nil embed-as))
+	   (width (car size)) (height (cdr size)))
+      (cond
+       ((not (or caption label))
+	(case embed-as
+	  (paragraph (org-odt-format-entity "DisplayImage" href width height))
+	  (character (org-odt-format-entity "InlineImage" href width height))
+	  (t (error "Unknown value for embed-as %S" embed-as))))
+       (t
+	(org-odt-format-entity
+	 "CaptionedDisplayImage" href width height caption label))))))
 
-(defun org-odt-format-frame (text style &optional
-				  width height extra anchor-type)
+(defun org-odt-format-frame (text width height style &optional
+				  extra anchor-type)
   (let ((frame-attrs
 	 (concat
 	  (if width (format " svg:width=\"%0.2fcm\"" width) "")
@@ -1272,13 +1402,14 @@ MAY-INLINE-P allows inlining it as an image."
      '("<draw:frame draw:style-name=\"%s\"%s>" . "</draw:frame>")
      text style frame-attrs)))
 
-(defun org-odt-format-textbox (text style &optional width height extra)
+(defun org-odt-format-textbox (text width height style &optional
+				    extra anchor-type)
   (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))
+   width nil style extra anchor-type))
 
 (defun org-odt-format-inlinetask (heading content
 					  &optional todo priority tags)
@@ -1289,33 +1420,34 @@ MAY-INLINE-P allows inlining it as an image."
 		 (org-lparse-format
 		  'HEADLINE (concat (org-lparse-format-todo todo) " " heading)
 		  nil tags))
-		content) "OrgInlineTaskFrame" nil nil " style:rel-width=\"100%\"")))
-(defun org-export-odt-do-format-image (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 " 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))))))
+		content) nil nil "OrgInlineTaskFrame" " style:rel-width=\"100%\"")))
+
+(defvar org-odt-entity-frame-styles
+  '(("InlineImage" "Figure" ("OrgInlineImage" nil "as-char"))
+    ("DisplayImage" "Figure" ("OrgDisplayImage" nil "paragraph"))
+    ("CaptionedDisplayImage" "Figure"
+     ("OrgCaptionedImage"
+      " style:rel-width=\"100%\" style:rel-height=\"scale\"" "paragraph")
+     ("OrgImageCaptionFrame"))
+    ("InlineFormula" "Equation" ("OrgInlineFormula" nil "as-char"))
+    ("DisplayFormula" "Equation" ("OrgDisplayFormula" nil "as-char"))
+    ("CaptionedDisplayFormula" "Equation"
+     ("OrgCaptionedFormula" nil "paragraph")
+     ("OrgFormulaCaptionFrame" nil "as-char"))))
+
+(defun org-odt-format-entity (entity href width height &optional caption label)
+  (let* ((entity-style (assoc entity org-odt-entity-frame-styles))
+	 (entity-frame (apply 'org-odt-format-frame
+			      href width height (nth 2 entity-style))))
+    (if (not (or caption label)) entity-frame
+      (apply 'org-odt-format-textbox
+	     (org-odt-format-stylized-paragraph
+	      'illustration
+	      (concat entity-frame (org-odt-format-entity-caption
+				    label caption (nth 1 entity-style))))
+	     width height (nth 3 entity-style)))))
+
+
 
 (defvar org-odt-embedded-images-count 0)
 (defun org-odt-copy-image-file (path)
@@ -1401,22 +1533,105 @@ MAY-INLINE-P allows inlining it as an image."
      (t (ignore)))
     (cons width height)))
 
-(defvar org-odt-default-entity "Illustration")
-(defun org-odt-format-entity-caption (label caption &optional default-entity)
-  (if (not label) (or caption "")
-    (let* ((label-components (org-odt-parse-label label))
-	   (entity (car label-components))
-	   (seqno (cdr label-components))
-	   (caption (and caption (concat ": " caption))))
-      (unless seqno
-	(setq seqno label
-	      entity (or default-entity org-odt-default-entity)))
-      (concat
-       entity " "
-       (org-odt-format-tags
-	'("<text:sequence text:ref-name=\"%s\" text:name=\"%s\" text:formula=\"ooow:%s+1\" style:num-format=\"1\">" . "</text:sequence>")
-	seqno label entity entity)
-       caption))))
+(defvar org-odt-entity-labels-alist nil
+  "Associate Labels with the Labelled entities.
+Each element of the alist is of the form (LABEL-NAME
+CATEGORY-NAME SEQNO).  LABEL-NAME is same as that specified by
+\"#+LABEL: ...\" line.  CATEGORY-NAME is the type of the entity
+that LABEL-NAME is attached to.  CATEGORY-NAME can be one of
+\"Table\", \"Figure\" or \"Equation\".  SEQNO is the unique
+number assigned to the referenced entity on a per-CATEGORY basis.
+It is generated sequentially and is 1-based.
+
+Update this alist with `org-odt-add-label-definition' and
+retrieve an entry with `org-odt-get-label-definition'.")
+
+(defvar org-odt-entity-counts-plist nil
+  "Plist of running counters of SEQNOs for each of the CATEGORY-NAMEs.
+See `org-odt-entity-labels-alist' for known CATEGORY-NAMEs.")
+
+(defvar org-odt-label-def-ref-spec
+  '(("Equation" "(%n)" "text" "(%n)")
+    ("" "%e %n%c" "category-and-value" "%e %n"))
+  "Specify how labels are applied and referenced.
+This is an alist where each element is of the form (CATEGORY-NAME
+LABEL-APPLY-FMT LABEL-REF-MODE LABEL-REF-FMT).  CATEGORY-NAME is
+as defined in `org-odt-entity-labels-alist'.  It can additionally
+be an empty string in which case it is used as a catch-all
+specifier.
+
+LABEL-APPLY-FMT is used for applying labels and captions.  It may
+contain following specifiers - %e, %n and %c.  %e is replaced
+with the CATEGORY-NAME.  %n is replaced with \"<text:sequence
+...> SEQNO </text:sequence>\".  %c is replaced with CAPTION. See
+`org-odt-format-label-definition'.
+
+LABEL-REF-MODE and LABEL-REF-FMT are used for generating the
+following label reference - \"<text:sequence-ref
+text:reference-format=\"LABEL-REF-MODE\" ...> LABEL-REF-FMT
+</text:sequence-ref>\".  LABEL-REF-FMT may contain following
+specifiers - %e and %n.  %e is replaced with the CATEGORY-NAME.  %n is
+replaced with SEQNO. See `org-odt-format-label-reference'.")
+
+(defun org-odt-add-label-definition (label category)
+  "Return (SEQNO . LABEL-APPLY-FMT).
+See `org-odt-label-def-ref-spec'."
+  (setq label (substring-no-properties label))
+  (let (seqno label-props fmt (category-sym (intern category)))
+    (setq seqno (1+ (plist-get org-odt-entity-counts-plist category-sym))
+	  org-odt-entity-counts-plist (plist-put org-odt-entity-counts-plist
+						 category-sym seqno)
+	  fmt (cadr (or (assoc-string category org-odt-label-def-ref-spec t)
+			(assoc-string "" org-odt-label-def-ref-spec t)))
+	  label-props (list label category seqno))
+    (push label-props org-odt-entity-labels-alist)
+    (cons seqno fmt)))
+
+(defun org-odt-get-label-definition (label)
+  "Return (LABEL-NAME CATEGORY-NAME SEQNO LABEL-REF-MODE LABEL-REF-FMT).
+See `org-odt-entity-labels-alist' and
+`org-odt-label-def-ref-spec'."
+  (let* ((label-props (assoc label org-odt-entity-labels-alist))
+	 (category (nth 1 label-props)))
+    (append label-props
+	    (cddr (or (assoc-string category org-odt-label-def-ref-spec t)
+		      (assoc-string "" org-odt-label-def-ref-spec t))))))
+
+(defun org-odt-format-label-definition (label category caption)
+  (assert label)
+  (let* ((label-props (org-odt-add-label-definition label category))
+	 (seqno (car label-props))
+	 (fmt (cdr label-props)))
+    (or (format-spec
+	 fmt
+	 `((?e . ,category)
+	   (?n . ,(org-odt-format-tags
+		   '("<text:sequence text:ref-name=\"%s\" text:name=\"%s\" text:formula=\"ooow:%s+1\" style:num-format=\"1\">" . "</text:sequence>")
+		   (format "%d" seqno) label category category))
+	   (?c . ,(or (and caption (concat ": " caption)) ""))))
+	caption "")))
+
+(defun org-odt-format-label-reference (label category seqno fmt1 fmt2)
+  (assert label)
+  (save-match-data
+    (org-odt-format-tags
+     '("<text:sequence-ref text:reference-format=\"%s\" text:ref-name=\"%s\">"
+       . "</text:sequence-ref>")
+     (format-spec fmt2 `((?e . ,category)
+			 (?n . ,(format "%d" seqno)))) fmt1 label)))
+
+(defun org-odt-fixup-label-references ()
+  (goto-char (point-min))
+  (while (re-search-forward
+	  "<text:sequence-ref text:ref-name=\"\\([^\"]+\\)\"/>" nil t)
+    (let* ((label (match-string 1)))
+      (replace-match
+       (apply 'org-odt-format-label-reference
+	      (org-odt-get-label-definition label)) t t))))
+
+(defun org-odt-format-entity-caption (label caption category)
+  (or (and label (org-odt-format-label-definition label category caption))
+      caption ""))
 
 (defun org-odt-format-tags (tag text &rest args)
   (let ((prefix (when org-lparse-encode-pending "@"))
@@ -1437,8 +1652,9 @@ MAY-INLINE-P allows inlining it as an image."
     ;; reset variables
     (setq org-odt-manifest-file-entries nil
 	  org-odt-embedded-images-count 0
-	  org-odt-embedded-formulas-count 0)
-
+	  org-odt-embedded-formulas-count 0
+	  org-odt-entity-labels-alist nil
+	  org-odt-entity-counts-plist (list 'Table 0 'Equation 0 'Figure 0))
     content-file))
 
 (defcustom org-export-odt-prettify-xml nil
@@ -1673,14 +1889,6 @@ visually."
     (CODING-SYSTEM-FOR-SAVE 'utf-8)
     (t (error "Unknown property: %s"  what))))
 
-(defun org-odt-parse-label (label)
-  (save-match-data
-    (if (not (string-match "\\`[a-zA-Z]+:\\(.+\\)" label))
-	(cons label nil)
-      (cons
-       (capitalize (substring label 0 (1- (match-beginning 1))))
-       (substring label (match-beginning 1))))))
-
 (defvar org-lparse-latex-fragment-fallback) ; set by org-do-lparse
 (defvar org-lparse-opt-plist)		    ; bound during org-do-lparse
 (defun org-export-odt-do-preprocess-latex-fragments ()
@@ -1722,16 +1930,18 @@ visually."
   (let (label label-components category value pretty-label)
     (while (re-search-forward "\\\\ref{\\([^{}\n]+\\)}" nil t)
       (org-if-unprotected-at (match-beginning 1)
-	(setq label (match-string 1)
-	      label-components (org-odt-parse-label label)
-	      category (car label-components)
-	      value (cdr label-components)
-	      pretty-label (if value (concat category " " value) label))
 	(replace-match
-	 (let ((org-lparse-encode-pending t))
+	 (let ((org-lparse-encode-pending t)
+	       (label (match-string 1)))
+	   ;; markup generated below is mostly an eye-candy.  At
+	   ;; pre-processing stage, there is no information on which
+	   ;; entity a label reference points to.  The actual markup
+	   ;; is generated as part of `org-odt-fixup-label-references'
+	   ;; which gets called at the fag end of export.  By this
+	   ;; time we would have seen and collected all the label
+	   ;; definitions in `org-odt-entity-labels-alist'.
 	   (org-odt-format-tags
-	    '("<text:sequence-ref text:reference-format=\"category-and-value\" text:ref-name=\"%s\">"
-	      . "</text:sequence-ref>") pretty-label label)) t t)))))
+	    "<text:sequence-ref text:ref-name=\"%s\"/>" "" label)) t t)))))
 
 ;; process latex fragments as part of
 ;; `org-export-preprocess-after-blockquote-hook'. Note that this hook

+ 39 - 17
contrib/odt/styles/OrgOdtContentTemplate.xml

@@ -46,7 +46,7 @@
   <!-- automatic styles -->
   <office:automatic-styles>
     <style:style style:name="OrgTable" style:family="table">
-      <style:table-properties style:rel-width="90%" table:align="center"/>
+      <style:table-properties style:rel-width="90%" fo:margin-top="0cm" fo:margin-bottom="0.20cm" table:align="center"/>
     </style:style>
 
     <style:style style:name="OrgTableColumn" style:family="table-column">
@@ -57,50 +57,72 @@
       <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: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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="none" fo:border-left="0.002cm solid #000000" fo:border-right="none"/>
     </style:style>
     <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: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.002cm solid #000000"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="none" fo:border-left="0.002cm solid #000000" fo:border-right="0.002cm solid #000000"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="none" fo:border-left="none" fo:border-right="none"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="none" fo:border-left="0.002cm solid #000000" fo:border-right="none"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="none" fo:border-left="none" fo:border-right="0.002cm solid #000000"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="none" fo:border-left="0.002cm solid #000000" fo:border-right="0.002cm solid #000000"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.002cm solid #000000" fo:border-left="none" fo:border-right="none"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.002cm solid #000000" fo:border-left="0.002cm solid #000000" fo:border-right="none"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.002cm solid #000000" fo:border-left="none" fo:border-right="0.002cm solid #000000"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="none" fo:border-bottom="0.002cm solid #000000" fo:border-left="0.002cm solid #000000" fo:border-right="0.002cm solid #000000"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="0.002cm solid #000000" fo:border-left="none" fo:border-right="none"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="0.002cm solid #000000" fo:border-left="0.002cm solid #000000" fo:border-right="none"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="0.002cm solid #000000" fo:border-left="none" fo:border-right="0.002cm solid #000000"/>
     </style:style>
     <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:table-cell-properties style:vertical-align="middle" fo:padding="0.159cm" fo:border-top="0.002cm solid #000000" fo:border-bottom="0.002cm solid #000000" fo:border-left="0.002cm solid #000000" fo:border-right="0.002cm solid #000000"/>
     </style:style>
+
+    <!-- BEGIN: Table styles for numbered equations -->
+    <style:style style:name="OrgEquation" style:family="table">
+      <style:table-properties style:rel-width="100%" fo:margin-top="0cm" fo:margin-bottom="0.20cm" table:align="center"/>
+    </style:style>
+    <style:style style:name="OrgEquationTableColumn" style:family="table-column">
+      <style:table-column-properties style:rel-column-width="1*"/>
+    </style:style>
+    <style:style style:name="OrgFirstEquationFirstColumnTableCell" 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="OrgEquationLastColumnTableCell" 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="OrgEquationFirstColumnTableParagraph" style:family="paragraph" style:parent-style-name="Table_20_Contents">
+      <style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
+    </style:style>
+    <style:style style:name="OrgEquationLastColumnTableParagraph" style:family="paragraph" style:parent-style-name="Table_20_Contents">
+      <style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
+    </style:style>
+    <!-- END: Table styles for numbered equations -->
+
   </office:automatic-styles>
 
   <office:body>
@@ -111,8 +133,8 @@
 	<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-decl text:display-outline-level="0" text:name="Figure"/>
       </text:sequence-decls>
-
     </office:text>
   </office:body>
 </office:document-content>

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

@@ -363,29 +363,49 @@
   </style:style>
 
   <!-- Simple Images   -->
-  <style:style style:name="OrgSimpleGraphics" style:family="graphic" style:parent-style-name="Graphics">
+  <style:style style:name="OrgDisplayImage" 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:style style:name="OrgCaptionedImage" 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:style style:name="OrgImageCaptionFrame" 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:style style:name="OrgInlineImage" 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="OrgFormula" style:family="graphic">
+    <style:graphic-properties text:anchor-type="as-char" svg:y="0cm" fo:margin-left="0.201cm" fo:margin-right="0.201cm" style:vertical-pos="middle" style:vertical-rel="text" style:shadow="none"/>
+  </style:style>
+
   <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>
 
+  <style:style style:name="OrgInlineFormula" style:family="graphic" style:parent-style-name="Formula">
+    <style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" draw:ole-draw-aspect="1"/>
+  </style:style>
+
+  <style:style style:name="OrgDisplayFormula" style:family="graphic" style:parent-style-name="OrgFormula">
+    <style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="from-left" style:horizontal-rel="paragraph-content" draw:ole-draw-aspect="1"/>
+  </style:style>
+
+  <style:style style:name="OrgFormulaCaptionFrame" style:family="graphic" style:parent-style-name="Frame">
+    <style:graphic-properties fo:margin-top="0cm" fo:margin-bottom="0cm" style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="from-left" style:horizontal-rel="paragraph-content" fo:padding="0cm" fo:border="none"/>
+  </style:style>
+
+  <style:style style:name="OrgCaptionedFormula" style:family="graphic" style:parent-style-name="OrgFormula">
+    <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="center" style:horizontal-rel="paragraph-content" fo:padding="0cm" fo:border="none" style:shadow="none" draw:ole-draw-aspect="1"/>
+  </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-C.el

@@ -179,7 +179,7 @@ of the same value."
       (format "int %S = %S;" var val))
      ((floatp val)
       (format "double %S = %S;" var val))
-     ((or (characterp val))
+     ((or (integerp val))
       (format "char %S = '%S';" var val))
      ((stringp val)
       (format "char %S[%d] = \"%s\";"

+ 24 - 12
lisp/ob-R.el

@@ -79,7 +79,8 @@
   "Execute a block of R code.
 This function is called by `org-babel-execute-src-block'."
   (save-excursion
-    (let* ((result-type (cdr (assoc :result-type params)))
+    (let* ((result-params (cdr (assoc :result-params params)))
+	   (result-type (cdr (assoc :result-type params)))
            (session (org-babel-R-initiate-session
 		     (cdr (assoc :session params)) params))
 	   (colnames-p (cdr (assoc :colnames params)))
@@ -88,7 +89,7 @@ This function is called by `org-babel-execute-src-block'."
 	   (full-body (org-babel-expand-body:R body params graphics-file))
 	   (result
 	    (org-babel-R-evaluate
-	     session full-body result-type
+	     session full-body result-type result-params
 	     (or (equal "yes" colnames-p)
 		 (org-babel-pick-name
 		  (cdr (assoc :colname-names params)) colnames-p))
@@ -231,16 +232,15 @@ current code buffer."
 (defvar org-babel-R-write-object-command "{function(object,transfer.file){object;invisible(if(inherits(try({tfile<-tempfile();write.table(object,file=tfile,sep=\"\\t\",na=\"nil\",row.names=%s,col.names=%s,quote=FALSE);file.rename(tfile,transfer.file)},silent=TRUE),\"try-error\")){if(!file.exists(transfer.file))file.create(transfer.file)})}}(object=%s,transfer.file=\"%s\")")
 
 (defun org-babel-R-evaluate
-  (session body result-type column-names-p row-names-p)
+  (session body result-type result-params column-names-p row-names-p)
   "Evaluate R code in BODY."
-  (if session
-      (org-babel-R-evaluate-session
-       session body result-type column-names-p row-names-p)
-    (org-babel-R-evaluate-external-process
-     body result-type column-names-p row-names-p)))
+  (funcall (if session
+	       #'org-babel-R-evaluate-session
+	     #'org-babel-R-evaluate-external-process)
+	   body result-type result-params column-names-p row-names-p))
 
 (defun org-babel-R-evaluate-external-process
-  (body result-type column-names-p row-names-p)
+  (body result-type result-params column-names-p row-names-p)
   "Evaluate BODY in external R process.
 If RESULT-TYPE equals 'output then return standard output as a
 string. If RESULT-TYPE equals 'value then return the value of the
@@ -257,11 +257,17 @@ last statement in BODY, as elisp."
 			       (format "{function ()\n{\n%s\n}}()" body)
 			       (org-babel-process-file-name tmp-file 'noquote)))
        (org-babel-R-process-value-result
-	(org-babel-import-elisp-from-file tmp-file '(16)) column-names-p)))
+	(if (or (member "scalar" result-params)
+		(member "verbatim" result-params))
+	    (with-temp-buffer
+	      (insert-file-contents tmp-file)
+	      (buffer-string))
+	  (org-babel-import-elisp-from-file tmp-file '(16)))
+	column-names-p)))
     (output (org-babel-eval org-babel-R-command body))))
 
 (defun org-babel-R-evaluate-session
-  (session body result-type column-names-p row-names-p)
+  (session body result-type result-params column-names-p row-names-p)
   "Evaluate BODY in SESSION.
 If RESULT-TYPE equals 'output then return standard output as a
 string. If RESULT-TYPE equals 'value then return the value of the
@@ -283,7 +289,13 @@ last statement in BODY, as elisp."
 		  "FALSE")
 		".Last.value" (org-babel-process-file-name tmp-file 'noquote)))
        (org-babel-R-process-value-result
-	(org-babel-import-elisp-from-file tmp-file '(16))  column-names-p)))
+	(if (or (member "scalar" result-params)
+		(member "verbatim" result-params))
+	    (with-temp-buffer
+	      (insert-file-contents tmp-file)
+	      (buffer-string))
+	  (org-babel-import-elisp-from-file tmp-file '(16)))
+	column-names-p)))
     (output
      (mapconcat
       #'org-babel-chomp

+ 27 - 16
lisp/ob-tangle.el

@@ -95,6 +95,14 @@ controlled by the :comments header argument."
   :group 'org-babel
   :type 'string)
 
+(defcustom org-babel-process-comment-text #'org-babel-trim
+  "Function called to process raw Org-mode text collected to be
+inserted as comments in tangled source-code files.  The function
+should take a single string argument and return a string
+result.  The default value is `org-babel-trim'."
+  :group 'org-babel
+  :type 'function)
+
 (defun org-babel-find-file-noselect-refresh (file)
   "Find file ensuring that the latest changes on disk are
 represented in the file."
@@ -345,16 +353,20 @@ code blocks by language."
 		    (when (or (string= "both" (cdr (assoc :comments params)))
 			      (string= "org" (cdr (assoc :comments params))))
 		      ;; from the previous heading or code-block end
-		      (buffer-substring
-		       (max (condition-case nil
-				(save-excursion
-				  (org-back-to-heading t) (point))
-			      (error 0))
-			    (save-excursion
-			      (re-search-backward
-			       org-babel-src-block-regexp nil t)
-			      (match-end 0)))
-		       (point))))
+		      (funcall
+		       org-babel-process-comment-text
+		       (buffer-substring
+			(max (condition-case nil
+				 (save-excursion
+				   (org-back-to-heading t)  ; sets match data
+				   (match-end 0))
+			       (error (point-min)))
+			     (save-excursion
+			       (if (re-search-backward
+				    org-babel-src-block-regexp nil t)
+				   (match-end 0)
+				 (point-min))))
+			(point)))))
 		   by-lang)
 	      ;; add the spec for this block to blocks under it's language
 	      (setq by-lang (cdr (assoc src-lang blocks)))
@@ -396,12 +408,11 @@ form
 				     (eval el))))
 			    '(start-line file link source-name))))
     (flet ((insert-comment (text)
-            (let ((text (org-babel-trim text)))
-	      (when (and comments (not (string= comments "no"))
-			 (> (length text) 0))
-		(when padline (insert "\n"))
-		(comment-region (point) (progn (insert text) (point)))
-		(end-of-line nil) (insert "\n")))))
+            (when (and comments (not (string= comments "no"))
+		       (> (length text) 0))
+	      (when padline (insert "\n"))
+	      (comment-region (point) (progn (insert text) (point)))
+	      (end-of-line nil) (insert "\n"))))
       (when comment (insert-comment comment))
       (when link-p
 	(insert-comment

+ 13 - 4
lisp/ob.el

@@ -220,8 +220,16 @@ Returns a list
 	    (when (match-string 6)
 	      (setf (nth 2 info) ;; merge functional-syntax vars and header-args
 		    (org-babel-merge-params
-		     (mapcar (lambda (ref) (cons :var ref))
-			     (org-babel-ref-split-args (match-string 6)))
+		     (mapcar
+		      (lambda (ref) (cons :var ref))
+		      (mapcar
+		       (lambda (var) ;; check that each variable is initialized
+			 (if (string-match ".+=.+" var)
+			     var
+			   (error
+			    "variable \"%s\"%s must be assigned a default value"
+			    var (if name (format " in block \"%s\"" name) ""))))
+		       (org-babel-ref-split-args (match-string 6))))
 		     (nth 2 info))))))
       ;; inline source block
       (when (org-babel-get-inline-src-block-matches)
@@ -550,6 +558,7 @@ arguments and pop open the results in a preview buffer."
   (interactive)
   ;; TODO: report malformed code block
   ;; TODO: report incompatible combinations of header arguments
+  ;; TODO: report uninitialized variables
   (let ((too-close 2)) ;; <- control closeness to report potential match
     (dolist (header (mapcar (lambda (arg) (substring (symbol-name (car arg)) 1))
 			    (and (org-babel-where-is-src-block-head)
@@ -1795,8 +1804,8 @@ Later elements of PLISTS override the values of previous elements.
 This takes into account some special considerations for certain
 parameters when merging lists."
   (let ((results-exclusive-groups
-	 '(("file" "list" "vector" "table" "scalar" "verbatim" "raw" "org"
-            "html" "latex" "code" "pp" "wrap")
+	 '(("file" "list" "vector" "table" "scalar" "verbatim")
+	   ("raw" "org" "html" "latex" "code" "pp" "wrap")
 	   ("replace" "silent" "append" "prepend")
 	   ("output" "value")))
 	(exports-exclusive-groups

+ 1 - 1
lisp/org-footnote.el

@@ -249,7 +249,7 @@ footnote text is included and defined locally.
 
 The return value will be nil if not at a footnote definition, and a list with
 label, start, end and definition of the footnote otherwise."
-  (when (org-footnote-in-valid-context-p)
+  (when (save-excursion (beginning-of-line) (org-footnote-in-valid-context-p))
     (save-excursion
       (end-of-line)
       (let ((lim (save-excursion (re-search-backward

+ 15 - 0
testing/examples/babel-dangerous.org

@@ -0,0 +1,15 @@
+#+Title: dangerous code block examples which should be isolated
+#+OPTIONS: ^:nil
+
+* no default value for vars
+  :PROPERTIES:
+  :ID:       f2df5ba6-75fa-4e6b-8441-65ed84963627
+  :END:
+
+There is no default value assigned to =x= variable. This is not permitted
+anymore.
+
+#+source: carre(x)
+#+begin_src python
+  return x*x
+#+end_src

+ 19 - 0
testing/examples/babel.org

@@ -289,3 +289,22 @@ 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" }.
+* returning file names -- interpreted as lists
+  :PROPERTIES:
+  :ID:       a73a2ab6-b8b2-4c0e-ae7f-23ad14eab7bc
+  :END:
+
+#+begin_src sh :results scalar
+  echo "[[file:./cv.cls]]"
+#+end_src
+
+#+results:
+: [[file:./cv.cls]]
+
+#+begin_src sh :results raw scalar
+   echo "[[file:./cv.cls]]"
+#+end_src
+
+#+results:
+[[file:./cv.cls]]
+

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

@@ -1,6 +1,6 @@
 ;;; test-ob.el --- tests for ob.el
 
-;; Copyright (c) 2010 Eric Schulte
+;; Copyright (c) 2010, 2011 Eric Schulte
 ;; Authors: Eric Schulte, Martyn Jago
 
 ;; Released under the GNU General Public License version 3
@@ -409,6 +409,27 @@
       (should (string= (concat test-line " =\"x\"=")
 		       (buffer-substring-no-properties (point-min) (point-max)))))))
 
+(ert-deftest test-org-babel/combining-scalar-and-raw-result-types ()
+  (flet ((next-result ()
+		      (org-babel-next-src-block)
+		      (org-babel-execute-src-block)
+		      (goto-char (org-babel-where-is-src-block-result))
+		      (forward-line 1)))
+    (org-test-at-id "a73a2ab6-b8b2-4c0e-ae7f-23ad14eab7bc"
+      (next-result)
+      (should (org-babel-in-example-or-verbatim))
+      (next-result)
+      (should (not (org-babel-in-example-or-verbatim))))))
+
+(ert-deftest test-org-babel/no-defaut-value-for-var ()
+  "Test that the absence of a default value for a variable DOES THROW
+  a proper error."
+  (org-test-at-id "f2df5ba6-75fa-4e6b-8441-65ed84963627"
+    (org-babel-next-src-block)
+    (let ((err
+	   (should-error (org-babel-execute-src-block) :type 'error)))
+      (should (equal '(error "variable \"x\" in block \"carre\" must be assigned a default value") err)))))
+
 (provide 'test-ob)
 
 ;;; test-ob ends here

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

@@ -82,7 +82,7 @@
   (should
    (string=
     "àâçèéêîôùû"
-    (org-link-unescape "%E0%E2%E7%E8%E9%EA%EE%F4%F9%FB"))))
+        (decode-coding-string (org-link-unescape "%E0%E2%E7%E8%E9%EA%EE%F4%F9%FB") 'latin-1))))
 
 (ert-deftest test-org/org-link-escape-url-with-escaped-char ()
   "Escape and unscape a URL that includes an escaped char.

+ 41 - 1
testing/org-test.el

@@ -4,10 +4,14 @@
 ;; Authors:
 ;;     Sebastian Rose, Hannover, Germany, sebastian_rose gmx de
 ;;     Eric Schulte, Santa Fe, New Mexico, USA, schulte.eric gmail com
+;;     David Maus, Brunswick, Germany, dmaus ictsoc de
 
 ;; Released under the GNU General Public License version 3
 ;; see: http://www.gnu.org/licenses/gpl-3.0.html
 
+;; Definition of `special-mode' copied from Emacs23's simple.el to be
+;; provide a testing environment for Emacs22.
+
 ;;;; Comments:
 
 ;; Interactive testing for Org mode.
@@ -31,7 +35,7 @@
 		       (or load-file-name buffer-file-name)))))
    (let ((org-lisp-dir (expand-file-name
    		       (concat org-test-dir "../lisp"))))
-     (unless (member 'features "org")
+     (unless (featurep 'org)
        (setq load-path (cons org-lisp-dir load-path))
        (org-babel-do-load-languages
 	'org-babel-load-languages '((sh . t)))))
@@ -41,6 +45,25 @@
 		      (expand-file-name "jump" org-test-dir)
 		      load-path))))
     (require 'cl)
+    (when (= emacs-major-version 22)
+      (defvar special-mode-map
+	(let ((map (make-sparse-keymap)))
+	  (suppress-keymap map)
+	  (define-key map "q" 'quit-window)
+	  (define-key map " " 'scroll-up)
+	  (define-key map "\C-?" 'scroll-down)
+	  (define-key map "?" 'describe-mode)
+	  (define-key map "h" 'describe-mode)
+	  (define-key map ">" 'end-of-buffer)
+	  (define-key map "<" 'beginning-of-buffer)
+	  (define-key map "g" 'revert-buffer)
+	  (define-key map "z" 'kill-this-buffer)
+	  map))
+
+      (put 'special-mode 'mode-class 'special)
+      (define-derived-mode special-mode nil "Special"
+	"Parent major mode from which special major modes should inherit."
+	(setq buffer-read-only t)))
     (require 'ert)
     (require 'ert-x)
     (when (file-exists-p
@@ -138,6 +161,23 @@ files."
      (re-search-forward (regexp-quote ,marker))
      ,@body))
 
+(defmacro org-test-with-temp-text (text &rest body)
+  "Run body in a temporary buffer with Org-mode as the active
+mode holding TEXT.  If the string \"<point>\" appears in TEXT
+then remove it and place the point there before running BODY."
+  (declare (indent 1))
+  `(with-temp-buffer
+     (org-mode)
+     ,(let ((point (string-match (regexp-quote "<point>") text)))
+	(if point
+	    `(progn
+	       (insert `(replace-match "" nil nil text))
+	       (goto-char ,(match-beginning 0)))
+	  `(progn
+	     (insert ,text)
+	     (goto-char (point-min)))))
+     ,@body))
+
 
 ;;; Navigation Functions
 (when (featurep 'jump)