emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Code snippet for Message Sequence Diagram export
@ 2010-05-16 20:18 Juan
  2010-05-17  8:13 ` Eric S Fraga
  0 siblings, 1 reply; 6+ messages in thread
From: Juan @ 2010-05-16 20:18 UTC (permalink / raw)
  To: Emacs-orgmode

Hi,

The following code adds an export block of type 'mscgen'. The block
body will be processed by the mscgen application. Sort of works, not
very tested yet.

;;; org-exp-mscgen.el --- message sequence chart support for org-export

;; Copyright (C) 2010
;;   Free Software Foundation, Inc.

;; Author: Juan Pechiar
;; Version: 0.1 2010-05-16

;; This 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 software is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;;
;; This software provides EMACS org-mode export support for message
;; sequence charts. The mscgen utility is used for processing the
;; sequence definition, and must therefore be installed in the system.
;;
;; The code is a direct modification of org-export-blocks-format-ditaa
;; from the org-mode distribution.
;;
;; Mscgen is available and documented at http://www.mcternan.me.uk/mscgen/index.html
;;
;; Customize path to mscgen utility with org-mscgen-path variable
;;
;; Example:
;;
;; #+begin_mscgen example1
;;  A,B;
;;  --- [ label = "start of sequence" ];
;;  A -> B [ label = "send message" ];
;; #+end_mscgen
;;
;; TODO: check cleanup of temp files
;; TODO: fix automatic filename generation when name not given
;; TODO: export in EPS format for LaTeX (need to convert EPS to PDF for pdflatex to use)

(defvar org-mscgen-path
  "/opt/local/bin/mscgen"
  "Complete path to the mscgen executable")

(defun org-export-blocks-format-mscgen (body &rest headers)
  "Pass block BODY to the mscgen utility creating an image.
Enclosing tags \"msc{\" and \"}\" must not appear in BODY.

Specify the path at which the image should be saved as the first
element of headers. Additional header elements are ignored and
for future use."
  (message "mscgen-formatting...")
  (let* ((args (if (cdr headers) (mapconcat 'identity (cdr headers) " "))) ;; for building hash
         (data-file (make-temp-file "org-mscgen"))                         ;; temp storage for BODY
         (hash (sha1 (prin1-to-string (list body args))))                  ;; hash (body + args)
         (raw-out-file (if headers (car headers) "out_mscgen" ))           ;; output file
         (out-file-parts (cons raw-out-file "png"))
         (out-file (concat (car out-file-parts) "_" hash "." (cdr out-file-parts)))
    (unless (file-exists-p org-mscgen-path)
      (error (format "Could not find mscgen at %s" org-mscgen-path)))
    (cond
     ((or latexp htmlp docbookp)
      ;; HTML, LaTeX and DocBook export
      (unless (file-exists-p out-file)
        (mapc ;; remove old hashed versions of this file
         (lambda (file)
           (when (and (string-match (concat (regexp-quote (car out-file-parts))
                                            "_\\([[:alnum:]]+\\)\\."
                                            (regexp-quote (cdr out-file-parts)))
                                    file)
                      (= (length (match-string 1 out-file)) 40))
             (delete-file (expand-file-name file
                                            (file-name-directory out-file)))))
         (directory-files (or (file-name-directory out-file)
                              default-directory)))
        (with-temp-file data-file (insert (concat "msc {\n" body "\n}\n")))
        (message (concat org-mscgen-path " -T png  -o " out-file " -i " data-file))
        (shell-command (concat org-mscgen-path " -T png  -o " out-file " -i " data-file)))
      (cond
       (latexp
        (format "\n#+ATTR_LaTeX: width=0.85\\textwidth\n[[file:%s]]\n" out-file))
       (t
        (format "\n[[file:%s]]\n" out-file))))
     ;; export to other formats: keep body as is
     (t (concat
	 "\n#+BEGIN_EXAMPLE\n"
	 body (if (string-match "\n$" body) "" "\n")
	 "#+END_EXAMPLE\n")))))

(org-export-blocks-add-block '(mscgen org-export-blocks-format-mscgen nil))

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

* Re: Code snippet for Message Sequence Diagram export
  2010-05-16 20:18 Code snippet for Message Sequence Diagram export Juan
@ 2010-05-17  8:13 ` Eric S Fraga
  2010-05-17 20:04   ` Juan
  0 siblings, 1 reply; 6+ messages in thread
From: Eric S Fraga @ 2010-05-17  8:13 UTC (permalink / raw)
  To: Juan; +Cc: Emacs-orgmode

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

On Sun, 16 May 2010 17:18:39 -0300, Juan <pechiar@computer.org> wrote:
> 
> Hi,
> 
> The following code adds an export block of type 'mscgen'. The block
> body will be processed by the mscgen application. Sort of works, not
> very tested yet.

[...]

Juan,

this could be very useful.  Thanks!  I do wonder, however, whether it
would make sense to have this as a org-babel language?  It would be
nice to have the images generated appear in the org file directly...

Thanks again,
eric

[-- Attachment #2: Type: text/plain, Size: 75 bytes --]

-- 
Eric S Fraga
GnuPG: 8F5C 279D 3907 E14A 5C29  570D C891 93D8 FFFC F67D

[-- Attachment #3: Type: text/plain, Size: 201 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

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

* Re: Code snippet for Message Sequence Diagram export
  2010-05-17  8:13 ` Eric S Fraga
@ 2010-05-17 20:04   ` Juan
  2010-05-17 23:04     ` Dan Davison
  0 siblings, 1 reply; 6+ messages in thread
From: Juan @ 2010-05-17 20:04 UTC (permalink / raw)
  To: e.fraga; +Cc: Emacs-orgmode

Below goes code snippet using org-babel instead of org-export.

On Mon, May 17, 2010 at 09:13:29AM +0100, Eric S Fraga wrote:
> On Sun, 16 May 2010 17:18:39 -0300, Juan <pechiar@computer.org> wrote:
> > The following code adds an export block of type 'mscgen'. The block
> > body will be processed by the mscgen application. Sort of works, not
> > very tested yet.
>
> [...]
>
> Juan,
>
> this could be very useful.  Thanks!  I do wonder, however, whether it
> would make sense to have this as a org-babel language?  It would be
> nice to have the images generated appear in the org file directly...
>
> Thanks again,
> eric

;;; org-babel-mscgen.el --- org-babel functions for mscgen evaluation

;;; TODO insert GPL header here

;;; Commentary:
;;
;; This software provides EMACS org-babel export support for message
;; sequence charts. The mscgen utility is used for processing the
;; sequence definition, and must therefore be installed in the system.
;;
;; The code is a direct modification of org-babel-ditaa
;; from the org-mode distribution.
;;
;; Mscgen is available and documented at http://www.mcternan.me.uk/mscgen/index.html
;;
;; Customize path to mscgen utility with org-mscgen-path variable
;;
;; Example:
;;
;; #+begin_src mscgen :file example.png
;;  A,B;
;;  A -> B [ label = "send message" ];
;;  B <: A [ label = "get answer" ];
;; #+end_src

;;; Code:
(require 'org-babel)

(defvar org-mscgen-path
  "/opt/local/bin/mscgen"
  "Complete path to the mscgen executable")

(org-babel-add-interpreter "mscgen")

(add-to-list 'org-babel-tangle-langs '("mscgen" "mscgen"))

(defvar org-babel-default-header-args:mscgen
  '((:results . "file") (:exports . "results"))
  "Default arguments to use when evaluating a mscgen source block.")

(defun org-babel-expand-body:mscgen (body params &optional processed-params) body)

(defun org-babel-execute:mscgen (body params)
  "Execute a block of Mscgen code with org-babel.  This function is
called by `org-babel-execute-src-block'."
  (message "executing Mscgen source code block")
  (let ((result-params (split-string (or (cdr (assoc :results params)) "")))
        (out-file (cdr (assoc :file params)))
        (cmdline (cdr (assoc :cmdline params)))
        (in-file (make-temp-file "org-babel-mscgen")))
    (unless (file-exists-p org-mscgen-path)
      (error (format "Could not find mscgen at %s" org-mscgen-path)))
    (with-temp-file in-file (insert (concat "msc {\n" body "\n}\n")))
    (message (concat org-mscgen-path " -T png  -o " out-file " -i " in-file))
    (shell-command (concat org-mscgen-path " -T png  -o " out-file " -i " in-file))
    out-file))

(defun org-babel-prep-session:mscgen (session params)
  (error "Mscgen does not support sessions"))

(provide 'org-babel-mscgen)
;;; org-babel-mscgen.el ends here

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

* Re: Code snippet for Message Sequence Diagram export
  2010-05-17 20:04   ` Juan
@ 2010-05-17 23:04     ` Dan Davison
  2010-05-18  1:24       ` Juan
  0 siblings, 1 reply; 6+ messages in thread
From: Dan Davison @ 2010-05-17 23:04 UTC (permalink / raw)
  To: Juan; +Cc: Emacs-orgmode

Juan <Pechiar@computer.org> writes:

> Below goes code snippet using org-babel instead of org-export.

Hi Juan,

Thanks, we'd be pleased to include this in org-babel. First question is:
if you haven't already, can you sign FSF copyright transfer forms for
Emacs / Org-mode?

http://orgmode.org/worg/org-contribute.php

And a couple of little questions:

- I think I'd prefer to get rid of the org-mscgen-path variable, and
  simply require that mscgen is on the user's $PATH. Is that OK or am I
  missing a reason for doing it differently?
- Is it definitely correct to automatically wrap the user's code in msg
  { ... }? I initially fell into the trap of including that inside my
  code block. I do not know the language; are there situations where the
  desired mscgen code will not be generated by wrapping everything in a
  msg { ... } block?
- If you are feeling energetic, it would be really nice to check the
  exit code from the shell-command and use org-babel-error-notify if
  necessary, similar to this fragment from org-babel-python

		     (setq exit-code (org-babel-shell-command-on-region
				      (point-min) (point-max) "python" nil 'replace (current-buffer)))
		     (buffer-string))))
	     (if (> exit-code 0) (org-babel-error-notify exit-code stderr))

  (Looks like we should be doing this in org-babel-ditaa also)

Thanks again,

Dan


>
> On Mon, May 17, 2010 at 09:13:29AM +0100, Eric S Fraga wrote:
>> On Sun, 16 May 2010 17:18:39 -0300, Juan <pechiar@computer.org> wrote:
>> > The following code adds an export block of type 'mscgen'. The block
>> > body will be processed by the mscgen application. Sort of works, not
>> > very tested yet.
>>
>> [...]
>>
>> Juan,
>>
>> this could be very useful.  Thanks!  I do wonder, however, whether it
>> would make sense to have this as a org-babel language?  It would be
>> nice to have the images generated appear in the org file directly...
>>
>> Thanks again,
>> eric
>
> ;;; org-babel-mscgen.el --- org-babel functions for mscgen evaluation
>
> ;;; TODO insert GPL header here
>
> ;;; Commentary:
> ;;
> ;; This software provides EMACS org-babel export support for message
> ;; sequence charts. The mscgen utility is used for processing the
> ;; sequence definition, and must therefore be installed in the system.
> ;;
> ;; The code is a direct modification of org-babel-ditaa
> ;; from the org-mode distribution.
> ;;
> ;; Mscgen is available and documented at http://www.mcternan.me.uk/mscgen/index.html
> ;;
> ;; Customize path to mscgen utility with org-mscgen-path variable
> ;;
> ;; Example:
> ;;
> ;; #+begin_src mscgen :file example.png
> ;;  A,B;
> ;;  A -> B [ label = "send message" ];
> ;;  B <: A [ label = "get answer" ];
> ;; #+end_src
>
> ;;; Code:
> (require 'org-babel)
>
> (defvar org-mscgen-path
>   "/opt/local/bin/mscgen"
>   "Complete path to the mscgen executable")
>
> (org-babel-add-interpreter "mscgen")
>
> (add-to-list 'org-babel-tangle-langs '("mscgen" "mscgen"))
>
> (defvar org-babel-default-header-args:mscgen
>   '((:results . "file") (:exports . "results"))
>   "Default arguments to use when evaluating a mscgen source block.")
>
> (defun org-babel-expand-body:mscgen (body params &optional processed-params) body)
>
> (defun org-babel-execute:mscgen (body params)
>   "Execute a block of Mscgen code with org-babel.  This function is
> called by `org-babel-execute-src-block'."
>   (message "executing Mscgen source code block")
>   (let ((result-params (split-string (or (cdr (assoc :results params)) "")))
>         (out-file (cdr (assoc :file params)))
>         (cmdline (cdr (assoc :cmdline params)))
>         (in-file (make-temp-file "org-babel-mscgen")))
>     (unless (file-exists-p org-mscgen-path)
>       (error (format "Could not find mscgen at %s" org-mscgen-path)))
>     (with-temp-file in-file (insert (concat "msc {\n" body "\n}\n")))
>     (message (concat org-mscgen-path " -T png  -o " out-file " -i " in-file))
>     (shell-command (concat org-mscgen-path " -T png  -o " out-file " -i " in-file))
>     out-file))
>
> (defun org-babel-prep-session:mscgen (session params)
>   (error "Mscgen does not support sessions"))
>
> (provide 'org-babel-mscgen)
> ;;; org-babel-mscgen.el ends here
>
> _______________________________________________
> Emacs-orgmode mailing list
> Please use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

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

* Re: Code snippet for Message Sequence Diagram export
  2010-05-17 23:04     ` Dan Davison
@ 2010-05-18  1:24       ` Juan
  2010-05-23 22:43         ` Juan
  0 siblings, 1 reply; 6+ messages in thread
From: Juan @ 2010-05-18  1:24 UTC (permalink / raw)
  To: Dan Davison; +Cc: Emacs-orgmode

On Mon, May 17, 2010 at 07:04:14PM -0400, Dan Davison wrote:
> Juan <Pechiar@computer.org> writes:
> > Below goes code snippet using org-babel instead of org-export.

...

> Thanks, we'd be pleased to include this in org-babel. First question is:
> if you haven't already, can you sign FSF copyright transfer forms for
> Emacs / Org-mode?
> http://orgmode.org/worg/org-contribute.php

I just sent the email to gnu.org

> And a couple of little questions:
>
> - I think I'd prefer to get rid of the org-mscgen-path variable, and
>   simply require that mscgen is on the user's $PATH. Is that OK or am I
>   missing a reason for doing it differently?

You're right. I'll get rid of it.

That variable was inherited from both ditaa (which I used as a
template) and my non-standard path (darwin-ports on mac).

> - Is it definitely correct to automatically wrap the user's code in msg
>   { ... }? I initially fell into the trap of including that inside my
>   code block. I do not know the language; are there situations where the
>   desired mscgen code will not be generated by wrapping everything in a
>   msg { ... } block?

All the mscgen script must go inside msg{ ... }. 1st version was an
org-export block, so I felt OK not having to include that every time.

But now that it's gone to org-babel -which is more source-code purist
with the literate programming halo- I'd rather make the user include
the complete mscgen source code.

Eventually (version 2), it can be made optional (check if the msc{ }
wrapper is not there and add it on the fly).

> - If you are feeling energetic, it would be really nice to check the
>   exit code from the shell-command and use org-babel-error-notify if
>   necessary

I'll look into it.

Thank you for your support!

Saludos,
.j.

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

* Re: Code snippet for Message Sequence Diagram export
  2010-05-18  1:24       ` Juan
@ 2010-05-23 22:43         ` Juan
  0 siblings, 0 replies; 6+ messages in thread
From: Juan @ 2010-05-23 22:43 UTC (permalink / raw)
  To: Dan Davison; +Cc: Emacs-orgmode

Dan,

Below is the final proposal for org-babel-mscgen.el.

Already sent form to assign@gnu.org, got no answer (I assume it is
OK).

I remade all of the code, so almost no traces from org-babel-ditaa.

On Mon, May 17, 2010 at 10:24:10PM -0300, Juan wrote:
> On Mon, May 17, 2010 at 07:04:14PM -0400, Dan Davison wrote:
> > Juan <Pechiar@computer.org> writes:
> > > Below goes code snippet using org-babel instead of org-export.

> > And a couple of little questions:
> >
> > - I think I'd prefer to get rid of the org-mscgen-path variable, and
> >   simply require that mscgen is on the user's $PATH. Is that OK or am I
> >   missing a reason for doing it differently?
>
> You're right. I'll get rid of it.

Done. Now mscgen must be accessible on exec-path.

> ...

> > - If you are feeling energetic, it would be really nice to check the
> >   exit code from the shell-command and use org-babel-error-notify if
> >   necessary
>
> I'll look into it.

Done. Now error messages from mscgen are passed to
org-babel-error-notify.

Just a question on style:

If you look at the '(unless' line below, I throw an elisp 'error' if
the user forgets to add an output file to the #+begin_src header.

Is this OK, or should I stick to org-babel-error-notify with a dummy
exit code?

Thanks & regards,
.j.

8<------------------------------------------------------------

;;; org-babel-mscgen.el --- org-babel functions for mscgen evaluation

;;; TODO insert license information
;;; Author: Juan Pechiar (juan@pechiar.com)

;;; Commentary:
;;
;; This software provides EMACS org-babel export support for message
;; sequence charts. The mscgen utility is used for processing the
;; sequence definition, and must therefore be installed in the system.
;;
;; Mscgen is available and documented at http://www.mcternan.me.uk/mscgen/index.html
;;
;; Example:
;;
;; #+begin_src mscgen :file example.png
;; msc {
;;  A,B;
;;  A -> B [ label = "send message" ];
;;  A <- B [ label = "get answer" ];
;; }
;; #+end_src

;;; Code:
(require 'org-babel)

(org-babel-add-interpreter "mscgen")

(add-to-list 'org-babel-tangle-langs '("mscgen" "mscgen"))

(defvar org-babel-default-header-args:mscgen
  '((:results . "file") (:exports . "results"))
  "Default arguments to use when evaluating a mscgen source block.")

(defun org-babel-expand-body:mscgen (body params &optional processed-params) body)

(defun org-babel-execute:mscgen (body params)
  "Execute a block of Mscgen code with org-babel.  This function is
called by `org-babel-execute-src-block'."
  (message "executing Mscgen source code block")
  (let* ((out-file (or (cdr (assoc :file params)) "output.png" ))
         exit-code
         (stderr
          (with-temp-buffer
            (insert body)
            (setq exit-code (org-babel-shell-command-on-region
                             (point-min) (point-max) (concat "mscgen -T png -o " out-file)
                             nil 'replace (current-buffer)))
            (buffer-string))))
    (unless (cdr (assoc :file params)) (setq stderr (concat stderr "\nERROR: no output file specified. Add \":file some_name.png\" to the src header" )) (error stderr))
    (if (> exit-code 0) (org-babel-error-notify exit-code stderr))
    out-file))

(defun org-babel-prep-session:mscgen (session params)
  (error "Mscgen does not support sessions"))

(provide 'org-babel-mscgen)
;;; org-babel-mscgen.el ends here

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

end of thread, other threads:[~2010-05-23 22:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-16 20:18 Code snippet for Message Sequence Diagram export Juan
2010-05-17  8:13 ` Eric S Fraga
2010-05-17 20:04   ` Juan
2010-05-17 23:04     ` Dan Davison
2010-05-18  1:24       ` Juan
2010-05-23 22:43         ` Juan

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).