Skip to content

Commit 287ad14

Browse files
committed
Add display of SVG images in REPL.
1 parent d71cca7 commit 287ad14

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

doc/haskell-mode.texi

+37
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,43 @@ Or @kbd{C-c C-v}:
19391939
There you can choose `haskell-mode`, for example, to pretty print the
19401940
output as Haskell.
19411941

1942+
@subsection @acronym{SVG} images rendering
1943+
1944+
@cindex Rendering SVG images
1945+
@cindex SVG images, rendering
1946+
@cindex Images, rendering SVG images
1947+
1948+
If you are working on @acronym{SVG} images, you can instruct Emacs to
1949+
render the image as the output of an image producing command at the
1950+
@acronym{REPL}@.
1951+
1952+
The following example uses the @code{diamgrams} library with the default
1953+
@acronym{SVG} backend to produce a circle:
1954+
1955+
@example
1956+
@{-# LANGUAGE OverloadedStrings #-@}
1957+
1958+
import Diagrams.Prelude
1959+
import Diagrams.Backend.SVG
1960+
1961+
myCircle :: Diagram B
1962+
myCircle = circle 1 # lc purple # fc yellow
1963+
1964+
circle = renderDia SVG (SVGOptions (mkWidth 250) Nothing "" [] True) myCircle
1965+
@end example
1966+
1967+
@findex haskell-svg-toggle-render-images
1968+
1969+
After enabling @acronym{SVG} rendering with @kbd{M-x
1970+
haskell-svg-toggle-render-images}, if you load the above code and type
1971+
@code{circle} at the @acronym{REPL}, you will see the rendered circle
1972+
instead of the @acronym{XML} representation of the image.
1973+
1974+
@vindex haskell-svg-render-images
1975+
1976+
This feature can be enabled by default by setting the customization
1977+
variable @code{haskell-svg-render-images} to a non-nil value.
1978+
19421979
@subsection Presentations
19431980

19441981
If you have the @file{present} package installed, you can use the following

haskell-repl.el

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
(require 'cl-lib)
2121
(require 'haskell-interactive-mode)
2222
(require 'haskell-collapse)
23+
(require 'haskell-svg)
2324

2425
(defun haskell-interactive-handle-expr ()
2526
"Handle an inputted expression at the REPL."
@@ -116,7 +117,7 @@
116117
(let ((inhibit-read-only t))
117118
(delete-region (1+ haskell-interactive-mode-prompt-start) (point))
118119
(goto-char (point-max))
119-
(insert (haskell-fontify-as-mode text
120+
(insert (haskell-fontify-as-mode (haskell-svg-maybe-render-images text)
120121
haskell-interactive-mode-eval-mode))
121122
(when haskell-interactive-mode-collapse
122123
(haskell-hide-toggle)))))

haskell-svg.el

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
;;; haskell-svg.el --- SVG Rendering -*- lexical-binding: t -*-
2+
3+
;; Copyright (c) 2018 Federico Beffa. All rights reserved.
4+
5+
;; This file is free software; you can redistribute it and/or modify
6+
;; it under the terms of the GNU General Public License as published by
7+
;; the Free Software Foundation; either version 3, or (at your option)
8+
;; any later version.
9+
10+
;; This file is distributed in the hope that it will be useful,
11+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
;; GNU General Public License for more details.
14+
15+
;; You should have received a copy of the GNU General Public License
16+
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
;;; Code:
19+
20+
(defcustom haskell-svg-render-images nil
21+
"Replace SVG image text with actual images."
22+
:group 'haskell-interactive
23+
:type 'boolean)
24+
25+
(defconst haskell-svg-supported (image-type-available-p 'svg)
26+
"Defines if SVG images are supported by this instance of Emacs.")
27+
28+
29+
30+
(defun haskell-svg-render-images-p ()
31+
"Shall we render SVG images?"
32+
(and haskell-svg-supported (display-images-p) haskell-svg-render-images))
33+
34+
(defun haskell-svg-maybe-render-images (text)
35+
"Render SVG images if desired and supported, or terurn the
36+
input unmodified."
37+
(if (haskell-svg-render-images-p)
38+
(haskell-svg-render-images text)
39+
text))
40+
41+
(defun haskell-svg-render-images (text)
42+
"Replace an SVG image text with an actual image."
43+
(with-temp-buffer
44+
(insert text)
45+
(goto-char (point-min))
46+
(when (re-search-forward
47+
"\"?<\\?xml\\(.\\|\n\\|\r\\)* PUBLIC \"-//W3C//DTD SVG [0-9]\.[0-9]//EN\\(.\\|\n\\|\r\\)*</svg>\"?"
48+
nil t)
49+
(let ((svg-string (match-string 0))
50+
(begin (match-beginning 0))
51+
(end (match-end 0)))
52+
(delete-region begin end)
53+
(goto-char begin)
54+
(insert-image (create-image svg-string nil t) "SVG image")))
55+
(buffer-substring (point-min) (point-max))))
56+
57+
(defun haskell-svg-toggle-render-images ()
58+
"Toggle rendering of SVG images at the REPL output."
59+
(interactive)
60+
(setq haskell-svg-render-images (not haskell-svg-render-images)))
61+
62+
63+
64+
(provide 'haskell-svg)
65+
66+
;;; haskell-svg.el ends here

0 commit comments

Comments
 (0)