mirror of
https://github.com/logseq/logseq.git
synced 2026-05-04 19:06:21 +00:00
feat: export as roam json
This commit is contained in:
84
src/main/frontend/external/roam_export.cljs
vendored
Normal file
84
src/main/frontend/external/roam_export.cljs
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
(ns frontend.external.roam-export
|
||||
(:require [clojure.string :as str]
|
||||
[clojure.set :as s]
|
||||
[datascript.core :as d]
|
||||
[frontend.state :as state]
|
||||
|
||||
[frontend.db :as db]
|
||||
[clojure.walk :as walk]))
|
||||
|
||||
(def todo-marker-regex
|
||||
#"^(NOW|LATER|TODO|DOING|WAITING|WAIT|CANCELED|CANCELLED|STARTED|IN-PROGRESS)")
|
||||
|
||||
(def done-marker-regex #"^DONE")
|
||||
|
||||
(def nano-char-range "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
|
||||
(defn- nano-id-char []
|
||||
(rand-nth nano-char-range))
|
||||
|
||||
(defn nano-id []
|
||||
(->> (repeatedly 9 nano-id-char)
|
||||
(str/join)))
|
||||
|
||||
(defn uuid->uid-map []
|
||||
(let [conn (db/get-conn (state/get-current-repo))]
|
||||
(->> conn
|
||||
(d/q '[:find (pull ?r [:block/uuid])
|
||||
:in $
|
||||
:where
|
||||
[?b :block/refs ?r]])
|
||||
(map (comp :block/uuid first))
|
||||
(distinct)
|
||||
(map (fn [uuid] [uuid (nano-id)]))
|
||||
(into {}))))
|
||||
|
||||
(defn update-content [content uuid->uid-map]
|
||||
(let [uuids (keys uuid->uid-map)]
|
||||
(reduce
|
||||
(fn [acc uuid]
|
||||
(if (str/includes? acc (str uuid))
|
||||
(str/replace acc (str uuid) (get uuid->uid-map uuid))
|
||||
acc))
|
||||
content
|
||||
uuids)))
|
||||
|
||||
(defn update-uid [{:block/keys [uuid content] :as b}
|
||||
uuid->uid-map]
|
||||
(cond-> b
|
||||
(contains? uuid->uid-map uuid)
|
||||
(assoc :block/uid (get uuid->uid-map uuid))
|
||||
|
||||
(some (fn [id] (str/includes? (str content) (str id))) (keys uuid->uid-map))
|
||||
(update :block/content #(update-content % uuid->uid-map))))
|
||||
|
||||
(defn update-todo [{:block/keys [content] :as block}]
|
||||
(if content
|
||||
(update block :block/content
|
||||
(fn [c]
|
||||
(-> c
|
||||
(str/replace todo-marker-regex "{{[[TODO]]}}")
|
||||
(str/replace done-marker-regex "{{[[DONE]]}}"))))
|
||||
block))
|
||||
|
||||
(defn traverse
|
||||
[keyseq vec-tree]
|
||||
(let [uuid->uid-map (uuid->uid-map)]
|
||||
(walk/postwalk
|
||||
(fn [x]
|
||||
(cond
|
||||
(and (map? x) (contains? x :block/uuid))
|
||||
(-> x
|
||||
|
||||
(update-uid uuid->uid-map)
|
||||
|
||||
(update-todo)
|
||||
|
||||
(s/rename-keys {:block/original-name :page/title
|
||||
:block/content :block/string})
|
||||
|
||||
(select-keys keyseq))
|
||||
|
||||
:else
|
||||
x))
|
||||
vec-tree)))
|
||||
Reference in New Issue
Block a user