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
(require '[babashka.fs :as fs])
;; :obsidian_dir, :hugo_dir
(def config (yaml/parse-string (slurp "./helpers/obsidian-sync-settings.yml")))
;; file path clean up utils
(defn remove-commas [s] (str/replace s #"," "")) ;; The French Chef Cookbook, Julia Child -> The French Chef Cookbook, Julia Child
(defn spaces-to-underscores [s] (str/replace s #"\W" "_")) ;; The French Chef Cookbook, Julia Child -> The_French_Chef_Cookbook_Julia_Child
(defn obsidian-path-to-hugo-path [path]
(->>
path
(fs/file-name)
(fs/split-ext)
(first)
(remove-commas)
(spaces-to-underscores)
(str/lower-case)
(#(str (:hugo_dir config) "/" % "/index.md"))))
(defn obsidian-path-to-title [path]
(->>
path
(fs/file-name)
(fs/split-ext)
(first)))
(defn create-parent-dir-if-needed [path]
(let [parent (fs/parent path)]
(when (not (fs/exists? parent))
(fs/create-dir parent))))
(defn extract-front-matter [content]
(->>
content
(re-find #"(?sm)^(---)(.*)(---)$")
(#(get % 2))
(#(if % (yaml/parse-string %) %))))
(defn delete-front-matter [content]
(str/replace content #"(?sm)^(---)(.*)(---)$" ""))
(defn rename-tags-field [front-matter]
(if (contains? front-matter :tags)
(set/rename-keys front-matter {:tags :cooking-tags})
front-matter))
(defn re-link [content]
(str/replace
content
#"\[\[([^\]*]*)\]\]"
(fn [[_ name]]
(str
"["
name
"](/cooking/notes/"
(->> name
(remove-commas)
(spaces-to-underscores)
(str/lower-case))
")"))))
(defn re-link-images [content]
(str/replace
content
#"!\[([^\]]*)[^\)]*\)(.*)"
"{{< image-with-caption name=\"$1\" title=\"$2\" >}}"))
;; date? 2022-08-28T12:16:09+02:00
;; last modified??
;; seo_description?
;; featured_image: plate_3.jpeg
(defn compute-fields [file]
(let [content (slurp (str file))]
{:obsidian-file file
:title (obsidian-path-to-title (str file))
:hugo-file (obsidian-path-to-hugo-path (str file))
:front-matter (rename-tags-field (extract-front-matter content))
:content (re-link-images (re-link (delete-front-matter content)))}))
(defn create-hugo-file [{:keys [hugo-file title content front-matter]}]
(create-parent-dir-if-needed hugo-file)
(->>
(str
"---\n"
(yaml/generate-string
(merge front-matter {:title title :draft false})
:dumper-options {:flow-style :block})
"---\n"
content)
(spit hugo-file)))
;; main
(def files
(->>
(fs/list-dir (:obsidian_dir config) "*.md")
(map compute-fields)))
(map create-hugo-file files)