|
|
@@ -3,14 +3,139 @@
|
|
|
(:require [frontend.worker.handler.page :as worker-page]
|
|
|
[datascript.core :as d]
|
|
|
[clojure.string :as string]
|
|
|
+ [clojure.walk :as walk]
|
|
|
[logseq.common.util.page-ref :as page-ref]
|
|
|
[frontend.worker.file.util :as wfu]
|
|
|
- [frontend.worker.file.page-rename :as page-rename]
|
|
|
[logseq.db :as ldb]
|
|
|
[logseq.common.util :as common-util]
|
|
|
+ [logseq.common.config :as common-config]
|
|
|
[logseq.graph-parser.text :as text]
|
|
|
+ [logseq.graph-parser.property :as gp-property]
|
|
|
[logseq.db.frontend.order :as db-order]))
|
|
|
|
|
|
+
|
|
|
+(defn- replace-page-ref-aux
|
|
|
+ "Unsanitized names"
|
|
|
+ [config content old-name new-name]
|
|
|
+ (let [preferred-format (common-config/get-preferred-format config)
|
|
|
+ [original-old-name original-new-name] (map string/trim [old-name new-name])
|
|
|
+ [old-ref new-ref] (map page-ref/->page-ref [old-name new-name])
|
|
|
+ [old-name new-name] (map #(if (string/includes? % "/")
|
|
|
+ (string/replace % "/" ".")
|
|
|
+ %)
|
|
|
+ [original-old-name original-new-name])
|
|
|
+ old-org-ref (and (= :org preferred-format)
|
|
|
+ (:org-mode/insert-file-link? config)
|
|
|
+ (re-find
|
|
|
+ (re-pattern
|
|
|
+ (common-util/format
|
|
|
+ "\\[\\[file:\\.*/.*%s\\.org\\]\\[(.*?)\\]\\]" old-name))
|
|
|
+ content))]
|
|
|
+ (-> (if old-org-ref
|
|
|
+ (let [[old-full-ref old-label] old-org-ref
|
|
|
+ new-label (if (= old-label original-old-name)
|
|
|
+ original-new-name
|
|
|
+ old-label)
|
|
|
+ new-full-ref (-> (string/replace old-full-ref old-name new-name)
|
|
|
+ (string/replace (str "[" old-label "]")
|
|
|
+ (str "[" new-label "]")))]
|
|
|
+ (string/replace content old-full-ref new-full-ref))
|
|
|
+ content)
|
|
|
+ (string/replace old-ref new-ref))))
|
|
|
+
|
|
|
+(defn replace-tag-ref!
|
|
|
+ [content old-name new-name]
|
|
|
+ (let [old-tag (common-util/format "#%s" old-name)
|
|
|
+ new-tag (if (re-find #"[\s\t]+" new-name)
|
|
|
+ (common-util/format "#[[%s]]" new-name)
|
|
|
+ (str "#" new-name))]
|
|
|
+ ;; hash tag parsing rules https://github.com/logseq/mldoc/blob/701243eaf9b4157348f235670718f6ad19ebe7f8/test/test_markdown.ml#L631
|
|
|
+ ;; Safari doesn't support look behind, don't use
|
|
|
+ ;; TODO: parse via mldoc
|
|
|
+ (string/replace content
|
|
|
+ (re-pattern (str "(?i)(^|\\s)(" (common-util/escape-regex-chars old-tag) ")(?=[,\\.]*($|\\s))"))
|
|
|
+ ;; case_insense^ ^lhs ^_grp2 look_ahead^ ^_grp3
|
|
|
+ (fn [[_match lhs _grp2 _grp3]]
|
|
|
+ (str lhs new-tag)))))
|
|
|
+
|
|
|
+(defn- replace-property-ref!
|
|
|
+ [content old-name new-name format]
|
|
|
+ (let [new-name (keyword (string/replace (string/lower-case new-name) #"\s+" "-"))
|
|
|
+ org-format? (= :org format)
|
|
|
+ old-property (if org-format? (gp-property/colons-org old-name) (str old-name gp-property/colons))
|
|
|
+ new-property (if org-format? (gp-property/colons-org (name new-name)) (str (name new-name) gp-property/colons))]
|
|
|
+ (common-util/replace-ignore-case content old-property new-property)))
|
|
|
+
|
|
|
+(defn- replace-old-page!
|
|
|
+ "Unsanitized names"
|
|
|
+ [config content old-name new-name format]
|
|
|
+ (when (and (string? content) (string? old-name) (string? new-name))
|
|
|
+ (-> (replace-page-ref-aux config content old-name new-name)
|
|
|
+ (replace-tag-ref! old-name new-name)
|
|
|
+ (replace-property-ref! old-name new-name format))))
|
|
|
+
|
|
|
+(defn- walk-replace-old-page!
|
|
|
+ "Unsanitized names"
|
|
|
+ [config form old-name new-name format]
|
|
|
+ (walk/postwalk (fn [f]
|
|
|
+ (cond
|
|
|
+ (and (vector? f)
|
|
|
+ (contains? #{"Search" "Label"} (first f))
|
|
|
+ (string/starts-with? (second f) (str old-name "/")))
|
|
|
+ [(first f) (string/replace-first (second f)
|
|
|
+ (str old-name "/")
|
|
|
+ (str new-name "/"))]
|
|
|
+
|
|
|
+ (string? f)
|
|
|
+ (if (= f old-name)
|
|
|
+ new-name
|
|
|
+ (replace-old-page! config f old-name new-name format))
|
|
|
+
|
|
|
+ (and (keyword f) (= (name f) old-name))
|
|
|
+ (keyword (string/replace (string/lower-case new-name) #"\s+" "-"))
|
|
|
+
|
|
|
+ :else
|
|
|
+ f))
|
|
|
+ form))
|
|
|
+
|
|
|
+(defn- rename-update-block-refs!
|
|
|
+ [refs from-id to-id]
|
|
|
+ (if to-id
|
|
|
+ (->> refs
|
|
|
+ (remove #{{:db/id from-id}})
|
|
|
+ (cons {:db/id to-id})
|
|
|
+ (distinct)
|
|
|
+ (vec))
|
|
|
+ ;; New page not exists so that we keep using the old page's block as a ref
|
|
|
+ refs))
|
|
|
+
|
|
|
+(defn replace-page-ref
|
|
|
+ "Unsanitized only"
|
|
|
+ [db config page new-name]
|
|
|
+ ;; update all pages which have references to this page
|
|
|
+ (let [to-page (ldb/get-page db new-name)
|
|
|
+ old-original-name (:block/original-name page)
|
|
|
+ blocks (:block/_refs (d/entity db (:db/id page)))
|
|
|
+ tx (->> (map (fn [{:block/keys [uuid content properties format] :as block}]
|
|
|
+ (let [content (let [content' (replace-old-page! config content old-original-name new-name format)]
|
|
|
+ (when-not (= content' content)
|
|
|
+ content'))
|
|
|
+ properties (let [properties' (walk-replace-old-page! config properties old-original-name new-name format)]
|
|
|
+ (when-not (= properties' properties)
|
|
|
+ properties'))]
|
|
|
+ (when (or content properties)
|
|
|
+ (common-util/remove-nils-non-nested
|
|
|
+ {:block/uuid uuid
|
|
|
+ :block/content content
|
|
|
+ :block/properties properties
|
|
|
+ :block/properties-order (when (seq properties)
|
|
|
+ (map first properties))
|
|
|
+ :block/refs (->> (rename-update-block-refs! (:block/refs block) (:db/id page) (:db/id to-page))
|
|
|
+ (map :db/id)
|
|
|
+ (set))})))) blocks)
|
|
|
+ (remove nil?))]
|
|
|
+ tx))
|
|
|
+
|
|
|
(defn rename-update-namespace!
|
|
|
"update :block/namespace of the renamed block"
|
|
|
[repo conn config page old-original-name new-name]
|
|
|
@@ -34,14 +159,6 @@
|
|
|
:else
|
|
|
nil)))
|
|
|
|
|
|
-(defn- rename-update-block-refs!
|
|
|
- [refs from-id to-id]
|
|
|
- (->> refs
|
|
|
- (remove #{{:db/id from-id}})
|
|
|
- (cons {:db/id to-id})
|
|
|
- (distinct)
|
|
|
- (vec)))
|
|
|
-
|
|
|
(declare rename-page-aux)
|
|
|
|
|
|
(defn- based-merge-pages!
|
|
|
@@ -67,7 +184,7 @@
|
|
|
|
|
|
(= (:block/parent block) {:db/id from-id})
|
|
|
(assoc :block/parent {:db/id to-id})))) blocks)
|
|
|
- replace-ref-tx-data (page-rename/replace-page-ref db config from-page to-page-name)
|
|
|
+ replace-ref-tx-data (replace-page-ref db config from-page to-page-name)
|
|
|
tx-data (concat blocks-tx-data replace-ref-tx-data)]
|
|
|
|
|
|
(rename-page-aux repo conn config old-name new-name
|
|
|
@@ -119,7 +236,7 @@
|
|
|
(->>
|
|
|
(concat
|
|
|
;; update page refes in block content when ref name changes
|
|
|
- (page-rename/replace-page-ref db config page new-name)
|
|
|
+ (replace-page-ref db config page new-name)
|
|
|
;; update file path
|
|
|
tx-data)
|
|
|
|