mirror of
https://git.savannah.gnu.org/git/emacs/org-mode.git
synced 2024-11-22 07:09:47 +00:00
Add Freemind Mindmap Back-End for Org Export Engine
* contrib/lisp/ox-freemind.el: New file. * lisp/ox-html.el (org-html--tags, org-html-format-headline) (org-html--format-toc-headline, org-html-checkbox) (org-html-table-cell, org-html-timestamp) (org-html-verse-block, org-html-special-string-regexps): Replace named HTML entities with their numeric counterparts. This keeps Freemind backend happy.
This commit is contained in:
parent
25f2ae88f5
commit
f2b2c8318f
543
contrib/lisp/ox-freemind.el
Normal file
543
contrib/lisp/ox-freemind.el
Normal file
@ -0,0 +1,543 @@
|
||||
;;; ox-freemind.el --- Freemind Mindmap Back-End for Org Export Engine
|
||||
|
||||
;; Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Jambunathan K <kjambunathan at gmail dot com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This library implements a Freemind Mindmap back-end for Org generic
|
||||
;; exporter.
|
||||
|
||||
;; To test it, run:
|
||||
;;
|
||||
;; M-x org-freemind-export-to-freemind
|
||||
;;
|
||||
;; in an Org mode buffer. See ox.el for more details on how this
|
||||
;; exporter works.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;;; Dependencies
|
||||
|
||||
(require 'ox-html)
|
||||
|
||||
|
||||
|
||||
;;; Define Back-End
|
||||
|
||||
(org-export-define-derived-backend freemind html
|
||||
:export-block "FREEMIND"
|
||||
:menu-entry
|
||||
(?f "Export to Freemind Mindmap"
|
||||
((?f "As Freemind Mindmap file" org-freemind-export-to-freemind)
|
||||
(?o "As Freemind Mindmap file and open"
|
||||
(lambda (a s v b)
|
||||
(if a (org-freemind-export-to-freemind t s v b)
|
||||
(org-open-file (org-freemind-export-to-freemind nil s v b)))))))
|
||||
:translate-alist ((headline . org-freemind-headline)
|
||||
(template . org-freemind-template)
|
||||
(inner-template . org-freemind-inner-template)
|
||||
(section . org-freemind-section)
|
||||
(entity . org-freemind-entity))
|
||||
:filters-alist ((:filter-options . org-freemind-options-function)
|
||||
(:filter-final-output . org-freemind-final-function)))
|
||||
|
||||
|
||||
|
||||
;;; User Configuration Variables
|
||||
|
||||
(defgroup org-export-freemind nil
|
||||
"Options for exporting Org mode files to Freemind Mindmap."
|
||||
:tag "Org Export Freemind Mindmap"
|
||||
:group 'org-export
|
||||
:version "24.4")
|
||||
|
||||
(defcustom org-freemind-styles
|
||||
'((default . "<node>\n</node>")
|
||||
(0 . "<node COLOR=\"#000000\">\n<font NAME=\"SansSerif\" SIZE=\"20\"/>\n</node>")
|
||||
(1 . "<node COLOR=\"#0033ff\">\n<edge STYLE=\"sharp_bezier\" WIDTH=\"8\"/>\n<font NAME=\"SansSerif\" SIZE=\"18\"/>\n</node>")
|
||||
(2 . "<node COLOR=\"#00b439\">\n<edge STYLE=\"bezier\" WIDTH=\"thin\"/>\n<font NAME=\"SansSerif\" SIZE=\"16\"/>\n</node>")
|
||||
(3 . "<node COLOR=\"#990000\" FOLDED=\"true\">\n<font NAME=\"SansSerif\" SIZE=\"14\"/>\n</node>")
|
||||
(4 . "<node COLOR=\"#111111\">\n</node>"))
|
||||
"List of Freemind node styles.
|
||||
Each entry is of the form (STYLE-NAME . STYLE-SPEC). STYLE-NAME
|
||||
can be one of an integer (signifying an outline level), a string
|
||||
or the symbol `default'. STYLE-SPEC, a string, is a Freemind
|
||||
node style."
|
||||
:type '(alist :options (default 0 1 2 3)
|
||||
:key-type (choice :tag "Style tag"
|
||||
(integer :tag "Outline level")
|
||||
(const :tag "Default value" default)
|
||||
(string :tag "Node style"))
|
||||
:value-type (string :tag "Style spec"))
|
||||
:group 'org-export-freemind
|
||||
:version "24.4")
|
||||
|
||||
(defcustom org-freemind-style-map-function 'org-freemind-style-map--automatic
|
||||
"Function to map an Org element to it's node style.
|
||||
The mapping function takes two arguments an Org ELEMENT and INFO.
|
||||
ELEMENT can be one of the following types - `org-data',
|
||||
`headline' or `section'. INFO is a plist holding contextual
|
||||
information during export. The function must return a STYLE-SPEC
|
||||
to be applied to ELEMENT.
|
||||
|
||||
See `org-freemind-style-map--automatic' for a sample style
|
||||
function. See `org-freemind-styles' for a list of named styles."
|
||||
:type '(radio
|
||||
(function-item org-freemind-style-map--automatic)
|
||||
(function-item org-freemind-style-map--default)
|
||||
function)
|
||||
:group 'org-export-freemind
|
||||
:version "24.4")
|
||||
|
||||
(defcustom org-freemind-section-format 'note
|
||||
"Specify how outline sections are to be formatted.
|
||||
If `inline', append it to the contents of it's heading node. If
|
||||
`note', attach it as a note to it's heading node. If `node',
|
||||
attach it as a separate node to it's heading node.
|
||||
|
||||
Use `note', if the input Org file contains large sections. Use
|
||||
`node', if the Org file contains mid-sized sections that need to
|
||||
stand apart. Otherwise, use `inline'."
|
||||
:type '(choice
|
||||
(const :tag "Append to outline title" inline)
|
||||
(const :tag "Attach as a note" note)
|
||||
(const :tag "Create a separate node" node))
|
||||
:group 'org-export-freemind
|
||||
:version "24.4")
|
||||
|
||||
;;;; Debugging
|
||||
|
||||
(defcustom org-freemind-pretty-output nil
|
||||
"Enable this to generate pretty Freemind Mindmap."
|
||||
:type 'boolean
|
||||
:group 'org-export-freemind
|
||||
:version "24.4")
|
||||
|
||||
|
||||
;;; Internal Functions
|
||||
|
||||
;;;; XML Manipulation
|
||||
|
||||
(defun org-freemind--serialize (parsed-xml &optional contents)
|
||||
"Convert PARSED-XML in to XML string.
|
||||
PARSED-XML is a parse tree as returned by
|
||||
`libxml-parse-xml-region'. CONTENTS is an optional string.
|
||||
|
||||
Ignore CONTENTS, if PARSED-XML is not a sole XML element.
|
||||
Otherwise, append CONTENTS to the contents of top-level element
|
||||
in PARSED-XML.
|
||||
|
||||
This is an inverse function of `libxml-parse-xml-region'.
|
||||
|
||||
For purposes of Freemind export, PARSED-XML is a node style
|
||||
specification - \"<node ...>...</node>\" - as a parse tree."
|
||||
(when contents
|
||||
(assert (symbolp (car parsed-xml))))
|
||||
(cond
|
||||
((null parsed-xml) "")
|
||||
((stringp parsed-xml) parsed-xml)
|
||||
((symbolp (car parsed-xml))
|
||||
(let ((attributes (mapconcat
|
||||
(lambda (av)
|
||||
(format "%s=\"%s\"" (car av) (cdr av)))
|
||||
(cadr parsed-xml) " ")))
|
||||
(if (or (cddr parsed-xml) contents)
|
||||
(format "\n<%s%s>%s\n</%s>"
|
||||
(car parsed-xml)
|
||||
(if (string= attributes "") "" (concat " " attributes))
|
||||
(concat (org-freemind--serialize (cddr parsed-xml))
|
||||
contents )
|
||||
(car parsed-xml))
|
||||
(format "\n<%s%s/>"
|
||||
(car parsed-xml)
|
||||
(if (string= attributes "") "" (concat " " attributes))))))
|
||||
(t (mapconcat #'org-freemind--serialize parsed-xml ""))))
|
||||
|
||||
(defun org-freemind--parse-xml (xml-string)
|
||||
"Return parse tree for XML-STRING using `libxml-parse-xml-region'.
|
||||
For purposes of Freemind export, XML-STRING is a node style
|
||||
specification - \"<node ...>...</node>\" - as a string."
|
||||
(with-temp-buffer
|
||||
(insert (or xml-string ""))
|
||||
(libxml-parse-xml-region (point-min) (point-max))))
|
||||
|
||||
|
||||
;;;; Style mappers :: Default and Automatic layout
|
||||
|
||||
(defun org-freemind-style-map--automatic (element info)
|
||||
"Return a node style corresponding to relative outline level of ELEMENT.
|
||||
ELEMENT can be any of the following types - `org-data',
|
||||
`headline' or `section'. See `org-freemind-styles' for style
|
||||
mappings of different outline levels."
|
||||
(let ((style-name
|
||||
(case (org-element-type element)
|
||||
(headline
|
||||
(org-export-get-relative-level element info))
|
||||
(section
|
||||
(let ((parent (org-export-get-parent-headline element)))
|
||||
(if (not parent) 1
|
||||
(1+ (org-export-get-relative-level parent info)))))
|
||||
(t 0))))
|
||||
(or (assoc-default style-name org-freemind-styles)
|
||||
(assoc-default 'default org-freemind-styles)
|
||||
"<node></node>")))
|
||||
|
||||
(defun org-freemind-style-map--default (element info)
|
||||
"Return the default style for all ELEMENTs.
|
||||
ELEMENT can be any of the following types - `org-data',
|
||||
`headline' or `section'. See `org-freemind-styles' for current
|
||||
value of default style."
|
||||
(or (assoc-default 'default org-freemind-styles)
|
||||
"<node></node>"))
|
||||
|
||||
|
||||
;;;; Helpers :: Retrieve, apply Freemind styles
|
||||
|
||||
(defun org-freemind--get-node-style (element info)
|
||||
"Return Freemind node style applicable for HEADLINE.
|
||||
ELEMENT is an Org element of type `org-data', `headline' or
|
||||
`section'. INFO is a plist holding contextual information."
|
||||
(unless (fboundp org-freemind-style-map-function)
|
||||
(setq org-freemind-style-map-function 'org-freemind-style-map--default))
|
||||
(let ((style (funcall org-freemind-style-map-function element info)))
|
||||
;; Sanitize node style.
|
||||
|
||||
;; Loop through the attributes of node element and purge those
|
||||
;; attributes that look suspicious. This is an extra bit of work
|
||||
;; that allows one to copy verbatim node styles from an existing
|
||||
;; Freemind Mindmap file without messing with the exported data.
|
||||
(let* ((data (org-freemind--parse-xml style))
|
||||
(attributes (cadr data))
|
||||
(ignored-attrs '(POSITION FOLDED TEXT CREATED ID
|
||||
MODIFIED)))
|
||||
(let (attr)
|
||||
(while (setq attr (pop ignored-attrs))
|
||||
(setq attributes (assq-delete-all attr attributes))))
|
||||
(when data (setcar (cdr data) attributes))
|
||||
(org-freemind--serialize data))))
|
||||
|
||||
(defun org-freemind--build-stylized-node (style-1 style-2 &optional contents)
|
||||
"Build a Freemind node with style STYLE-1 + STYLE-2 and add CONTENTS to it.
|
||||
STYLE-1 and STYLE-2 are Freemind node styles as a string.
|
||||
STYLE-1 is the base node style and STYLE-2 is the overriding
|
||||
style that takes precedence over STYLE-1. CONTENTS is a string.
|
||||
|
||||
Return value is a Freemind node with following properties:
|
||||
|
||||
1. The attributes of \"<node ...> </node>\" element is the union
|
||||
of corresponding attributes of STYLE-1 and STYLE-2. When
|
||||
STYLE-1 and STYLE-2 specify values for the same attribute
|
||||
name, choose the attribute value from STYLE-2.
|
||||
|
||||
2. The children of \"<node ...> </node>\" element is the union of
|
||||
top-level children of STYLE-1 and STYLE-2 with CONTENTS
|
||||
appended to it. When STYLE-1 and STYLE-2 share a child
|
||||
element of same type, the value chosen is that from STYLE-2.
|
||||
|
||||
For example, merging with following parameters
|
||||
|
||||
STYLE-1 =>
|
||||
<node COLOR=\"#00b439\" STYLE=\"Bubble\">
|
||||
<edge STYLE=\"bezier\" WIDTH=\"thin\"/>
|
||||
<font NAME=\"SansSerif\" SIZE=\"16\"/>
|
||||
</node>
|
||||
|
||||
STYLE-2 =>
|
||||
<node COLOR=\"#990000\" FOLDED=\"true\">
|
||||
<font NAME=\"SansSerif\" SIZE=\"14\"/>
|
||||
</node>
|
||||
|
||||
CONTENTS =>
|
||||
<attribute NAME=\"ORGTAG\" VALUE=\"@home\"/>
|
||||
|
||||
will result in following node:
|
||||
|
||||
RETURN =>
|
||||
<node STYLE=\"Bubble\" COLOR=\"#990000\" FOLDED=\"true\">
|
||||
<edge STYLE=\"bezier\" WIDTH=\"thin\"/>
|
||||
<font NAME=\"SansSerif\" SIZE=\"14\"/>
|
||||
<attribute NAME=\"ORGTAG\" VALUE=\"@home\"/>
|
||||
</node>."
|
||||
(let* ((data1 (org-freemind--parse-xml (or style-1 "")))
|
||||
(data2 (org-freemind--parse-xml (or style-2 "")))
|
||||
(attr1 (cadr data1))
|
||||
(attr2 (cadr data2))
|
||||
(merged-attr attr2)
|
||||
(children1 (cddr data1))
|
||||
(children2 (cddr data2))
|
||||
(merged-children children2))
|
||||
(let (attr)
|
||||
(while (setq attr (pop attr1))
|
||||
(unless (assq (car attr) merged-attr)
|
||||
(push attr merged-attr))))
|
||||
(let (child)
|
||||
(while (setq child (pop children1))
|
||||
(when (or (stringp child) (not (assq (car child) merged-children)))
|
||||
(push child merged-children))))
|
||||
(let ((merged-data (nconc (list 'node merged-attr) merged-children)))
|
||||
(org-freemind--serialize merged-data contents))))
|
||||
|
||||
|
||||
;;;; Helpers :: Node contents
|
||||
|
||||
(defun org-freemind--richcontent (type contents &optional css-style)
|
||||
(let* ((type (case type
|
||||
(note "NOTE")
|
||||
(node "NODE")
|
||||
(t "NODE")))
|
||||
(contents (org-trim contents)))
|
||||
(if (string= (org-trim contents) "") ""
|
||||
(format "\n<richcontent TYPE=\"%s\">%s\n</richcontent>"
|
||||
type
|
||||
(format "\n<html>\n<head>%s\n</head>\n%s\n</html>"
|
||||
(or css-style "")
|
||||
(format "<body>\n%s\n</body>" contents))))))
|
||||
|
||||
(defun org-freemind--build-node-contents (element contents info)
|
||||
(let* ((title (case (org-element-type element)
|
||||
(headline
|
||||
(org-element-property :title element))
|
||||
(org-data
|
||||
(plist-get info :title))
|
||||
(t (error "Shouldn't come here."))))
|
||||
(element-contents (org-element-contents element))
|
||||
(section (assoc 'section element-contents))
|
||||
(section-contents
|
||||
(let* ((translations
|
||||
(nconc (list (cons 'section
|
||||
(lambda (section contents info)
|
||||
contents)))
|
||||
(plist-get info :translate-alist))))
|
||||
(org-export-data-with-translations section translations info)))
|
||||
(itemized-contents-p (let ((first-child-headline
|
||||
(org-element-map element-contents
|
||||
'headline 'identity info t)))
|
||||
(when first-child-headline
|
||||
(org-export-low-level-p first-child-headline
|
||||
info))))
|
||||
(node-contents (concat section-contents
|
||||
(when itemized-contents-p
|
||||
contents))))
|
||||
(concat (let ((title (org-export-data title info)))
|
||||
(case org-freemind-section-format
|
||||
(inline
|
||||
(org-freemind--richcontent
|
||||
'node (concat (format "\n<h2>%s</h2>" title)
|
||||
node-contents) ))
|
||||
(note
|
||||
(concat (org-freemind--richcontent
|
||||
'node (format "\n<p>%s\n</p>" title))
|
||||
(org-freemind--richcontent
|
||||
'note node-contents)))
|
||||
(node
|
||||
(concat
|
||||
(org-freemind--richcontent
|
||||
'node (format "\n<p>%s\n</p>" title))
|
||||
(when section
|
||||
(org-freemind--build-stylized-node
|
||||
(org-freemind--get-node-style section info) nil
|
||||
(org-freemind--richcontent 'node node-contents)))))))
|
||||
(unless itemized-contents-p
|
||||
contents))))
|
||||
|
||||
|
||||
|
||||
;;; Template
|
||||
|
||||
(defun org-freemind-template (contents info)
|
||||
"Return complete document string after Freemind Mindmap conversion.
|
||||
CONTENTS is the transcoded contents string. RAW-DATA is the
|
||||
original parsed data. INFO is a plist holding export options."
|
||||
(format
|
||||
"<map version=\"0.9.0\">\n%s\n</map>"
|
||||
(org-freemind--build-stylized-node
|
||||
(org-freemind--get-node-style nil info) nil
|
||||
(let ((org-data (plist-get info :parse-tree)))
|
||||
(org-freemind--build-node-contents org-data contents info)))))
|
||||
|
||||
(defun org-freemind-inner-template (contents info)
|
||||
"Return body of document string after Freemind Mindmap conversion.
|
||||
CONTENTS is the transcoded contents string. INFO is a plist
|
||||
holding export options."
|
||||
contents)
|
||||
|
||||
;;;; Tags
|
||||
|
||||
(defun org-freemind--tags (tags)
|
||||
(mapconcat (lambda (tag)
|
||||
(format "\n<attribute NAME=\"%s\" VALUE=\"%s\"/>" tag ""))
|
||||
tags "\n"))
|
||||
|
||||
|
||||
|
||||
;;; Transcode Functions
|
||||
|
||||
;;;; Entity
|
||||
|
||||
(defun org-freemind-entity (entity contents info)
|
||||
"Transcode an ENTITY object from Org to Freemind Mindmap.
|
||||
CONTENTS are the definition itself. INFO is a plist holding
|
||||
contextual information."
|
||||
(org-element-property :utf-8 entity))
|
||||
|
||||
;;;; Headline
|
||||
|
||||
(defun org-freemind-headline (headline contents info)
|
||||
"Transcode a HEADLINE element from Org to Freemind Mindmap.
|
||||
CONTENTS holds the contents of the headline. INFO is a plist
|
||||
holding contextual information."
|
||||
;; Empty contents?
|
||||
(setq contents (or contents ""))
|
||||
(let* ((numberedp (org-export-numbered-headline-p headline info))
|
||||
(level (org-export-get-relative-level headline info))
|
||||
(text (org-export-data (org-element-property :title headline) info))
|
||||
(todo (and (plist-get info :with-todo-keywords)
|
||||
(let ((todo (org-element-property :todo-keyword headline)))
|
||||
(and todo (org-export-data todo info)))))
|
||||
(todo-type (and todo (org-element-property :todo-type headline)))
|
||||
(tags (and (plist-get info :with-tags)
|
||||
(org-export-get-tags headline info)))
|
||||
(priority (and (plist-get info :with-priority)
|
||||
(org-element-property :priority headline)))
|
||||
(section-number (and (not (org-export-low-level-p headline info))
|
||||
(org-export-numbered-headline-p headline info)
|
||||
(mapconcat 'number-to-string
|
||||
(org-export-get-headline-number
|
||||
headline info) ".")))
|
||||
;; Create the headline text.
|
||||
(full-text (org-export-data (org-element-property :title headline)
|
||||
info))
|
||||
;; Headline order (i.e, first digit of the section number)
|
||||
(headline-order (car (org-export-get-headline-number headline info))))
|
||||
(cond
|
||||
;; Case 1: This is a footnote section: ignore it.
|
||||
((org-element-property :footnote-section-p headline) nil)
|
||||
;; Case 2. This is a deep sub-tree, export it as a list item.
|
||||
;; Delegate the actual export to `html' backend.
|
||||
((org-export-low-level-p headline info)
|
||||
(org-html-headline headline contents info))
|
||||
;; Case 3. Standard headline. Export it as a section.
|
||||
(t
|
||||
(let* ((section-number (mapconcat 'number-to-string
|
||||
(org-export-get-headline-number
|
||||
headline info) "-"))
|
||||
(ids (remove 'nil
|
||||
(list (org-element-property :CUSTOM_ID headline)
|
||||
(concat "sec-" section-number)
|
||||
(org-element-property :ID headline))))
|
||||
(preferred-id (car ids))
|
||||
(extra-ids (cdr ids))
|
||||
(left-p (zerop (% headline-order 2))))
|
||||
(org-freemind--build-stylized-node
|
||||
(org-freemind--get-node-style headline info)
|
||||
(format "<node ID=\"%s\" POSITION=\"%s\" FOLDED=\"%s\">\n</node>"
|
||||
preferred-id
|
||||
(if left-p "left" "right")
|
||||
(if (= level 1) "true" "false"))
|
||||
(concat (org-freemind--build-node-contents headline contents info)
|
||||
(org-freemind--tags tags))))))))
|
||||
|
||||
|
||||
;;;; Section
|
||||
|
||||
(defun org-freemind-section (section contents info)
|
||||
"Transcode a SECTION element from Org to Freemind Mindmap.
|
||||
CONTENTS holds the contents of the section. INFO is a plist
|
||||
holding contextual information."
|
||||
(let ((parent (org-export-get-parent-headline section)))
|
||||
(when (and parent (org-export-low-level-p parent info))
|
||||
contents)))
|
||||
|
||||
|
||||
|
||||
;;; Filter Functions
|
||||
|
||||
(defun org-freemind-final-function (contents backend info)
|
||||
"Return CONTENTS as pretty XML using `indent-region'."
|
||||
(if (not org-freemind-pretty-output) contents
|
||||
(with-temp-buffer
|
||||
(nxml-mode)
|
||||
(insert contents)
|
||||
(indent-region (point-min) (point-max))
|
||||
(buffer-substring-no-properties (point-min) (point-max)))))
|
||||
|
||||
(defun org-freemind-options-function (info backend)
|
||||
"Install script in export options when appropriate.
|
||||
EXP-PLIST is a plist containing export options. BACKEND is the
|
||||
export back-end currently used."
|
||||
;; Freemind/Freeplane doesn't seem to like named html entities in
|
||||
;; richcontent. For now, turn off smart quote processing so that
|
||||
;; entities like "’" & friends are avoided in the exported
|
||||
;; output.
|
||||
(plist-put info :with-smart-quotes nil))
|
||||
|
||||
|
||||
|
||||
;;; End-user functions
|
||||
|
||||
;;;###autoload
|
||||
(defun org-freemind-export-to-freemind
|
||||
(&optional async subtreep visible-only body-only ext-plist)
|
||||
"Export current buffer to a Freemind Mindmap file.
|
||||
|
||||
If narrowing is active in the current buffer, only export its
|
||||
narrowed part.
|
||||
|
||||
If a region is active, export that region.
|
||||
|
||||
A non-nil optional argument ASYNC means the process should happen
|
||||
asynchronously. The resulting file should be accessible through
|
||||
the `org-export-stack' interface.
|
||||
|
||||
When optional argument SUBTREEP is non-nil, export the sub-tree
|
||||
at point, extracting information from the headline properties
|
||||
first.
|
||||
|
||||
When optional argument VISIBLE-ONLY is non-nil, don't export
|
||||
contents of hidden elements.
|
||||
|
||||
When optional argument BODY-ONLY is non-nil, only write code
|
||||
between \"<body>\" and \"</body>\" tags.
|
||||
|
||||
EXT-PLIST, when provided, is a property list with external
|
||||
parameters overriding Org default settings, but still inferior to
|
||||
file-local settings.
|
||||
|
||||
Return output file's name."
|
||||
(interactive)
|
||||
(let* ((extension (concat ".mm" ))
|
||||
(file (org-export-output-file-name extension subtreep)))
|
||||
(if async
|
||||
(org-export-async-start
|
||||
(lambda (f) (org-export-add-to-stack f 'freemind))
|
||||
(let ((org-export-coding-system 'utf-8))
|
||||
`(expand-file-name
|
||||
(org-export-to-file
|
||||
'freemind ,file ,subtreep ,visible-only ,body-only ',ext-plist))))
|
||||
(let ((org-export-coding-system 'utf-8))
|
||||
(org-export-to-file
|
||||
'freemind file subtreep visible-only body-only ext-plist)))))
|
||||
|
||||
(provide 'ox-freemind)
|
||||
|
||||
;; Local variables:
|
||||
;; generated-autoload-file: "org-loaddefs.el"
|
||||
;; End:
|
||||
|
||||
;;; ox-freemind.el ends here
|
@ -137,10 +137,10 @@
|
||||
(defvar htmlize-buffer-places) ; from htmlize.el
|
||||
|
||||
(defconst org-html-special-string-regexps
|
||||
'(("\\\\-" . "­")
|
||||
("---\\([^-]\\)" . "—\\1")
|
||||
("--\\([^-]\\)" . "–\\1")
|
||||
("\\.\\.\\." . "…"))
|
||||
'(("\\\\-" . "­") ; shy
|
||||
("---\\([^-]\\)" . "—\\1") ; mdash
|
||||
("--\\([^-]\\)" . "–\\1") ; ndash
|
||||
("\\.\\.\\." . "…")) ; hellip
|
||||
"Regular expressions for special string conversion.")
|
||||
|
||||
(defconst org-html-scripts
|
||||
@ -1580,7 +1580,7 @@ INFO is a plist used as a communication channel."
|
||||
(concat org-html-tag-class-prefix
|
||||
(org-html-fix-class-name tag))
|
||||
tag))
|
||||
tags " "))))
|
||||
tags " "))))
|
||||
|
||||
;;;; Headline
|
||||
|
||||
@ -1594,7 +1594,7 @@ INFO is a plist used as a communication channel."
|
||||
(todo (org-html--todo todo))
|
||||
(tags (org-html--tags tags)))
|
||||
(concat section-number todo (and todo " ") text
|
||||
(and tags " ") tags)))
|
||||
(and tags "   ") tags)))
|
||||
|
||||
;;;; Src Code
|
||||
|
||||
@ -1781,7 +1781,7 @@ INFO is a plist used as a communication channel."
|
||||
(target . ignore))
|
||||
(org-export-backend-translate-table 'html))
|
||||
info)
|
||||
(and tags " ") (org-html--tags tags)))))
|
||||
(and tags "   ") (org-html--tags tags)))))
|
||||
|
||||
(defun org-html-list-of-listings (info)
|
||||
"Build a list of listings.
|
||||
@ -2185,7 +2185,7 @@ contextual information."
|
||||
|
||||
(defun org-html-checkbox (checkbox)
|
||||
(case checkbox (on "<code>[X]</code>")
|
||||
(off "<code>[ ]</code>")
|
||||
(off "<code>[ ]</code>")
|
||||
(trans "<code>[-]</code>")
|
||||
(t "")))
|
||||
|
||||
@ -2857,7 +2857,7 @@ channel."
|
||||
" align=\"%s\"" " class=\"%s\"")
|
||||
(org-export-table-cell-alignment table-cell info)))))
|
||||
(when (or (not contents) (string= "" (org-trim contents)))
|
||||
(setq contents " "))
|
||||
(setq contents " "))
|
||||
(cond
|
||||
((and (org-export-table-has-header-p table info)
|
||||
(= 1 (org-export-table-row-group table-row info)))
|
||||
@ -3010,7 +3010,7 @@ information."
|
||||
(let ((value (org-html-plain-text
|
||||
(org-timestamp-translate timestamp) info)))
|
||||
(format "<span class=\"timestamp-wrapper\"><span class=\"timestamp\">%s</span></span>"
|
||||
(replace-regexp-in-string "--" "–" value))))
|
||||
(replace-regexp-in-string "--" "–" value))))
|
||||
|
||||
|
||||
;;;; Underline
|
||||
@ -3050,7 +3050,7 @@ contextual information."
|
||||
(while (string-match "^[ \t]+" contents)
|
||||
(let* ((num-ws (length (match-string 0 contents)))
|
||||
(ws (let (out) (dotimes (i num-ws out)
|
||||
(setq out (concat out " "))))))
|
||||
(setq out (concat out " "))))))
|
||||
(setq contents (replace-match ws nil t contents))))
|
||||
(format "<p class=\"verse\">\n%s</p>" contents))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user