-
-
Notifications
You must be signed in to change notification settings - Fork 123
/
scimax-inkscape.el
200 lines (174 loc) · 6.37 KB
/
scimax-inkscape.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
;;; scimax-inkscape.el --- Using inkscape in org-mode
;;; Commentary:
;;
;; This library provides a new org-mode link for inkscape svg files. When you
;; click on an inkscape link, it will open the figure in inkscape. A thumbnail
;; image will be placed on the inkscape link.
;;
;; Export to HTML:
;; (browse-url (let ((org-export-before-processing-hook '(scimax-inkscape-preprocess)))
;; (org-html-export-to-html)))
;;
;; (org-open-file (let ((org-export-before-processing-hook '(scimax-inkscape-preprocess)))
;; (org-latex-export-to-pdf)))
;;
;; inkscape does not allow you to create empty files. We save the template in a
;; variable and create them on demand.
(defcustom scimax-inkscape-thumbnail-width 300
"Width of thumbnails in pts."
:group 'scimax-inkscape
:type 'integer)
(defcustom scimax-inkscape-template-svg
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
xmlns:cc=\"http://creativecommons.org/ns#\"
xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"
xmlns:svg=\"http://www.w3.org/2000/svg\"
xmlns=\"http://www.w3.org/2000/svg\"
xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"
xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"
width=\"6in\"
height=\"4in\"
viewBox=\"0 100 152.4 201.6\"
version=\"1.1\"
id=\"svg8\"
inkscape:version=\"0.92.2 (5c3e80d, 2017-08-06)\"
sodipodi:docname=\"drawing.svg\">
<defs
id=\"defs2\" />
<sodipodi:namedview
id=\"base\"
pagecolor=\"#ffffff\"
bordercolor=\"#666666\"
borderopacity=\"1.0\"
inkscape:pageopacity=\"0.0\"
inkscape:pageshadow=\"2\"
inkscape:zoom=\"1\"
inkscape:cx=\"400\"
inkscape:cy=\"214.9\"
inkscape:document-units=\"in\"
inkscape:current-layer=\"layer1\"
showgrid=\"false\"
units=\"in\"
inkscape:window-width=\"1080\"
inkscape:window-height=\"675\"
inkscape:window-x=\"0\"
inkscape:window-y=\"78\"
inkscape:window-maximized=\"0\"
inkscape:lockguides=\"true\"
fit-margin-top=\"0\"
fit-margin-left=\"0\"
fit-margin-right=\"0\"
fit-margin-bottom=\"0\" />
<metadata
id=\"metadata5\">
<rdf:RDF>
<cc:Work
rdf:about=\"\">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label=\"Layer 1\"
inkscape:groupmode=\"layer\"
id=\"layer1\"
transform=\"translate(0,0)\" />
</svg>
"
"Blank document for inkscape. You cannot create a file at the
command line, so we put this template in and open it. This one works for Inkscape 0.92.2"
:group 'scimax-inkscape
:type 'string)
(defun scimax-inkscape-open (path &optional _)
"Open the PATH in inkscape.
On an inkscape link, make a new file if needed. When used on a
file link, if `org-open-non-existing-files' is non-nil make a new
file if needed."
(interactive)
(unless (f-ext-p path "svg") (error "Must be an svg file."))
(unless (file-exists-p path)
(with-temp-file path
(insert scimax-inkscape-template-svg)))
(let ((display-buffer-alist '(("*Async Shell Command*" . (display-buffer-no-window . ())))))
(shell-command (format "inkscape %s &" path))))
(defun scimax-inkscape-thumbnail (start end path bracketp)
"Put a thumbnail on an inkscape link."
(let (img ov)
(when (and
;; got a path
path
;; it is an image
(org-string-match-p (image-file-name-regexp) path)
;; and it exists
(f-exists? path)
;; and there is no overlay here.
(not (ov-at start)))
(setq img (create-image
(expand-file-name path)
nil nil
:background "lightgray"))
(setq ov (make-overlay start end))
(overlay-put ov 'display img)
(overlay-put ov 'face 'default)
(overlay-put ov 'org-image-overlay t)
(overlay-put ov 'modification-hooks
(list
`(lambda (&rest args)
(org-display-inline-remove-overlay ,ov t ,start ,end))))
(push ov org-inline-image-overlays))))
(defun scimax-inkscape-redraw-thumbnails (&optional include-linked refresh beg end)
"Use font-lock to redraw the links."
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(org-restart-font-lock)))
;; This gets the thumbnails to be redrawn with inline image toggling.
(advice-add 'org-display-inline-images :after 'scimax-inkscape-redraw-thumbnails)
(defun scimax-inkscape-preprocess (backend)
"Preprocessing function to run in `org-export-before-processing-hook'.
Here are two examples:
(browse-url (let ((org-export-before-processing-hook '(scimax-inkscape-preprocess)))
(org-html-export-to-html)))
(org-open-file (let ((org-export-before-processing-hook '(scimax-inkscape-preprocess)))
(org-latex-export-to-pdf)))"
(let ((links (reverse (org-element-map (org-element-parse-buffer) 'link
(lambda (link)
(when (string= (org-element-property :type link) "inkscape")
link))))))
(cl-loop for link in links
do
(goto-char (org-element-property :begin link))
(re-search-forward "inkscape:" (org-element-property :end link))
(replace-match "file:"))))
(org-link-set-parameters
"inkscape"
:follow 'scimax-inkscape-open
:help-echo "Click to open in inkscape."
:activate-func 'scimax-inkscape-thumbnail
:export (lambda (path desc backend)
;; You need to use the `scimax-inkscape-preprocess' function in a hook for
;; more advanced export options like captions.
(cond
((eq 'latex backend)
(format "\\includesvg{%s}" path))
((eq 'html backend)
(format "<img src=\"%s\"" path)))))
(defun scimax-inkscape-insert-drawing (path)
"Convenience function to insert a drawing with filename PATH."
(interactive "sFilename: ")
(insert (format "inkscape:%s" path)))
;; * Use file links instead
;; from https://github.com/jkitchin/scimax/issues/382
;; This leverages other org-capabilities, e.g. you can use captions, attributes.
(add-to-list 'org-file-apps '("\\.svg\\'" . scimax-inkscape-open))
;; Load this library if you want thumbnails on file links: `scimax-link-thumbnail'
;; Alternatively, you can also try this.
;; (org-link-set-parameters
;; "file"
;; :activate-func 'scimax-inkscape-thumbnail)
(provide 'scimax-inkscape)
;;; scimax-inkscape.el ends here