Просмотр исходного кода

fix: duplicate block ids in same file (#8657)

fix: duplicate block ids in the same file
Tienson Qin 3 лет назад
Родитель
Сommit
3372b3bfbd

+ 26 - 5
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -592,6 +592,23 @@
                 (assoc :block/updated-at updated-at))]
                 (assoc :block/updated-at updated-at))]
     (dissoc block :title :body :anchor)))
     (dissoc block :title :body :anchor)))
 
 
+(defn fix-duplicate-id
+  [block]
+  (println "Logseq will assign a new id for this block: " block)
+  (-> block
+      (assoc :uuid (d/squuid))
+      (update :properties dissoc :id)
+      (update :properties-text-values dissoc :id)
+      (update :properties-order #(vec (remove #{:id} %)))
+      (update :content (fn [c]
+                         (let [replace-str (re-pattern
+                                            (str
+                                             "\n*\\s*"
+                                             (if (= :markdown (:format block))
+                                               (str "id" gp-property/colons " " (:uuid block))
+                                               (str (gp-property/colons-org "id") " " (:uuid block)))))]
+                           (string/replace-first c replace-str ""))))))
+
 (defn extract-blocks
 (defn extract-blocks
   "Extract headings from mldoc ast.
   "Extract headings from mldoc ast.
   Args:
   Args:
@@ -606,6 +623,7 @@
   (let [encoded-content (utf8/encode content)
   (let [encoded-content (utf8/encode content)
         [blocks body pre-block-properties]
         [blocks body pre-block-properties]
         (loop [headings []
         (loop [headings []
+               block-ids #{}
                blocks (reverse blocks)
                blocks (reverse blocks)
                timestamps {}
                timestamps {}
                properties {}
                properties {}
@@ -621,19 +639,22 @@
                 (paragraph-timestamp-block? block)
                 (paragraph-timestamp-block? block)
                 (let [timestamps (extract-timestamps block)
                 (let [timestamps (extract-timestamps block)
                       timestamps' (merge timestamps timestamps)]
                       timestamps' (merge timestamps timestamps)]
-                  (recur headings (rest blocks) timestamps' properties body))
+                  (recur headings block-ids (rest blocks) timestamps' properties body))
 
 
                 (gp-property/properties-ast? block)
                 (gp-property/properties-ast? block)
                 (let [properties (extract-properties (second block) (assoc user-config :format format))]
                 (let [properties (extract-properties (second block) (assoc user-config :format format))]
-                  (recur headings (rest blocks) timestamps properties body))
+                  (recur headings block-ids (rest blocks) timestamps properties body))
 
 
                 (heading-block? block)
                 (heading-block? block)
                 (let [block' (construct-block block properties timestamps body encoded-content format pos-meta with-id? options)
                 (let [block' (construct-block block properties timestamps body encoded-content format pos-meta with-id? options)
-                      block'' (assoc block' :macros (extract-macros-from-ast (cons block body)))]
-                  (recur (conj headings block'') (rest blocks) {} {} []))
+                      block'' (assoc block' :macros (extract-macros-from-ast (cons block body)))
+                      [block-ids block] (if (block-ids (:uuid block''))
+                                          [block-ids (fix-duplicate-id block'')]
+                                          [(conj block-ids (:uuid block'')) block''])]
+                  (recur (conj headings block) block-ids (rest blocks) {} {} []))
 
 
                 :else
                 :else
-                (recur headings (rest blocks) timestamps properties (conj body block))))
+                (recur headings block-ids (rest blocks) timestamps properties (conj body block))))
             [(-> (reverse headings)
             [(-> (reverse headings)
                  sanity-blocks-data)
                  sanity-blocks-data)
              body
              body

+ 25 - 0
deps/graph-parser/test/logseq/graph_parser/block_test.cljs

@@ -13,6 +13,31 @@
     properties)
     properties)
    user-config))
    user-config))
 
 
+(deftest test-fix-duplicate-id
+  (are [x y]
+      (let [result (gp-block/fix-duplicate-id x)]
+        (and (:uuid result)
+             (not= (:uuid x) (:uuid result))
+             (= (select-keys result
+                             [:properties :content :properties-text-values :properties-order]) y)))
+    {:properties {:id "63f199bc-c737-459f-983d-84acfcda14fe"}, :tags [], :format :markdown, :meta {:start_pos 51, :end_pos 101}, :macros [], :unordered true, :content "bar\nid:: 63f199bc-c737-459f-983d-84acfcda14fe", :properties-text-values {:id "63f199bc-c737-459f-983d-84acfcda14fe"}, :level 1, :uuid #uuid "63f199bc-c737-459f-983d-84acfcda14fe", :properties-order [:id]}
+    {:properties {},
+     :content "bar",
+     :properties-text-values {},
+     :properties-order []}
+
+    {:properties {:id "63f199bc-c737-459f-983d-84acfcda14fe"}, :tags [], :format :org, :meta {:start_pos 51, :end_pos 101}, :macros [], :unordered true, :content "bar\n:id: 63f199bc-c737-459f-983d-84acfcda14fe", :properties-text-values {:id "63f199bc-c737-459f-983d-84acfcda14fe"}, :level 1, :uuid #uuid "63f199bc-c737-459f-983d-84acfcda14fe", :properties-order [:id]}
+    {:properties {},
+     :content "bar",
+     :properties-text-values {},
+     :properties-order []}
+
+    {:properties {:id "63f199bc-c737-459f-983d-84acfcda14fe"}, :tags [], :format :markdown, :meta {:start_pos 51, :end_pos 101}, :macros [], :unordered true, :content "bar\n  \n  id:: 63f199bc-c737-459f-983d-84acfcda14fe\nblock body", :properties-text-values {:id "63f199bc-c737-459f-983d-84acfcda14fe"}, :level 1, :uuid #uuid "63f199bc-c737-459f-983d-84acfcda14fe", :properties-order [:id]}
+    {:properties {},
+     :content "bar\nblock body",
+     :properties-text-values {},
+     :properties-order []}))
+
 (deftest test-extract-properties
 (deftest test-extract-properties
   (are [x y] (= (:properties (extract-properties x {})) y)
   (are [x y] (= (:properties (extract-properties x {})) y)
        ;; Built-in properties
        ;; Built-in properties