1

I'm the maintainer of puml-mode, a major mode for editing PlantUML files. It works by submitting the content of the current buffer to an external Java process, PlantUML, which then outputs an image to stdout. This image is then put in a newly created buffer to display.

While it correctly works for both SVG and ASCII art outputs, when I try to produce a PNG something goes wrong and the new buffer shows empty, with no error messages whatsoever. The weird thing is that when I C-c C-c in the image buffer, I actually see the PNG as text, so the image is supposedly properly loaded.

When I manually open PNG files they correctly display as images.

Here's the relevant part of the code:

(defun puml-is-image-output-p ()
  "Return true if the diagram output format is an image, false if it's text based."
  (not (equalp 'utxt
               (puml-output-type)))) ;; << feature detection, either 'png 'svg or 'utxt

(defun puml-preview-sentinel (ps event)
  "For the PlantUML process (as PS) reacts on the termination event (as EVENT)."
  (if (equal event "finished\n")
      (progn
        (switch-to-buffer puml-preview-buffer)
        (when (and (display-images-p)
                   (puml-is-image-output-p))
          (image-mode)))
    (warn "PUML Preview failed: %s" event)))
  • While not exactly an answer to your question. Is there any problem in actually storing the output of planetuml to a file and displaying it? – Iqbal Ansari Sep 25 '15 at 14:45
  • @IqbalAnsari that would introduce some maintenance concerns (e.g. cleanup) which I would rather avoid – skuro Sep 26 '15 at 7:21
2

Let bound coding-system-for-read to raw-text or no-conversion in function starting the process for getting png data. This will instruct emacs to treat the process output as raw bytes.

Looking at your code in github it seems the puml-preview starts the planetuml process, change its definition as follows

(defun puml-preview ()
  "Preview diagram."
  (interactive)
  (let ((b (get-buffer puml-preview-buffer)))
    (when b
      (kill-buffer b)))
  (let ((process-connection-type nil)
        (buf (get-buffer-create puml-preview-buffer))
        (coding-system-for-read 'raw-text))
    (let ((ps (start-process "PUML" buf
                             "java" "-jar" (shell-quote-argument puml-plantuml-jar-path)
                             (puml-output-type-opt) "-p")))
      (process-send-region ps (point-min) (point-max))
      (process-send-eof ps)
      (set-process-sentinel ps 'puml-preview-sentinel))))
  • That was it! Just an extra note: I also had to let (coding-system-for-write 'binary), but your lead was simply essential – skuro Sep 26 '15 at 7:20
  • Glad I could help. I don't think you need to set coding-system-for-write unless you are saving the image file – Iqbal Ansari Sep 26 '15 at 7:38
  • Testing it by hand, without setting it for write it would still display a blank buffer – skuro Sep 26 '15 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.