-
-
Save correl/8347cd28b6f9218a1507 to your computer and use it in GitHub Desktop.
| ;;; ox-confluence-en.el --- Enhanced Confluence Wiki Back-End for Org Export Engine | |
| ;; Copyright (C) 2015, Correl Roush | |
| ;; Author: Correl Roush <[email protected]> | |
| ;; Keywords: outlines, confluence, wiki | |
| ;; This file is not part of GNU Emacs. | |
| ;; This program 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. | |
| ;; This program 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: | |
| ;; | |
| ;; ox-confluence.el lets you convert Org files to confluence files | |
| ;; using the ox.el export engine. | |
| ;; | |
| ;; Put this file into your load-path and the following into your ~/.emacs: | |
| ;; (require 'ox-confluence-en) | |
| ;; | |
| ;; Export Org files to confluence: | |
| ;; M-x org-confluence-en-export-as-confluence RET | |
| ;; | |
| ;;; Code: | |
| (require 'ox-confluence) | |
| (defgroup org-export-confluence-en nil | |
| "Options for exporting to Confluence" | |
| :tag "Org Confluence" | |
| :group 'org-export) | |
| (defcustom org-confluence-en-use-plantuml-macro t | |
| "Embed PlantUML graphs using the PlantUML macro. | |
| When exporting the results of a PlantUML, dot, or ditaa source | |
| block, use the Confluence PlantUML macro to render the graph | |
| rather than linking to the resulting image generated locally. | |
| Requires the free confluence PlantUML plugin to be installed: | |
| https://marketplace.atlassian.com/plugins/de.griffel.confluence.plugins.plant-uml" | |
| :group 'org-export-confluence-en | |
| :type 'boolean) | |
| (org-export-define-derived-backend 'confluence-en 'confluence | |
| :translate-alist '((headline . org-confluence-en-headline) | |
| (paragraph . org-confluence-en-paragraph) | |
| (src-block . org-confluence-en-src-block) | |
| (quote-block . org-confluence-en-quote-block) | |
| (special-block . org-confluence-en-special-block) | |
| (verbatim . org-confluence-en-verbatim) | |
| (code . org-confluence-en-verbatim) | |
| (fixed-width . org-confluence-en-verbatim) | |
| (table-cell . org-confluence-en-table-cell) | |
| (item . org-confluence-en-item) | |
| (timestamp . org-confluence-en-timestamp) | |
| (property-drawer . org-confluence-en-property-drawer)) | |
| :menu-entry | |
| '(?C "Export to Confluence" | |
| ((?C "As Wiki buffer" | |
| (lambda (a s v b) | |
| (org-confluence-en-export-as-confluence a s v b)))))) | |
| (defun org-confluence-en-headline (headline contents info) | |
| (let* ((low-level-rank (org-export-low-level-p headline info)) | |
| (text (org-export-data (org-element-property :title headline) | |
| info)) | |
| (todo (org-export-data (org-element-property :todo-keyword headline) | |
| info)) | |
| (level (org-export-get-relative-level headline info)) | |
| (todo-text (if (or (not (plist-get info :with-todo-keywords)) | |
| (string= todo "")) | |
| "" | |
| (let* ((todo-type (org-element-property :todo-type headline)) | |
| (status-color (cond | |
| ((equal todo-type 'todo) "red") | |
| ((equal todo-type 'done) "green") | |
| (t "green")))) | |
| (format "%s " (org-confluence-en--macro "status" nil `((color . ,status-color) (title . ,todo)))))))) | |
| ;; Else: Standard headline. | |
| (format "h%s. %s%s\n%s" level todo-text text | |
| (if (org-string-nw-p contents) contents "")))) | |
| (defun org-confluence-en-paragraph (paragraph contents info) | |
| "Strip newlines from paragraphs. | |
| Confluence will include any line breaks in the paragraph, rather | |
| than treating it as reflowable whitespace." | |
| (replace-regexp-in-string "\n" " " contents)) | |
| (defun org-confluence-en-src-block (src-block contents info) | |
| "Embed source block results using available macros. | |
| Currently, PlantUML, Graphviz, and Ditaa graphs will be embedded | |
| using the macros provided by the PlantUML plugin, if it is | |
| available." | |
| (let ((lang (org-element-property :language src-block)) | |
| (code (org-export-format-code-default src-block info)) | |
| (caption (if (org-export-get-caption src-block) | |
| (org-trim (org-export-data (org-export-get-caption src-block) info))))) | |
| (if (and org-confluence-en-use-plantuml-macro | |
| (member lang '("plantuml" "dot" "ditaa"))) | |
| (org-confluence-en--macro "plantuml" code `((type . ,lang))) | |
| (org-confluence-en--block lang "Emacs" caption code)))) | |
| (defun org-confluence-en--block (language theme caption contents) | |
| (concat "\{code:theme=" theme | |
| (when language (format "|language=%s" language)) | |
| (when caption (format "|title=%s" caption)) | |
| "}\n" | |
| contents | |
| "\{code\}\n")) | |
| (defun org-confluence-en-quote-block (quote-block contents info) | |
| (org-confluence-en--macro "quote" contents)) | |
| (defun org-confluence-en-special-block (special-block contents info) | |
| (let ((block-type (downcase (org-element-property :type special-block)))) | |
| (if (member block-type '("info" "note" "warning")) | |
| (org-confluence-en--macro block-type contents) | |
| (org-ascii-special-block special-block contents info)))) | |
| (defun org-confluence-en-verbatim (verbatim contents info) | |
| (format "{{%s}}" | |
| (org-trim (org-element-property :value verbatim)))) | |
| (defun org-confluence-en--macro (name contents &optional arguments) | |
| (let ((open-tag (concat "\{" name | |
| (when arguments | |
| (concat ":" | |
| (mapconcat (lambda (pair) (format "%s=%s" | |
| (car pair) | |
| (cdr pair))) | |
| arguments | |
| "|"))) | |
| "}")) | |
| (close-tag (concat "{" name "}"))) | |
| (if contents (concat open-tag "\n" contents "\n" close-tag) | |
| open-tag))) | |
| (defun org-confluence-en-export-as-confluence | |
| (&optional async subtreep visible-only body-only ext-plist) | |
| (interactive) | |
| (let ((org-babel-default-header-args:plantuml '((:exports . "code"))) | |
| (org-babel-default-header-args:dot '((:exports . "code"))) | |
| (org-babel-default-header-args:ditaa '((:exports . "code")))) | |
| (org-export-to-buffer 'confluence-en "*org CONFLUENCE Export*" | |
| async subtreep visible-only body-only ext-plist (lambda () (text-mode))))) | |
| (defun org-confluence-en-table-cell (table-cell contents info) | |
| "Wrap table cell contents in whitespace. | |
| Without the extra whitespace, cells will collapse together thanks | |
| to confluence's table header syntax being multiple pipes." | |
| (let ((table-row (org-export-get-parent table-cell))) | |
| (concat | |
| (when (org-export-table-row-starts-header-p table-row info) | |
| "|") | |
| " " contents " |"))) | |
| (defun org-confluence-en--checkbox (item info) | |
| "Return checkbox string for ITEM or nil. | |
| INFO is a plist used as a communication channel." | |
| (cl-case (org-element-property :checkbox item) | |
| (on "β ") | |
| (off "β ") | |
| (trans "β "))) | |
| (defun org-confluence-en-item (item contents info) | |
| (let ((list-type (org-element-property :type (org-export-get-parent item))) | |
| (checkbox (org-confluence-en--checkbox item info)) | |
| (depth (1+ (org-confluence--li-depth item)))) | |
| (cl-case list-type | |
| (descriptive | |
| (concat (make-string depth ?-) " " | |
| (org-export-data (org-element-property :tag item) info) ": " | |
| (org-trim contents))) | |
| (ordered | |
| (concat (make-string depth ?#) " " | |
| (org-trim contents))) | |
| (t | |
| (concat (make-string depth ?-) | |
| " " | |
| (org-trim contents)))))) | |
| (defun org-confluence-en-timestamp (timestamp contents info) | |
| (s-replace-all | |
| '(("[" . "") | |
| ("]" . "")) | |
| (org-ascii-timestamp timestamp contents info))) | |
| (defun org-confluence-en-property-drawer (property-drawer contents info) | |
| (and (org-string-nw-p contents) | |
| (org-confluence-en--macro "info" contents))) | |
| (provide 'ox-confluence-en) | |
| ;;; ox-confluence-en ends here |
@thklumpp I just saw your comment. I've updated it today to handle source block captions, and took care of the ": code" syntax as well.
I'm not a huge fan of confluence, so when I had to use it I was quite happy to find your gist. Have you considered putting it on elpa or some other more traditional form? Perhaps at least a repository with a README. I know that there's an 'official' ox-confluence but yours is the first search result that comes up so I think it would be helpful. Anyway, thanks.
@necromuralist I think I will, actually. If only because I never seem to get notified on gist comments. I just happened to notice yours, because I'm (finally) adding an export menu entry for it π
For anyone who lands here, this is available as repository: https://github.com/correl/ox-confluence-en
Many thanks for this, as this handles now also =verbatim=.
I think one style is still not supported:
: code
This is one line of code with a colon and a space in front of the code.
This should also lead to {{monospaced}}.
Please can you help me with that, where to get that?
Many thanks,
Thomas