emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [org-babel] [PATCH] Improve ditta.jar finding heuristics
@ 2011-11-20 13:37 Andrey Smirnov
  2011-11-20 16:35 ` Eric Schulte
  2011-12-11  3:12 ` Andrey Smirnov
  0 siblings, 2 replies; 6+ messages in thread
From: Andrey Smirnov @ 2011-11-20 13:37 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 788 bytes --]


Hi everybody,

I've been using org-mode for quite a while but only recently found
myself in need of using ditaa to draw some simple diagram. As it turns
out my installation of emacs(Ubuntu 10.10, emacs-snapshot from
https://launchpad.net/~cassou/+archive/emacs) doesn't come with
ditta.jar pre-bundled, although I'm not sure if it should. Anyway, despite
my installation of ditta with help of apt-get, org-babel kept
unsuccessfully trying to locate
/usr/share/emacs/24.0.91/lisp/contrib/ditta.jar, leaving me without any
diagrams produced.

So to alleviate the problem I cloned git repository and wrote a small
patch implementing very crude algorithm, which is, nonetheless, in my
opinion, still an improvement on default behavior. For more details see
commit message. 

Andrey Smirnov


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Add simple ditta.jar finding heuristics --]
[-- Type: text/x-diff, Size: 4353 bytes --]

From 03b434347e02c2fc95f38a7a4e87850eb5f87f56 Mon Sep 17 00:00:00 2001
From: Andrey Smirnov <andrew.smirnov@gmail.com>
Date: Sun, 20 Nov 2011 19:40:32 +0700
Subject: [PATCH] org-babel: Add simple ditaa.jar searching heuristics

lisp/ob-ditaa.el: Add two functions `org-ditaa-try-find-file-in' and
`org-ditaa-delete-if-not' and more complicated algorithm for setting
the value of `org-ditaa-jar-path'.

Prior to this the algorithm used to locate ditaa.jar was to look for
it in ${ob-ditaa.el path}/../contrib/ but that approach fails if said 'jar'
doesn't come pre-bundled with user's emacs install and even if it does
it precludes user from using system-wide installed(via apt-get or any
such tool) instance of ditaa in favor of pre-bundled one.

New heuristics does the following:
  1. Looks in the predefined set of locations, right now it is
         - /usr/share/ditaa/ (Location where it is installed in
                              Ubuntu)
         - ${ob-ditaa.el path}/../contrib/
  2. If previous set yeilds no results it tryies to locate said
     ditta.jar in either /usr/share/ or /usr/lib/
---
 lisp/ob-ditaa.el |   72 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/lisp/ob-ditaa.el b/lisp/ob-ditaa.el
index 0aba9a6..15b3fbe 100644
--- a/lisp/ob-ditaa.el
+++ b/lisp/ob-ditaa.el
@@ -42,7 +42,77 @@
   '((:results . "file") (:exports . "results") (:java . "-Dfile.encoding=UTF-8"))
   "Default arguments for evaluating a ditaa source block.")
 
-(defvar org-ditaa-jar-path)
+;;; Not having delete-if-not from cl package is rather annoying,
+;;; but, alright, we'll do it live.
+(defun org-ditaa-delete-if-not (pred seq)
+  "Destructively remove all elements of SEQ that do not satisfy predicat PRED"
+  (dolist (elt seq seq)
+    (when (not (apply pred (list elt)))
+      (setq seq (delete elt seq)))))
+
+(defun org-ditaa-try-find-file-in (dir filename)
+  "Traverse directory tree supplied in DIR and search for FILENAME.
+Return full path to FILENAME if found."
+  (let ((candidate-file (expand-file-name filename dir)))
+    (cond ((file-exists-p candidate-file)
+	   candidate-file)
+	  ((file-directory-p dir)
+	   (do ((path-to-file nil)
+		;; List of sub-directories with . , .. and all
+		;; items that are not directories filtered out
+		(subdir-list
+		 (org-ditaa-delete-if-not
+		  (lambda (e) (file-directory-p
+			  (file-name-as-directory
+			   (expand-file-name e dir))))
+		  (delete
+		   ".."
+		   (delete
+		    "."
+		    ;;  Access to some directories might result in
+		    ;;  "Permission denied" file error. Wrap the call
+		    ;;  in condition-case to avoid that
+		    (condition-case ex
+			(directory-files dir)
+		      ('file-error)))))
+		 (setq subdir-list (cdr subdir-list))))
+	       ((or (not subdir-list)
+		    path-to-file) path-to-file)
+	     (when subdir-list
+	       (let ((subdir (file-name-as-directory
+			      (expand-file-name (car subdir-list) dir))))
+		 (setq path-to-file (when (and subdir
+					       (file-directory-p subdir))
+				      (org-ditaa-try-find-file-in subdir filename)))))))
+	  (t
+	   nil))))
+
+;;; When looking for ditaa.jar go through predefined list of most
+;;; likely places to have it, then if else fails try to find it
+;;; somwhere in /usr/share or /usr/lib
+(defvar org-ditaa-jar-path
+  (let* ((potential-path-list
+	  (list "/usr/share/ditaa/ditaa.jar" ; Ubuntu 10.10 installed via apt-get
+		(expand-file-name            ; Bundled with emacs
+		 "ditaa.jar"
+		 (file-name-as-directory
+		  (expand-file-name
+		   "scripts"
+		   (file-name-as-directory
+		    (expand-file-name
+		     "../contrib"
+		     (file-name-directory (or load-file-name
+					      buffer-file-name)))))))))
+	 (actual-path (car potential-path-list)))
+    (while (and actual-path
+		(not (file-exists-p actual-path)))
+      (setq potential-path-list (cdr potential-path-list))
+      (setq actual-path (car potential-path-list)))
+    (when (not actual-path)
+      (setq actual-path (or (org-ditaa-try-find-file-in "/usr/share" "ditaa.jar")
+			    (org-ditaa-try-find-file-in "/usr/lib" "ditaa.jar"))))
+    actual-path))
+
 (defun org-babel-execute:ditaa (body params)
   "Execute a block of Ditaa code with org-babel.
 This function is called by `org-babel-execute-src-block'."
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-12-11  5:07 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-20 13:37 [org-babel] [PATCH] Improve ditta.jar finding heuristics Andrey Smirnov
2011-11-20 16:35 ` Eric Schulte
2011-11-21  5:16   ` Andrey Smirnov
2011-11-21 18:02     ` Eric Schulte
2011-12-11  3:12 ` Andrey Smirnov
2011-12-11  5:07   ` Eric Schulte

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).