# obsidian-sync.clj -rw-r--r-- 2.5 KiB View raw
                                                                                
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)