Browse Source

Merge branch 'master' of git+ssh://repo.or.cz/srv/git/org-mode

Carsten Dominik 14 years ago
parent
commit
325daa8228
5 changed files with 267 additions and 134 deletions
  1. 21 21
      lisp/ob-clojure.el
  2. 2 1
      lisp/org-docbook.el
  3. 231 108
      lisp/org-freemind.el
  4. 4 4
      lisp/org-html.el
  5. 9 0
      lisp/org-macs.el

+ 21 - 21
lisp/ob-clojure.el

@@ -91,28 +91,28 @@
 (defvar swank-clojure-extra-classpaths)
 (defvar swank-clojure-extra-classpaths)
 (defun org-babel-clojure-babel-clojure-cmd ()
 (defun org-babel-clojure-babel-clojure-cmd ()
   "Create the command to start clojure according to current settings."
   "Create the command to start clojure according to current settings."
-  (if (and (not swank-clojure-binary) (not swank-clojure-classpath))
+  (or (when swank-clojure-binary
+	(if (listp swank-clojure-binary)
+	    swank-clojure-binary
+	  (list swank-clojure-binary)))
+      (when swank-clojure-classpath
+	(delq
+	 nil
+	 (append
+	  (list swank-clojure-java-path)
+	  swank-clojure-extra-vm-args
+	  (list
+	   (when swank-clojure-library-paths
+	     (concat "-Djava.library.path="
+		     (swank-clojure-concat-paths swank-clojure-library-paths)))
+	   "-classpath"
+	   (swank-clojure-concat-paths
+	    (append
+	     swank-clojure-classpath
+	     swank-clojure-extra-classpaths))
+	   "clojure.main"))))
       (error "%s" (concat "You must specifiy either a `swank-clojure-binary' "
       (error "%s" (concat "You must specifiy either a `swank-clojure-binary' "
-			  "or a `swank-clojure-jar-path'"))
-    (if swank-clojure-binary
-        (if (listp swank-clojure-binary)
-            swank-clojure-binary
-          (list swank-clojure-binary))
-      (delq
-       nil
-       (append
-        (list swank-clojure-java-path)
-        swank-clojure-extra-vm-args
-        (list
-         (when swank-clojure-library-paths
-           (concat "-Djava.library.path="
-                   (swank-clojure-concat-paths swank-clojure-library-paths)))
-         "-classpath"
-         (swank-clojure-concat-paths
-          (append
-           swank-clojure-classpath
-           swank-clojure-extra-classpaths))
-         "clojure.main"))))))
+			  "or a `swank-clojure-classpath'"))))
 
 
 (defun org-babel-clojure-table-or-string (results)
 (defun org-babel-clojure-table-or-string (results)
   "Convert RESULTS to an elisp value.
   "Convert RESULTS to an elisp value.

+ 2 - 1
lisp/org-docbook.el

@@ -1005,7 +1005,8 @@ publishing directory."
 		    table-orig-buffer (nreverse table-orig-buffer))
 		    table-orig-buffer (nreverse table-orig-buffer))
 	      (org-export-docbook-close-para-maybe)
 	      (org-export-docbook-close-para-maybe)
 	      (insert (org-export-docbook-finalize-table
 	      (insert (org-export-docbook-finalize-table
-		       (org-format-table-html table-buffer table-orig-buffer)))))
+		       (org-format-table-html table-buffer table-orig-buffer
+					      'docbook)))))
 
 
 	   (t
 	   (t
 	    ;; Normal lines
 	    ;; Normal lines

+ 231 - 108
lisp/org-freemind.el

@@ -81,31 +81,35 @@
 
 
 (require 'xml)
 (require 'xml)
 (require 'org)
 (require 'org)
-(require 'rx)
+;(require 'rx)
 (require 'org-exp)
 (require 'org-exp)
 (eval-when-compile (require 'cl))
 (eval-when-compile (require 'cl))
 
 
+(defgroup org-freemind nil
+  "Customization group for org-freemind export/import."
+  :group 'org)
+
 ;; Fix-me: I am not sure these are useful:
 ;; Fix-me: I am not sure these are useful:
 ;;
 ;;
 ;; (defcustom org-freemind-main-fgcolor "black"
 ;; (defcustom org-freemind-main-fgcolor "black"
 ;;   "Color of main node's text."
 ;;   "Color of main node's text."
 ;;   :type 'color
 ;;   :type 'color
-;;   :group 'freemind)
+;;   :group 'org-freemind)
 
 
 ;; (defcustom org-freemind-main-color "black"
 ;; (defcustom org-freemind-main-color "black"
 ;;   "Background color of main node."
 ;;   "Background color of main node."
 ;;   :type 'color
 ;;   :type 'color
-;;   :group 'freemind)
+;;   :group 'org-freemind)
 
 
 ;; (defcustom org-freemind-child-fgcolor "black"
 ;; (defcustom org-freemind-child-fgcolor "black"
 ;;   "Color of child nodes' text."
 ;;   "Color of child nodes' text."
 ;;   :type 'color
 ;;   :type 'color
-;;   :group 'freemind)
+;;   :group 'org-freemind)
 
 
 ;; (defcustom org-freemind-child-color "black"
 ;; (defcustom org-freemind-child-color "black"
 ;;   "Background color of child nodes."
 ;;   "Background color of child nodes."
 ;;   :type 'color
 ;;   :type 'color
-;;   :group 'freemind)
+;;   :group 'org-freemind)
 
 
 (defvar org-freemind-node-style nil "Internal use.")
 (defvar org-freemind-node-style nil "Internal use.")
 
 
@@ -152,11 +156,25 @@ NOT READY YET."
                                   (string :tag "Font name" :value "SansSerif"))
                                   (string :tag "Font name" :value "SansSerif"))
                             (list :format "%v" (const :format "" font-size)
                             (list :format "%v" (const :format "" font-size)
                                   (integer :tag "Font size" :value 12)))))))
                                   (integer :tag "Font size" :value 12)))))))
-  :group 'freemind)
+  :group 'org-freemind)
 
 
 ;;;###autoload
 ;;;###autoload
-(defun org-export-as-freemind (arg &optional hidden ext-plist
+(defun org-export-as-freemind (&optional hidden ext-plist
 				   to-buffer body-only pub-dir)
 				   to-buffer body-only pub-dir)
+  "Export the current buffer as a Freemind file.
+If there is an active region, export only the region.  HIDDEN is
+obsolete and does nothing.  EXT-PLIST is a property list with
+external parameters overriding org-mode's default settings, but
+still inferior to file-local settings.  When TO-BUFFER is
+non-nil, create a buffer with that name and export to that
+buffer.  If TO-BUFFER is the symbol `string', don't leave any
+buffer behind but just return the resulting HTML as a string.
+When BODY-ONLY is set, don't produce the file header and footer,
+simply return the content of the document (all top level
+sections).  When PUB-DIR is set, use this as the publishing
+directory.
+
+See `org-freemind-from-org-mode' for more information."
   (interactive "P")
   (interactive "P")
   (let* ((opt-plist (org-combine-plists (org-default-export-plist)
   (let* ((opt-plist (org-combine-plists (org-default-export-plist)
 					ext-plist
 					ext-plist
@@ -196,14 +214,27 @@ NOT READY YET."
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-freemind-show (mm-file)
 (defun org-freemind-show (mm-file)
-  "Show file MM-FILE in FreeMind."
+  "Show file MM-FILE in Freemind."
   (interactive
   (interactive
    (list
    (list
     (save-match-data
     (save-match-data
       (let ((name (read-file-name "FreeMind file: "
       (let ((name (read-file-name "FreeMind file: "
                                   nil nil nil
                                   nil nil nil
                                   (if (buffer-file-name)
                                   (if (buffer-file-name)
-                                      (file-name-nondirectory (buffer-file-name))
+                                      (let* ((name-ext (file-name-nondirectory (buffer-file-name)))
+                                             (name (file-name-sans-extension name-ext))
+                                             (ext (file-name-extension name-ext)))
+                                        (cond
+                                         ((string= "mm" ext)
+                                          name-ext)
+                                         ((string= "org" ext)
+                                          (let ((name-mm (concat name ".mm")))
+                                            (if (file-exists-p name-mm)
+                                                name-mm
+                                              (message "Not exported to Freemind format yet")
+                                              "")))
+                                         (t
+                                          "")))
                                     "")
                                     "")
                                   ;; Fix-me: Is this an Emacs bug?
                                   ;; Fix-me: Is this an Emacs bug?
                                   ;; This predicate function is never
                                   ;; This predicate function is never
@@ -227,7 +258,7 @@ The characters \"&<> will be escaped."
     (dolist (cc chars)
     (dolist (cc chars)
       (setq fm-str
       (setq fm-str
             (concat fm-str
             (concat fm-str
-                    (if (< cc 256)
+                    (if (< cc 160)
                         (cond
                         (cond
                          ((= cc ?\") "&quot;")
                          ((= cc ?\") "&quot;")
                          ((= cc ?\&) "&amp;")
                          ((= cc ?\&) "&amp;")
@@ -265,52 +296,84 @@ will also unescape &#nn;."
                         )))
                         )))
                   org-str))))
                   org-str))))
 
 
-;; (org-freemind-test-escape)
-(defun org-freemind-test-escape ()
-  (let* ((str1 "a quote: \", an amp: &, lt: <; over 256: öåäÖÅÄ")
-         (str2 (org-freemind-escape-str-from-org str1))
-         (str3 (org-freemind-unescape-str-to-org str2))
+;; (let* ((str1 "a quote: \", an amp: &, lt: <; over 256: öåäÖÅÄ")
+;;        (str2 (org-freemind-escape-str-from-org str1))
+;;        (str3 (org-freemind-unescape-str-to-org str2)))
+;;     (unless (string= str1 str3)
+;;       (error "Error str3=%s" str3)))
+
+(defun org-freemind-convert-links-helper (matched)
+  "Helper for `org-freemind-convert-links-from-org'.
+MATCHED is the link just matched."
+  (let* ((link (match-string 1 matched))
+         (text (match-string 2 matched))
+         (ext (file-name-extension link))
+         (col-pos (string-match-p ":" link))
+         (is-img (and (image-type-from-file-name link)
+                      (let ((url-type (substring link 0 col-pos)))
+                        (member url-type '("file" "http" "https")))))
         )
         )
-    (unless (string= str1 str3)
-      (error "str3=%s" str3))
-    ))
+    (if is-img
+        ;; Fix-me: I can't find a way to get the border to "shrink
+        ;; wrap" around the image using <div>.
+        ;;
+        ;; (concat "<div style=\"border: solid 1px #ddd; width:auto;\">"
+        ;;         "<img src=\"" link "\" alt=\"" text "\" />"
+        ;;         "<br />"
+        ;;         "<i>" text "</i>"
+        ;;         "</div>")
+        (concat "<table border=\"0\" style=\"border: solid 1px #ddd;\"><tr><td>"
+                "<img src=\"" link "\" alt=\"" text "\" />"
+                "<br />"
+                "<i>" text "</i>"
+                "</td></tr></table>")
+      (concat "<a href=\"" link "\">" text "</a>"))))
 
 
 (defun org-freemind-convert-links-from-org (org-str)
 (defun org-freemind-convert-links-from-org (org-str)
-  "Convert org links in ORG-STR to FreeMind links and return the result."
+  "Convert org links in ORG-STR to freemind links and return the result."
   (let ((fm-str (replace-regexp-in-string
   (let ((fm-str (replace-regexp-in-string
-                 (rx (not (any "[\""))
-                     (submatch
-                      "http"
-                      (opt ?\s)
-                      "://"
-                      (1+
-                       (any "-%.?@a-zA-Z0-9()_/:~=&#"))))
+                 ;;(rx (not (any "[\""))
+                 ;;    (submatch
+                 ;;     "http"
+                 ;;     (opt ?\s)
+                 ;;     "://"
+                 ;;     (1+
+                 ;;      (any "-%.?@a-zA-Z0-9()_/:~=&#"))))
+		 "[^\"[]\\(http ?://[--:#%&()=?-Z_a-z~]+\\)"
                  "[[\\1][\\1]]"
                  "[[\\1][\\1]]"
-                 org-str)))
-    (replace-regexp-in-string (rx "[["
-                                  (submatch (*? nonl))
-                                  "]["
-                                  (submatch (*? nonl))
-                                  "]]")
-                              "<a href=\"\\1\">\\2</a>"
-                              fm-str)))
+                 org-str
+                 nil ;; fixedcase
+                 nil ;; literal
+                 1   ;; subexp
+                 )))
+    (replace-regexp-in-string
+     ;;(rx "[["
+     ;;	 (submatch (*? nonl))
+     ;; "]["
+     ;; (submatch (*? nonl))
+     ;; "]]")
+     "\\[\\[\\(.*?\\)]\\[\\(.*?\\)]]"
+     ;;"<a href=\"\\1\">\\2</a>"
+     'org-freemind-convert-links-helper
+     fm-str)))
 
 
 ;;(org-freemind-convert-links-to-org "<a href=\"http://www.somewhere/\">link-text</a>")
 ;;(org-freemind-convert-links-to-org "<a href=\"http://www.somewhere/\">link-text</a>")
 (defun org-freemind-convert-links-to-org (fm-str)
 (defun org-freemind-convert-links-to-org (fm-str)
-  "Convert FreeMind links in FM-STR to org links and return the result."
+  "Convert freemind links in FM-STR to org links and return the result."
   (let ((org-str (replace-regexp-in-string
   (let ((org-str (replace-regexp-in-string
-                  (rx "<a"
-                      space
-                      (0+
-                       (0+ (not (any ">")))
-                       space)
-                      "href=\""
-                      (submatch (0+ (not (any "\""))))
-                      "\""
-                      (0+ (not (any ">")))
-                       ">"
-                       (submatch (0+ (not (any "<"))))
-                       "</a>")
+                  ;;(rx "<a"
+                  ;;    space
+                  ;;    (0+
+                  ;;     (0+ (not (any ">")))
+                  ;;     space)
+                  ;;    "href=\""
+                  ;;    (submatch (0+ (not (any "\""))))
+                  ;;    "\""
+                  ;;    (0+ (not (any ">")))
+                  ;;     ">"
+                  ;;     (submatch (0+ (not (any "<"))))
+                  ;;     "</a>")
+		  "<a[[:space:]]\\(?:[^>]*[[:space:]]\\)*href=\"\\([^\"]*\\)\"[^>]*>\\([^<]*\\)</a>"
                   "[[\\1][\\2]]"
                   "[[\\1][\\2]]"
                   fm-str)))
                   fm-str)))
     org-str))
     org-str))
@@ -319,35 +382,66 @@ will also unescape &#nn;."
 ;;(defun org-freemind-convert-drawers-from-org (text)
 ;;(defun org-freemind-convert-drawers-from-org (text)
 ;;  )
 ;;  )
 
 
-;; (org-freemind-test-links)
-;; (defun org-freemind-test-links ()
 ;;   (let* ((str1 "[[http://www.somewhere/][link-text]")
 ;;   (let* ((str1 "[[http://www.somewhere/][link-text]")
 ;;          (str2 (org-freemind-convert-links-from-org str1))
 ;;          (str2 (org-freemind-convert-links-from-org str1))
-;;          (str3 (org-freemind-convert-links-to-org str2))
-;;         )
+;;        (str3 (org-freemind-convert-links-to-org str2)))
 ;;     (unless (string= str1 str3)
 ;;     (unless (string= str1 str3)
-;;       (error "str3=%s" str3))
-;;     ))
+;;     (error "Error str3=%s" str3)))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Org => FreeMind
 ;;; Org => FreeMind
 
 
+(defvar org-freemind-bol-helper-base-indent nil)
+
+(defun org-freemind-bol-helper (matched)
+  "Helper for `org-freemind-convert-text-p'.
+MATCHED is the link just matched."
+  (let ((res "")
+        (bi org-freemind-bol-helper-base-indent))
+    (dolist (cc (append matched nil))
+      (if (= 32 cc)
+          ;;(setq res (concat res "&nbsp;"))
+          ;; We need to use the numerical version. Otherwise Freemind
+          ;; ver 0.9.0 RC9 can not export to html/javascript.
+          (progn
+            (if (< 0 bi)
+                (setq bi (1- bi))
+              (setq res (concat res "&#160;"))))
+        (setq res (concat res (char-to-string cc)))))
+    res))
+;; (setq x (replace-regexp-in-string "\n +" 'org-freemind-bol-nbsp-helper "\n  "))
+
 (defun org-freemind-convert-text-p (text)
 (defun org-freemind-convert-text-p (text)
   "Convert TEXT to html with <p> paragraphs."
   "Convert TEXT to html with <p> paragraphs."
+  ;; (string-match-p "[^ ]" "  a")
+  (setq org-freemind-bol-helper-base-indent (string-match-p "[^ ]" text))
   (setq text (org-freemind-escape-str-from-org text))
   (setq text (org-freemind-escape-str-from-org text))
-  (setq text (replace-regexp-in-string (rx "\n" (0+ blank) "\n") "</p><p>\n" text))
-  ;;(setq text (replace-regexp-in-string (rx bol (1+ blank) eol) "" text))
-  ;;(setq text (replace-regexp-in-string (rx bol (1+ blank)) "<br />" text))
+
+  (setq text (replace-regexp-in-string "\\([[:space:]]\\)\\(/\\)\\([^/]+\\)\\(/\\)\\([[:space:]]\\)" "\\1<i>\\3</i>\\5" text))
+  (setq text (replace-regexp-in-string "\\([[:space:]]\\)\\(\*\\)\\([^*]+\\)\\(\*\\)\\([[:space:]]\\)" "\\1<b>\\3</b>\\5" text))
+
+  (setq text (concat "<p>" text))
+  (setq text (replace-regexp-in-string "\n[[:blank:]]*\n" "</p><p>" text))
+  (setq text (replace-regexp-in-string "\\(?:<p>\\|\n\\) +" 'org-freemind-bol-helper text))
   (setq text (replace-regexp-in-string "\n" "<br />" text))
   (setq text (replace-regexp-in-string "\n" "<br />" text))
-  (concat "<p>"
-          (org-freemind-convert-links-from-org text)
-          "</p>\n"))
+  (setq text (concat text "</p>"))
+
+  (org-freemind-convert-links-from-org text))
+
+(defcustom org-freemind-node-css-style
+  "p { margin-top: 3px; margin-bottom: 3px; }"
+  "CSS style for Freemind nodes."
+  ;; Fix-me: I do not understand this. It worked to export from Freemind
+  ;; with this setting now, but not before??? Was this perhaps a java
+  ;; bug or is it a windows xp bug (some resource gets exhausted if you
+  ;; use sticky keys which I do).
+  :group 'org-freemind)
 
 
 (defun org-freemind-org-text-to-freemind-subnode/note (node-name start end drawers-regexp)
 (defun org-freemind-org-text-to-freemind-subnode/note (node-name start end drawers-regexp)
-  "Convert text part of org node to FreeMind subnode or note.
-Convert the text part of the org node named NODE-NAME.  The text
-is in the current buffer between START and END.  Drawers matching
-DRAWERS-REGEXP are converted to FreeMind notes."
+  "Convert text part of org node to freemind subnode or note.
+Convert the text part of the org node named NODE-NAME. The text
+is in the current buffer between START and END. Drawers matching
+DRAWERS-REGEXP are converted to freemind notes."
   ;; fix-me: doc
   ;; fix-me: doc
   (let ((text (buffer-substring-no-properties start end))
   (let ((text (buffer-substring-no-properties start end))
         (node-res "")
         (node-res "")
@@ -390,11 +484,14 @@ DRAWERS-REGEXP are converted to FreeMind notes."
                         "<node style=\"bubble\" background_color=\"#eeee00\">\n"
                         "<node style=\"bubble\" background_color=\"#eeee00\">\n"
                         "<richcontent TYPE=\"NODE\"><html>\n"
                         "<richcontent TYPE=\"NODE\"><html>\n"
                         "<head>\n"
                         "<head>\n"
+                        (if (= 0 (length org-freemind-node-css-style))
+                            ""
+                          (concat
                         "<style type=\"text/css\">\n"
                         "<style type=\"text/css\">\n"
                         "<!--\n"
                         "<!--\n"
-                        "p { margin-top: 0 }\n"
+                           org-freemind-node-css-style
                         "-->\n"
                         "-->\n"
-                        "</style>\n"
+                           "</style>\n"))
                         "</head>\n"
                         "</head>\n"
                         "<body>\n"))
                         "<body>\n"))
         (let ((begin-html-mark (regexp-quote "#+BEGIN_HTML"))
         (let ((begin-html-mark (regexp-quote "#+BEGIN_HTML"))
@@ -427,21 +524,28 @@ DRAWERS-REGEXP are converted to FreeMind notes."
                         "</html>\n"
                         "</html>\n"
                         "</richcontent>\n"
                         "</richcontent>\n"
                         ;; Put a note that this is for the parent node
                         ;; Put a note that this is for the parent node
-                        "<richcontent TYPE=\"NOTE\"><html>"
-                        "<head>"
-                        "</head>"
-                        "<body>"
-                        "<p>"
-                        "-- This is more about \"" node-name "\" --"
-                        "</p>"
-                        "</body>"
-                        "</html>"
-                        "</richcontent>\n"
+                        ;; "<richcontent TYPE=\"NOTE\"><html>"
+                        ;; "<head>"
+                        ;; "</head>"
+                        ;; "<body>"
+                        ;; "<p>"
+                        ;; "-- This is more about \"" node-name "\" --"
+                        ;; "</p>"
+                        ;; "</body>"
+                        ;; "</html>"
+                        ;; "</richcontent>\n"
+                        note-res
                         "</node>\n" ;; ok
                         "</node>\n" ;; ok
                         )))
                         )))
       (list node-res note-res))))
       (list node-res note-res))))
 
 
-(defun org-freemind-write-node (mm-buffer drawers-regexp num-left-nodes base-level current-level next-level this-m2 this-node-end this-children-visible next-node-start next-has-some-visible-child)
+(defun org-freemind-write-node (mm-buffer drawers-regexp
+                                num-left-nodes base-level
+                                current-level next-level this-m2
+                                this-node-end
+                                this-children-visible
+                                next-node-start
+                                next-has-some-visible-child)
   (let* (this-icons
   (let* (this-icons
          this-bg-color
          this-bg-color
          this-m2-escaped
          this-m2-escaped
@@ -503,7 +607,7 @@ DRAWERS-REGEXP are converted to FreeMind notes."
           (insert "<icon builtin=\"" icon "\"/>\n")))
           (insert "<icon builtin=\"" icon "\"/>\n")))
       )
       )
     (with-current-buffer mm-buffer
     (with-current-buffer mm-buffer
-      (when this-rich-note (insert this-rich-note))
+      ;;(when this-rich-note (insert this-rich-note))
       (when this-rich-node (insert this-rich-node))))
       (when this-rich-node (insert this-rich-node))))
   num-left-nodes)
   num-left-nodes)
 
 
@@ -521,11 +625,13 @@ Otherwise give an error say the file exists."
         (error "File %s already exists" file))
         (error "File %s already exists" file))
     t))
     t))
 
 
-(defvar org-freemind-node-pattern (rx bol
-                         (submatch (1+ "*"))
-                         (1+ space)
-                         (submatch (*? nonl))
-                         eol))
+(defvar org-freemind-node-pattern
+  ;;(rx bol
+  ;;    (submatch (1+ "*"))
+  ;;    (1+ space)
+  ;;    (submatch (*? nonl))
+  ;;    eol)
+  "^\\(\\*+\\)[[:space:]]+\\(.*?\\)$")
 
 
 (defun org-freemind-look-for-visible-child (node-level)
 (defun org-freemind-look-for-visible-child (node-level)
   (save-excursion
   (save-excursion
@@ -552,7 +658,7 @@ Otherwise give an error say the file exists."
 (defun org-freemind-write-mm-buffer (org-buffer mm-buffer node-at-line)
 (defun org-freemind-write-mm-buffer (org-buffer mm-buffer node-at-line)
   (with-current-buffer org-buffer
   (with-current-buffer org-buffer
     (dolist (node-style org-freemind-node-styles)
     (dolist (node-style org-freemind-node-styles)
-      (when (org-string-match-p (car node-style) buffer-file-name)
+      (when (string-match-p (car node-style) buffer-file-name)
         (setq org-freemind-node-style (cadr node-style))))
         (setq org-freemind-node-style (cadr node-style))))
     ;;(message "org-freemind-node-style =%s" org-freemind-node-style)
     ;;(message "org-freemind-node-style =%s" org-freemind-node-style)
     (save-match-data
     (save-match-data
@@ -573,27 +679,31 @@ Otherwise give an error say the file exists."
              node-at-line-last)
              node-at-line-last)
         (with-current-buffer mm-buffer
         (with-current-buffer mm-buffer
           (erase-buffer)
           (erase-buffer)
-          (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
+          (setq buffer-file-coding-system 'utf-8)
+          ;; Fix-me: Currentl Freemind (ver 0.9.0 RC9) does not support this:
+          ;;(insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
           (insert "<map version=\"0.9.0\">\n")
           (insert "<map version=\"0.9.0\">\n")
           (insert "<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->\n"))
           (insert "<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->\n"))
         (save-excursion
         (save-excursion
           ;; Get special buffer vars:
           ;; Get special buffer vars:
           (goto-char (point-min))
           (goto-char (point-min))
-          (while (re-search-forward (rx bol "#+DRAWERS:") nil t)
+          (message "Writing Freemind file...")
+          (while (re-search-forward "^#\\+DRAWERS:" nil t)
             (let ((dr-txt (buffer-substring-no-properties (match-end 0) (line-end-position))))
             (let ((dr-txt (buffer-substring-no-properties (match-end 0) (line-end-position))))
               (setq drawers (append drawers (split-string dr-txt) nil))))
               (setq drawers (append drawers (split-string dr-txt) nil))))
           (setq drawers-regexp
           (setq drawers-regexp
-                (concat (rx bol (0+ blank) ":")
+                (concat "^[[:blank:]]*:"
                         (regexp-opt drawers)
                         (regexp-opt drawers)
-                        (rx ":" (0+ blank)
-                            "\n"
-                            (*? anything)
-                            "\n"
-                            (0+ blank)
-                            ":END:"
-                            (0+ blank)
-                            eol)
-                        ))
+                        ;;(rx ":" (0+ blank)
+                        ;;    "\n"
+                        ;;    (*? anything)
+                        ;;    "\n"
+                        ;;    (0+ blank)
+                        ;;    ":END:"
+                        ;;    (0+ blank)
+                        ;;    eol)
+			":[[:blank:]]*\n\\(?:.\\|\n\\)*?\n[[:blank:]]*:END:[[:blank:]]*$"
+			))
 
 
           (if node-at-line
           (if node-at-line
               ;; Get number of top nodes and last line for this node
               ;; Get number of top nodes and last line for this node
@@ -725,7 +835,7 @@ Otherwise give an error say the file exists."
     (dolist (style-list org-freemind-node-style)
     (dolist (style-list org-freemind-node-style)
       (let ((node-regexp (car style-list)))
       (let ((node-regexp (car style-list)))
         (message "node-regexp=%s node-name=%s" node-regexp node-name)
         (message "node-regexp=%s node-name=%s" node-regexp node-name)
-        (when (org-string-match-p node-regexp node-name)
+        (when (string-match-p node-regexp node-name)
           ;;(setq node-style (org-freemind-do-apply-node-style style-list))
           ;;(setq node-style (org-freemind-do-apply-node-style style-list))
           (setq node-style (cadr style-list))
           (setq node-style (cadr style-list))
           (when node-style
           (when node-style
@@ -795,7 +905,8 @@ Otherwise give an error say the file exists."
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-freemind-from-org-mode-node (node-line mm-file)
 (defun org-freemind-from-org-mode-node (node-line mm-file)
-  "Convert node at line NODE-LINE to the FreeMind file MM-FILE."
+  "Convert node at line NODE-LINE to the FreeMind file MM-FILE.
+See `org-freemind-from-org-mode' for more information."
   (interactive
   (interactive
    (progn
    (progn
      (unless (org-back-to-heading nil)
      (unless (org-back-to-heading nil)
@@ -808,20 +919,29 @@ Otherwise give an error say the file exists."
                                      ".mm"))
                                      ".mm"))
             (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file)))
             (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file)))
        (list line mm-file))))
        (list line mm-file))))
-  (when (org-freemind-check-overwrite mm-file (interactive-p))
+  (when (org-freemind-check-overwrite mm-file (org-called-interactively-p 'any))
     (let ((org-buffer (current-buffer))
     (let ((org-buffer (current-buffer))
           (mm-buffer (find-file-noselect mm-file)))
           (mm-buffer (find-file-noselect mm-file)))
       (org-freemind-write-mm-buffer org-buffer mm-buffer node-line)
       (org-freemind-write-mm-buffer org-buffer mm-buffer node-line)
       (with-current-buffer mm-buffer
       (with-current-buffer mm-buffer
         (basic-save-buffer)
         (basic-save-buffer)
-        (when (interactive-p)
+        (when (org-called-interactively-p 'any)
           (switch-to-buffer-other-window mm-buffer)
           (switch-to-buffer-other-window mm-buffer)
           (when (y-or-n-p "Show in FreeMind? ")
           (when (y-or-n-p "Show in FreeMind? ")
             (org-freemind-show buffer-file-name)))))))
             (org-freemind-show buffer-file-name)))))))
 
 
 ;;;###autoload
 ;;;###autoload
 (defun org-freemind-from-org-mode (org-file mm-file)
 (defun org-freemind-from-org-mode (org-file mm-file)
-  "Convert the `org-mode' file ORG-FILE to the FreeMind file MM-FILE."
+  "Convert the `org-mode' file ORG-FILE to the FreeMind file MM-FILE.
+All the nodes will be opened or closed in Freemind just as you
+have them in `org-mode'.
+
+Note that exporting to Freemind also gives you an alternative way
+to export from `org-mode' to html.  You can create a dynamic html
+version of the your org file, by first exporting to Freemind and
+then exporting from Freemind to html.  The 'As
+XHTML (JavaScript)' version in Freemind works very well \(and you
+can use a CSS stylesheet to style it)."
   ;; Fix-me: better doc, include recommendations etc.
   ;; Fix-me: better doc, include recommendations etc.
   (interactive
   (interactive
    (let* ((org-file buffer-file-name)
    (let* ((org-file buffer-file-name)
@@ -832,13 +952,13 @@ Otherwise give an error say the file exists."
                             ".mm"))
                             ".mm"))
           (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file)))
           (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file)))
      (list org-file mm-file)))
      (list org-file mm-file)))
-  (when (org-freemind-check-overwrite mm-file (interactive-p))
+  (when (org-freemind-check-overwrite mm-file (org-called-interactively-p 'any))
     (let ((org-buffer (if org-file (find-file-noselect org-file) (current-buffer)))
     (let ((org-buffer (if org-file (find-file-noselect org-file) (current-buffer)))
           (mm-buffer (find-file-noselect mm-file)))
           (mm-buffer (find-file-noselect mm-file)))
       (org-freemind-write-mm-buffer org-buffer mm-buffer nil)
       (org-freemind-write-mm-buffer org-buffer mm-buffer nil)
       (with-current-buffer mm-buffer
       (with-current-buffer mm-buffer
         (basic-save-buffer)
         (basic-save-buffer)
-        (when (interactive-p)
+        (when (org-called-interactively-p 'any)
           (switch-to-buffer-other-window mm-buffer)
           (switch-to-buffer-other-window mm-buffer)
           (when (y-or-n-p "Show in FreeMind? ")
           (when (y-or-n-p "Show in FreeMind? ")
             (org-freemind-show buffer-file-name)))))))
             (org-freemind-show buffer-file-name)))))))
@@ -855,7 +975,7 @@ Otherwise give an error say the file exists."
                             "-sparse.mm"))
                             "-sparse.mm"))
           (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file)))
           (mm-file (read-file-name "Output FreeMind file: " nil nil nil default-mm-file)))
      (list (current-buffer) mm-file)))
      (list (current-buffer) mm-file)))
-  (when (org-freemind-check-overwrite mm-file (interactive-p))
+  (when (org-freemind-check-overwrite mm-file (org-called-interactively-p 'any))
     (let (org-buffer
     (let (org-buffer
           (mm-buffer (find-file-noselect mm-file)))
           (mm-buffer (find-file-noselect mm-file)))
       (save-window-excursion
       (save-window-excursion
@@ -864,7 +984,7 @@ Otherwise give an error say the file exists."
       (org-freemind-write-mm-buffer org-buffer mm-buffer nil)
       (org-freemind-write-mm-buffer org-buffer mm-buffer nil)
       (with-current-buffer mm-buffer
       (with-current-buffer mm-buffer
         (basic-save-buffer)
         (basic-save-buffer)
-        (when (interactive-p)
+        (when (org-called-interactively-p 'any)
           (switch-to-buffer-other-window mm-buffer)
           (switch-to-buffer-other-window mm-buffer)
           (when (y-or-n-p "Show in FreeMind? ")
           (when (y-or-n-p "Show in FreeMind? ")
             (org-freemind-show buffer-file-name)))))))
             (org-freemind-show buffer-file-name)))))))
@@ -1019,7 +1139,7 @@ PATH should be a list of steps, where each step has the form
   (save-match-data
   (save-match-data
     (let* ((rc (org-freemind-get-richcontent-node node))
     (let* ((rc (org-freemind-get-richcontent-node node))
            (txt (org-freemind-get-tree-text rc)))
            (txt (org-freemind-get-tree-text rc)))
-      ;;(when txt (setq txt (replace-regexp-in-string (rx (1+ whitespace)) " " txt)))
+      ;;(when txt (setq txt (replace-regexp-in-string "[[:space:]]+" " " txt)))
       txt
       txt
       )))
       )))
 
 
@@ -1028,7 +1148,7 @@ PATH should be a list of steps, where each step has the form
   (save-match-data
   (save-match-data
     (let* ((rc (org-freemind-get-richcontent-note node))
     (let* ((rc (org-freemind-get-richcontent-note node))
            (txt (when rc (org-freemind-get-tree-text rc))))
            (txt (when rc (org-freemind-get-tree-text rc))))
-      ;;(when txt (setq txt (replace-regexp-in-string (rx (1+ whitespace)) " " txt)))
+      ;;(when txt (setq txt (replace-regexp-in-string "[[:space:]]+" " " txt)))
       txt
       txt
       )))
       )))
 
 
@@ -1044,6 +1164,7 @@ PATH should be a list of steps, where each step has the form
   (let ((qname (car node))
   (let ((qname (car node))
         (attributes (cadr node))
         (attributes (cadr node))
         text
         text
+        ;; Fix-me: note is never inserted
         (note (org-freemind-get-richcontent-note-text node))
         (note (org-freemind-get-richcontent-note-text node))
         (mark "-- This is more about ")
         (mark "-- This is more about ")
         (icons (org-freemind-get-icon-names node))
         (icons (org-freemind-get-icon-names node))
@@ -1074,6 +1195,8 @@ PATH should be a list of steps, where each step has the form
         (case qname
         (case qname
           ('node
           ('node
            (insert (make-string (- level skip-levels) ?*) " " text "\n")
            (insert (make-string (- level skip-levels) ?*) " " text "\n")
+           (when note
+             (insert ":COMMENT:\n" note "\n:END:\n"))
            ))))
            ))))
     (dolist (child children)
     (dolist (child children)
       (unless (or (null child)
       (unless (or (null child)
@@ -1091,7 +1214,7 @@ PATH should be a list of steps, where each step has the form
             (default-org-file (concat (file-name-nondirectory mm-file) ".org"))
             (default-org-file (concat (file-name-nondirectory mm-file) ".org"))
             (org-file (read-file-name "Output org-mode file: " nil nil nil default-org-file)))
             (org-file (read-file-name "Output org-mode file: " nil nil nil default-org-file)))
        (list mm-file org-file))))
        (list mm-file org-file))))
-  (when (org-freemind-check-overwrite org-file (interactive-p))
+  (when (org-freemind-check-overwrite org-file (org-called-interactively-p 'any))
     (let ((mm-buffer (find-file-noselect mm-file))
     (let ((mm-buffer (find-file-noselect mm-file))
           (org-buffer (find-file-noselect org-file)))
           (org-buffer (find-file-noselect org-file)))
       (with-current-buffer mm-buffer
       (with-current-buffer mm-buffer
@@ -1100,7 +1223,7 @@ PATH should be a list of steps, where each step has the form
                (note (org-freemind-get-richcontent-note-text top-node))
                (note (org-freemind-get-richcontent-note-text top-node))
                (skip-levels
                (skip-levels
                 (if (and note
                 (if (and note
-                         (string-match (rx bol "--org-mode: WHOLE FILE" eol) note))
+                         (string-match "^--org-mode: WHOLE FILE$" note))
                     1
                     1
                   0)))
                   0)))
           (with-current-buffer org-buffer
           (with-current-buffer org-buffer

+ 4 - 4
lisp/org-html.el

@@ -1838,13 +1838,13 @@ lang=\"%s\" xml:lang=\"%s\">
 	nil))))
 	nil))))
 
 
 (defvar org-table-number-regexp) ; defined in org-table.el
 (defvar org-table-number-regexp) ; defined in org-table.el
-(defun org-format-table-html (lines olines)
+(defun org-format-table-html (lines olines &optional docbook)
   "Find out which HTML converter to use and return the HTML code."
   "Find out which HTML converter to use and return the HTML code."
   (if (stringp lines)
   (if (stringp lines)
       (setq lines (org-split-string lines "\n")))
       (setq lines (org-split-string lines "\n")))
   (if (string-match "^[ \t]*|" (car lines))
   (if (string-match "^[ \t]*|" (car lines))
       ;; A normal org table
       ;; A normal org table
-      (org-format-org-table-html lines)
+      (org-format-org-table-html lines nil docbook)
     ;; Table made by table.el - test for spanning
     ;; Table made by table.el - test for spanning
     (let* ((hlines (delq nil (mapcar
     (let* ((hlines (delq nil (mapcar
 			      (lambda (x)
 			      (lambda (x)
@@ -1865,7 +1865,7 @@ lang=\"%s\" xml:lang=\"%s\">
 	(org-format-table-table-html-using-table-generate-source olines)))))
 	(org-format-table-table-html-using-table-generate-source olines)))))
 
 
 (defvar org-table-number-fraction) ; defined in org-table.el
 (defvar org-table-number-fraction) ; defined in org-table.el
-(defun org-format-org-table-html (lines &optional splice)
+(defun org-format-org-table-html (lines &optional splice docbook)
   "Format a table into HTML."
   "Format a table into HTML."
   (require 'org-table)
   (require 'org-table)
   ;; Get rid of hlines at beginning and end
   ;; Get rid of hlines at beginning and end
@@ -1997,7 +1997,7 @@ lang=\"%s\" xml:lang=\"%s\">
 		     (if (not org-export-html-table-align-individual-fields)
 		     (if (not org-export-html-table-align-individual-fields)
 			 ""
 			 ""
 		       (setq n (string-to-number (match-string 1 txt)))
 		       (setq n (string-to-number (match-string 1 txt)))
-		       (format " class=\"%s\""
+		       (format (if docbook " align=\"%s\"" " class=\"%s\"")
 			       (or (nth n aligns) "left"))))
 			       (or (nth n aligns) "left"))))
 		   x))
 		   x))
 		html))
 		html))

+ 9 - 0
lisp/org-macs.el

@@ -40,6 +40,15 @@
 (declare-function org-add-props "org-compat" (string plist &rest props))
 (declare-function org-add-props "org-compat" (string plist &rest props))
 (declare-function org-string-match-p "org-compat" (&rest args))
 (declare-function org-string-match-p "org-compat" (&rest args))
 
 
+(defmacro org-called-interactively-p (&optional kind)
+  `(if (featurep 'xemacs)
+       (interactive-p)
+     (if (or (> emacs-major-version 23)
+	     (and (>= emacs-major-version 23)
+		  (>= emacs-minor-version 2)))
+	 (called-interactively-p ,kind)
+       (interactive-p))))
+
 (defmacro org-bound-and-true-p (var)
 (defmacro org-bound-and-true-p (var)
   "Return the value of symbol VAR if it is bound, else nil."
   "Return the value of symbol VAR if it is bound, else nil."
   `(and (boundp (quote ,var)) ,var))
   `(and (boundp (quote ,var)) ,var))