Subject: bug#15384: closed (Re: bug#15384: 24.3.50; Org ODT exporter patches (released under cc0))

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 17 Sep 2013 21:44:02 +0000

Your bug report

#15384: 24.3.50; Org ODT exporter patches (released under cc0)

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
15384: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15384
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#15384: 24.3.50; Org ODT exporter patches (released under cc0)
From: Glenn Morris <[email-masked]>
To: [email-masked]
Date: Tue, 17 Sep 2013 17:43:08 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Some GNU projects require FSF copyright assignment, and some do not.
Emacs does. This applies equally to the elpa branch / elpa.gnu.org.

(A copyright disclaimer _is_ another option, but this also requires
sending signed paperwork to the FSF, simply saying "this is in the
public domain" is not enough. And it has to be re-done for each change.)

There's nothing to do from the Emacs side but close this as wontfix.

Any further discussion should probably go to gnu-misc-discuss.

Subject: 24.3.50; Org ODT exporter patches (released under cc0)
From: Jambunathan K <[email-masked]>
To: [email-masked]
Date: Sun, 15 Sep 2013 17:09:27 +0530
List-Id: <debbugs-submit.debbugs.gnu.org>

Org ODT exporter patches (released under cc0)

I am releasing a bunch of local changes that I have in my workarea under
the CC0 license.

I am hoping that this will enable the Emacs project manitainers to slap
GPL on top and distribute these files as part of GNU Emacs proper and
GNU ELPA.

I am not interested in signing any paperwork.  Otherwise, I am willing
to do whatever is necessary to have these changes incorporated.

----------------------------------------------------------------

Special requests:

I want two files authored by me to distribute from GNU ELPA (and not Org
contrib). 

1. ox-jabref.el (part of the patch, also included separately)
2. ox-freemind.el (part of org contrib dir)

----------------------------------------------------------------

Summary of patches:

There are 4 patches and it will apply cleanly to commit head fc2ec2eb88
of Orgmode git repo.

b3a6660058fadb2a67b977c553ded414f7a6a657 ox-odt: Add support for JabRef
d330d23b51a691d565a0245f1eb48765c67ad6c0 ox-odt.el: Support for pagebreaks, cust
58598cfd3909ae5a06b583e764f71d15147efe86 ox-odt.el: Fix handling of ODT attribut
f709741922122f76959414f9c152b1aff872ab4e ox-odt: Support for typesetting Descrip

c5f2ae7c8d2bb4f533f0a04bfab17b0db139a8f4 Merge branch 'master' of orgmode.org:or
fc2ec2eb886ae469dbc2fe4fcb3bee91cf94a227 Fix typo
bbe8518118646a28faaedd08f403036c2e2f9939 Given a block with an empty body org-ba

----------------------------------------------------------------

Patches:

>From f709741922122f76959414f9c152b1aff872ab4e Mon Sep 17 00:00:00 2001
From: Jambunathan K <[email-masked]>
Date: Sat, 29 Jun 2013 17:59:48 +0530
Subject: [PATCH 1/4] ox-odt: Support for typesetting Description lists as in LaTeX

* etc/styles.OrgOdtStyles.xml (OrgDescriptionTerm)
(OrgDescriptionDefinition): New styles for typesetting
description lists.

* lisp/ox-odt.el (org-odt-description-list-style): New user option.
(org-odt--translate-description-lists/html): Renmed from
`org-odt--translate-description-lists.  Use new style
"OrgDescriptionTerm".  Update comments.
(org-odt--translate-description-lists/latex): New.
(org-odt-bold): Add an internal `:style' property.

----------------------------------------------------------------

To the extent possible under law, the author(s) have dedicated
all copyright and related and neighboring rights to this software
to the public domain worldwide. This software is distributed
without any warranty.

You should have received a copy of the CC0 Public Domain
Dedication along with this software. If not, see

   <http://creativecommons.org/publicdomain/zero/1.0/>.

----------------------------------------------------------------
---
 etc/styles/OrgOdtStyles.xml |   10 +++
 lisp/ox-odt.el              |  141 +++++++++++++++++++++++++++++++++++++-----
 2 files changed, 134 insertions(+), 17 deletions(-)

diff --git a/etc/styles/OrgOdtStyles.xml b/etc/styles/OrgOdtStyles.xml
index f41d984..c2c32fa 100644
--- a/etc/styles/OrgOdtStyles.xml
+++ b/etc/styles/OrgOdtStyles.xml
@@ -729,6 +729,16 @@
    </text:list-level-style-number>
   </text:list-style>
 
+  <style:style style:name="OrgDescriptionTerm" style:family="text">
+   <style:text-properties fo:font-weight="bold"/>
+  </style:style>
+
+  <style:style style:name="OrgDescriptionDefinition" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="text">
+   <style:paragraph-properties fo:margin-left="0.64cm" fo:margin-right="0cm" fo:text-indent="-0.64cm" style:auto-text-indent="false">
+    <style:tab-stops/>
+   </style:paragraph-properties>
+  </style:style>
+
   <text:list-style style:name="OrgSrcBlockNumberedLine">
    <text:list-level-style-number text:level="1" style:num-format="1">
     <style:list-level-properties text:space-before="0.635cm" text:min-label-width="0.635cm" text:min-label-distance="0.101cm" fo:text-align="end"/>
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index ae9e473..5dcf9ec 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -86,7 +86,7 @@ (org-export-define-backend 'odt
   :export-block "ODT"
   :filters-alist '((:filter-parse-tree
 		    . (org-odt--translate-latex-fragments
-		       org-odt--translate-description-lists
+		       org-odt--translate-description-lists ; Dummy symbol
 		       org-odt--translate-list-tables)))
   :menu-entry
   '(?o "Export to ODT"
@@ -770,6 +770,22 @@ (defcustom org-odt-pixels-per-inch 96.0
   :package-version '(Org . "8.1"))

+;;;; Lists
+
+(defcustom org-odt-description-list-style #'org-odt--translate-description-lists/html
+  "Specify how description lists are rendered.
+Choose one of HTML or LaTeX style."
+  :type '(choice
+          (const :tag "Use HTML style" org-odt--translate-description-lists/html )
+          (const :tag "Use LaTeX style" org-odt--translate-description-lists/latex ))
+  :group 'org-export-odt
+  :set (lambda (symbol value)
+	 "Alias `org-odt--translate-description-lists'."
+	 (set-default symbol value)
+  	 (fset 'org-odt--translate-description-lists value))
+  :version "24.1")
+
+
 ;;;; Src Block
 
 (defcustom org-odt-create-custom-styles-for-srcblocks t
@@ -1561,7 +1577,11 @@ (defun org-odt-bold (bold contents info)
 CONTENTS is the text with bold markup.  INFO is a plist holding
 contextual information."
   (format "<text:span text:style-name=\"%s\">%s</text:span>"
-	  "Bold" contents))
+	  ;; Internally, `org-odt--translate-description-lists/html'
+	  ;; or `org-odt--translate-description-lists/latex' requests
+	  ;; a custom style for bold.
+	  (or (org-element-property :style bold) "Bold")
+	  contents))

 ;;;; Center Block
@@ -3643,7 +3663,7 @@ (defun org-odt-table (table contents info)
     ;;   item, but also within description lists and low-level
     ;;   headlines.
 
-    ;; See `org-odt-translate-description-lists' and
+    ;; See `org-odt--translate-description-lists' and
     ;; `org-odt-translate-low-level-headlines' for how this is
     ;; tackled.
 
@@ -3863,27 +3883,44 @@ (defun org-odt--translate-latex-fragments (tree backend info)
 ;; This translator is necessary to handle indented tables in a uniform
 ;; manner.  See comment in `org-odt--table'.
 
-(defun org-odt--translate-description-lists (tree backend info)
+;; Depending on user option `org-odt-description-list-style',
+;; description lists can be typeset either as in HTML documents or as
+;; in LaTeX documents.
+
+(defun org-odt--translate-description-lists/html (tree backend info)
   ;; OpenDocument has no notion of a description list.  So simulate it
   ;; using plain lists.  Description lists in the exported document
   ;; are typeset in the same manner as they are in a typical HTML
-  ;; document.
+  ;; document.  See `org-odt--translate-description-lists/latex' for
+  ;; yet another way of translation.
   ;;
   ;; Specifically, a description list like this:
   ;;
-  ;;     ,----
-  ;;     | - term-1 :: definition-1
-  ;;     | - term-2 :: definition-2
-  ;;     `----
+  ;; 	 ,----
+  ;; 	 | - term-1 :: definition-1
+  ;; 	 |
+  ;; 	 | 	    paragraph-1
+  ;; 	 |
+  ;; 	 | - term-2 :: definition-2
+  ;; 	 |
+  ;; 	 | 	    paragraph-2
+  ;; 	 `----
   ;;
   ;; gets translated in to the following form:
   ;;
-  ;;     ,----
-  ;;     | - term-1
-  ;;     |   - definition-1
-  ;;     | - term-2
-  ;;     |   - definition-2
-  ;;     `----
+  ;; 	 ,----
+  ;; 	 | - term-1
+  ;;     |
+  ;; 	 |   - definition-1
+  ;; 	 |
+  ;; 	 |     paragraph-1
+  ;; 	 |
+  ;; 	 | - term-2
+  ;;     |
+  ;; 	 |   - definition-2
+  ;; 	 |
+  ;; 	 |     paragraph-2
+  ;; 	 `----
   ;;
   ;; Further effect is achieved by fixing the OD styles as below:
   ;;
@@ -3906,8 +3943,9 @@ (defun org-odt--translate-description-lists (tree backend info)
 		   (org-element-adopt-elements
 		    (list 'item (list :checkbox (org-element-property
 						 :checkbox item)))
-		    (list 'paragraph (list :style "Text_20_body_20_bold")
-			  (or (org-element-property :tag item) "(no term)"))
+		    (list 'paragraph nil
+			  (list 'bold (list :style "OrgDescriptionTerm")
+				(or (org-element-property :tag item) "(no term)")))
 		    (org-element-adopt-elements
 		     (list 'plain-list (list :type 'descriptive-2))
 		     (apply 'org-element-adopt-elements
@@ -3918,6 +3956,75 @@ (defun org-odt--translate-description-lists (tree backend info)
     info)
   tree)
 
+(defun org-odt--translate-description-lists/latex (tree backend info)
+  ;; OpenDocument has no notion of a description list.  So simulate it
+  ;; using plain lists.  Description lists in the exported document
+  ;; are typeset in the same manner as they are in a typical LaTeX
+  ;; style document.  See `org-odt--translate-description-lists/html'
+  ;; for yet another way of translation.
+  ;;
+  ;; Specifically, a description list like this:
+  ;;
+  ;; 	,----
+  ;; 	| - term-1 :: definition-1
+  ;; 	|
+  ;; 	| 	    paragraph-1
+  ;; 	|
+  ;; 	| - term-2 :: definition-2
+  ;; 	|
+  ;; 	| 	    paragraph-2
+  ;; 	`----
+  ;;
+  ;; gets translated in to the following form:
+  ;;
+  ;; 	 ,----
+  ;; 	 | - *term-1* definition-1
+  ;; 	 |
+  ;; 	 |   - paragraph-1
+  ;; 	 |
+  ;; 	 | - *term-2* definition-2
+  ;; 	 |
+  ;; 	 |   - paragraph-2
+  ;; 	 `----
+  ;;
+  ;; Further effect is achieved by fixing the OD styles as below:
+  ;;
+  ;; 1. Set the :type property of the simulated lists to
+  ;;    `descriptive-1' and `descriptive-2'.  Map these to list-styles
+  ;;    that has *no* bullets whatsoever.
+  ;;
+  ;; 2. The paragraph containing the definition term is styled to be
+  ;;    use hanging indent.
+  ;;
+  (org-element-map tree 'plain-list
+    (lambda (el)
+      (when (equal (org-element-property :type el) 'descriptive)
+	(org-element-set-element
+	 el
+	 (apply 'org-element-adopt-elements
+		(list 'plain-list (list :type 'descriptive-1))
+		(mapcar
+		 (lambda (item)
+		   (let* ((item-contents (org-element-contents item))
+			  (leading-paragraph (car item-contents))
+			  (item-contents (cdr item-contents)))
+		     (org-element-adopt-elements
+		      (list 'item (list :checkbox (org-element-property :checkbox item)))
+		      (apply 'org-element-adopt-elements
+			     (list 'paragraph (list :style "OrgDescriptionDefinition"))
+			     (list 'bold (list :style "OrgDescriptionTerm" :post-blank 1)
+				   (or (org-element-property :tag item) "(no term)"))
+			     (org-element-contents leading-paragraph))
+		      (org-element-adopt-elements
+		       (list 'plain-list (list :type 'descriptive-2))
+		       (apply 'org-element-adopt-elements
+			      (list 'item nil)
+			      item-contents)))))
+		 (org-element-contents el)))))
+      nil)
+    info)
+  tree)
+
 ;;;; List tables
 
 ;; Lists that are marked with attribute `:list-table' are called as
-- 
1.7.2.5

>From 58598cfd3909ae5a06b583e764f71d15147efe86 Mon Sep 17 00:00:00 2001
From: Jambunathan K <[email-masked]>
Date: Sat, 24 Aug 2013 15:30:13 +0530
Subject: [PATCH 2/4] ox-odt.el: Fix handling of ODT attributes

* lisp/ox-odt.el (org-odt--read-attribute): New.
(org-odt-template, org-odt-link--inline-image, org-odt-src-block)
(org-odt-table-style-spec, org-odt-table-cell)
(org-odt--translate-list-tables): Use it.

----------------------------------------------------------------

To the extent possible under law, the author(s) have dedicated
all copyright and related and neighboring rights to this software
to the public domain worldwide. This software is distributed
without any warranty.

You should have received a copy of the CC0 Public Domain
Dedication along with this software. If not, see

   <http://creativecommons.org/publicdomain/zero/1.0/>.

----------------------------------------------------------------
---
 lisp/ox-odt.el |   46 +++++++++++++++++++++++++---------------------
 1 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index 5dcf9ec..f5458a5 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -1026,7 +1026,7 @@ (defun org-odt--frame (text width height style &optional extra
 				 (org-odt--encode-plain-text desc t)))))))))

-;;;; Library wrappers
+;;;; Library wrappers :: Arc Mode
 
 (defun org-odt--zip-extract (archive members target)
   (when (atom members) (setq members (list members)))
@@ -1054,6 +1054,15 @@ (defun org-odt--zip-extract (archive members target)
 	      (error "Extraction failed"))))
 	members))
 
+
+;;;; Library wrappers :: Ox
+
+(defun org-odt--read-attribute (element property)
+  (let* ((attrs (org-export-read-attribute :attr_odt element))
+	 (value (plist-get attrs property)))
+    (and value (ignore-errors (read value)))))
+
+
 ;;;; Target
 
 (defun org-odt--target (text id)
@@ -1472,7 +1481,8 @@ (defun org-odt-template (contents info)
       ;; - Dump automatic table styles.
       (loop for (style-name props) in
 	    (plist-get org-odt-automatic-styles 'Table) do
-	    (when (setq props (or (plist-get props :rel-width) 96))
+	    (when (setq props (or (let ((value (plist-get props :rel-width)))
+				    (and value (ignore-errors (read value)))) 96))
 	      (insert (format org-odt-table-style-format style-name props))))
       ;; - Dump date-styles.
       (when org-odt-use-date-fields
@@ -2349,16 +2359,14 @@ (defun org-odt-link--inline-image (element info)
 	 (attr-from (case (org-element-type element)
 		      (link (org-export-get-parent-element element))
 		      (t element)))
-	 ;; Convert attributes to a plist.
-	 (attr-plist (org-export-read-attribute :attr_odt attr-from))
 	 ;; Handle `:anchor', `:style' and `:attributes' properties.
 	 (user-frame-anchor
-	  (car (assoc-string (plist-get attr-plist :anchor)
+	  (car (assoc-string (org-odt--read-attribute attr-from :anchor)
 			     '(("as-char") ("paragraph") ("page")) t)))
 	 (user-frame-style
-	  (and user-frame-anchor (plist-get attr-plist :style)))
+	  (and user-frame-anchor (org-odt--read-attribute attr-from :style)))
 	 (user-frame-attrs
-	  (and user-frame-anchor (plist-get attr-plist :attributes)))
+	  (and user-frame-anchor (org-odt--read-attribute attr-from :attributes)))
 	 (user-frame-params
 	  (list user-frame-style user-frame-attrs user-frame-anchor))
 	 ;; (embed-as (or embed-as user-frame-anchor "paragraph"))
@@ -2368,12 +2376,9 @@ (defun org-odt-link--inline-image (element info)
 	 ;; them as numbers since we need them for computations.
 	 (size (org-odt--image-size
 		src-expanded
-		(let ((width (plist-get attr-plist :width)))
-		  (and width (read width)))
-		(let ((length (plist-get attr-plist :length)))
-		  (and length (read length)))
-		(let ((scale (plist-get attr-plist :scale)))
-		  (and scale (read scale)))
+		(org-odt--read-attribute attr-from :width)
+		(org-odt--read-attribute attr-from :height)
+		(org-odt--read-attribute attr-from :scale)
 		nil			; embed-as
 		"paragraph"		; FIXME
 		))
@@ -3241,7 +3246,6 @@ (defun org-odt-src-block (src-block contents info)
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
   (let* ((lang (org-element-property :language src-block))
-	 (attributes (org-export-read-attribute :attr_odt src-block))
 	 (captions (org-odt-format-label src-block info 'definition))
 	 (caption (car captions)) (short-caption (cdr captions)))
     (concat
@@ -3249,7 +3253,9 @@ (defun org-odt-src-block (src-block contents info)
 	  (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
 		  "Listing" caption))
      (let ((--src-block (org-odt-format-code src-block info)))
-       (if (not (plist-get attributes :textbox)) --src-block
+       ;; Is `:textbox' property non-nil?
+       (if (not (org-odt--read-attribute src-block :textbox)) --src-block
+	 ;; Yes.  Enclose it in a Text Box.
 	 (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
 		 "Text_20_body"
 		 (org-odt--textbox --src-block nil nil nil)))))))
@@ -3299,8 +3305,7 @@ (defun org-odt-superscript (superscript contents info)
 
 (defun org-odt-table-style-spec (element info)
   (let* ((table (org-export-get-parent-table element))
-	 (table-attributes (org-export-read-attribute :attr_odt table))
-	 (table-style (plist-get table-attributes :style)))
+	 (table-style (org-odt--read-attribute table :style)))
     (assoc table-style org-odt-table-styles)))
 
 (defun org-odt-get-table-cell-styles (table-cell info)
@@ -3385,9 +3390,8 @@ (defun org-odt-table-cell (table-cell contents info)
 		    (org-export-get-parent-table table-row) info))
 	      "OrgTableHeading")
 	     ((let* ((table (org-export-get-parent-table table-cell))
-		     (table-attrs (org-export-read-attribute :attr_odt table))
 		     (table-header-columns
-		      (let ((cols (plist-get table-attrs :header-columns)))
+		      (let ((cols (org-odt--read-attribute table :header-columns)))
 			(and cols (read cols)))))
 		(<= c (cond ((wholenump table-header-columns)
 			     (- table-header-columns 1))
@@ -4033,7 +4037,7 @@ (defun org-odt--translate-description-lists/latex (tree backend info)
 
 ;; Consider an example.  The following list table
 ;;
-;; #+attr_odt :list-table t
+;; #+ATTR_ODT: :list-table t
 ;; - Row 1
 ;;   - 1.1
 ;;   - 1.2
@@ -4069,7 +4073,7 @@ (defun org-odt--translate-description-lists/latex (tree backend info)
 (defun org-odt--translate-list-tables (tree backend info)
   (org-element-map tree 'plain-list
     (lambda (l1-list)
-      (when (org-export-read-attribute :attr_odt l1-list :list-table)
+      (when (org-odt--read-attribute l1-list :list-table)
 	;; Replace list with table.
 	(org-element-set-element
 	 l1-list
-- 
1.7.2.5

>From d330d23b51a691d565a0245f1eb48765c67ad6c0 Mon Sep 17 00:00:00 2001
From: Jambunathan K <[email-masked]>
Date: Fri, 30 Aug 2013 15:35:02 +0530
Subject: [PATCH 3/4] ox-odt.el: Support for pagebreaks, custom paragraph styles.

* etc/styles/OrgOdtStyles.xml (OrgPageBreakDefault)
(OrgPageBreakLandscape): New styles.

* lisp/ox-odt.el (org-odt-keyword): Add PAGEBREAK.
(org-odt--format-paragraph): Handle `:p-style' attribute
attached to `plain-list' and `item' elements.
(org-odt-paragraph):  Handle `:style' attribute.
(org-odt-plain-list): Handle `:style' attribute of `ordered'
and `unordered' lists.  Descriptive lists are ignored (for
now).
(org-odt-special-block): Use `org-odt--read-attribute'.

FIXME: Handle paragraph styles for description lists, standard and
user-defined special blocks and those within footnotes?

----------------------------------------------------------------

To the extent possible under law, the author(s) have dedicated
all copyright and related and neighboring rights to this software
to the public domain worldwide. This software is distributed
without any warranty.

You should have received a copy of the CC0 Public Domain
Dedication along with this software. If not, see

   <http://creativecommons.org/publicdomain/zero/1.0/>.

----------------------------------------------------------------
---
 etc/styles/OrgOdtStyles.xml |   12 ++++
 lisp/ox-odt.el              |  154 +++++++++++++++++++++++++++++++++++++++----
 2 files changed, 152 insertions(+), 14 deletions(-)

diff --git a/etc/styles/OrgOdtStyles.xml b/etc/styles/OrgOdtStyles.xml
index c2c32fa..3f408e2 100644
--- a/etc/styles/OrgOdtStyles.xml
+++ b/etc/styles/OrgOdtStyles.xml
@@ -775,6 +775,18 @@
   <text:notes-configuration text:note-class="footnote" text:citation-style-name="Footnote_20_Symbol" text:citation-body-style-name="Footnote_20_anchor" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
   <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
   <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+
+  <!-- Page breaks -->
+  <style:style style:name="OrgPageBreakDefault" style:family="paragraph" style:parent-style-name="Text_20_body" style:master-page-name="Standard">
+   <style:paragraph-properties style:page-number="auto" fo:break-before="auto"/>
+  </style:style>
+
+  <style:style style:name="OrgPageBreakLandscape" style:family="paragraph" style:parent-style-name="Text_20_body" style:master-page-name="Landscape">
+   <style:paragraph-properties style:page-number="auto"  fo:break-before="auto">
+    <style:tab-stops/>
+    <style:background-image/>
+   </style:paragraph-properties>
+  </style:style>
  </office:styles>
  <office:automatic-styles>
   <style:style style:name="MP1" style:family="paragraph" style:parent-style-name="Footer">
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index f5458a5..989d8e0 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -2044,7 +2044,39 @@ (defun org-odt-keyword (keyword contents info)
 	    (when (wholenump depth) (org-odt-toc depth info))))
 	 ((member value '("tables" "figures" "listings"))
 	  ;; FIXME
-	  (ignore))))))))
+	  (ignore)))))
+     ((string= key "PAGEBREAK")
+
+      ;; Pagebreaks created this way are a mere expedience.  These
+      ;; create extraneous "empty" paragraphs which take up "extra
+      ;; space".  A typographer will chide you for resorting to such
+      ;; underhanded means to create pagebreaks.
+      ;;
+      ;; As an expedience it has it's uses.  See
+      ;; `org-odt-special-block' for a realistic example of how
+      ;; pagebreak can be to service.
+      ;;
+      ;; The right way to create pagebreaks is to create new styles -
+      ;; custom or automatic - that set the "before/after" pagebreak
+      ;; of an element (a paragraph, table etc).
+      ;;
+      ;; For example, consider pagebreaks created as below.
+      ;;
+      ;; Text in first page.
+      ;;
+      ;; #+ATTR_ODT: :style "OrgPageBreakDefault"
+      ;; #+PAGEBREAK:
+      ;;
+      ;; This text goes in next page.
+
+      ;; Now look at the page that is introduced with forced page
+      ;; break.  You will realize that the first line of text in that
+      ;; page is a bit displaced from other pages created by
+      ;; LibreOffice.  A keen eye will definitely catch this
+      ;; aberration.
+      (let ((style (org-odt--read-attribute keyword :style)))
+	(when (and style (stringp style))
+	  (format "\n<text:p text:style-name=\"%s\"/>" style)))))))

 ;;;; Latex Environment
@@ -2895,6 +2927,35 @@ (defun org-odt-link (link desc info)
 
 ;;;; Paragraph
 
+;; You can customize paragraphs - standalone one and those occurring
+;; within lists - using `:style' and `:p-style' attributes.  Try out
+;; the following example and see for yourself what you can achieve.
+;;
+;; #+ATTR_ODT: :style "OrgBulletedList" :p-style "Text_20_body_20_bold"
+;; 1. N1
+;;    1. N11
+;;    2. N12
+;; 2. N2
+;;    #+ATTR_ODT: :style "OrgNumberedList" :p-style "Preformatted_20_Text"
+;;    * B21
+;;
+;;    * B22
+;;      - B221
+;;
+;;        First paragraph.
+;;
+;;        #+ATTR_ODT: :style "OrgBibliographyList" :p-style "Text_20_body"
+;;        1. one
+;;        2. two
+;;        3. three
+;;
+;;        #+ATTR_ODT: :style "Text_20_body_20_indent"
+;;        Second paragraph.
+;;
+;;      - B222
+;;    * B23
+;; 3. N3
+
 (defun org-odt--format-paragraph (paragraph contents default center quote)
   "Format paragraph according to given styles.
 PARAGRAPH is a paragraph type element.  CONTENTS is the
@@ -2904,10 +2965,48 @@ (defun org-odt--format-paragraph (paragraph contents default center quote)
 block."
   (let* ((parent (org-export-get-parent paragraph))
 	 (parent-type (org-element-type parent))
-	 (style (case parent-type
-		  (quote-block quote)
-		  (center-block center)
-		  (t default))))
+	 (style (or
+		 ;; Use the style that is explicitly specified via
+		 ;; #+ATTR_ODT: :style "Text_20_body_20_bold".
+		 default
+		 ;; Paragraph doesn't specify a style of it's own.
+		 ;; Infer it from the surrounding context.
+		 (case parent-type
+		   ;; Paragraph is within a QUOTE-BLOCK.  Use a style
+		   ;; specific to that block.
+		   (quote-block quote)
+		   ;; Paragraph is within a CENTER-BLOCK.  Use a style
+		   ;; specific to that block.
+		   (center-block center)
+		   ;; Paragraph is with an item.  Use the style
+		   ;; specified with `:p-style' attribute of the
+		   ;; nearest ancestor plain-list or item.
+
+		   ;; In other words, the `:p-style' specified in a
+		   ;; plain-list or an item gets inherited all the way
+		   ;; down.  A deeper plain-list or an item can
+		   ;; override the value it inherits from it's parents
+		   ;; with it's own `:p-style' attribute which then
+		   ;; gets handed down below.
+
+		   ;; NOTE: ITEMs cannot have #+ATTR_ODT attached to
+		   ;; them.  So, contrary to the implications in the
+		   ;; previous paragraphs, there is no such things as
+		   ;; paragraph styles to ITEMs. See
+		   ;;
+		   ;; http://lists.gnu.org/archive/html/emacs-orgmode/2013-08/msg00586.html
+		   ;;
+		   (item
+		    (let* ((genealogy (org-export-get-genealogy paragraph))
+			   (data (reverse genealogy))
+			   (p-styles (loop for x on data
+					   when (memq (org-element-type (car x))
+						      '(item plain-list)) ; ITEM is an eye-candy
+					   collect (org-odt--read-attribute (car x) :p-style))))
+		      (car (last (delq nil p-styles))))))
+		 ;; Paragraph is not so interesting.  Use the default
+		 ;; style.
+		 "Text_20_body")))
     ;; If this paragraph is a leading paragraph in an item and the
     ;; item has a checkbox, splice the checkbox and paragraph contents
     ;; together.
@@ -2922,7 +3021,8 @@ (defun org-odt-paragraph (paragraph contents info)
 the plist used as a communication channel."
   (org-odt--format-paragraph
    paragraph contents
-   (or (org-element-property :style paragraph) "Text_20_body")
+   (or (org-element-property :style paragraph)
+       (org-odt--read-attribute paragraph :style))
    "OrgCenter"
    "Quotations"))
 
@@ -2936,8 +3036,12 @@ (defun org-odt-plain-list (plain-list contents info)
   (format "\n<text:list text:style-name=\"%s\" %s>\n%s</text:list>"
 	  ;; Choose style based on list type.
 	  (case (org-element-property :type plain-list)
-	    (ordered "OrgNumberedList")
-	    (unordered "OrgBulletedList")
+	    (ordered (or (org-odt--read-attribute  plain-list :style)
+			 "OrgNumberedList"))
+	    (unordered (or (org-odt--read-attribute  plain-list :style)
+			   "OrgBulletedList"))
+	    ;; FIXME: Define and handle `:style' attributes for
+	    ;; description lists.
 	    (descriptive-1 "OrgDescriptionList")
 	    (descriptive-2 "OrgDescriptionList"))
 	  ;; If top-level list, re-start numbering.  Otherwise,
@@ -3111,14 +3215,36 @@ (defun org-odt-special-block (special-block contents info)
 			 contents)))))
      ;; Textbox.
      ((string= type "textbox")
-      (let ((width (plist-get attributes :width))
-	    (height (plist-get attributes :height))
-	    (style (plist-get attributes :style))
-	    (extra (plist-get attributes :extra))
-	    (anchor (plist-get attributes :anchor)))
+      ;; Textboxes an be used for centering tables etc horizontally
+      ;; and vertically within a page.
+
+      ;; In the example below, a landscape and centered table is
+      ;; created in the middle of what is essentially a portrait
+      ;; document.
+
+      ;; Leading text.
+      ;;
+      ;; #+ATTR_ODT: :style "OrgPageBreakLandscape"
+      ;; #+PAGEBREAK:
+      ;;
+      ;; #+ATTR_ODT: :width 5 :style "OrgPageImage" :anchor "page"
+      ;; #+BEGIN_TEXTBOX
+      ;; | a          | b          |
+      ;; | e          | f          |
+      ;; #+END_TEXTBOX
+      ;;
+      ;; #+ATTR_ODT: :style "OrgPageBreakDefault"
+      ;; #+PAGEBREAK:
+      ;;
+      ;; Trailing text.
+      (let ((width (org-odt--read-attribute special-block :width))
+	    (height (org-odt--read-attribute special-block :height))
+	    (style (org-odt--read-attribute special-block :style))
+	    (extra (org-odt--read-attribute special-block :extra))
+	    (anchor (org-odt--read-attribute special-block :anchor)))
 	(format "\n<text:p text:style-name=\"%s\">%s</text:p>"
 		"Text_20_body" (org-odt--textbox contents width height
-						   style extra anchor))))
+						 style extra anchor))))
      (t contents))))

-- 
1.7.2.5

>From b3a6660058fadb2a67b977c553ded414f7a6a657 Mon Sep 17 00:00:00 2001
From: Jambunathan K <[email-masked]>
Date: Wed, 24 Jul 2013 19:25:02 +0530
Subject: [PATCH 4/4] ox-odt: Add support for JabRef

* contrib/lisp/ox-jabref.el: New file.

* lisp/org.el (org-modules): Add ox-jabref.

* etc/styles/OrgOdtStyles.xml (Bibliography_20_Heading)
(Bibliography, OrgBibliographyList): New styles.

* lisp/ox-odt.el (org-export-define-backend): New non-standard
element `citation-reference'.  Register
`org-odt--translate-cite-fragments'.
(org-odt--translate-cite-fragments):  New filter.
(org-odt-citation-transcoders): New user option.
(org-odt-citation-reference, org-odt-citation-reference/numbered):
Stock transcoders for `citation-reference' elements.
(org-odt-keyword): Handle BIBLIOGRAPHY.
(org-odt--export-wrap): Make the condition case debuggable.

NOTE: Review all the above changes once ox.el provides standard
tools for handling citaitons.

----------------------------------------------------------------

To the extent possible under law, the author(s) have dedicated
all copyright and related and neighboring rights to this software
to the public domain worldwide. This software is distributed
without any warranty.

You should have received a copy of the CC0 Public Domain
Dedication along with this software. If not, see

   <http://creativecommons.org/publicdomain/zero/1.0/>.

----------------------------------------------------------------
---
 contrib/lisp/ox-jabref.el   |  637 +++++++++++++++++++++++++++++++++++++++++++
 etc/styles/OrgOdtStyles.xml |   41 +++
 lisp/org.el                 |    1 +
 lisp/ox-odt.el              |   88 ++++++-
 4 files changed, 762 insertions(+), 5 deletions(-)
 create mode 100644 contrib/lisp/ox-jabref.el

diff --git a/contrib/lisp/ox-jabref.el b/contrib/lisp/ox-jabref.el
new file mode 100644
index 0000000..2665dad
--- /dev/null
+++ b/contrib/lisp/ox-jabref.el
@@ -0,0 +1,637 @@
+;;; ox-jabref.el --- JabRef Citation Processor for Orgmode
+
+;; Copyright (C) 2013 Jambunathan K <kjambunathan at gmail dot com>
+
+;; Author: Jambunathan K <kjambunathan at gmail dot com>
+;; Keywords: outlines, hypermedia, calendar, wp
+;; Homepage: http://orgmode.org
+;; Version: 8.0.6
+
+;;; Commentary:
+
+;;;; Quick start guide:
+;;
+;; 1. Install [[http://jabref.sourceforge.net/][JabRef]]
+;;
+;;    This module is tested with version JabRef-2.9.2.jar.
+;;
+;; 2. Install the JabRef plugin [[http://repo.or.cz/w/JabRefChicagoForOrgmode.git/blob_plain/HEAD:/net.sf.jabref.export.Chicago.ODF(English)-1.2.jar][Chicago Export filters for Org-mode]].
+;;
+;; 3. Configure ox-jabref.el
+;;
+;;    #+BEGIN_EXAMPLE
+;;      M-x customize-group RET org-jabref RET
+;;    #+END_EXAMPLE
+;;
+;;    Review the settings.
+;;
+;; 4. Configure ox-odt.el
+;;
+;;    #+BEGIN_EXAMPLE
+;;      M-x customize-variable RET org-jabref-odt-citation-transcoders RET
+;;    #+END_EXAMPLE
+;;
+;;    Following settings are recommended.
+;;
+;;    1. No citation support
+;;
+;;      #+BEGIN_SRC emacs-lisp
+;;        (setq org-jabref-odt-citation-transcoders
+;;              '(org-odt-latex-fragment . ignore))
+;;      #+END_SRC
+;;
+;;      This is the default setting.
+;;
+;;       - #+BIBLIOGRAPHY is ignored.
+;;       - \cite{} directives are typeset as plain text.
+
+;;    2. Numeric Citations
+;;
+;;       #+BEGIN_SRC emacs-lisp
+;;         (setq org-jabref-odt-citation-transcoders
+;;               '(org-odt-citation-reference/numbered
+;;                 . org-jabref-odt-bibliography/numbered))
+;;       #+END_SRC
+;;
+;;       - #+BIBLIOGRAPHY is replaced with numerical listing of
+;;         Bibliographic entries.  The listing includes only cited keys
+;;         and is sorted on the order in which the cite keys are seen in
+;;         the Org file.
+;;
+;;       - \cite{} directives are replaced with numeric links to the
+;;         associated Bibliographic entry.
+;;
+;;    3. Unnumbered (or Text) Citations with Filtered Bibliography
+;;
+;;       #+BEGIN_SRC emacs-lisp
+;;         (setq org-jabref-odt-citation-transcoders
+;;               '(org-jabref-odt-citation-reference/text
+;;               . org-jabref-odt-bibliography/filtered))
+;;       #+END_SRC
+;;
+;;       - #+BIBLIOGRAPHY is replaced with listing of Bibliographic
+;;         entries.  The listing is limited to just the cited keys.  The
+;;         listing is sorted based on the order chosen by JabRef engine.
+;;
+;;       - \cite{} directives are replaced with textual links to the
+;;         associated Bibliographic entry.
+;;
+;;    4. Unnumbered (or Text) Citations with Filtered Bibliography
+;;
+;;       #+BEGIN_SRC emacs-lisp
+;;         (setq org-jabref-odt-citation-transcoders
+;;               '(org-jabref-odt-citation-reference/text
+;;               . org-jabref-odt-bibliography/unfiltered))
+;;       #+END_SRC
+;;
+;;       - #+BIBLIOGRAPHY is replaced with listing of *all* Bibliographic
+;;         entries.  The listing is limited to just the cited keys.  The
+;;         listing is sorted based on the order chosen by JabRef engine.
+;;
+;;       - \cite{} directives are replaced with textual links to the
+;;         associated Bibliographic entry.
+;;
+;;    5. Add the following line to your Org file and export.
+;;
+;;       #+BEGIN_SRC org
+;;         ,#+BIBLIOGRAPHY: MyLibrary.bib
+;;       #+END_SRC
+
+;;;; Developer (or Implementation) notes
+;;
+;; The current #+BIBLIOGRAPHY is defined in contrib/lisp/ox-bibtex.el.
+;; The syntax defined therein, is specific to a particular Citation
+;; Processor (i.e., bibtex2html) and cannot be expected to be honored
+;; by all backends AND citation processors[fn:1].
+;;
+;;   1. So having a "style" specification in a keyword line that is
+;;      shared across all backends is absurd.[fn:2][fn:3].
+;;
+;;   2. It is unclear how well a "limit: " option can be honored by
+;;      *ALL* citation processors.
+;;
+;; To keep things simple (and flexible), ox-jabref.el resorts to the
+;; following:
+;;
+;;   1. *Always* use the first found style registered for the current
+;;      backend in `org-jabref-export-formats'
+;;
+;;   2. "Limit"-ed (or non-"limit"-ed) export of Bibliographic entries
+;;      can be achieved by using a different transcoder.  See "Quick
+;;      start guide" above.
+;;
+;; Footnotes
+;; ---------
+;;
+;; [fn:1] Note that the same Citation Processor (for example, JabRef)
+;; can be used for catering to *both* HTML, ODT and even ASCII
+;; backends.
+;;
+;; [fn:2] *If* one settles for Org-wide styles, a possible translation
+;; from Org-specific style to Citation-specific style needs to be done
+;; by each backend.  This is the sole purpose of
+;; `org-jabref-export-formats'.
+;;
+;; Having an Org-wide styles is well-neigh impossible.  In that case,
+;; the best option is to settle for a specification like
+;;
+;;    #+ATTR_HTML: :bib2html-style "plain"
+;;    #+ATTR_ODT: :jabref-style "Chicago (author-date)"
+;;    #+BIBLIOGRAPHY: MyLibrary.bib
+;;
+;; Note the keywords in #+ATTR_BACKEND lines are prefixed with the
+;; Citation Processor.  This is important in light of earlier comments
+;; [fn:1].
+;;
+;;; Code:
+
+(require 'ox)
+(require 'ox-odt)
+
+;;; User Configuration Options.
+
+(defgroup org-jabref nil
+  "Options for processing citations via JabRef."
+  :tag "Org Jabref"
+  :group 'org-export)
+
+(defcustom org-jabref-command '("java" "-jar" "JabRef-2.9.2.jar" "-n" "true")
+  "Jabref program."
+  :type '(choice
+	  (const :tag "Not configured" nil)
+	  (repeat string))
+  :group 'org-jabref
+  :version "24.4")
+
+(defcustom org-jabref-export-formats
+  '(("odt"
+     ("Chicago Manual of Style (author-date)"
+      :in-text "chicago.ODF.text" :bibliography "chicago.ODF.reference")))
+  "JabRef export formats for various backends.
+Each element in this list is of the form:
+
+  \(EXPORT-BACKEND-NAME . BACKEND-STYLE-FITLERS\)
+
+BACKEND-STYLE-FILTERS is of the form:
+
+  \(CITATION-STYLE . EXPORT-FORMATS-PLIST\)
+
+EXPORT-FORMATS-PLIST is property list with two well-known
+properties - `:in-text' and `:bibliography'.  The values
+of these properties are the export formats registered with
+JabRef.
+
+A typical value for this variable could be:
+
+  '((\"odt\"
+     (\"default\" :in-text \"chicago.ODF.text\"
+      :bibliography \"chicago.ODF.reference\"))
+    (\"html\"
+     (\"default\" :bibliography \"html\")
+     (\"simple\" :bibliography \"simplehtml\")))
+
+For a list of export formats registered with JabRef use:
+
+  java -jar JabRef-2.9.2.jar -n true -h."
+  :group 'org-jabref
+  :version "24.4"
+  :type '(alist :key-type (string :tag "Export backend")
+		:options ("odt" "html")
+		:value-type
+		(alist :key-type (string :tag "Citation style")
+		       :options ("Chicago Manual of Style (author-date)")
+		       :value-type
+		       (plist :tag "export formats"
+			      :value-type (string :tag "export format")
+			      :options (:in-text
+					:bibliography)))))
+
+(defcustom org-jabref-export-formats
+  '(("odt"
+     ("Chicago Manual of Style (author-date)"
+      :in-text "chicago.ODF.text" :bibliography "chicago.ODF.reference")))
+  "JabRef export formats for various backends.
+Each element in this list is of the form:
+
+  \(EXPORT-BACKEND-NAME . BACKEND-STYLE-FITLERS\)
+
+BACKEND-STYLE-FILTERS is of the form:
+
+  \(CITATION-STYLE . EXPORT-FORMATS-PLIST\)
+
+EXPORT-FORMATS-PLIST is property list with two well-known
+properties - `:in-text' and `:bibliography'.  The values
+of these properties are the export formats registered with
+JabRef.
+
+A typical value for this variable could be:
+
+  '((\"odt\"
+     (\"default\" :in-text \"chicago.ODF.text\"
+      :bibliography \"chicago.ODF.reference\"))
+    (\"html\"
+     (\"default\" :bibliography \"html\")
+     (\"simple\" :bibliography \"simplehtml\")))
+
+For a list of export formats registered with JabRef use:
+
+  java -jar JabRef-2.9.2.jar -n true -h."
+  :group 'org-jabref
+  :version "24.4"
+  :type '(alist :key-type (string :tag "Export backend")
+		:options ("odt" "html")
+		:value-type
+		(alist :key-type (string :tag "Citation style")
+		       :options ("Chicago Manual of Style (author-date)")
+		       :value-type
+		       (plist :tag "export formats"
+			      :value-type (string :tag "export format")
+			      :options (:in-text
+					:bibliography)))))
+
+(defcustom org-jabref-odt-citation-transcoders
+  '(org-odt-citation-reference/numbered . org-jabref-odt-bibliography/numbered)
+  "Transcoders to handle citations.
+Use CAR as the transcoder for CITATION-REFERENCE elements.  Use
+CDR as the transcoder for BIBLIOGRAPHY.  See
+`org-odt--translate-cite-fragments'.
+
+For full citation support, install the required Citation
+Processor (JabRef, for example) and turn on the associated Elisp
+module in `org-modules'."
+  :type `(cons
+	  (radio :tag ,(format "%-35s" "Transcoder for \\cite{ } fragments")
+		 (function-item :doc "Export Verbatim"
+				org-odt-latex-fragment)
+		 (function-item :doc "(JabRef) Enumerate"
+				org-odt-citation-reference/numbered)
+		 (function-item :doc "(JabRef) Text Description"
+				org-jabref-odt-citation-reference/text)
+		 function)
+	  (radio :tag ,(format "%-35s" "Transcoder for Bibliography")
+		 (function-item :doc "Strip Bibliography"
+				ignore)
+		 (function-item :doc "(JabRef) Enumerate, only cited entries, sort by reference"
+				org-jabref-odt-bibliography/numbered)
+		 (function-item :doc "(JabRef) Only cited entries, sort by reference"
+				org-jabref-odt-bibliography/unnumbered)
+		 (function-item :doc "(JabRef) Only cited entries, sort by application order"
+				org-jabref-odt-bibliography/filtered)
+		 (function-item :doc "(JabRef) Full bibliography, sort by application order"
+				org-jabref-odt-bibliography/unfiltered)
+		 function))
+  :group 'org-export-odt
+  :version "24.1")
+
+
+
+;;; Loading and Unloaing
+
+(defvar org-jabref--stock-odt-backend
+  (org-export-get-backend 'odt)
+  "Backend definition of stock ODT exporter.")
+
+(defvar org-jabref--enhanced-odt-backend
+  (let* (;; Copy over the stock backend.
+	 (enhanced-backend (copy-tree org-jabref--stock-odt-backend t)))
+    ;; Override default citation transcoders with our own.
+    (setf (org-export-backend-transcoders enhanced-backend)
+	  (append
+	   '((keyword . org-jabref-odt-keyword)
+	     (citation-reference . org-jabref-odt-citation-reference))
+	   (org-export-backend-transcoders org-jabref--stock-odt-backend)))
+    ;; Modify the menu description.
+    (let ((menu (org-export-backend-menu enhanced-backend)))
+      (setf (cadr menu) (concat (cadr menu) " (With Jabref Processing)")))
+    ;; Replace the existing ODT backend.
+    (org-export-register-backend enhanced-backend)
+    ;; Return the enhanced backend.
+    enhanced-backend)
+  "Backend definition of ODT exporter with JabRef processing.")
+
+(defun ox-jabref-unload-function ()
+  "Restore the stock ODT backend."
+  (prog1 nil
+    (org-export-register-backend org-jabref--stock-odt-backend)
+    (message "ox-jabref: Unloaded")))
+
+;;; Internal functions
+
+(defun org-jabref--read-bibliography-attribute (info property)
+  "Return value of PROPERTY of #+BIBLIOGRAPHY keyword.
+INFO is a plist holding contextual information for purposes of
+export.  PROPERTY is one of `:bib-file' or `:citation-style'.  If
+it is neither, treat is as one of the properties in
+#+ATTR_BACKEND attribute of #+BIBLIOGRAPHY keyword, where BACKEND
+is the current export backend."
+  (let* ((data (plist-get info :parse-tree))
+	 (bibliography (org-element-map data 'keyword
+			 (lambda (keyword)
+			   (let ((key (org-element-property :key keyword)))
+			     (and (string= (upcase key) "BIBLIOGRAPHY")
+				  keyword)))
+			 info 'first-match)))
+    (cond
+     ((memq property '(:bib-file :citation-style))
+      (let* ((value (org-element-property :value bibliography))
+     	     (values (split-string value))
+     	     (attributes (list :bib-file
+     			       (let ((bib-file (nth 0 values)))
+     				 (concat (file-name-sans-extension bib-file)
+					 ".bib"))
+     			       :citation-style (nth 1 values))))
+	(plist-get attributes property)))
+     (t
+      (let ((attribute (intern (format ":attr_%s" (plist-get info :backend)))))
+	(org-export-read-attribute attribute bibliography property))))))
+
+(defun org-jabref--get-export-format (info op)
+  "Return the EXPORT-FORMAT configured for operation OP.
+INFO is a plist holding contextual information.  OP can be one of
+`:in-text' or `:bibliography'.  Return EXPORT-FORMAT is
+that is registered for the current export backend.  See
+`org-jabref-export-formats'."
+  (let* ((backend (plist-get info :back-end))
+	 (backend-name (symbol-name (org-export-backend-name backend)))
+	 (styles-alist (assoc-default backend-name org-jabref-export-formats))
+	 ;; FIXME: Ignore the "style" entry in "#+BIBLIOGRAPHY" line.
+	 ;; Just go with the first registered style for this backend
+	 ;; in `org-jabref-export-formats'.
+
+	 ;; (citation-style (org-jabref--read-bibliography-attribute
+	 ;; 		  info :citation-style))
+	 (citation-style (caar styles-alist))
+ 	 ;; Get JabRef export format that match this backend and
+	 ;; citation-style.
+	 (export-formats-plist (assoc-default citation-style styles-alist)))
+    (if (null op) export-formats-plist
+      (plist-get export-formats-plist op))))
+
+(defun org-jabref--run-cmd (&rest args)
+  "Run JabRef command with ARGS.
+Append ARGS to `org-jabref-command' and use `call-process'."
+  (let ((cmd (append org-jabref-command args)))
+    (let (exitcode err-string)
+      (message "Running %s" (mapconcat 'identity cmd " "))
+      (setq err-string
+	    (with-output-to-string
+	      (setq exitcode
+		    (apply 'call-process (car cmd)
+			   nil standard-output nil (cdr cmd)))))
+      (or (zerop exitcode)
+	  (error (format "JabRef command failed with error (%s)"
+			 err-string))))))
+
+(defun org-jabref--create-filtered-bibfile (bib-file cite-keys)
+  "Truncate BIB-FILE so that it contains only CITE-KEYS.
+Return name of the newly created bib file.
+
+Specifically,
+
+  - Create a temporary auxiliary file FILTERED.AUX file which
+    contains just the CITE-KEYS
+
+  - Run the following command (for example)
+
+        jabref -n true -a FILTERED.AUX,FILTERED.BIB BIB-FILE
+
+  - Return FILTERED.BIB."
+
+  (let* ((aux-file (make-temp-file "jabref" nil ".aux"))
+	 (filtered-bib-file (concat (file-name-sans-extension aux-file) ".bib")))
+    ;; Create an .aux file out of CITE-KEYS.
+    (with-current-buffer (find-file-noselect aux-file)
+      (insert (mapconcat (lambda (cite-key)
+			    (format "\\citation{%s}" cite-key))
+			  cite-keys "\n"))
+      (save-buffer 0))
+    ;; Create a filtered bib file out of the aux file.
+    (org-jabref--run-cmd "-a" (concat aux-file ","  filtered-bib-file) bib-file)
+    ;; Delete aux file.
+    (delete-file aux-file)
+    ;; Return filtered bib file.
+    filtered-bib-file))
+
+;;;; Export a BIB file, enbloc
+
+(defun org-jabref-export-bib-file (bib-file export-format)
+  "Export BIB-FILE to EXPORT-FORMAT.
+Return the resulting XML as string.  Specifically,
+
+  - Run the following command (for example)
+
+        jabref -n true -o OUT.XML,EXPORT-FORMAT BIB-FILE
+
+  - Return contents of OUT.XML as a string."
+  (when (and bib-file (file-readable-p bib-file) export-format)
+    (with-demoted-errors
+      (let* ((xml-file (make-temp-file "jabref-" nil ".xml")))
+	;; Export the Citation to it's XML representation.
+	(org-jabref--run-cmd "-o"  (concat xml-file "," export-format) bib-file)
+	;; Return the XML string.
+	(prog1 (with-temp-buffer
+		 (insert-file-contents xml-file)
+		 (buffer-string))
+	  ;; Delete temporary xml file.
+	  (delete-file xml-file))))))
+
+(defun org-jabref-export-bib-file-with-filtering (bib-file cite-keys
+							   export-format)
+  "Export BIB-FILE to EXPORT-FORMAT, but limit output to just the CITE-KEYS.
+Use `org-jabref--create-filtered-bibfile' and `org-jabref-export-bib-file'."
+  (when (and bib-file (file-readable-p bib-file) cite-keys export-format)
+    (let ((filtered-bib-file (org-jabref--create-filtered-bibfile bib-file
+								  cite-keys)))
+      (prog1 (org-jabref-export-bib-file filtered-bib-file export-format)
+	(delete-file filtered-bib-file)))))
+
+;;;; Export a CITE-KEY
+
+(defun org-jabref-export-cite-key (bib-file cite-key export-format)
+  "Export CITE-KEY from BIB-FILE to EXPORT-FORMAT.
+Return the XML representation as a string. Specifically,
+
+  - Run the following command (for example)
+
+        jabref -n true -m CITE-KEY,OUT.XML,EXPORT-FORMAT BIB-FILE
+
+  - Return contents of OUT.XML as a string."
+  (when (and bib-file (file-readable-p bib-file) cite-key export-format)
+    (with-demoted-errors
+      (let* ((xml-file (file-name-nondirectory (make-temp-file "jabref-" nil
+							       ".xml"))))
+	;; Export the Citation to it's XML representation.
+	(org-jabref--run-cmd "-m" (format "%s,%s,%s" cite-key xml-file
+					  export-format) bib-file)
+	;; Return the XML string.
+	(prog1 (with-temp-buffer
+		 (insert-file-contents xml-file)
+		 (buffer-string))
+	  ;; Delete temporary xml file.
+	  (delete-file xml-file))))))
+
+
+;;; Transcoders
+
+;;;; Bibliography
+
+(defun org-jabref-odt-keyword (keyword contents info)
+  "Transcode a KEYWORD element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information.
+
+If KEYWORD is a BIBLIOGRAPHY element, use the transcoder
+specified in `org-jabref-odt-citation-transcoders'.  If no such
+transcoder exists, return nil."
+  (let ((key (org-element-property :key keyword))
+	(value (org-element-property :value keyword)))
+    (cond
+     ;; Handle BIBLIOGRAPHY code.
+     ((string= key "BIBLIOGRAPHY")
+      (let* ((transcoder (cdr org-jabref-odt-citation-transcoders)))
+	(when (and transcoder (fboundp transcoder))
+	  (funcall transcoder keyword contents info))))
+     ;; Keyword is other than BIBLIOGRAPHY.  Use the stock transcoder.
+     (t (let ((transcoder (assoc-default 'keyword (org-export-backend-transcoders
+						   org-jabref--stock-odt-backend))))
+	  (funcall transcoder keyword contents info))))))
+
+
+;;;; Bibliography :: Un-numbered
+
+;;;###autoload
+(defun org-jabref-odt-bibliography/unnumbered (bibliography contents info)
+  "Transcode a BIBLIOGRAPHY element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information.
+
+Export each CITE-KEY in the parse tree through `:bibliography'
+EXPORT-FORMAT.  Return the concatenated result, after adding some
+separators."
+  (let* ((bib-file (org-jabref--read-bibliography-attribute info :bib-file))
+	 (cite-keys (mapcar 'car (plist-get info :citations-alist)))
+	 (export-format (org-jabref--get-export-format info :bibliography)))
+    (format "<text:section text:style-name=\"%s\" text:name=\"%s\">\n%s\n</text:section>"
+	    "OrgIndexSection"
+	    "Bibliography"
+	    (concat (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
+			    "Bibliography_20_Heading" "References")
+		    (mapconcat
+		     (lambda (cite-key)
+		       (message "Generating BIBLIOGRAPHY entry for cite-key (%s)..."
+				cite-key)
+		       (org-jabref-export-cite-key bib-file cite-key
+						   export-format))
+		     cite-keys "\n")))))
+
+;;;; Bibliography :: Numbered
+
+;;;###autoload
+(defun org-jabref-odt-bibliography/numbered (bibliography contents info)
+  "Transcode a BIBLIOGRAPHY element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information.
+
+Export each CITE-KEY in the parse tree through `:bibliography'
+EXPORT-FORMAT.  Enclose the entries in a numbered list and return
+the result."
+  (let* ((bib-file (org-jabref--read-bibliography-attribute info :bib-file))
+	 ;; Reverse the entries in `:citation-alist' so that CITE-KEYs
+	 ;; are sorted based on their order of occurrence in the Org
+	 ;; file.
+	 (cite-keys (reverse (mapcar 'car (plist-get info :citations-alist))))
+	 (export-format (org-jabref--get-export-format info :bibliography)))
+    ;; Enclose Bibliography in it's own section.
+    (format
+     "<text:section text:style-name=\"%s\" text:name=\"%s\">\n%s\n</text:section>"
+     "OrgIndexSection"
+     "Bibliography"
+     (concat
+      ;; Bibliography Heading
+      (format "\n<text:p text:style-name=\"%s\">%s</text:p>" "Bibliography_20_Heading" "References")
+      ;; Format Bibliography entries as a numbered list.
+      (format
+       "<text:list text:style-name=\"OrgBibliographyList\" text:continue-numbering=\"false\">%s</text:list>"
+       (mapconcat
+	(lambda (cite-key)
+	  ;; Format each entry as a numbered item.
+	  (format "\n<text:list-item>%s\n</text:list-item>"
+		  (org-jabref-export-cite-key bib-file cite-key export-format)))
+	cite-keys "\n"))))))
+
+;;;; Bibliography :: Plain, Filtered
+
+;;;###autoload
+(defun org-jabref-odt-bibliography/filtered (bibliography contents info)
+  "Transcode a BIBLIOGRAPHY element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information.
+
+Filter the BIB-FILE to just the cited entries.  Export the
+filtered BIB-FILE through `:bibliography' EXPORT-FORMAT, return
+the result as string."
+  (let* ((bib-file (org-jabref--read-bibliography-attribute info :bib-file))
+	 ;; Reverse the entries in `:citation-alist' so that CITE-KEYs
+	 ;; are sorted based on their order of occurrence in the Org
+	 ;; file.
+	 (cite-keys (mapcar 'car (plist-get info :citations-alist)))
+	 (export-format (org-jabref--get-export-format info :bibliography)))
+    (message "Compiling BIBLIOGRAPHY (FILTERED)...")
+    (format "<text:section text:style-name=\"%s\" text:name=\"%s\">\n%s\n</text:section>"
+	    "OrgIndexSection"
+	    "Bibliography"
+	    (concat (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
+			    "Bibliography_20_Heading" "References")
+		    (org-jabref-export-bib-file-with-filtering
+		     bib-file cite-keys export-format)))))
+
+;;;; Bibliography :: Plain, Unfiltered
+
+;;;###autoload
+(defun org-jabref-odt-bibliography/unfiltered (bibliography contents info)
+  "Transcode a BIBLIOGRAPHY element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information.
+
+Export the BIB-FILE through `:bibliography' EXPORT-FORMAT, return
+the result as string."
+  (let* ((bib-file (org-jabref--read-bibliography-attribute info :bib-file))
+	 (export-format (org-jabref--get-export-format info :bibliography)))
+    (message "Compiling BIBLIOGRAPHY UN-FILTERED" )
+    (format "<text:section text:style-name=\"%s\" text:name=\"%s\">\n%s\n</text:section>"
+	    "OrgIndexSection"
+	    "Bibliography"
+	    (concat (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
+			    "Bibliography_20_Heading" "References")
+		    (org-jabref-export-bib-file bib-file export-format)))))
+
+;;;; Citation reference
+
+(defun org-jabref-odt-citation-reference (citation-reference contents info)
+  "Transcode a CITATION-REFERENCE element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information."
+  (let ((transcoder (car org-jabref-odt-citation-transcoders)))
+    (when (and transcoder (fboundp transcoder))
+      (funcall transcoder citation-reference contents info))))
+
+
+;;;; Citation reference :: Plain Text (Author-Date etc.)
+
+;;;###autoload
+(defun org-jabref-odt-citation-reference/text (citation-reference contents info)
+  "Transcode a CITATION-REFERENCE element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information.
+
+Pass each CITE-KEY from CITATION-REFERENCE in to `:in-text'
+EXPORT-FORMAT.  Return the concatenated result, after adding some
+separators."
+  (let* ((latex-frag (org-element-property :value citation-reference))
+	 (value (and (string-match "\\\\cite{\\(.*?\\)}" latex-frag)
+		     (match-string 1 latex-frag)))
+	 (cite-keys (org-split-string value ","))
+	 (bib-file (org-jabref--read-bibliography-attribute info :bib-file))
+	 (export-format (org-jabref--get-export-format info :in-text)))
+    (mapconcat
+     (lambda (cite-key)
+       (message "Generating IN-TEXT entry for cite-key (%s)..." cite-key)
+       (org-jabref-export-cite-key bib-file cite-key export-format))
+     cite-keys ", ")))
+
+(provide 'ox-jabref)
+
+;;; ox-jabref.el ends here
diff --git a/etc/styles/OrgOdtStyles.xml b/etc/styles/OrgOdtStyles.xml
index 3f408e2..5b1e973 100644
--- a/etc/styles/OrgOdtStyles.xml
+++ b/etc/styles/OrgOdtStyles.xml
@@ -776,6 +776,47 @@
   <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
   <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
 
+  <!-- Bibliography -->
+  <style:style style:name="Bibliography_20_Heading" style:display-name="Bibliography Heading" style:family="paragraph" style:parent-style-name="Heading" style:class="index">
+   <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false" text:number-lines="false" text:line-number="0"/>
+   <style:text-properties fo:font-size="16pt" fo:font-weight="bold" style:font-size-asian="16pt" style:font-weight-asian="bold" style:font-size-complex="16pt" style:font-weight-complex="bold"/>
+  </style:style>
+  <style:style style:name="Bibliography" style:family="paragraph" style:parent-style-name="Text_20_body"/>
+
+  <!--  List style for Bibliographic entries -->
+  <text:list-style style:name="OrgBibliographyList">
+   <text:list-level-style-number text:level="1" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:min-label-width="0.64cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="2" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="1.27cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="3" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="1.905cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="4" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="2.54cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="5" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="3.175cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="6" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="3.81cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="7" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="4.445cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="8" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="5.08cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="9" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="5.715cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+   <text:list-level-style-number text:level="10" style:num-prefix="[" style:num-suffix="] " style:num-format="1">
+    <style:list-level-properties text:space-before="6.35cm" text:min-label-width="0.635cm"/>
+   </text:list-level-style-number>
+  </text:list-style>
+
   <!-- Page breaks -->
   <style:style style:name="OrgPageBreakDefault" style:family="paragraph" style:parent-style-name="Text_20_body" style:master-page-name="Standard">
    <style:paragraph-properties style:page-number="auto" fo:break-before="auto"/>
diff --git a/lisp/org.el b/lisp/org.el
index 8e970a1..56917ce 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -390,6 +390,7 @@ (defcustom org-modules '(org-w3m org-bbdb org-bibtex org-docview org-gnus org-in
 	(const :tag "   info:              Links to Info nodes" org-info)
 	(const :tag "   inlinetask:        Tasks independent of outline hierarchy" org-inlinetask)
 	(const :tag "   irc:               Links to IRC/ERC chat sessions" org-irc)
+	(const :tag "   JabRef:            Export citations with JabRef" ox-jabref)
 	(const :tag "   mhe:               Links to MHE folders/messages" org-mhe)
 	(const :tag "   mouse:             Additional mouse support" org-mouse)
 	(const :tag "   protocol:          Intercept calls from emacsclient" org-protocol)
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el
index 989d8e0..8de60db 100644
--- a/lisp/ox-odt.el
+++ b/lisp/ox-odt.el
@@ -82,10 +82,13 @@ (org-export-define-backend 'odt
     (timestamp . org-odt-timestamp)
     (underline . org-odt-underline)
     (verbatim . org-odt-verbatim)
-    (verse-block . org-odt-verse-block))
+    (verse-block . org-odt-verse-block)
+    ;; Non-standard transcoders used just by the ODT exporter.
+    (citation-reference . org-odt-citation-reference))
   :export-block "ODT"
   :filters-alist '((:filter-parse-tree
-		    . (org-odt--translate-latex-fragments
+		    . (org-odt--translate-cite-fragments
+		       org-odt--translate-latex-fragments
 		       org-odt--translate-description-lists ; Dummy symbol
 		       org-odt--translate-list-tables)))
   :menu-entry
@@ -1780,6 +1783,39 @@ (defun org-odt-footnote-reference (footnote-reference contents info)
 	   (funcall --format-footnote-definition n def))))))))

+;;;; Citation Reference
+
+(defun org-odt-citation-reference (citation-reference contents info)
+  "Transcode a CITATION-REFERENCE element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information."
+  ;; Citation references are treated like any other latex fragments.
+  ;; Citation processors (see ox-jabref.el) may handle citation
+  ;; references by registering their own transcoders.
+  (let ((latex-fragment citation-reference))
+    (org-odt-latex-fragment latex-fragment contents info)))
+
+(defun org-odt-citation-reference/numbered (citation-reference contents info)
+  "Transcode a CITATION-REFERENCE element from Org to ODT.
+CONTENTS is nil.  INFO is a plist holding contextual information.
+
+Replace each CITE-KEY from CITATION-REFERENCE with it's numerical
+order in the exported Org file.  Return the concatenated result,
+after adding some separators."
+  (let* ((latex-frag (org-element-property :value citation-reference))
+	 (value (and (string-match "\\\\cite{\\(.*?\\)}" latex-frag)
+		     (match-string 1 latex-frag)))
+	 (cite-keys (org-split-string value ",")))
+    (format "[%s]"
+	    (mapconcat
+	     (lambda (cite-key)
+	       (let* ((citations-alist (plist-get info :citations-alist))
+		      (cite-key-entry (assoc cite-key citations-alist))
+		      (n (length (memq cite-key-entry citations-alist))))
+		 (format "<text:a xlink:type=\"simple\" xlink:href=\"#%s\">%s</text:a>"
+			 cite-key (format "%d" n))))
+	     cite-keys ", "))))
+
+
 ;;;; Headline
 
 (defun* org-odt-format-headline
@@ -2045,6 +2081,11 @@ (defun org-odt-keyword (keyword contents info)
 	 ((member value '("tables" "figures" "listings"))
 	  ;; FIXME
 	  (ignore)))))
+     ;; Handle BIBLIOGRAPHY.  Ignore it.
+     ((string= key "BIBLIOGRAPHY")
+      ;; Citation Processors (see ox-jabref.el) may handle this by
+      ;; registering their own transcoders.
+      (ignore))
      ((string= key "PAGEBREAK")
 
       ;; Pagebreaks created this way are a mere expedience.  These
@@ -2109,8 +2150,7 @@ (defun org-odt-latex-environment (latex-environment contents info)
 (defun org-odt-latex-fragment (latex-fragment contents info)
   "Transcode a LATEX-FRAGMENT object from Org to ODT.
 CONTENTS is nil.  INFO is a plist holding contextual information."
-  (let* ((latex-frag (org-element-property :value latex-fragment))
-	 (processing-type (plist-get info :with-latex)))
+  (let* ((latex-frag (org-element-property :value latex-fragment)))
     (format "<text:span text:style-name=\"%s\">%s</text:span>"
 	    "OrgCode" (org-odt--encode-plain-text latex-frag t))))
 
@@ -3907,6 +3947,43 @@ (defun org-odt-verse-block (verse-block contents info)
 
 ;;; Filters
 
+(defun org-odt--translate-cite-fragments (tree backend info)
+  "Translate all \\cite{} LaTeX fragments in TREE to `citation-reference'.
+Return the translated tree.
+
+`citation-reference' is a non-standard element (stricly speaking,
+an object) used internally by the ODT exporter.  See
+`org-odt-citation-transcoders'.
+
+Modify INFO plist by appending a `:citations-alist' property.
+The value of this property is a list where each element is of the
+form (CITE-KEY . CITATION-REFERENCE), with CITATION-REFERENCE
+being the first element that references CITE-KEY.  The list is
+sorted in reverse order of appearance of CITE-KEYs in the
+exported file."
+  (let ((citations-alist nil))
+    (org-element-map tree 'latex-fragment
+      (lambda (latex-*)
+	(let* ((latex-frag (org-element-property :value latex-*)))
+	  (when (string-match "\\\\cite{\\(.*?\\)}" latex-frag)
+	    ;; LaTeX fragment matches \cite{...}
+	    (let* ((value (match-string 1 latex-frag)))
+	      ;; Replace LaTeX fragment with a `citation-reference' object.
+	      (let* ((citation-reference (org-element-adopt-elements
+					  (list 'citation-reference
+						(list :value latex-frag)))))
+		(org-element-set-element latex-* citation-reference)
+		;; Check if this citation-reference is the first
+		;; reference for any of the cite keys.
+		(let ((cite-keys (split-string value ",")))
+		  (mapc (lambda (cite-key)
+			  (unless (assoc cite-key citations-alist)
+			    (push (cons cite-key latex-*) citations-alist)))
+			cite-keys))))))) info)
+    ;; Modify INFO by side-effects.
+    (nconc info (list :citations-alist citations-alist)))
+  tree)
+
 ;;;; LaTeX fragments
 
 (defun org-odt--translate-latex-fragments (tree backend info)
@@ -4242,6 +4319,7 @@ (defun org-odt--translate-list-tables (tree backend info)
     info)
   tree)
 
+
 
 ;;; Interactive functions
 
@@ -4375,7 +4453,7 @@ (defmacro org-odt--export-wrap (out-file &rest body)
 	      ;; Case 2: No further conversion.  Return exported
 	      ;; OpenDocument file.
 	      (t target))))
-       (error
+       ((debug error)
 	;; Cleanup work directory and work files.
 	(funcall --cleanup-xml-buffers)
 	(message "OpenDocument export failed: %s"
-- 
1.7.2.5

----------------------------------------------------------------

ox-jabref.el (Standalone) and ox-freemind.el