From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms13.migadu.com with LMTPS id 2PTzKpODJ2e1SgAAe85BDQ:P1 (envelope-from ) for ; Sun, 03 Nov 2024 14:07:15 +0000 Received: from aspmx1.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id 2PTzKpODJ2e1SgAAe85BDQ (envelope-from ) for ; Sun, 03 Nov 2024 15:07:15 +0100 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1730642835; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:list-id:list-help:list-unsubscribe: list-subscribe:list-post; bh=aBAUNpaXNN4WuyEMKHI5uIo73Gw/pvRH9MhImpl2ZRI=; b=WVJ4TkH2Epz8spzDAqDqE8DY6jPTHeAqfTsE2Vth17oLpFtWCKJcv1bW+BLZdoFYcKWCNW Q69hAXcpBThgqwKRhzN1yXXEiWujd5ADTFKnTmdmFKOeGtQ9G9chKNXF7TQW7aUsn41hTr GGuDDMexScEf6NezJh9FyaBPDpCptsLCH9mezTZom+rEis0Z2NtG1IJ2MrRzZiN7UOaPJO fUIPhjpCwWmBMRPRt7tsPXXGdzH1dZ4Gclz8BdUw1XWOatN0JRKAUgShYiYPt+TUbuJccx ZlL640ImhbRhtqAXZ8k0eja4o0RryOGGsNgy3r5gFv0Yj4Rvr5z+Dg6P1vAEiQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=none ARC-Seal: i=1; s=key1; d=yhetil.org; t=1730642835; a=rsa-sha256; cv=none; b=Mcy8HcaVPbc8zCAgexknrWH/MOMPMrW7Wq2A77OE0TYlbQ3a1Gln/V3Fc7ZGNslk8F8DSn rJVICuCogPW65zVEdptZA0bi7pWs8smgGeoKS6+hfJUKY00GR5mNQuIbA+3y+fgbx2/EUa S/wXwxfYl5UDnmzf5huhG9w/of25+gxgU68qs6ktnmal2VM7tIEzT/7tzi5N5OBEL4B2ED p40ysuHl3RYcsrtFg0R9LK5NQPGoM0xb1k7D/rN8oY+da+/9lYSLDjqSSvg/1Ey9ZuSMwt af0qoMh6fRXIkuCMwtW9GgzBSPpiZx2bIPsfCRBXxyTAJCyzIHcfEj4z3lK4CA== Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 3D8A087F7A for ; Sun, 03 Nov 2024 15:07:15 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t7bFA-0003se-CL; Sun, 03 Nov 2024 09:06:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t7bF3-0003rs-Qw for emacs-orgmode@gnu.org; Sun, 03 Nov 2024 09:06:10 -0500 Received: from ciao.gmane.io ([116.202.254.214]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t7bEx-0006mW-Hu for emacs-orgmode@gnu.org; Sun, 03 Nov 2024 09:06:07 -0500 Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1t7bEs-0005L2-84 for emacs-orgmode@gnu.org; Sun, 03 Nov 2024 15:05:58 +0100 X-Injected-Via-Gmane: http://gmane.org/ To: emacs-orgmode@gnu.org From: Jarmo Hurri Subject: [PATCH] ob-ditaa.el: custom var name, ditaa executable, SVG output, and chararacter encoding Date: Sun, 03 Nov 2024 16:05:50 +0200 Message-ID: <875xp476pt.fsf@iki.fi> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:It0nIBI4MhfEu8nZ2sZ5EnHJgPA= Received-SPF: pass client-ip=116.202.254.214; envelope-from=geo-emacs-orgmode@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: -15 X-Spam_score: -1.6 X-Spam_bar: - X-Spam_report: (-1.6 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN X-Migadu-Scanner: mx11.migadu.com X-Migadu-Spam-Score: 1.05 X-Spam-Score: 1.05 X-Migadu-Queue-Id: 3D8A087F7A X-TUID: l2TnxzbPFkaY --=-=-= Content-Type: text/plain Greetings. Please find attached a patch written mainly to allow a ditaa executable to be used instead of a JAR file. Assuming that this patch is (eventually) accepted, I can also volunteer to be a maintainer for this file if one is needed. All the best, Jarmo --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-ob-ditaa.el-custom-var-name-ditaa-executable-SVG-out.patch Content-Description: ditaa exec patch >From 090beafd82518380aa59eecf0e35110566b26d41 Mon Sep 17 00:00:00 2001 From: Jarmo Hurri Date: Sun, 3 Nov 2024 15:22:33 +0200 Subject: [PATCH] ob-ditaa.el: custom var name, ditaa executable, SVG output, and chararacter encoding * lisp/ob-ditaa.el (org-babel-default-header-args:ditaa) Include new header arg `:encoding`. (org-ditaa-default-exec-mode): Define new customizable variable for controlling ditaa execution via jar or executable. (org-ditaa-exec): Define new customizable variable for controlling path to ditaa executable. (org-ditaa-java-exec): Rename old customizable variable to conform to ditaa variable naming (not containing word `babel`). (org-ditaa-ensure-jar-file): Write a small helper function checking existence of jar file. (org-babel-execute:ditaa): Add support for executable. Add support for SVG output. Automatically deduce output type if possible. Override type with header argument. Set default type to PNG. Check that no more than one result type is specified. Echo shell commands in message buffer. Clarify code structure and local variable naming. * 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 (=ob-ditaa=: custom variable name, ditaa executable, SVG output, and chararacter encoding): Document breaking change and new features. 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 from file suffix if possible, can be overridden by header argument, and defaults to PNG. Character encoding of ditaa source code blocks was passed via Java, while the encoding can be specified directly as a parameter to ditaa. Character encoding is now passed directly to ditaa, with a corresponding header argument `:encoding`. --- doc/org-manual.org | 5 +- etc/ORG-NEWS | 23 ++++++ lisp/ob-ditaa.el | 180 +++++++++++++++++++++++++++++++++------------ 3 files changed, 157 insertions(+), 51 deletions(-) diff --git a/doc/org-manual.org b/doc/org-manual.org index 451fd72cd..8562fbd74 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -23020,8 +23020,9 @@ be complete if the ones above were not mentioned in this manual. - Ilya Shlyakhter proposed the Archive Sibling, line numbering in 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. +- Stathis Sideris wrote the =ditaa.jar= ASCII to PNG/SVG converter + that is 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 de4f11b25..8a19f3fdf 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -71,6 +71,29 @@ This should have minimal impact on non-iCalendar exporters, since users who manually set ~org-export-with-timestamps~ to ~active~ will now have diary timestamps included as well. +*** =ob-ditaa=: custom variable name, ditaa executable, SVG output, and chararacter encoding + +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=. + +In order to use an 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 be generated by using =:svg= header argument, or by +specifying a result file with =.svg= suffix; note, however, that this +requires a ditaa version of at least 0.11.0. Result file type is +deduced from result file suffix, can be overruled by a header +argument, and is PNG by default. An error is signalled if more than +one output type is specified via header arguments. + +Character encoding is passed directly to ditaa (earlier to Java) and +can be controlled by new header argument =:encoding=. + +Shell commands run when executing a ditaa code block are echoed in +the message buffer. + ** New features # We list the most important features, and the features that may diff --git a/lisp/ob-ditaa.el b/lisp/ob-ditaa.el index cc01d7e28..8931e9a6b 100644 --- a/lisp/ob-ditaa.el +++ b/lisp/ob-ditaa.el @@ -2,7 +2,7 @@ ;; Copyright (C) 2009-2024 Free Software Foundation, Inc. -;; Author: Eric Schulte +;; Authors: Eric Schulte, Jarmo Hurri ;; Keywords: literate programming, reproducible research ;; URL: https://orgmode.org @@ -25,15 +25,62 @@ ;; 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" +;; - there is no "output", so source code blocks always export "results" ;; -;; 3) we are adding the "file" and "cmdline" header arguments +;; - only results of type "file" are returned ;; -;; 4) there are no variables (at least for now) +;; - there are no variables +;; +;; - output file type is deduced from result file suffix by default, +;; but can be overwritten; if no type is specified and none can be +;; deduced, the default is png +;; +;; - 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' | +;; +;; - the following header arguments are added: +;; "file" : path to generated result file +;; "png" : toggle for generating png file (default) +;; "svg" : toggle for generating svg file (requires ditaa version >= 0.11.0) +;; "eps" : toggle for generating eps file (requires org-ditaa-eps-jar-path) +;; "pdf" : toggle for generating pdf file (requires org-ditaa-eps-jar-path and epstopdf) +;; "cmdline" : command line parameters passed to ditaa +;; "encoding" : character encoding (default UTF-8) +;; "java" : additional parameters passed to java if ditaa run via a jar +;; + +;;; 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: @@ -46,9 +93,33 @@ (defvar org-babel-default-header-args:ditaa '((:results . "file") (:exports . "results") - (:java . "-Dfile.encoding=UTF-8")) + (:encoding . "UTF-8")) "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 'symbol + :options '(ditaa jar)) + +(defcustom org-ditaa-exec "ditaa" + "File name of the ditaa executable." + :group 'org-babel + :package-version '(Org . "9.8") + :type 'string) + +(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 +129,75 @@ (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) +;;; small helper function returning file if it exists and signalling +;;; error otherwise +(defun org-ditaa-ensure-jar-file (file) + (if (file-exists-p file) + file + (error "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-")) + "ditaa code block requires :file header argument"))) + (png (cdr (assq :png params))) + (svg (cdr (assq :svg params))) (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 + (pdf (cdr (assq :pdf params))) + (num-out-types-set (seq-count 'identity (list png svg eps pdf)))) + (when (> num-out-types-set 1) + (error "more than one output type specified for ditaa code block")) + (when (= num-out-types-set 0) + ;; deduce outfile type from suffix or set to default + (let ((out-file-suffix (file-name-extension out-file))) + (setq svg (string= out-file-suffix "svg")) + (setq eps (string= out-file-suffix "eps")) + (setq pdf (string= out-file-suffix "pdf")) + (setq png (or (string= out-file-suffix "png") + (not svg eps pdf))))) + (let* ((ditaa-options (cdr (assq :cmdline params))) + (ditaa-encoding (cdr (assq :encoding 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)) + " " "-jar" " " + (shell-quote-argument + (org-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))) + (cmd (concat exec-form + (when ditaa-options (concat " " ditaa-options)) + (when svg (concat " " "--svg")) + (when ditaa-encoding (concat " " "-e " ditaa-encoding)) + " " in-file " " ditaa-out-file))) + (with-temp-file in-file (insert body)) + (message cmd) + (shell-command cmd) + (when pdf + (let ((pdf-cmd (concat "epstopdf" " " ditaa-out-file " " + "-o=" (org-babel-process-file-name out-file)))) + (message pdf-cmd) + (shell-command pdf-cmd))) + 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." -- 2.47.0 --=-=-=--