branch: externals/org
commit 46bfd06ad868978c5dff698bfd83688705cf9ed3
Author: Jarmo Hurri <[email protected]>
Commit: Ihor Radchenko <[email protected]>
ob-ditaa.el: ditaa executable, SVG output, and output type control
* lisp/ob-ditaa.el (org-babel-default-header-args:ditaa) Add graphics
to default value of :results. Add png as default value of header arg
:file-ext.
(org-ditaa--ensure-jar-file): Write a small helper function checking
existence of jar file.
(org-babel-execute:ditaa): Add support for ditaa executable. Add
support for SVG output. Define new customizable variable
`org-ditaa-default-exec-mode' for controlling ditaa execution via jar
or executable. Define new customizable variable `org-ditaa-exec' for
controlling path to ditaa executable. Rename old customizable
variable `org-babel-ditaa-java-cmd' to `org-ditaa-java-exec' to
conform to ditaa variable naming (not containing word babel); provide
an obsolete alias for backwards-compatibility. Use standard
`org-babel-graphical-output-file' to determine output file and type.
Clarify code structure and local variable naming. Provide
backwards-compatibility for :eps and :pdf header arguments. Make
`org-ditaa-jar-option' obsolete.
* doc/org-manual.org (List of contributors): Remove reference to
non-existing location of ditaa.jar in org contrib, refer to ditaa
github page instead.
* etc/ORG-NEWS: Document new features, new options, renamed variable
and obsolete variable.
There was a mismatch between what ob-ditaa expected and what some
operating systems provide. In particular, ob-ditaa expected a JAR
executable via java -jar, while some operating systems provide a shell
script which executes the JAR in a more complicated manner. Therefore
support for executing ditaa source code blocks directly via an
executable was added.
Newer versions of ditaa can generate SVG output, which was not
supported by ob-ditaa. This is now fixed. Output type is deduced
automatically, and defaults to PNG. Legacy output-type controlling
header arguments :eps and :pdf are still there for
backwards-compatibility, and override output type determination from
file type.
---
doc/org-manual.org | 3 +-
etc/ORG-NEWS | 27 ++++++++
lisp/ob-ditaa.el | 186 ++++++++++++++++++++++++++++++++++++++---------------
3 files changed, 162 insertions(+), 54 deletions(-)
diff --git a/doc/org-manual.org b/doc/org-manual.org
index ff5a569d4e..02763f4ecb 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -23276,7 +23276,8 @@ community and the code.
literal examples, and remote highlighting for referenced code lines.
- Stathis Sideris wrote the =ditaa.jar= ASCII to PNG converter that is
- now packaged into the [[https://git.sr.ht/~bzg/org-contrib][org-contrib]]
repository.
+ available as a package in some operating systems or can be
+ downloaded from [[https://github.com/stathissideris/ditaa]].
- Daniel Sinder came up with the idea of internal archiving by locking
subtrees.
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index ad01b69ecb..3cfc2b011d 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -256,6 +256,15 @@ When editing Dot source blocks, Org now uses Graphviz Dot
mode, if installed.
Org now officially enables C# code block evaluation based on the .NET SDK.
+*** =ob-ditaa=: ditaa executable, and SVG output
+
+In order to use a ditaa executable instead of a JAR file, you can set
+=org-ditaa-default-exec-mode= to ='ditaa=. The location of the
+executable can be configured via =org-ditaa-exec=.
+
+SVG output can now be generated; note, however, that this requires a
+ditaa version of at least 0.11.0.
+
** New and changed options
# Changes dealing with changing default values of customizations,
@@ -443,6 +452,13 @@ can be used.
This option specifies the path where MathML files generated from LaTeX
fragments are stored.
+*** =ob-ditaa=: output type control
+
+Output file type is determined as specified in Babel documentation:
+the suffix of =:file= is the primary determinant, and =:file-ext=
+secondary. Header arguments =:pdf= and =:eps= are supported for
+backwards compatibility. Default output type is still PNG.
+
** New functions and changes in function arguments
# This also includes changes in function behavior from Elisp perspective.
@@ -594,6 +610,17 @@ capture ~:tree-type~ options]], the internal variable
~org-datetree-base-level~ has been removed, as well as the
undocumented helper function ~org-datetree-insert-line~.
+*** =ob-ditaa=: =org-babel-ditaa-java-cmd= renamed and =org-ditaa-jar-option=
made obsolete
+
+To align with other customizable variable names, which do not contain
+the word =babel=, variable =org-babel-ditaa-java-cmd= has been renamed
+to =org-ditaa-java-exec=. The old variable =org-babel-ditaa-java-cmd=
+is still available as an obsolete alias.
+
+Variable =org-ditaa-jar-option= did not serve any sensible purpose and
+has been made obsolete. Its value is still used in place of default
+parameter -jar if the variable is defined.
+
** Miscellaneous
*** Inline tasks in a clocktable will be indented to a level below their
heading
diff --git a/lisp/ob-ditaa.el b/lisp/ob-ditaa.el
index 77eadd6c2b..8b6c660b5c 100644
--- a/lisp/ob-ditaa.el
+++ b/lisp/ob-ditaa.el
@@ -2,7 +2,7 @@
;; Copyright (C) 2009-2025 Free Software Foundation, Inc.
-;; Author: Eric Schulte
+;; Authors: Eric Schulte, Jarmo Hurri
;; Keywords: literate programming, reproducible research
;; URL: https://orgmode.org
@@ -25,15 +25,52 @@
;; Org-Babel support for evaluating ditaa source code.
;;
-;; This differs from most standard languages in that
+;; Source code blocks of type ditaa have some special features:
;;
-;; 1) there is no such thing as a "session" in ditaa
+;; - there is no such thing as a "session"
;;
-;; 2) we are generally only going to return results of type "file"
+;; - :export results is the default
;;
-;; 3) we are adding the "file" and "cmdline" header arguments
+;; - only results of type "file" are returned
+;;
+;; - there are no variables
+;;
+;; - three different variants of "ditaa" exist: a ditaa executable
+;; (shell script), ditaa.jar Java archive and DitaaEPS.jar Java
+;; archive; the third one is a fork generating eps output, and is
+;; also a prerequisite for producing pdf output; ob-ditaa supports
+;; all three of these; if ditaa.jar or DitaaEPS.jar is used, paths
+;; to file(s) must be set; the following table summarizes which
+;; variant is used in which case; column mode refers to
+;; `org-ditaa-default-exec-mode'
+;;
+;; | mode | output | command
|
+;;
|----------------+----------+-----------------------------------------------------|
+;; | `ditaa' | png, svg | `org-ditaa-exec'
|
+;; | `jar' | png, svg | `org-ditaa-java-exec' -jar
`org-ditaa-jar-path' |
+;; | `ditaa', `jar' | eps | `org-ditaa-java-exec' -jar
`org-ditaa-eps-jar-path' |
+;; | `ditaa', `jar' | pdf | `org-ditaa-java-exec' -jar
`org-ditaa-eps-jar-path' |
+;;
+;; - standard header argument "cmdline" controls command line parameters
passed to ditaa
+;; - the following header arguments are added:
+;; "java" : additional parameters passed to java if ditaa run via a jar
;;
-;; 4) there are no variables (at least for now)
+
+;;; Requirements:
+
+;; at least one of the following:
+;;
+;; ditaa (executable)
+;; - packaged in some distributions
+;; - configurable via `org-ditaa-exec'
+;;
+;; ditaa.jar | when exec mode is `jar'
+;; - `org-ditaa-jar-path' must point to this jar file
+;; - see https://github.com/stathissideris/ditaa
+;;
+;; DitaaEps.jar | when generating eps or pdf output
+;; - `org-ditaa-eps-jar-path' must point to this jar file
+;; - see https://sourceforge.net/projects/ditaa-addons/files/DitaaEps/
;;; Code:
@@ -44,11 +81,36 @@
(require 'org-compat)
(defvar org-babel-default-header-args:ditaa
- '((:results . "file")
+ '((:results . "file graphics")
(:exports . "results")
- (:java . "-Dfile.encoding=UTF-8"))
+ (:file-ext . "png"))
"Default arguments for evaluating a ditaa source block.")
+(defcustom org-ditaa-default-exec-mode 'jar
+ "Method to use for ditaa diagram generation when generating png or svg
output.
+`jar' means to use java together with a JAR.
+The JAR must be set via `org-ditaa-jar-path'.
+
+`ditaa' means to use the ditaa executable.
+The executable can be configured via `org-ditaa-exec'."
+
+ :group 'org-babel
+ :package-version '(Org . "9.8")
+ :type '(choice (const :tag "Use java together with a JAR file." jar)
+ (const :tag "Use ditaa executable." ditaa)))
+
+(defcustom org-ditaa-exec "ditaa"
+ "File name of the ditaa executable."
+ :group 'org-babel
+ :package-version '(Org . "9.8")
+ :type 'string)
+
+(define-obsolete-variable-alias 'org-babel-ditaa-java-cmd 'org-ditaa-java-exec
"9.8")
+(defcustom org-ditaa-java-exec "java"
+ "Java executable to use when evaluating ditaa blocks using a JAR."
+ :group 'org-babel
+ :type 'string)
+
(defcustom org-ditaa-jar-path (expand-file-name
"ditaa.jar"
(file-name-as-directory
@@ -58,64 +120,82 @@
(expand-file-name
"../contrib"
(file-name-directory (org-find-library-dir
"org")))))))
- "Path to the ditaa jar executable."
- :group 'org-babel
- :type 'string)
-
-(defcustom org-babel-ditaa-java-cmd "java"
- "Java executable to use when evaluating ditaa blocks."
+ "Path to the ditaa.jar file."
:group 'org-babel
:type 'string)
(defcustom org-ditaa-eps-jar-path
(expand-file-name "DitaaEps.jar" (file-name-directory org-ditaa-jar-path))
- "Path to the DitaaEps.jar executable."
+ "Path to the DitaaEps.jar executable.
+Used when generating eps or pdf output."
:group 'org-babel
:version "24.4"
:package-version '(Org . "8.0")
:type 'string)
-(defcustom org-ditaa-jar-option "-jar"
- "Option for the ditaa jar file.
-Do not leave leading or trailing spaces in this string."
- :group 'org-babel
- :version "24.1"
- :type 'string)
+(make-obsolete-variable 'org-ditaa-jar-option
+ "(ob-ditaa) variable org-ditaa-jar-option is obsolete"
+ "9.8")
+
+(defun ob-ditaa--ensure-jar-file (file)
+ "Return FILE if it exists, signal error otherwise."
+ (if (file-exists-p file)
+ file
+ (error "(ob-ditaa) Could not find jar file %s" file)))
(defun org-babel-execute:ditaa (body params)
- "Execute BODY of Ditaa code with org-babel according to PARAMS.
+ "Execute BODY of ditaa code with org-babel according to PARAMS.
This function is called by `org-babel-execute-src-block'."
- (let* ((out-file (or (cdr (assq :file params))
- (error
- "Ditaa code block requires :file header argument")))
- (cmdline (cdr (assq :cmdline params)))
- (java (cdr (assq :java params)))
- (in-file (org-babel-temp-file "ditaa-"))
- (eps (cdr (assq :eps params)))
- (eps-file (when eps
- (org-babel-process-file-name (concat in-file ".eps"))))
- (pdf-cmd (when (and (or (string= (file-name-extension out-file) "pdf")
- (cdr (assq :pdf params))))
- (concat
- "epstopdf"
- " " eps-file
- " -o=" (org-babel-process-file-name out-file))))
- (cmd (concat org-babel-ditaa-java-cmd
- " " java " " org-ditaa-jar-option " "
- (shell-quote-argument
- (expand-file-name
- (if eps org-ditaa-eps-jar-path org-ditaa-jar-path)))
- " " cmdline
- " " (org-babel-process-file-name in-file)
- " " (if pdf-cmd
- eps-file
- (org-babel-process-file-name out-file)))))
- (unless (file-exists-p org-ditaa-jar-path)
- (error "Could not find ditaa.jar at %s" org-ditaa-jar-path))
- (with-temp-file in-file (insert body))
- (shell-command cmd)
- (when pdf-cmd (shell-command pdf-cmd))
- nil)) ;; signal that output has already been written to file
+ (let* ((out-file (org-babel-graphical-output-file params))
+ (out-file-suffix (file-name-extension out-file))
+ ;; backwards-compatibility of :eps and :pdf header arguments
+ ;; notice that these take precedence over file type (suffix)
+ (legacy-eps (cdr (assq :eps params)))
+ (legacy-pdf (cdr (assq :pdf params))))
+ (when (and legacy-eps legacy-pdf)
+ (error "(ob-ditaa) Both :eps and :pdf legacy output types specified"))
+ (let* ((legacy-output-type (or legacy-eps legacy-pdf))
+ (eps (or legacy-eps (string= out-file-suffix "eps")))
+ (pdf (or legacy-pdf (string= out-file-suffix "pdf")))
+ (svg (and (not legacy-output-type) (string= out-file-suffix "svg")))
+ (png (and (not legacy-output-type)
+ (or (string= out-file-suffix "png")
+ (not (or svg pdf eps))))) ;; default output type is
png
+ (ditaa-options (cdr (assq :cmdline params)))
+ (java-options (cdr (assq :java params)))
+ (use-eps-jar (or eps pdf))
+ (exec-form (if (or (equal org-ditaa-default-exec-mode 'jar)
use-eps-jar)
+ (concat org-ditaa-java-exec
+ (when java-options (concat " " java-options))
+ " "
+ ;; use obsolete variable instead of default
param if defined
+ (if (boundp 'org-ditaa-jar-option)
org-ditaa-jar-option "-jar")
+ " "
+ (shell-quote-argument
+ (ob-ditaa--ensure-jar-file (if use-eps-jar
org-ditaa-eps-jar-path
+
org-ditaa-jar-path))))
+ org-ditaa-exec))
+ (in-file (org-babel-temp-file "ditaa-"))
+ (ditaa-out-file (org-babel-process-file-name (if pdf (concat
in-file ".eps") out-file)))
+ (ditaa-coding-system 'utf-8)
+ (cmd (concat exec-form
+ (when ditaa-options (concat " " ditaa-options))
+ (when svg (concat " " "--svg"))
+ " " "-e" " " (symbol-name ditaa-coding-system)
+ " " in-file " " ditaa-out-file)))
+ ;; verify that output file type is specified - note that this
+ ;; error should in fact never happen, since default png type is
+ ;; set above if no other supported type is specified
+ (unless (or eps pdf svg png)
+ (error (concat "(ob-ditaa) Unknown output file extension: "
out-file-suffix)))
+ (with-temp-file in-file
+ (set-buffer-file-coding-system ditaa-coding-system)
+ (insert body))
+ (shell-command cmd)
+ (when pdf
+ (shell-command (concat "epstopdf" " " ditaa-out-file " "
+ "-o=" (org-babel-process-file-name out-file))))
+ nil))) ;; signal that output has already been written to file
(defun org-babel-prep-session:ditaa (_session _params)
"Return an error because ditaa does not support sessions."