-
Notifications
You must be signed in to change notification settings - Fork 2
/
legend.clj
78 lines (67 loc) · 2.44 KB
/
legend.clj
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
;;; 2D vector graphics for markings on keycaps.
(ns dmote-keycap.legend
(:require [clojure.string :refer [join]]
[clojure.java.io :as io]
[clojure.java.shell :refer [sh]]
[hiccup2.core :refer [html]]))
;;;;;;;;;;;;;;
;; Internal ;;
;;;;;;;;;;;;;;
(defn- format-css
"Present a Clojure map as a CSS-like style specification."
[mapping]
(join ";" (for [[k v] mapping] (str (name k) ":" v))))
(defn- format-options
[[k v]]
(if (map? v)
[k (format-css v)]
[k (str v)]))
(defn- text-svg
"A string representing an SVG image with a text element.
The nominal size of this document, and positions within it,
are based on the assumption that OpenSCAD will display elements
from the SVG file even if they fall outside the viewbox."
[text-content text-options]
(html
[:svg
{:xmlns "http://www.w3.org/2000/svg"
:width "1mm"
:height "1mm"
:viewBox "0 0 1 1"
:version "1.1"}
[:text
(into {} (map format-options text-options))
text-content]]))
(defn- path-filename [basename] (str basename "_path.svg"))
(defn- convert-to-plain-svg
"Simplify text elements in an SVG file to paths.
This requires Inkscape 1 and needs input and output file paths.
It makes the content more readable to OpenSCAD."
[in out]
(let [cmd ["inkscape" in "--export-plain-svg" "--export-text-to-path"
"--export-filename" out]
status (:exit (apply sh cmd))]
(when-not (zero? status)
(throw (ex-info "File conversion with Inkscape failed"
{:command cmd, :exit-status status})))
out))
;;;;;;;;;;;;;;;
;; Interface ;;
;;;;;;;;;;;;;;;
(defn make-importable
"Author an SVG file from another SVG. Return the new filename."
[filepath-fn basename filepath-text]
(let [filename-out (path-filename basename)]
(convert-to-plain-svg filepath-text (filepath-fn filename-out))
filename-out))
(defn make-from-char
"Author an SVG file from a string, with an intermediate artefact.
Create directories to hold the file. Return only its name as a string."
[filepath-fn basename text-content text-options]
(let [filepath-text (filepath-fn (str basename "_text.svg"))
filename-out (path-filename basename)
filepath-out (filepath-fn filename-out)]
(->> filepath-out io/file .getParentFile .mkdirs)
(spit filepath-text (text-svg text-content text-options))
(convert-to-plain-svg filepath-text filepath-out)
filename-out))