From: Andreas Gerler Date: Fri, 25 Nov 2016 15:55:15 +0000 (+0100) Subject: updated keyfreq and ox-jira X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=e6c8fff3c5f10ddb62b3994c7502af37dbd6289a;p=emacsconfig.git updated keyfreq and ox-jira Signed-off-by: Andreas Gerler --- diff --git a/bba.org b/bba.org index e206ba11..ba8a2369 100644 --- a/bba.org +++ b/bba.org @@ -897,7 +897,6 @@ Very useful for repetitive literate devops jobs. #+END_SRC - ** copy previous src block [2016-08-25 Thu 23:36] @@ -1007,8 +1006,6 @@ selections I call this script: #+END_SRC - - ** insert arrow [2016-10-07 Fri 12:25] diff --git a/elpa/keyfreq-20150924.2005/keyfreq-autoloads.el b/elpa/keyfreq-20150924.2005/keyfreq-autoloads.el deleted file mode 100644 index 71f160a8..00000000 --- a/elpa/keyfreq-20150924.2005/keyfreq-autoloads.el +++ /dev/null @@ -1,53 +0,0 @@ -;;; keyfreq-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil "keyfreq" "keyfreq.el" (22215 7928 0 0)) -;;; Generated autoloads from keyfreq.el - -(defvar keyfreq-mode nil "\ -Non-nil if Keyfreq mode is enabled. -See the command `keyfreq-mode' for a description of this minor mode. -Setting this variable directly does not take effect; -either customize it (see the info node `Easy Customization') -or call the function `keyfreq-mode'.") - -(custom-autoload 'keyfreq-mode "keyfreq" nil) - -(autoload 'keyfreq-mode "keyfreq" "\ -Keyfreq mode records number of times each command was -called making it possible to access usage statistics through -various keyfreq-* functions. - -\(fn &optional ARG)" t nil) - -(defvar keyfreq-autosave-mode nil "\ -Non-nil if Keyfreq-Autosave mode is enabled. -See the command `keyfreq-autosave-mode' for a description of this minor mode. -Setting this variable directly does not take effect; -either customize it (see the info node `Easy Customization') -or call the function `keyfreq-autosave-mode'.") - -(custom-autoload 'keyfreq-autosave-mode "keyfreq" nil) - -(autoload 'keyfreq-autosave-mode "keyfreq" "\ -Keyfreq Autosave mode automatically saves -`keyfreq-table' every `keyfreq-autosave-timeout' seconds -and when emacs is killed. - -\(fn &optional ARG)" t nil) - -(autoload 'keyfreq-save-now "keyfreq" "\ -Save keyfreq data now. - -\(fn)" t nil) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; keyfreq-autoloads.el ends here diff --git a/elpa/keyfreq-20150924.2005/keyfreq-pkg.el b/elpa/keyfreq-20150924.2005/keyfreq-pkg.el deleted file mode 100644 index 9fd306f0..00000000 --- a/elpa/keyfreq-20150924.2005/keyfreq-pkg.el +++ /dev/null @@ -1 +0,0 @@ -(define-package "keyfreq" "20150924.2005" "track command frequencies" 'nil) diff --git a/elpa/keyfreq-20150924.2005/keyfreq.el b/elpa/keyfreq-20150924.2005/keyfreq.el deleted file mode 100644 index 8078f535..00000000 --- a/elpa/keyfreq-20150924.2005/keyfreq.el +++ /dev/null @@ -1,584 +0,0 @@ -;;; keyfreq.el --- track command frequencies -;; Package-Version: 20150924.2005 -;; -*- coding: utf-8 -*- -;; -;; Copyright 2009-2010, 2015 by David Capello -;; Copyright 2008 by Xah Lee -;; Copyright 2006 by Michal Nazarewicz -;; Copyright 2006 by Ryan Yeske -;; -;; Author: Ryan Yeske, Michal Nazarewicz (mina86/AT/mina86.com) -;; Maintainer: David Capello, Xah lee -;; Created: 2006 -;; -;; Keyfreq 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. -;; -;; Version 1.7 - 2015-09 - David Capello -;; * Avoid accumulating key frequency if keyfreq-file-release-lock fails -;; -;; Version 1.6 - 2015-09 - David Capello -;; * Added keyfreq-reset thanks to @w-vi -;; * Fixed issue running multiple instances of Emacs 24.5 -;; -;; Version 1.5 - 2014-11 - David Capello -;; * Support cl-lib or cl -;; * Minor doc fixes -;; -;; Version 1.4 - 2010-09 - David Capello -;; * Renamed from command-frequency to keyfreq -;; * Now keyfreq-table holds "deltas" -;; * Removed a lot of "facility" functions to keep the code simple. -;; * Rename keyfreq-summarize-all-modes -> keyfreq-groups-major-modes. -;; * Added keyfreq-filter-major-mode -;; * Added lock file to avoid overwrite the file by two processes at -;; the same time. -;; -;; Version 1.3 - 2009-09 - David Capello -;; * Added keyfreq-summarize-all-modes -;; -;; Version 1.2 - 2009-09 - David Capello -;; * Now each hash hash-key is a (major-mode . command) cons. Now only -;; symbols are recorded. -;; -;; Version 1.1 - 2008-09 -;; - Replaced the use of this-command var by real-last-command, so -;; that the commands backward-kill-word, kill-word, kill-line, -;; kill-region, do not all get counted as kill-region. Changed -;; post-command-hook to pre-command-hook -;; -;; Version 1.0 - 2007 -;; - Made into a full featured minor mode. Added full doc -;; strings. Added feature to save and read to disk the frequency -;; hash table. Added ability to set user preference using emacs's -;; customization system. Code is ~400 lines. This version is made by -;; Michal Nazarewicz in 2007. -;; -;; Version 0.1 - 2006 -;; - First version by Ryan Yeske. A quick hack of about 40 lines. -;; - -;;; Commentary: -;; -;; HOW TO USE IT? -;; -;; Include the following lines in your .emacs file: -;; -;; (require 'keyfreq) -;; (keyfreq-mode 1) -;; (keyfreq-autosave-mode 1) -;; -;; And use `keyfreq-show' to see how many times you used a command. -;; -;;; Code: - -(if (featurep 'cl-lib) - (require 'cl-lib) - (require 'cl)) -;; (require 'json)? - -(defgroup keyfreq nil - "Customization group for Keyfreq mode. -This mode stores number of times each command was called and -provides it as a statistical data." - :package-version '(keyfreq . "1.7") - :group 'local - :prefix "keyfreq") - -;;;###autoload -(define-minor-mode keyfreq-mode - "Keyfreq mode records number of times each command was -called making it possible to access usage statistics through -various keyfreq-* functions." - :global t - :init-value nil - :lighter nil - :keymap nil - :group 'keyfreq - - (if keyfreq-mode - (add-hook 'pre-command-hook 'keyfreq-pre-command-hook) - (remove-hook 'pre-command-hook 'keyfreq-pre-command-hook))) - - -(defcustom keyfreq-buffer "*frequencies*" - "Buffer where frequencies are displayed." - :group 'keyfreq - :type 'string) - - -(defcustom keyfreq-file "~/.emacs.keyfreq" - "File `keyfreq-table' is saved to/loaded from by -`keyfreq-table-save' and `keyfreq-table-load' functions -by default." - :group 'keyfreq - :type 'file) - -(defcustom keyfreq-file-lock "~/.emacs.keyfreq.lock" - "Lock file to update the `keyfreq-file'." - :group 'keyfreq - :type 'file) - - -(defvar keyfreq-table (make-hash-table :test 'equal :size 128) - "Hash table storing number of times each command was called in each major mode -since the last time the frequencies were saved in `keyfreq-file'.") - -(defvar keyfreq-excluded-commands '() - "List of commands excluded by keyfreq.") - -(defun keyfreq-pre-command-hook () - "Record command execution in `keyfreq-table' hash." - (let ((command real-last-command) count) - (when (and command (symbolp command)) - (setq count (gethash (cons major-mode command) keyfreq-table)) - (unless (memq command keyfreq-excluded-commands) - (puthash (cons major-mode command) (if count (1+ count) 1) - keyfreq-table) - )))) - - -(defun keyfreq-groups-major-modes (table) - "Group major modes in TABLE by command. -Return a hash table where each entry has COMMAND as key and -COUNTER as value." - (let ((new-table (make-hash-table :test 'equal :size 128))) - (maphash (lambda (k v) - (puthash (cdr k) (+ (gethash (cdr k) new-table 0) v) new-table)) - table) - new-table)) - - -(defun keyfreq-filter-major-mode (table major-mode) - "Leave the frequencies of the specified major mode. -Return a hash table where each entry has COMMAND as key and -COUNTER as value." - - (let ((new-table (make-hash-table :test 'equal :size 128))) - (maphash (lambda (k v) - (when (eq (car k) major-mode) - (puthash (cdr k) (+ (gethash (cdr k) new-table 0) v) new-table))) - table) - new-table)) - - -(defun keyfreq-used-major-modes (table) - "Return a list with the used major modes (major modes -contained in the TABLE)." - (let ((list)) - (maphash (lambda (k v) - (add-to-list 'list (car k))) - table) - list)) - - -(defun keyfreq-list (table &optional reverse limit) - "Return a cons which car is sum of times any command was used -and cdr is a list of (command . count) pairs. - -If REVERSE is nil, sort it starting from the most used command; -if it is `no-sort' the list is not sorted; if it is non-nil and -not `no-sort', sort it from the least used commands. If LIMIT is -a positive number, only commands which were used more then LIMIT -times will be added. If it is a negative number, only commands -which were used less then -LIMIT times will be added." - - (let (l (sum 0)) - (maphash - (cond - ((or (not (numberp limit)) (= limit 0)) - (lambda (k v) (setq l (cons (cons k v) l) sum (+ sum v)))) - ((= limit -1) (lambda (k v) (setq sum (+ sum v)))) - ((< limit 0) - (setq limit (- limit)) - (lambda (k v) (setq sum (+ sum v)) - (if (< v limit) (setq l (cons (cons k v) l))))) - (t - (lambda (k v) (setq sum (+ sum v)) - (if (> v limit) (setq l (cons (cons k v) l)))))) - table) - (cons sum - (cond - ((equal reverse 'no-sort) l) - (reverse (sort l (lambda (a b) (< (cdr a) (cdr b))))) - (t (sort l (lambda (a b) (> (cdr a) (cdr b))))))))) - - -(defun keyfreq-format-list (list &optional func) - "Return formatted string with command usage statistics. - -The LIST is the `keyfreq-table' converted to a list using the `keyfreq-list'. - -If FUNC is nil each line contains number of times command was -called and the command; if it is t percentage usage is added in -the middle; if it is 'raw each line will contain number an -command separated by single line (with no formatting) otherwise -FUNC must be a function returning a string which will be called -for each entry with three arguments: number of times command was -called, percentage usage and the command." - (let* ((sum (car list)) - (max-len - (reduce (lambda (a b) (max a (length (symbol-name (car b))))) - (cdr list) - :initial-value 0))) - (mapconcat - (cond - ((not func) (lambda (e) (format "%7d %s\n" (cdr e) (car e)))) - ((equal func t) - (lambda (e) (format (concat "%7d %6.2f%% %- " - (format "%d" max-len) - "s %s\n") - (cdr e) (/ (* 1e2 (cdr e)) sum) (car e) - (ignore-errors (keyfreq-where-is (car e)))))) - ((equal func 'raw) (lambda (e) (format "%d %s\n" (cdr e) (car e)))) - (t (lambda (e) (funcall func (cdr e) (/ (* 1e2 (cdr e)) sum) (car e))))) - (cdr list) ""))) - -(defun keyfreq-where-is (command) - (mapconcat 'key-description - (where-is-internal command) - ", ")) - -(defun keyfreq-show (&optional major-mode-symbol) - "Show command usage statistics in `keyfreq-buffer'. - -If MAJOR-MODE-SYMBOL is given, the function shows the statistics -for that particular major mode only. - -With a universal argument, the major-mode of the current buffer -is used as MAJOR-MODE-SYMBOL argument." - (interactive (list (cond (current-prefix-arg major-mode) - (t nil)))) - - (let ((table (copy-hash-table keyfreq-table))) - ;; Merge with the values in `keyfreq-file' - (keyfreq-table-load table) - - (let* ((list (keyfreq-list - (cond - (major-mode-symbol (keyfreq-filter-major-mode table major-mode-symbol)) - (t (keyfreq-groups-major-modes table))))) - (formatted-list (keyfreq-format-list list t))) - - ;; Display the table - (display-message-or-buffer (concat (if major-mode-symbol - (concat "For " (symbol-name major-mode)) - (concat "For all major modes")) - ":\n\n" - formatted-list) - keyfreq-buffer) - ))) - - -(defun keyfreq-html (filename &optional confirm) - "Save an HTML file as FILENAME with all the statistics of each mode." - - (interactive - (list (if buffer-file-name - (read-file-name "Write HTML file: " - nil nil nil nil) - (read-file-name "Write HTML file: " default-directory - (expand-file-name - (file-name-nondirectory (buffer-name)) - default-directory) - nil nil)) - (not current-prefix-arg))) - - (and confirm - (file-exists-p filename) - (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) - (error "Canceled"))) - - (let ((table (copy-hash-table keyfreq-table)) - (htmltable (lambda (list) - (insert "\n") - (insert "\n") - (insert "\n") - (keyfreq-format-list list - (lambda (count perc command) - (insert (format "\n" count perc command)))) - (insert "\n") - (insert "
TimesPercetageCommand
%d%.2f%%%s
\n")))) - - ;; Merge with the values in `keyfreq-file' - (keyfreq-table-load table) - - (with-temp-file filename - (insert "\n\n") - (insert "

Keyfreq Report

\n") - (insert "\n") - - (insert "

All major modes

\n") - (funcall htmltable (keyfreq-list (keyfreq-groups-major-modes table))) - - (mapc - (lambda (major-mode-symbol) - (insert (format "

%s

\n" - (symbol-name major-mode-symbol) - (symbol-name major-mode-symbol))) - (funcall htmltable (keyfreq-list (keyfreq-filter-major-mode table major-mode-symbol)))) - (keyfreq-used-major-modes table)) - - (insert "\n\n") - ) - )) - - -(defun keyfreq-json-encode (table) - "Return a JSON representation of the table of frequencies." - (require 'json) - (let ((commands-indexes (make-hash-table :test 'equal :size 128)) - commands-list frequencies-matrix i) - - ;; Build the "commands" property of the JSON object. - (setq i 0) - (maphash - (lambda (command-symbol counter) - (add-to-list 'commands-list command-symbol t) - (puthash command-symbol i commands-indexes) - (setq i (+ i 1)) - ) - (keyfreq-groups-major-modes table)) - - ;; Build the "frequencies" property. - (mapc - (lambda (major-mode-symbol) - (let ((cmd-count-pairs '())) - (keyfreq-format-list (keyfreq-list (keyfreq-filter-major-mode table major-mode-symbol)) - (lambda (count perc command) - (add-to-list 'cmd-count-pairs (gethash command commands-indexes) t) - (add-to-list 'cmd-count-pairs count t))) - (add-to-list 'frequencies-matrix major-mode-symbol t) - (add-to-list 'frequencies-matrix (append cmd-count-pairs nil) t))) - (keyfreq-used-major-modes table)) - - (json-encode `((:format . 1) - (:commands . ,commands-list) - (:frequencies . ,frequencies-matrix))))) - - -(defun keyfreq-json (filename &optional confirm) - "Save a file (as FILENAME) with a JSON structure of the data." - - (interactive - (list (if buffer-file-name - (read-file-name "Write JSON file: " - nil nil nil nil) - (read-file-name "Write JSON file: " default-directory - (expand-file-name - (file-name-nondirectory (buffer-name)) - default-directory) - nil nil)) - (not current-prefix-arg))) - - (and confirm - (file-exists-p filename) - (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) - (error "Canceled"))) - - (let ((table (copy-hash-table keyfreq-table))) - - ;; Merge with the values in `keyfreq-file' - (keyfreq-table-load table) - - (with-temp-file filename - (insert (keyfreq-json-encode table))))) - - -(defun keyfreq-reset () - "Reset all statistics including those in the file." - (interactive) - (when (yes-or-no-p (concat "Delete keyfreq file? You will lost all your stats. ")) - ;; clear the hash table - (clrhash keyfreq-table) - ;; Deal with the file - (when (keyfreq-file-is-unlocked) - ;; Lock the file - (keyfreq-file-claim-lock) - ;; Check that we have the lock - (if (eq (keyfreq-file-owner) (emacs-pid)) - (unwind-protect - ;; if the file exists just delete it - (if (file-exists-p keyfreq-file) - (delete-file keyfreq-file)) - ;; Release the lock. - (keyfreq-file-release-lock)))))) - - -(defun keyfreq-file-owner () - "Return the PID of the Emacs process that owns the table file lock file." - (let (owner) - (and (file-exists-p keyfreq-file-lock) - (ignore-errors - (with-temp-buffer - (insert-file-contents-literally keyfreq-file-lock) - (goto-char (point-min)) - (setq owner (read (current-buffer))) - (integerp owner))) - owner))) - - -(defun keyfreq-file-claim-lock () - (ignore-errors - (write-region (number-to-string (emacs-pid)) nil - keyfreq-file-lock nil 'nomessage nil 'excl))) - - -(defun keyfreq-file-release-lock () - (when (file-exists-p keyfreq-file-lock) - (delete-file keyfreq-file-lock))) - - -(defun keyfreq-file-is-unlocked () - ;; If the lock file exists.... - (if (file-exists-p keyfreq-file-lock) - ;; If the process which has the lock does not exist - (if (not (memql (keyfreq-file-owner) (list-system-processes))) - ;; Delete the lock - (delete-file keyfreq-file-lock))) - ;; Check again the lock existence (just in case...) - (not (file-exists-p keyfreq-file-lock))) - - -(defun keyfreq-table-save (table &optional mustsave) - "Append all values from the specified TABLE into the -`keyfreq-file' as a sexp of an alist. Then resets the TABLE -if it was successfully merged. - -If MUSTSAVE is t, this function tries to save the table until it -gets the lock and successfully saves it. If MUSTSAVE is nil, it -does nothing if the table cannot be saved." - - ;; Avoid adding nothing to the file - (if (> (hash-table-count table) 0) - (let (done) - ;; Check that the lock file doesn't exist - (while (not done) - (when (keyfreq-file-is-unlocked) - ;; Lock the file - (keyfreq-file-claim-lock) - - ;; Check that we have the lock - (if (eq (keyfreq-file-owner) (emacs-pid)) - (unwind-protect - (progn - ;; Load values and merge them with the current keyfreq-table - (keyfreq-table-load table) - - ;; Write the new frequencies - (with-temp-file keyfreq-file - (let ((l (cdr (keyfreq-list table 'no-sort)))) - (insert "(") - (dolist (item l) - (prin1 item (current-buffer)) - ;; Easy for git to track if every command is - ;; one line - (insert "\n")) - (insert ")")))) - - ;; Reset the hash table, enable the 'done' flag, and - ;; release the lock. - (clrhash table) - (setq done t) - (keyfreq-file-release-lock)))) - - (if (and (not done) mustsave) - ;; If we must save the file right now, we'll just keep - ;; trying until we can get the lock. So we can sleep some - ;; milliseconds for the next while-loop cycle. - (sleep-for 0.1) - ;; If we can wait to the next timer's timeout, just enable - ;; the 'done' flag to break the while-loop. - (setq done t)) - - )))) - - -(defun keyfreq-table-load (table) - "Load all values from the `keyfreq-file' and add them in the TABLE. -The table is not reset, so the values are appended to the table." - - ;; Does `keyfreq-file' exist? - (if (file-exists-p keyfreq-file) - ;; Load sexp - (let ((l (with-temp-buffer - (insert-file-contents keyfreq-file) - (goto-char (point-min)) - (read (current-buffer))))) - - ;; Add the values in the table - (while (and (listp l) l) - (if (listp (car l)) - (unless (memq (cdr (caar l)) keyfreq-excluded-commands) - (puthash (caar l) (+ (gethash (caar l) table 0) (cdar l)) table))) - (setq l (cdr l))) - ))) - - -;;;###autoload -(define-minor-mode keyfreq-autosave-mode - "Keyfreq Autosave mode automatically saves -`keyfreq-table' every `keyfreq-autosave-timeout' seconds -and when emacs is killed." - :global t - :init-value nil - :lighter nil - :keymap nil - :group 'keyfreq - - (when keyfreq-autosave--timer - (cancel-timer keyfreq-autosave--timer) - (setq keyfreq-autosave--timer nil)) - - (if keyfreq-autosave-mode - (progn - (setq keyfreq-autosave--timer - (run-at-time t keyfreq-autosave-timeout - 'keyfreq-autosave--do)) - (add-hook 'kill-emacs-hook 'keyfreq-mustsave--do)) - (keyfreq-mustsave--do) - (remove-hook 'kill-emacs-hook 'keyfreq-mustsave--do))) - - -(defcustom keyfreq-autosave-timeout 600 - "How often in seconds `keyfreq-table' should be saved -when `keyfreq-autosave-mode' is enabled. Setting this -value will take effect only after (re)enabling -`keyfreq-autosave-mode'." - :group 'keyfreq - :type 'number) - - -(defvar keyfreq-autosave--timer nil) - - -(defun keyfreq-autosave--do () - "Function executed periodically to save the `keyfreq-table' in `keyfreq-file'." - (keyfreq-table-save keyfreq-table)) - - -(defun keyfreq-mustsave--do () - "Function executed when we close Emacs." - (keyfreq-table-save keyfreq-table t)) - - -;;;###autoload -(defun keyfreq-save-now () - "Save keyfreq data now." - (interactive) - (keyfreq-mustsave--do) - (message "keyfreq data saved into %s" keyfreq-file)) - -(provide 'keyfreq) - -;;; keyfreq.el ends here diff --git a/elpa/keyfreq-20160516.716/keyfreq-autoloads.el b/elpa/keyfreq-20160516.716/keyfreq-autoloads.el new file mode 100644 index 00000000..4be71eaa --- /dev/null +++ b/elpa/keyfreq-20160516.716/keyfreq-autoloads.el @@ -0,0 +1,55 @@ +;;; keyfreq-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path)))) + +;;;### (autoloads nil "keyfreq" "keyfreq.el" (22581 35909 0 0)) +;;; Generated autoloads from keyfreq.el + +(defvar keyfreq-mode nil "\ +Non-nil if Keyfreq mode is enabled. +See the `keyfreq-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `keyfreq-mode'.") + +(custom-autoload 'keyfreq-mode "keyfreq" nil) + +(autoload 'keyfreq-mode "keyfreq" "\ +Keyfreq mode records number of times each command was +called making it possible to access usage statistics through +various keyfreq-* functions. + +\(fn &optional ARG)" t nil) + +(defvar keyfreq-autosave-mode nil "\ +Non-nil if Keyfreq-Autosave mode is enabled. +See the `keyfreq-autosave-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `keyfreq-autosave-mode'.") + +(custom-autoload 'keyfreq-autosave-mode "keyfreq" nil) + +(autoload 'keyfreq-autosave-mode "keyfreq" "\ +Keyfreq Autosave mode automatically saves +`keyfreq-table' every `keyfreq-autosave-timeout' seconds +and when emacs is killed. + +\(fn &optional ARG)" t nil) + +(autoload 'keyfreq-save-now "keyfreq" "\ +Save keyfreq data now. + +\(fn)" t nil) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; keyfreq-autoloads.el ends here diff --git a/elpa/keyfreq-20160516.716/keyfreq-pkg.el b/elpa/keyfreq-20160516.716/keyfreq-pkg.el new file mode 100644 index 00000000..e1292d1b --- /dev/null +++ b/elpa/keyfreq-20160516.716/keyfreq-pkg.el @@ -0,0 +1,2 @@ +;;; -*- no-byte-compile: t -*- +(define-package "keyfreq" "20160516.716" "track command frequencies" '((cl-lib "0.5"))) diff --git a/elpa/keyfreq-20160516.716/keyfreq.el b/elpa/keyfreq-20160516.716/keyfreq.el new file mode 100644 index 00000000..d107c264 --- /dev/null +++ b/elpa/keyfreq-20160516.716/keyfreq.el @@ -0,0 +1,590 @@ +;;; keyfreq.el --- track command frequencies +;; -*- coding: utf-8 -*- +;; +;; Copyright 2009-2010, 2015 by David Capello +;; Copyright 2008 by Xah Lee +;; Copyright 2006 by Michal Nazarewicz +;; Copyright 2006 by Ryan Yeske +;; +;; Author: Ryan Yeske, Michal Nazarewicz (mina86/AT/mina86.com) +;; Maintainer: David Capello, Xah lee +;; Created: 2006 +;; +;; Package-Requires: ((cl-lib "0.5")) +;; Package-Version: 20160516.716 +;; +;; +;; Keyfreq 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. +;; +;; Version 1.7 - 2015-09 - David Capello +;; * Avoid accumulating key frequency if keyfreq-file-release-lock fails +;; +;; Version 1.6 - 2015-09 - David Capello +;; * Added keyfreq-reset thanks to @w-vi +;; * Fixed issue running multiple instances of Emacs 24.5 +;; +;; Version 1.5 - 2014-11 - David Capello +;; * Support cl-lib or cl +;; * Minor doc fixes +;; +;; Version 1.4 - 2010-09 - David Capello +;; * Renamed from command-frequency to keyfreq +;; * Now keyfreq-table holds "deltas" +;; * Removed a lot of "facility" functions to keep the code simple. +;; * Rename keyfreq-summarize-all-modes -> keyfreq-groups-major-modes. +;; * Added keyfreq-filter-major-mode +;; * Added lock file to avoid overwrite the file by two processes at +;; the same time. +;; +;; Version 1.3 - 2009-09 - David Capello +;; * Added keyfreq-summarize-all-modes +;; +;; Version 1.2 - 2009-09 - David Capello +;; * Now each hash hash-key is a (major-mode . command) cons. Now only +;; symbols are recorded. +;; +;; Version 1.1 - 2008-09 +;; - Replaced the use of this-command var by real-last-command, so +;; that the commands backward-kill-word, kill-word, kill-line, +;; kill-region, do not all get counted as kill-region. Changed +;; post-command-hook to pre-command-hook +;; +;; Version 1.0 - 2007 +;; - Made into a full featured minor mode. Added full doc +;; strings. Added feature to save and read to disk the frequency +;; hash table. Added ability to set user preference using emacs's +;; customization system. Code is ~400 lines. This version is made by +;; Michal Nazarewicz in 2007. +;; +;; Version 0.1 - 2006 +;; - First version by Ryan Yeske. A quick hack of about 40 lines. +;; + +;;; Commentary: +;; +;; HOW TO USE IT? +;; +;; Include the following lines in your .emacs file: +;; +;; (require 'keyfreq) +;; (keyfreq-mode 1) +;; (keyfreq-autosave-mode 1) +;; +;; And use `keyfreq-show' to see how many times you used a command. +;; +;;; Code: + +(if (not (featurep 'cl-lib)) + (progn + (require 'cl) + ;; fix conflict name + (defalias 'cl-reduce 'reduce)) + (require 'cl-lib)) +;; (require 'json)? + +(defgroup keyfreq nil + "Customization group for Keyfreq mode. +This mode stores number of times each command was called and +provides it as a statistical data." + :package-version '(keyfreq . "1.7") + :group 'local + :prefix "keyfreq") + +;;;###autoload +(define-minor-mode keyfreq-mode + "Keyfreq mode records number of times each command was +called making it possible to access usage statistics through +various keyfreq-* functions." + :global t + :init-value nil + :lighter nil + :keymap nil + :group 'keyfreq + + (if keyfreq-mode + (add-hook 'pre-command-hook 'keyfreq-pre-command-hook) + (remove-hook 'pre-command-hook 'keyfreq-pre-command-hook))) + + +(defcustom keyfreq-buffer "*frequencies*" + "Buffer where frequencies are displayed." + :group 'keyfreq + :type 'string) + + +(defcustom keyfreq-file "~/.emacs.keyfreq" + "File `keyfreq-table' is saved to/loaded from by +`keyfreq-table-save' and `keyfreq-table-load' functions +by default." + :group 'keyfreq + :type 'file) + +(defcustom keyfreq-file-lock "~/.emacs.keyfreq.lock" + "Lock file to update the `keyfreq-file'." + :group 'keyfreq + :type 'file) + + +(defvar keyfreq-table (make-hash-table :test 'equal :size 128) + "Hash table storing number of times each command was called in each major mode +since the last time the frequencies were saved in `keyfreq-file'.") + +(defvar keyfreq-excluded-commands '() + "List of commands excluded by keyfreq.") + +(defun keyfreq-pre-command-hook () + "Record command execution in `keyfreq-table' hash." + (let ((command real-last-command) count) + (when (and command (symbolp command)) + (setq count (gethash (cons major-mode command) keyfreq-table)) + (unless (memq command keyfreq-excluded-commands) + (puthash (cons major-mode command) (if count (1+ count) 1) + keyfreq-table) + )))) + + +(defun keyfreq-groups-major-modes (table) + "Group major modes in TABLE by command. +Return a hash table where each entry has COMMAND as key and +COUNTER as value." + (let ((new-table (make-hash-table :test 'equal :size 128))) + (maphash (lambda (k v) + (puthash (cdr k) (+ (gethash (cdr k) new-table 0) v) new-table)) + table) + new-table)) + + +(defun keyfreq-filter-major-mode (table major-mode) + "Leave the frequencies of the specified major mode. +Return a hash table where each entry has COMMAND as key and +COUNTER as value." + + (let ((new-table (make-hash-table :test 'equal :size 128))) + (maphash (lambda (k v) + (when (eq (car k) major-mode) + (puthash (cdr k) (+ (gethash (cdr k) new-table 0) v) new-table))) + table) + new-table)) + + +(defun keyfreq-used-major-modes (table) + "Return a list with the used major modes (major modes +contained in the TABLE)." + (let ((list)) + (maphash (lambda (k v) + (add-to-list 'list (car k))) + table) + list)) + + +(defun keyfreq-list (table &optional reverse limit) + "Return a cons which car is sum of times any command was used +and cdr is a list of (command . count) pairs. + +If REVERSE is nil, sort it starting from the most used command; +if it is `no-sort' the list is not sorted; if it is non-nil and +not `no-sort', sort it from the least used commands. If LIMIT is +a positive number, only commands which were used more then LIMIT +times will be added. If it is a negative number, only commands +which were used less then -LIMIT times will be added." + + (let (l (sum 0)) + (maphash + (cond + ((or (not (numberp limit)) (= limit 0)) + (lambda (k v) (setq l (cons (cons k v) l) sum (+ sum v)))) + ((= limit -1) (lambda (k v) (setq sum (+ sum v)))) + ((< limit 0) + (setq limit (- limit)) + (lambda (k v) (setq sum (+ sum v)) + (if (< v limit) (setq l (cons (cons k v) l))))) + (t + (lambda (k v) (setq sum (+ sum v)) + (if (> v limit) (setq l (cons (cons k v) l)))))) + table) + (cons sum + (cond + ((equal reverse 'no-sort) l) + (reverse (sort l (lambda (a b) (< (cdr a) (cdr b))))) + (t (sort l (lambda (a b) (> (cdr a) (cdr b))))))))) + + +(defun keyfreq-format-list (list &optional func) + "Return formatted string with command usage statistics. + +The LIST is the `keyfreq-table' converted to a list using the `keyfreq-list'. + +If FUNC is nil each line contains number of times command was +called and the command; if it is t percentage usage is added in +the middle; if it is 'raw each line will contain number an +command separated by single line (with no formatting) otherwise +FUNC must be a function returning a string which will be called +for each entry with three arguments: number of times command was +called, percentage usage and the command." + (let* ((sum (car list)) + (max-len + (cl-reduce (lambda (a b) (max a (length (symbol-name (car b))))) + (cdr list) + :initial-value 0))) + (mapconcat + (cond + ((not func) (lambda (e) (format "%7d %s\n" (cdr e) (car e)))) + ((equal func t) + (lambda (e) (format (concat "%7d %6.2f%% %- " + (format "%d" max-len) + "s %s\n") + (cdr e) (/ (* 1e2 (cdr e)) sum) (car e) + (ignore-errors (keyfreq-where-is (car e)))))) + ((equal func 'raw) (lambda (e) (format "%d %s\n" (cdr e) (car e)))) + (t (lambda (e) (funcall func (cdr e) (/ (* 1e2 (cdr e)) sum) (car e))))) + (cdr list) ""))) + +(defun keyfreq-where-is (command) + (mapconcat 'key-description + (where-is-internal command) + ", ")) + +(defun keyfreq-show (&optional major-mode-symbol) + "Show command usage statistics in `keyfreq-buffer'. + +If MAJOR-MODE-SYMBOL is given, the function shows the statistics +for that particular major mode only. + +With a universal argument, the major-mode of the current buffer +is used as MAJOR-MODE-SYMBOL argument." + (interactive (list (cond (current-prefix-arg major-mode) + (t nil)))) + + (let ((table (copy-hash-table keyfreq-table))) + ;; Merge with the values in `keyfreq-file' + (keyfreq-table-load table) + + (let* ((list (keyfreq-list + (cond + (major-mode-symbol (keyfreq-filter-major-mode table major-mode-symbol)) + (t (keyfreq-groups-major-modes table))))) + (formatted-list (keyfreq-format-list list t))) + + ;; Display the table + (display-message-or-buffer (concat (if major-mode-symbol + (concat "For " (symbol-name major-mode)) + (concat "For all major modes")) + ":\n\n" + formatted-list) + keyfreq-buffer) + ))) + + +(defun keyfreq-html (filename &optional confirm) + "Save an HTML file as FILENAME with all the statistics of each mode." + + (interactive + (list (if buffer-file-name + (read-file-name "Write HTML file: " + nil nil nil nil) + (read-file-name "Write HTML file: " default-directory + (expand-file-name + (file-name-nondirectory (buffer-name)) + default-directory) + nil nil)) + (not current-prefix-arg))) + + (and confirm + (file-exists-p filename) + (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) + (error "Canceled"))) + + (let ((table (copy-hash-table keyfreq-table)) + (htmltable (lambda (list) + (insert "\n") + (insert "\n") + (insert "\n") + (keyfreq-format-list list + (lambda (count perc command) + (insert (format "\n" count perc command)))) + (insert "\n") + (insert "
TimesPercetageCommand
%d%.2f%%%s
\n")))) + + ;; Merge with the values in `keyfreq-file' + (keyfreq-table-load table) + + (with-temp-file filename + (insert "\n\n") + (insert "

Keyfreq Report

\n") + (insert "\n") + + (insert "

All major modes

\n") + (funcall htmltable (keyfreq-list (keyfreq-groups-major-modes table))) + + (mapc + (lambda (major-mode-symbol) + (insert (format "

%s

\n" + (symbol-name major-mode-symbol) + (symbol-name major-mode-symbol))) + (funcall htmltable (keyfreq-list (keyfreq-filter-major-mode table major-mode-symbol)))) + (keyfreq-used-major-modes table)) + + (insert "\n\n") + ) + )) + + +(defun keyfreq-json-encode (table) + "Return a JSON representation of the table of frequencies." + (require 'json) + (let ((commands-indexes (make-hash-table :test 'equal :size 128)) + commands-list frequencies-matrix i) + + ;; Build the "commands" property of the JSON object. + (setq i 0) + (maphash + (lambda (command-symbol counter) + (add-to-list 'commands-list command-symbol t) + (puthash command-symbol i commands-indexes) + (setq i (+ i 1)) + ) + (keyfreq-groups-major-modes table)) + + ;; Build the "frequencies" property. + (mapc + (lambda (major-mode-symbol) + (let ((cmd-count-pairs '())) + (keyfreq-format-list (keyfreq-list (keyfreq-filter-major-mode table major-mode-symbol)) + (lambda (count perc command) + (add-to-list 'cmd-count-pairs (gethash command commands-indexes) t) + (add-to-list 'cmd-count-pairs count t))) + (add-to-list 'frequencies-matrix major-mode-symbol t) + (add-to-list 'frequencies-matrix (append cmd-count-pairs nil) t))) + (keyfreq-used-major-modes table)) + + (json-encode `((:format . 1) + (:commands . ,commands-list) + (:frequencies . ,frequencies-matrix))))) + + +(defun keyfreq-json (filename &optional confirm) + "Save a file (as FILENAME) with a JSON structure of the data." + + (interactive + (list (if buffer-file-name + (read-file-name "Write JSON file: " + nil nil nil nil) + (read-file-name "Write JSON file: " default-directory + (expand-file-name + (file-name-nondirectory (buffer-name)) + default-directory) + nil nil)) + (not current-prefix-arg))) + + (and confirm + (file-exists-p filename) + (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) + (error "Canceled"))) + + (let ((table (copy-hash-table keyfreq-table))) + + ;; Merge with the values in `keyfreq-file' + (keyfreq-table-load table) + + (with-temp-file filename + (insert (keyfreq-json-encode table))))) + + +(defun keyfreq-reset () + "Reset all statistics including those in the file." + (interactive) + (when (yes-or-no-p (concat "Delete keyfreq file? You will lost all your stats. ")) + ;; clear the hash table + (clrhash keyfreq-table) + ;; Deal with the file + (when (keyfreq-file-is-unlocked) + ;; Lock the file + (keyfreq-file-claim-lock) + ;; Check that we have the lock + (if (eq (keyfreq-file-owner) (emacs-pid)) + (unwind-protect + ;; if the file exists just delete it + (if (file-exists-p keyfreq-file) + (delete-file keyfreq-file)) + ;; Release the lock. + (keyfreq-file-release-lock)))))) + + +(defun keyfreq-file-owner () + "Return the PID of the Emacs process that owns the table file lock file." + (let (owner) + (and (file-exists-p keyfreq-file-lock) + (ignore-errors + (with-temp-buffer + (insert-file-contents-literally keyfreq-file-lock) + (goto-char (point-min)) + (setq owner (read (current-buffer))) + (integerp owner))) + owner))) + + +(defun keyfreq-file-claim-lock () + (ignore-errors + (write-region (number-to-string (emacs-pid)) nil + keyfreq-file-lock nil 'nomessage nil 'excl))) + + +(defun keyfreq-file-release-lock () + (when (file-exists-p keyfreq-file-lock) + (delete-file keyfreq-file-lock))) + + +(defun keyfreq-file-is-unlocked () + ;; If the lock file exists.... + (if (file-exists-p keyfreq-file-lock) + ;; If the process which has the lock does not exist + (if (not (memql (keyfreq-file-owner) (list-system-processes))) + ;; Delete the lock + (delete-file keyfreq-file-lock))) + ;; Check again the lock existence (just in case...) + (not (file-exists-p keyfreq-file-lock))) + + +(defun keyfreq-table-save (table &optional mustsave) + "Append all values from the specified TABLE into the +`keyfreq-file' as a sexp of an alist. Then resets the TABLE +if it was successfully merged. + +If MUSTSAVE is t, this function tries to save the table until it +gets the lock and successfully saves it. If MUSTSAVE is nil, it +does nothing if the table cannot be saved." + + ;; Avoid adding nothing to the file + (if (> (hash-table-count table) 0) + (let (done) + ;; Check that the lock file doesn't exist + (while (not done) + (when (keyfreq-file-is-unlocked) + ;; Lock the file + (keyfreq-file-claim-lock) + + ;; Check that we have the lock + (if (eq (keyfreq-file-owner) (emacs-pid)) + (unwind-protect + (progn + ;; Load values and merge them with the current keyfreq-table + (keyfreq-table-load table) + + ;; Write the new frequencies + (with-temp-file keyfreq-file + (let ((l (cdr (keyfreq-list table 'no-sort)))) + (insert "(") + (dolist (item l) + (prin1 item (current-buffer)) + ;; Easy for git to track if every command is + ;; one line + (insert "\n")) + (insert ")")))) + + ;; Reset the hash table, enable the 'done' flag, and + ;; release the lock. + (clrhash table) + (setq done t) + (keyfreq-file-release-lock)))) + + (if (and (not done) mustsave) + ;; If we must save the file right now, we'll just keep + ;; trying until we can get the lock. So we can sleep some + ;; milliseconds for the next while-loop cycle. + (sleep-for 0.1) + ;; If we can wait to the next timer's timeout, just enable + ;; the 'done' flag to break the while-loop. + (setq done t)) + + )))) + + +(defun keyfreq-table-load (table) + "Load all values from the `keyfreq-file' and add them in the TABLE. +The table is not reset, so the values are appended to the table." + + ;; Does `keyfreq-file' exist? + (if (file-exists-p keyfreq-file) + ;; Load sexp + (let ((l (with-temp-buffer + (insert-file-contents keyfreq-file) + (goto-char (point-min)) + (read (current-buffer))))) + + ;; Add the values in the table + (while (and (listp l) l) + (if (listp (car l)) + (unless (memq (cdr (caar l)) keyfreq-excluded-commands) + (puthash (caar l) (+ (gethash (caar l) table 0) (cdar l)) table))) + (setq l (cdr l))) + ))) + + +;;;###autoload +(define-minor-mode keyfreq-autosave-mode + "Keyfreq Autosave mode automatically saves +`keyfreq-table' every `keyfreq-autosave-timeout' seconds +and when emacs is killed." + :global t + :init-value nil + :lighter nil + :keymap nil + :group 'keyfreq + + (when keyfreq-autosave--timer + (cancel-timer keyfreq-autosave--timer) + (setq keyfreq-autosave--timer nil)) + + (if keyfreq-autosave-mode + (progn + (setq keyfreq-autosave--timer + (run-at-time t keyfreq-autosave-timeout + 'keyfreq-autosave--do)) + (add-hook 'kill-emacs-hook 'keyfreq-mustsave--do)) + (keyfreq-mustsave--do) + (remove-hook 'kill-emacs-hook 'keyfreq-mustsave--do))) + + +(defcustom keyfreq-autosave-timeout 600 + "How often in seconds `keyfreq-table' should be saved +when `keyfreq-autosave-mode' is enabled. Setting this +value will take effect only after (re)enabling +`keyfreq-autosave-mode'." + :group 'keyfreq + :type 'number) + + +(defvar keyfreq-autosave--timer nil) + + +(defun keyfreq-autosave--do () + "Function executed periodically to save the `keyfreq-table' in `keyfreq-file'." + (keyfreq-table-save keyfreq-table)) + + +(defun keyfreq-mustsave--do () + "Function executed when we close Emacs." + (keyfreq-table-save keyfreq-table t)) + + +;;;###autoload +(defun keyfreq-save-now () + "Save keyfreq data now." + (interactive) + (keyfreq-mustsave--do) + (message "keyfreq data saved into %s" keyfreq-file)) + +(provide 'keyfreq) + +;;; keyfreq.el ends here diff --git a/elpa/ox-jira-20160426.553/ox-jira-autoloads.el b/elpa/ox-jira-20160426.553/ox-jira-autoloads.el deleted file mode 100644 index 75daa69c..00000000 --- a/elpa/ox-jira-20160426.553/ox-jira-autoloads.el +++ /dev/null @@ -1,15 +0,0 @@ -;;; ox-jira-autoloads.el --- automatically extracted autoloads -;; -;;; Code: -(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) - -;;;### (autoloads nil nil ("ox-jira.el") (22337 64108 292221 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; End: -;;; ox-jira-autoloads.el ends here diff --git a/elpa/ox-jira-20160426.553/ox-jira-pkg.el b/elpa/ox-jira-20160426.553/ox-jira-pkg.el deleted file mode 100644 index 7a04e306..00000000 --- a/elpa/ox-jira-20160426.553/ox-jira-pkg.el +++ /dev/null @@ -1 +0,0 @@ -(define-package "ox-jira" "20160426.553" "JIRA Backend for Org Export Engine" '((org "8.0")) :url "https://github.com/stig/ox-jira.el" :keywords '("outlines" "hypermedia" "wp")) diff --git a/elpa/ox-jira-20160426.553/ox-jira.el b/elpa/ox-jira-20160426.553/ox-jira.el deleted file mode 100644 index ccd1a0b5..00000000 --- a/elpa/ox-jira-20160426.553/ox-jira.el +++ /dev/null @@ -1,409 +0,0 @@ -;;; ox-jira.el --- JIRA Backend for Org Export Engine - -;; Copyright (C) 2016 Stig Brautaset - -;; Author: Stig Brautaset -;; Version: 0.1-SNAPSHOT -;; Package-Version: 20160426.553 -;; Keywords: outlines, hypermedia, wp -;; Homepage: https://github.com/stig/ox-jira.el -;; Package-Requires: ((org "8.0")) - -;; 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 this program. If not, see . - -;;; Commentary: - -;; This module plugs into the regular Org Export Engine and transforms Org -;; files to JIRA markup for pasting into JIRA tickets & comments. - -;; In an Org buffer, hit `C-c C-e j j' to bring up *Org Export Dispatcher* -;; and export it as a JIRA buffer. I usually use `C-x h' to mark the whole -;; buffer, then `M-w' to save it to the kill ring (and global pasteboard) for -;; pasting into JIRA issues. - -;;; Code: - -(eval-when-compile (require 'cl)) -(require 'ox) -(require 'ox-publish) - -(org-export-define-backend 'jira - '((babel-call . (lambda (&rest args) (ox-jira--not-implemented 'babel-call))) - (body . (lambda (&rest args) (ox-jira--not-implemented 'body))) - (bold . ox-jira-bold) - (center-block . (lambda (&rest args) (ox-jira--not-implemented 'center-block))) - (clock . (lambda (&rest args) (ox-jira--not-implemented 'clock))) - (code . ox-jira-code) - (diary-sexpexample-block . (lambda (&rest args) (ox-jira--not-implemented 'diary-sexpexample-block))) - (drawer . (lambda (&rest args) (ox-jira--not-implemented 'drawer))) - (dynamic-block . (lambda (&rest args) (ox-jira--not-implemented 'dynamic-block))) - (entity . (lambda (&rest args) (ox-jira--not-implemented 'entity))) - (example-block . ox-jira-example-block) - (export-block . (lambda (&rest args) (ox-jira--not-implemented 'export-block))) - (export-snippet . (lambda (&rest args) (ox-jira--not-implemented 'export-snippet))) - (final-output . (lambda (&rest args) (ox-jira--not-implemented 'final-output))) - (fixed-width . ox-jira-fixed-width) - (footnote-definition . ox-jira-footnote-definition) - (footnote-reference . ox-jira-footnote-reference) - (headline . ox-jira-headline) - (horizontal-rule . ox-jira-horizontal-rule) - (inline-babel-call . (lambda (&rest args) (ox-jira--not-implemented 'inline-babel-call))) - (inline-src-block . (lambda (&rest args) (ox-jira--not-implemented 'inline-src-block))) - (inlinetask . (lambda (&rest args) (ox-jira--not-implemented 'inlinetask))) - (italic . ox-jira-italic) - (item . ox-jira-item) - (keyword . (lambda (&rest args) "")) - (latex-environment . (lambda (&rest args) (ox-jira--not-implemented 'latex-environment))) - (latex-fragment . (lambda (&rest args) (ox-jira--not-implemented 'latex-fragment))) - (line-break . (lambda (&rest args) (ox-jira--not-implemented 'line-break))) - (link . ox-jira-link) - (node-property . (lambda (&rest args) (ox-jira--not-implemented 'node-property))) - (options . (lambda (&rest args) (ox-jira--not-implemented 'options))) - (paragraph . ox-jira-paragraph) - (parse-tree . (lambda (&rest args) (ox-jira--not-implemented 'parse-tree))) - (plain-list . ox-jira-plain-list) - (plain-text . ox-jira-plain-text) - (planning . (lambda (&rest args) (ox-jira--not-implemented 'planning))) - (property-drawer . (lambda (&rest args) (ox-jira--not-implemented 'property-drawer))) - (quote-block . ox-jira-quote-block) - (radio-target . (lambda (&rest args) (ox-jira--not-implemented 'radio-target))) - (section . ox-jira-section) - (special-block . (lambda (&rest args) (ox-jira--not-implemented 'special-block))) - (src-block . ox-jira-src-block) - (statistics-cookie . ox-jira-statistics-cookie) - (strike-through . ox-jira-strike-through) - (subscript . ox-jira-subscript) - (superscript . ox-jira-superscript) - (table . ox-jira-table) - (table-cell . ox-jira-table-cell) - (table-row . ox-jira-table-row) - (target . (lambda (&rest args) (ox-jira--not-implemented 'target))) - (timestamp . (lambda (&rest args) (ox-jira--not-implemented 'timestamp))) - (underline . ox-jira-underline) - (verbatim . ox-jira-verbatim) - (verse-block . (lambda (&rest args) (ox-jira--not-implemented 'verse-block)))) - :filters-alist '((:filter-parse-tree . ox-jira-fix-multi-paragraph-items)) - :menu-entry - '(?j "Export to JIRA" - ((?j "As JIRA buffer" ox-jira-export-as-jira)))) - -;;; Internal Helpers - -(defun ox-jira--not-implemented (element-type) - "Replace anything we don't handle yet wiht a big red marker." - (format "{color:red}Element of type '%s' not implemented!{color}" element-type)) - -(defun ox-jira--text-transform-embeddable (transform-char contents) - (concat "{anchor}" transform-char contents transform-char)) - -;;; Filters - -(defun ox-jira-fix-multi-paragraph-items (tree backend info) - "Remove extra blank line between paragraphs in plain-list items. - -TREE is the parse tree being exported. BACKEND is the export -back-end used. INFO is a plist used as a communication channel. - -Assume BACKEND is `jira'." - (org-element-map tree '(item paragraph src-block) - (lambda (e) - (org-element-put-property - e :post-blank - (if (or (eq (org-element-type e) 'item) - (eq (org-element-type (org-element-property :parent e)) 'item)) - 0 1)))) - ;; Return updated tree. - tree) - -;;; Transcode functions - -(defun ox-jira-bold (bold contents info) - "Transcode BOLD from Org to JIRA. -CONTENTS is the text with bold markup. INFO is a plist holding -contextual information." - (format "*%s*" contents)) - -(defun ox-jira-code (code _contents info) - "Transcode a CODE object from Org to JIRA. -CONTENTS is nil. INFO is a plist used as a communication -channel." - (format "{{%s}}" (org-element-property :value code))) - -(defun ox-jira-example-block (example-block contents info) - "Transcode an EXAMPLE-BLOCK element from Org to Jira. -CONTENTS is nil. INFO is a plist holding contextual -information." - (when (org-string-nw-p (org-element-property :value example-block)) - (format "{noformat}\n%s{noformat}" - (org-export-format-code-default example-block info)))) - -(defun ox-jira-fixed-width (fixed-width contents info) - "Transcode an FIXED-WIDTH element from Org to Jira. -CONTENTS is nil. INFO is a plist holding contextual -information." - (format "{noformat}\n%s{noformat}" - (org-remove-indentation - (org-element-property :value fixed-width)))) - -(defun ox-jira--footnote-anchor (element) - (let ((label (org-element-property :label element))) - (replace-regexp-in-string ":" "" label))) - -(defun ox-jira--footnote-ref (anchor) - (replace-regexp-in-string "fn" "" anchor)) - -(defun ox-jira-footnote-reference (footnote-reference contents info) - "Transcode an FOOTNOTE-REFERENCE element from Org to Jira. -CONTENTS is nil. INFO is a plist holding contextual -information." - (let* ((anchor (ox-jira--footnote-anchor footnote-reference)) - (ref (ox-jira--footnote-ref anchor))) - (format "{anchor:back%s}[^%s^|#%s]" - anchor ref anchor))) - -(defun ox-jira-footnote-definition (footnote-definition contents info) - "Transcode an FOOTNOTE-DEFINITION element from Org to Jira. -CONTENTS is nil. INFO is a plist holding contextual -information." - (let* ((anchor (ox-jira--footnote-anchor footnote-definition)) - (ref (ox-jira--footnote-ref anchor))) - (format "{anchor:%s}[^%s^|#back%s] %s" - anchor ref anchor contents))) - -(defun ox-jira-headline (headline contents info) - "Transcode a HEADLINE element from Org to JIRA. -CONTENTS is the contents of the headline, as a string. INFO is -the plist used as a communication channel." - (let* ((level (org-export-get-relative-level headline info)) - (title (org-export-data-with-backend - (org-element-property :title headline) - 'jira info))) - (concat - (format "h%d. %s\n" level title) - contents))) - -(defun ox-jira-horizontal-rule (horizontal-rule contents info) - "Transcode a HORIZONTAL-RULE element from Org to JIRA." - "----\n") - -(defun ox-jira-italic (italic contents info) - "Transcode ITALIC from Org to JIRA. -CONTENTS is the text with italic markup. INFO is a plist holding -contextual information." - (format "_%s_" contents)) - -(defun ox-jira--list-type-path (item) - (when (and item (eq 'item (org-element-type item))) - (let* ((list (org-element-property :parent item)) - (list-type (org-element-property :type list))) - (cons list-type (ox-jira--list-type-path - (org-element-property :parent list)))))) - -(defun ox-jira--bullet-string (list-type-path) - (apply 'string - (mapcar (lambda (x) (if (eq x 'ordered) ?# ?*)) - list-type-path))) - -(defun ox-jira-item (item contents info) - "Transcode ITEM from Org to JIRA. -CONTENTS is the text with item markup. INFO is a plist holding -contextual information." - (let* ((list-type-path (ox-jira--list-type-path item)) - (bullet-string (ox-jira--bullet-string (reverse list-type-path))) - (tag (let ((tag (org-element-property :tag item))) - (when tag - (org-export-data tag info)))) - (checkbox (case (org-element-property :checkbox item) - (on "(/)") - (off "(x)") - (trans "(i)")))) - (concat - bullet-string - " " - (when checkbox - (concat checkbox " ")) - (when tag - (format "*%s*: " tag)) - contents))) - -(defun ox-jira-link (link desc info) - "Transcode a LINK object from Org to JIRA. - -DESC is the description part of the link, or the empty string. -INFO is a plist holding contextual information. See -`org-export-data'." - (let* ((type (org-element-property :type link)) - (raw-path (org-element-property :path link)) - (desc (and (not (string= desc "")) desc)) - (path (cond - ((member type '("http" "https" "ftp" "mailto" "doi")) - (concat type ":" raw-path)) - ((string= type "file") - (org-export-file-uri raw-path)) - (t raw-path)))) - (cond - ;; Link with description - ((and path desc) (format "[%s|%s]" desc path)) - ;; Link without description - (path (format "[%s]" path)) - ;; Link with only description?! - (t desc)))) - -(defun ox-jira-underline (underline contents info) - "Transcode UNDERLINE from Org to JIRA. -CONTENTS is the text with underline markup. INFO is a plist holding -contextual information." - (format "+%s+" contents)) - -(defun ox-jira-verbatim (verbatim _contents info) - "Transcode a VERBATIM object from Org to Jira. -CONTENTS is nil. INFO is a plist used as a communication -channel." - (format "{{%s}}" (org-element-property :value verbatim))) - -(defun ox-jira-paragraph (paragraph contents info) - "Transcode a PARAGRAPH element from Org to JIRA. -CONTENTS is the contents of the paragraph, as a string. INFO is -the plist used as a communication channel." - (replace-regexp-in-string "\n\\([^\']\\)" " \\1" contents)) - -(defun ox-jira-plain-list (plain-list contents info) - "Transcode PLAIN-LIST from Org to JIRA. -CONTENTS is the text with plain-list markup. INFO is a plist holding -contextual information." - contents) - -(defun ox-jira-plain-text (text info) - "Transcode TEXT from Org to JIRA. -TEXT is the string to transcode. INFO is a plist holding -contextual information." - (replace-regexp-in-string "\\([[{]\\)" - '(lambda (p) (format "\\\\%s" p)) - text)) - -(defun ox-jira-section (section contents info) - "Transcode a SECTION element from Org to JIRA. -CONTENTS is the contents of the section, as a string. INFO is -the plist used as a communication channel." - contents) - -(defun ox-jira-src-block (src-block contents info) - "Transcode a SRC-BLOCK element from Org to Jira. -CONTENTS holds the contents of the src-block. INFO is a plist holding -contextual information." - (when (org-string-nw-p (org-element-property :value src-block)) - (let* ((lang (org-element-property :language src-block)) - (lang (if (member lang '("actionscript" "html" "java" "javascript" "sql" "xhtml" "xml")) lang)) - (code (org-export-format-code-default src-block info))) - (concat - (if lang - (format "{code:%s}" lang) - "{code}") - code - "{code}")))) - -(defun ox-jira-subscript (subscript contents info) - "Transcode SUBSCRIPT from Org to JIRA. -CONTENTS is the text with subscript markup. INFO is a plist holding -contextual information." - (ox-jira--text-transform-embeddable "~" contents)) - -(defun ox-jira-superscript (superscript contents info) - "Transcode SUPERSCRIPT from Org to JIRA. -CONTENTS is the text with superscript markup. INFO is a plist holding -contextual information." - (ox-jira--text-transform-embeddable "^" contents)) - -(defun ox-jira-table (table contents info) - "Transcode a TABLE element from Org to JIRA. -CONTENTS holds the contents of the table. INFO is a plist holding -contextual information." - contents) - -(defun ox-jira-table-row (table-row contents info) - "Transcode a TABLE-ROW element from Org to JIRA. -CONTENTS holds the contents of the table-row. INFO is a plist holding -contextual information." - (when (eq 'standard (org-element-property :type table-row)) - (format "%s\n" contents))) - -(defun ox-jira-table-cell (table-cell contents info) - "Transcode a TABLE-CELL element from Org to JIRA. -CONTENTS holds the contents of the table-cell. INFO is a plist holding -contextual information." - (let* ((row (org-element-property :parent table-cell)) - (table (org-element-property :parent row)) - (has-header (org-export-table-has-header-p table info)) - (group (org-export-table-row-group row info)) - (is-header (and has-header (eq 1 group))) - (sep (if is-header "||" "|"))) - (format "%s %s %s" sep contents - (if (org-export-last-sibling-p table-cell info) sep "")))) - -(defun ox-jira-statistics-cookie (statistics-cookie _contents _info) - "Transcode a STATISTICS-COOKIE object from Org to JIRA. -CONTENTS is nil. INFO is a plist holding contextual information." - (format "\\%s" (org-element-property :value statistics-cookie))) - -(defun ox-jira-strike-through (strike-through contents info) - "Transcode STRIKE-THROUGH from Org to JIRA. -CONTENTS is the text with strike-through markup. INFO is a plist holding -contextual information." - (format "-%s-" contents)) - -(defun ox-jira-quote-block (quote-block contents info) - "Transcode a QUOTE-BLOCK element from Org to Jira. -CONTENTS holds the contents of the block. INFO is a plist -holding contextual information." - (format "{quote}\n%s{quote}" contents)) - -(defun ox-jira-export-as-jira - (&optional async subtreep visible-only body-only ext-plist) - "Export current buffer as a Jira buffer. - -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 buffer 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, omit header -stuff. (e.g. AUTHOR and TITLE.) - -EXT-PLIST, when provided, is a property list with external -parameters overriding Org default settings, but still inferior to -file-local settings. - -Export is done in a buffer named \"*Org JIRA Export*\", which -will be displayed when `org-export-show-temporary-export-buffer' -is non-nil." - (interactive) - (org-export-to-buffer 'jira "*Org JIRA Export*" - async subtreep visible-only body-only ext-plist)) - -(provide 'ox-jira) - -;;; ox-jira.el ends here diff --git a/elpa/ox-jira-20161026.429/ox-jira-autoloads.el b/elpa/ox-jira-20161026.429/ox-jira-autoloads.el new file mode 100644 index 00000000..400ce081 --- /dev/null +++ b/elpa/ox-jira-20161026.429/ox-jira-autoloads.el @@ -0,0 +1,15 @@ +;;; ox-jira-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path)))) + +;;;### (autoloads nil nil ("ox-jira.el") (22584 24229 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; ox-jira-autoloads.el ends here diff --git a/elpa/ox-jira-20161026.429/ox-jira-pkg.el b/elpa/ox-jira-20161026.429/ox-jira-pkg.el new file mode 100644 index 00000000..e36dbc64 --- /dev/null +++ b/elpa/ox-jira-20161026.429/ox-jira-pkg.el @@ -0,0 +1,2 @@ +;;; -*- no-byte-compile: t -*- +(define-package "ox-jira" "20161026.429" "JIRA Backend for Org Export Engine" '((org "8.3")) :url "https://github.com/stig/ox-jira.el" :keywords '("outlines" "hypermedia" "wp")) diff --git a/elpa/ox-jira-20161026.429/ox-jira.el b/elpa/ox-jira-20161026.429/ox-jira.el new file mode 100644 index 00000000..84523809 --- /dev/null +++ b/elpa/ox-jira-20161026.429/ox-jira.el @@ -0,0 +1,519 @@ +;;; ox-jira.el --- JIRA Backend for Org Export Engine + +;; Copyright (C) 2016 Stig Brautaset + +;; Author: Stig Brautaset +;; Version: 0.1-SNAPSHOT +;; Package-Version: 20161026.429 +;; Keywords: outlines, hypermedia, wp +;; Homepage: https://github.com/stig/ox-jira.el +;; Package-Requires: ((org "8.3")) + +;; 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 this program. If not, see . + +;;; Commentary: + +;; This module plugs into the regular Org Export Engine and transforms Org +;; files to JIRA markup for pasting into JIRA tickets & comments. + +;; In an Org buffer, hit `C-c C-e j j' to bring up *Org Export Dispatcher* +;; and export it as a JIRA buffer. I usually use `C-x h' to mark the whole +;; buffer, then `M-w' to save it to the kill ring (and global pasteboard) for +;; pasting into JIRA issues. + +;;; Code: + +;; This is Cargo-culted from `ox-latex.el'` +(eval-when-compile (require 'cl)) +(require 'ox) +(require 'ox-publish) + +(org-export-define-backend 'jira + '((babel-call . (lambda (&rest args) (ox-jira--not-implemented 'babel-call))) + (body . (lambda (&rest args) (ox-jira--not-implemented 'body))) + (bold . ox-jira-bold) + (center-block . (lambda (&rest args) (ox-jira--not-implemented 'center-block))) + (clock . (lambda (&rest args) (ox-jira--not-implemented 'clock))) + (code . ox-jira-code) + (diary-sexpexample-block . (lambda (&rest args) (ox-jira--not-implemented 'diary-sexpexample-block))) + (drawer . (lambda (&rest args) (ox-jira--not-implemented 'drawer))) + (dynamic-block . (lambda (&rest args) (ox-jira--not-implemented 'dynamic-block))) + (entity . (lambda (&rest args) (ox-jira--not-implemented 'entity))) + (example-block . ox-jira-example-block) + (export-block . (lambda (&rest args) (ox-jira--not-implemented 'export-block))) + (export-snippet . (lambda (&rest args) (ox-jira--not-implemented 'export-snippet))) + (final-output . (lambda (&rest args) (ox-jira--not-implemented 'final-output))) + (fixed-width . ox-jira-fixed-width) + (footnote-definition . ox-jira-footnote-definition) + (footnote-reference . ox-jira-footnote-reference) + (headline . ox-jira-headline) + (horizontal-rule . ox-jira-horizontal-rule) + (inline-babel-call . (lambda (&rest args) (ox-jira--not-implemented 'inline-babel-call))) + (inline-src-block . (lambda (&rest args) (ox-jira--not-implemented 'inline-src-block))) + (inlinetask . (lambda (&rest args) (ox-jira--not-implemented 'inlinetask))) + (italic . ox-jira-italic) + (item . ox-jira-item) + (keyword . (lambda (&rest args) "")) + (latex-environment . (lambda (&rest args) (ox-jira--not-implemented 'latex-environment))) + (latex-fragment . (lambda (&rest args) (ox-jira--not-implemented 'latex-fragment))) + (line-break . (lambda (&rest args) (ox-jira--not-implemented 'line-break))) + (link . ox-jira-link) + (node-property . (lambda (&rest args) (ox-jira--not-implemented 'node-property))) + (options . (lambda (&rest args) (ox-jira--not-implemented 'options))) + (paragraph . ox-jira-paragraph) + (parse-tree . (lambda (&rest args) (ox-jira--not-implemented 'parse-tree))) + (plain-list . ox-jira-plain-list) + (plain-text . ox-jira-plain-text) + (planning . (lambda (&rest args) (ox-jira--not-implemented 'planning))) + (property-drawer . (lambda (&rest args) (ox-jira--not-implemented 'property-drawer))) + (quote-block . ox-jira-quote-block) + (radio-target . (lambda (&rest args) (ox-jira--not-implemented 'radio-target))) + (section . ox-jira-section) + (special-block . (lambda (&rest args) (ox-jira--not-implemented 'special-block))) + (src-block . ox-jira-src-block) + (statistics-cookie . ox-jira-statistics-cookie) + (strike-through . ox-jira-strike-through) + (subscript . ox-jira-subscript) + (superscript . ox-jira-superscript) + (table . ox-jira-table) + (table-cell . ox-jira-table-cell) + (table-row . ox-jira-table-row) + (target . (lambda (&rest args) (ox-jira--not-implemented 'target))) + (timestamp . (lambda (&rest args) (ox-jira--not-implemented 'timestamp))) + (underline . ox-jira-underline) + (verbatim . ox-jira-verbatim) + (verse-block . (lambda (&rest args) (ox-jira--not-implemented 'verse-block)))) + :filters-alist '((:filter-parse-tree . ox-jira-fix-multi-paragraph-items)) + :menu-entry + '(?j "Export to JIRA" + ((?j "As JIRA buffer" ox-jira-export-as-jira)))) + +;;; Internal Helpers + +;; Because I'm adding support for things as I find I need it rather than all +;; in one go, let's put a big fat red marker in for things we have not +;; implemented yet, to avoid missing it. +;; +(defun ox-jira--not-implemented (element-type) + "Replace anything we don't handle yet wiht a big red marker." + (format "{color:red}Element of type '%s' not implemented!{color}" element-type)) + +;; Super^script and sub_script I often want at the end of words, with no +;; whitespace immediately before it. Unfortunately JIRA doesn't support +;; that,so we have to fake it. This function makes simple text transforms +;; "embeddable" by preceding them with an empty anchor. This is admittedly a +;; bit of a hack, but I haven't found anything better. +;; +(defun ox-jira--text-transform-embeddable (transform-char contents) + (concat "{anchor}" transform-char contents transform-char)) + +;;; Filters + +;; Org support a single blank line between items in a list, but if we export +;; like that to JIRA format it will be interpreted as multiple consecutive +;; lists, which is never what I want. We can attempt to fix this by removing +;; the "post-blank" after a items (and paragraphs inside items) using a +;; filter. +;; +(defun ox-jira-fix-multi-paragraph-items (tree backend info) + "Remove extra blank line between paragraphs in plain-list items. + +TREE is the parse tree being exported. BACKEND is the export +back-end used. INFO is a plist used as a communication channel. + +Assume BACKEND is `jira'." + (org-element-map tree '(item paragraph src-block) + (lambda (e) + (org-element-put-property + e :post-blank + (if (or (eq (org-element-type e) 'item) + (eq (org-element-type (org-element-property :parent e)) 'item)) + 0 1)))) + ;; Return updated tree. + tree) + +;;; Transcode functions + +;; These functions do the actual translation to JIRA format. For this section +;; I've used Atlassian's Text Formatting Notation Help page as a reference: +;; https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all + +(defun ox-jira-bold (bold contents info) + "Transcode BOLD from Org to JIRA. +CONTENTS is the text with bold markup. INFO is a plist holding +contextual information." + (format "*%s*" contents)) + +(defun ox-jira-code (code _contents info) + "Transcode a CODE object from Org to JIRA. +CONTENTS is nil. INFO is a plist used as a communication +channel." + (format "{{%s}}" (org-element-property :value code))) + +(defun ox-jira-example-block (example-block contents info) + "Transcode an EXAMPLE-BLOCK element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (when (org-string-nw-p (org-element-property :value example-block)) + (format "{noformat}\n%s{noformat}" + (org-export-format-code-default example-block info)))) + +(defun ox-jira-fixed-width (fixed-width contents info) + "Transcode an FIXED-WIDTH element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (format "{noformat}\n%s{noformat}" + (org-remove-indentation + (org-element-property :value fixed-width)))) + +;; Footnotes have two parts: the reference, and the definition. +;; +(defun ox-jira--footnote-anchor (element) + (let ((label (org-element-property :label element))) + (replace-regexp-in-string ":" "" label))) + +(defun ox-jira--footnote-ref (anchor) + (replace-regexp-in-string "fn" "" anchor)) + +(defun ox-jira-footnote-reference (footnote-reference contents info) + "Transcode an FOOTNOTE-REFERENCE element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (let* ((anchor (ox-jira--footnote-anchor footnote-reference)) + (ref (ox-jira--footnote-ref anchor))) + (format "{anchor:back%s}[^%s^|#%s]" + anchor ref anchor))) + +(defun ox-jira-footnote-definition (footnote-definition contents info) + "Transcode an FOOTNOTE-DEFINITION element from Org to Jira. +CONTENTS is nil. INFO is a plist holding contextual +information." + (let* ((anchor (ox-jira--footnote-anchor footnote-definition)) + (ref (ox-jira--footnote-ref anchor))) + (format "{anchor:%s}[^%s^|#back%s] %s" + anchor ref anchor contents))) + +;; Headlines are a little bit more complex. I'm not even attempting to support +;; TODO labels and meta-information, just the straight-up text. It would be +;; nice to support the six standard levels of headlines JIRA offers though. +;; +;; Since the headline level is _relative_ rather than absolute, if the +;; exporter sees a '** second level' heading before it's seen a '* first +;; level' then the '** second level' will think it's a top-level heading. +;; That's a bit weird, but there you go. +;; +(defun ox-jira-headline (headline contents info) + "Transcode a HEADLINE element from Org to JIRA. +CONTENTS is the contents of the headline, as a string. INFO is +the plist used as a communication channel." + (let* ((level (org-export-get-relative-level headline info)) + (title (org-export-data-with-backend + (org-element-property :title headline) + 'jira info))) + (concat + (format "h%d. %s\n" level title) + contents))) + +(defun ox-jira-horizontal-rule (horizontal-rule contents info) + "Transcode a HORIZONTAL-RULE element from Org to JIRA." + "----\n") + +(defun ox-jira-italic (italic contents info) + "Transcode ITALIC from Org to JIRA. +CONTENTS is the text with italic markup. INFO is a plist holding +contextual information." + (format "_%s_" contents)) + +;; A list item. The JIRA format for nested lists follows. (You can also mix +;; ordered and unordered lists.) +;; +;; * item +;; ** sub-item +;; ** sub-item 2 +;; * item 2 +;; +;; The item element itself does not know what type it is: that is an attribute +;; of its parent, a plain-list element. We need to walk the path of +;; alternating plain-list and item nodes until there are no more, and extract +;; their type. The type list is used to create a bullet string. +;; +;; JIRA doesn't really have support for definition lists, so we fake it with a +;; bullet list and some bold text for the term. +;; +(defun ox-jira--list-type-path (item) + (when (and item (eq 'item (org-element-type item))) + (let* ((list (org-element-property :parent item)) + (list-type (org-element-property :type list))) + (cons list-type (ox-jira--list-type-path + (org-element-property :parent list)))))) + +(defun ox-jira--bullet-string (list-type-path) + (apply 'string + (mapcar (lambda (x) (if (eq x 'ordered) ?# ?*)) + list-type-path))) + +(defun ox-jira-item (item contents info) + "Transcode ITEM from Org to JIRA. +CONTENTS is the text with item markup. INFO is a plist holding +contextual information." + (let* ((list-type-path (ox-jira--list-type-path item)) + (bullet-string (ox-jira--bullet-string (reverse list-type-path))) + (tag (let ((tag (org-element-property :tag item))) + (when tag + (org-export-data tag info)))) + (checkbox (case (org-element-property :checkbox item) + (on "(/)") + (off "(x)") + (trans "(i)")))) + (concat + bullet-string + " " + (when checkbox + (concat checkbox " ")) + (when tag + (format "*%s*: " tag)) + contents))) + +;; JIRA supports many types of links. I don't expect we support them all, but +;; we must make a token effort. A lot of this code is cribbed from +;; `ox-latex.el'. +;; +(defun ox-jira-link (link desc info) + "Transcode a LINK object from Org to JIRA. + +DESC is the description part of the link, or the empty string. +INFO is a plist holding contextual information. See +`org-export-data'." + (let* ((type (org-element-property :type link)) + (raw-path (org-element-property :path link)) + (desc (and (not (string= desc "")) desc)) + (path (cond + ((member type '("http" "https" "ftp" "mailto" "doi")) + (concat type ":" raw-path)) + ((string= type "file") + (org-export-file-uri raw-path)) + (t raw-path)))) + (cond + ;; Link with description + ((and path desc) (format "[%s|%s]" desc path)) + ;; Link without description + (path (format "[%s]" path)) + ;; Link with only description?! + (t desc)))) + +(defun ox-jira-underline (underline contents info) + "Transcode UNDERLINE from Org to JIRA. +CONTENTS is the text with underline markup. INFO is a plist holding +contextual information." + (format "+%s+" contents)) + +(defun ox-jira-verbatim (verbatim _contents info) + "Transcode a VERBATIM object from Org to Jira. +CONTENTS is nil. INFO is a plist used as a communication +channel." + (format "{{%s}}" (org-element-property :value verbatim))) + +;; One of the most annoying things about JIRA markup is the way it doesn't +;; reflow text properly, so any linebreaks becomes hard linebreaks in the +;; rendered output. Let's fix that! +;; +;; What we need to do is replace any *internal* newlines (i.e. any not at the +;; end of the string) with a space. Regexes to the rescue! I used the +;; following reference to help me with this function: +;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Regexp-Backslash.html#Regexp-Backslash + + +(defun ox-jira-paragraph (paragraph contents info) + "Transcode a PARAGRAPH element from Org to JIRA. +CONTENTS is the contents of the paragraph, as a string. INFO is +the plist used as a communication channel." + (replace-regexp-in-string "\n\\([^\']\\)" " \\1" contents)) + +;; I make a lot of lists. Let's make sure we handle them! This is very simple, +;; as in the JIRA format all the logic is actually _for each item_ in the +;; list. +;; +(defun ox-jira-plain-list (plain-list contents info) + "Transcode PLAIN-LIST from Org to JIRA. +CONTENTS is the text with plain-list markup. INFO is a plist holding +contextual information." + contents) + +;; This is text with no markup, but we have to escape certain characters to +;; avoid tripping up JIRA. In particular: +;; +;; - ={= :: Introduces macros +;; - =[= :: Introduces links +;; +(defun ox-jira-plain-text (text info) + "Transcode TEXT from Org to JIRA. +TEXT is the string to transcode. INFO is a plist holding +contextual information." + (replace-regexp-in-string "\\([[{]\\)" + '(lambda (p) (format "\\\\%s" p)) + text)) + +;; Paragraphs are grouped into sections. I've not found any mention in the Org +;; documentation, but it appears to be essential for any export to happen. +;; I've essentially cribbed this from `ox-latex.el`. +;; + +(defun ox-jira-section (section contents info) + "Transcode a SECTION element from Org to JIRA. +CONTENTS is the contents of the section, as a string. INFO is +the plist used as a communication channel." + contents) + +;; JIRA supports formatting for these languages: actionscript, html, +;; java,javascript, sql, xhtml, xml. If none of them fits, we can use 'none', +;; or leave out the language altogether, which I imagine will be a bit like +;; ={noformat}=. +;; +(defun ox-jira-src-block (src-block contents info) + "Transcode a SRC-BLOCK element from Org to Jira. +CONTENTS holds the contents of the src-block. INFO is a plist holding +contextual information." + (when (org-string-nw-p (org-element-property :value src-block)) + (let* ((lang (org-element-property :language src-block)) + (lang (if (member lang '("actionscript" "html" "java" "javascript" "sql" "xhtml" "xml")) lang)) + (code (org-export-format-code-default src-block info))) + (concat + (if lang + (format "{code:%s}" lang) + "{code}") + code + "{code}")))) + +(defun ox-jira-subscript (subscript contents info) + "Transcode SUBSCRIPT from Org to JIRA. +CONTENTS is the text with subscript markup. INFO is a plist holding +contextual information." + (ox-jira--text-transform-embeddable "~" contents)) + +(defun ox-jira-superscript (superscript contents info) + "Transcode SUPERSCRIPT from Org to JIRA. +CONTENTS is the text with superscript markup. INFO is a plist holding +contextual information." + (ox-jira--text-transform-embeddable "^" contents)) + + +;; Org's table editor is one of the many reasons to use Org. It is excellent. +;; Org and JIRA's tables are quite similar. Where Org marks tables up like +;; this: +;; +;; | Name | Score | +;; |--------+-------| +;; | Ashley | 2 | +;; | Alex | 3 | +;; +;; Jira uses the following format: +;; +;; || Name || Score || +;; | Ashley | 2 | +;; | Alex | 3 | +;; +;; Tables are complex beasts. I only hope to support very simple ones. Looks +;; like most of the logic will live in the row and cell transcoding functions. +;; +(defun ox-jira-table (table contents info) + "Transcode a TABLE element from Org to JIRA. +CONTENTS holds the contents of the table. INFO is a plist holding +contextual information." + contents) + +;; We only want to output =standard= rows, not horizontal lines. I'm not sure +;; if detection of header rows belong here or in the cells. +;; +(defun ox-jira-table-row (table-row contents info) + "Transcode a TABLE-ROW element from Org to JIRA. +CONTENTS holds the contents of the table-row. INFO is a plist holding +contextual information." + (when (eq 'standard (org-element-property :type table-row)) + (format "%s\n" contents))) + +;; The cell itself does not know if it is a header cell or not, so we have to +;; ask its containing row if it is the first row, and the table if it has a +;; header row at all. If those things are true, make the cell a header cell. +;; +(defun ox-jira-table-cell (table-cell contents info) + "Transcode a TABLE-CELL element from Org to JIRA. +CONTENTS holds the contents of the table-cell. INFO is a plist holding +contextual information." + (let* ((row (org-element-property :parent table-cell)) + (table (org-element-property :parent row)) + (has-header (org-export-table-has-header-p table info)) + (group (org-export-table-row-group row info)) + (is-header (and has-header (eq 1 group))) + (sep (if is-header "||" "|"))) + (format "%s %s %s" sep contents + (if (org-export-last-sibling-p table-cell info) sep "")))) + +;; This is updated to show progress of subsequent list of check boxes. +;; +(defun ox-jira-statistics-cookie (statistics-cookie _contents _info) + "Transcode a STATISTICS-COOKIE object from Org to JIRA. +CONTENTS is nil. INFO is a plist holding contextual information." + (format "\\%s" (org-element-property :value statistics-cookie))) + +(defun ox-jira-strike-through (strike-through contents info) + "Transcode STRIKE-THROUGH from Org to JIRA. +CONTENTS is the text with strike-through markup. INFO is a plist holding +contextual information." + (format "-%s-" contents)) + +(defun ox-jira-quote-block (quote-block contents info) + "Transcode a QUOTE-BLOCK element from Org to Jira. +CONTENTS holds the contents of the block. INFO is a plist +holding contextual information." + (format "{quote}\n%s{quote}" contents)) + +(defun ox-jira-export-as-jira + (&optional async subtreep visible-only body-only ext-plist) + "Export current buffer as a Jira buffer. + +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 buffer 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, omit header +stuff. (e.g. AUTHOR and TITLE.) + +EXT-PLIST, when provided, is a property list with external +parameters overriding Org default settings, but still inferior to +file-local settings. + +Export is done in a buffer named \"*Org JIRA Export*\", which +will be displayed when `org-export-show-temporary-export-buffer' +is non-nil." + (interactive) + (org-export-to-buffer 'jira "*Org JIRA Export*" + async subtreep visible-only body-only ext-plist)) + +(provide 'ox-jira) + +;;; ox-jira.el ends here