Skip to content

Instantly share code, notes, and snippets.

@tiensonqin
Created August 8, 2022 00:09
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 tiensonqin/96ddd5ae43657cc068bbb9d83ffe28a8 to your computer and use it in GitHub Desktop.
Save tiensonqin/96ddd5ae43657cc068bbb9d83ffe28a8 to your computer and use it in GitHub Desktop.
Sort page blocks for Logseq
;; Logseq's block order is determined by both :block/parent and :block/left.
;;
;; Let's say we have a list like this:
;; - 1
;; - 1.1
;; - 1.2
;; - 2
;;
;; Block `2`'s left is block 1, block `1.2`'s left is block `1.1`,
;; Block `1.2`'s left and parent is block `1`.
(defn sort-by-left
[blocks parent]
(let [left->blocks (reduce (fn [acc b] (assoc acc (:db/id (:block/left b)) b)) {} blocks)]
(loop [block parent
result []]
(if-let [next (get left->blocks (:db/id block))]
(recur next (conj result next))
(vec result)))))
(defn blocks->vec-tree
[blocks root]
(let [id-map (fn [m] {:db/id (:db/id m)})
root (id-map root)
parent-blocks (group-by :block/parent blocks)
sort-fn (fn [parent]
(sort-by-left (get parent-blocks parent) parent))
block-children (fn block-children [parent]
(map (fn [m]
(let [parent (id-map m)
children (-> (block-children parent)
(sort-by-left parent))]
(assoc m :block/children children)))
(sort-fn parent)))]
(block-children root)))
(defn sort-blocks
[page-db-id page-blocks]
(->> (blocks->vec-tree page-blocks {:db/id page-db-id})
(mapcat #(tree-seq map? :block/children %))
(map #(dissoc % :block/children))))
(comment
;; get sorted blocks
(let [page-name "aug 4th, 2022" ; lowercase
db datascript-db
page (d/entity db [:block/name page-name])
blocks (map #(d/pull db '[*] (:db/id %)) (:block/_page page))]
(sort-blocks (:db/id page) blocks)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment