Skip to content

Instantly share code, notes, and snippets.

@jeroenvandijk
Last active May 12, 2020 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeroenvandijk/62e3a52550f3aef5b69e4f0e91b73d18 to your computer and use it in GitHub Desktop.
Save jeroenvandijk/62e3a52550f3aef5b69e4f0e91b73d18 to your computer and use it in GitHub Desktop.
Meander script to import Roam data
(require '[clojure.edn]
'[meander.epsilon :as m]
'[meander.strategy.epsilon :as m*])
(defn pp-str [data]
(with-out-str (clojure.pprint/pprint data)))
(defn pp-spit [f data]
(spit f (pp-str data)))
(defn timestamp->inst [t]
(if t
(java.util.Date. t)
"TODO-missing-timestamp"))
(def data (clojure.edn/read-string (slurp "https://gist.githubusercontent.com/jeroenvandijk/cf829fb559ee431d456e51d60aa1a243/raw/75032c8c4d58887dad1def466ea6d7319e0f437a/roam_ego.edn")))
(do
(def rewrite-export
(m*/rewrite
;; Top-level node, doesn't have string, but always has "title"
{(m/some "title") ?node-title
"create-email" ?create-email
"create-time" ?create-time
"edit-time" ?edit-time
"edit-email" ?edit-email
"children" ?node-children}
#_{:other-top !others}
{:create/email ?create-email
:create/time (m/app timestamp->inst ?create-time )
:edit/time ?edit-time
:edit/email ?edit-email
;; Top-level node misses uid
:block/uid (m/app (constantly "TODO-uid") nil)
:node/title ?node-title
:node/children ?node-children}
{ ;; Child-node doesn't have a title, but always has a text node
(m/some "string") ?node-string
"uid" ?uid
;; Not sure about edit and create, sometimes they are missing
"create-email" ?create-email
"create-time" (m/app timestamp->inst ?create-time )
"edit-time" ?edit-time
"edit-email" ?edit-email
"heading" !node-heading
"children" ?node-children}
{:create/email ?create-email
:create/time ?create-time
:edit/time ?edit-time
:edit/email ?edit-email
:node/heading !node-heading
:node/string ?node-string
:block/uid ?uid
:node/children ?node-children}
;; Images
{(m/some "props")
{(m/some "image-size")
{?image-url
{"width" ?image-width
"height" ?image-height
}}}}
{:image/url ?image-url
:image/width ?image-width
:image/height ?image-height}))
(def rewrite-all
(m*/bottom-up
(m*/attempt rewrite-export)))
(pp-spit "output.edn" #_:others (rewrite-all data)))
;; Still missing:
;; text-align
;; emoji
;;; emojis
; diagram
;; https://github.com/athensresearch/athens/blob/master/src/cljs/athens/db.cljs#L8
(def str-kw-mappings
"Maps attributes from \"Export All as JSON\" to original datascript attributes."
{"children" :block/children
"create-email" :create/email
"create-time" :create/time
"edit-email" :edit/email
"edit-time" :edit/time
"email" :user/email
"emoji" :ent/emoji
"emojis" :ent/emojis
"props" :block/props
"string" :block/string
"text-align" :block/text-align
"time" :create/time ;; emojis
"title" :node/title
"uid" :block/uid
;"users" nil
"heading" :block/heading
"id" :block/uid
"from" :block/uid
"to" :block/uid
"member-ids" [:array :block/uid]
"users" [:array :user]})
@noprompt
Copy link

Try starting with this:

(defn rewrite-data [data]
  (m/rewrite data
    {"title" (m/some ?node-title)
     "create-email" ?create-email
     "create-time" ?create-time
     "edit-time" ?edit-time
     "edit-email" ?edit-email       
     "children" (m/seqable (m/cata !node-children) ...)}
    {:create/email ?create-email
     :create/time (m/app timestamp->inst ?create-time )
     :edit/time  ?edit-time
     :edit/email ?edit-email
     :block/uid (m/app (constantly "TODO-uid") nil)
     :node/title ?node-title       
     :node/children [!node-children ...]}
    
    {;; Child-node doesn't have a title, but always has a text node
     "string" (m/some ?node-string)
     "uid" ?uid
     ;; Not sure about edit and create, sometimes they are missing
     "create-email" ?create-email
     "create-time" (m/app timestamp->inst ?create-time ) 
     "edit-time" ?edit-time
     "edit-email" ?edit-email
     "heading" ?node-heading
     "children" (m/seqable (m/cata !node-children) ...)}
    {:create/email ?create-email
     :create/time ?create-time
     :edit/time  ?edit-time
     :edit/email ?edit-email
     :node/heading ?node-heading
     :node/string ?node-string
     :block/uid ?uid
     :node/children [!node-children ...]}

    ;; Images
    {"props"
     {"image-size"
      {?image-url {"width" (m/some ?image-width)
                   "height" (m/some ?image-height)}}}}
    {:image/url ?image-url
     :image/width ?image-width
     :image/height ?image-height}

    ;; Everything else
    ?x
    ?x))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment