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

fix: CJK hashtag update failure

Junyi Du 3 лет назад
Родитель
Сommit
8dfa8dfb49

+ 8 - 3
src/main/frontend/handler/page.cljs

@@ -242,9 +242,14 @@
         new-tag (if (re-find #"[\s\t]+" new-name)
                   (util/format "#[[%s]]" new-name)
                   (str "#" new-name))]
-    (-> (util/replace-ignore-case content (str "^" old-tag "\\b") new-tag)
-        (util/replace-ignore-case (str " " old-tag " ") (str " " new-tag " "))
-        (util/replace-ignore-case (str " " old-tag "$") (str " " new-tag)))))
+    ;; 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)(" (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]

+ 10 - 9
src/main/frontend/util.cljc

@@ -532,17 +532,18 @@
          (str prefix new-value)))
      s)))
 
-(defonce default-escape-chars "[]{}().+*?|")
+(defonce escape-chars "[]{}().+*?|")
+
+(defn escape-regex-chars
+  "Escapes characters in string `old-value"
+  [old-value]
+  (reduce (fn [acc escape-char]
+            (string/replace acc escape-char (str "\\" escape-char)))
+          old-value escape-chars))
 
 (defn replace-ignore-case
-  [s old-value new-value & [escape-chars]]
-  (let [escape-chars (or escape-chars default-escape-chars)
-        old-value (if (string? escape-chars)
-                    (reduce (fn [acc escape-char]
-                              (string/replace acc escape-char (str "\\" escape-char)))
-                            old-value escape-chars)
-                    old-value)]
-    (string/replace s (re-pattern (str "(?i)" old-value)) new-value)))
+  [s old-value new-value]
+  (string/replace s (re-pattern (str "(?i)" (escape-regex-chars old-value))) new-value))
 
 ;; copy from https://stackoverflow.com/questions/18735665/how-can-i-get-the-positions-of-regex-matches-in-clojurescript
 #?(:cljs

+ 36 - 13
src/test/frontend/handler/page_test.cljs

@@ -68,23 +68,46 @@
   (are [x y] (= (let [[content old-name new-name] x]
                   (page-handler/replace-tag-ref! content old-name new-name))
                 y)
-       ["#foo" "foo" "bar"] "#bar"
-       ["#foo" "foo" "new bar"] "#[[new bar]]"
+    ["#foo" "foo" "bar"] "#bar"
+    ["#foo" "foo" "new bar"] "#[[new bar]]"
 
-       ["bla #foo bla" "foo" "bar"] "bla #bar bla"
-       ["bla #foo bla" "foo" "new bar"] "bla #[[new bar]] bla"
+    ["bla #foo bla" "foo" "bar"] "bla #bar bla"
+    ["bla #foo bla" "foo" "new bar"] "bla #[[new bar]] bla"
 
-       ["bla #foo" "foo" "bar"] "bla #bar"
-       ["bla #foo" "foo" "new bar"] "bla #[[new bar]]"
+    ["bla #foo" "foo" "bar"] "bla #bar"
+    ["bla #foo" "foo" "new bar"] "bla #[[new bar]]"
 
-       ["#foo #foobar bar#foo #foo" "foo" "bar"]
-       "#bar #foobar bar#foo #bar"
-       
-       ["#foo #foobar bar#foo #foo" "foo" "new bar"]
-       "#[[new bar]] #foobar bar#foo #[[new bar]]"
+    ["#foo #foobar" "foo" "bar"]
+    "#bar #foobar"
 
-       ["#logseq/foo #logseq/foobar bar#logseq/foo #logseq/foo" "logseq/foo" "logseq/bar"]
-       "#logseq/bar #logseq/foobar bar#logseq/foo #logseq/bar"))
+    ["#foo #foobar bar#foo #foo" "foo" "bar"]
+    "#bar #foobar bar#foo #bar"
+
+    ["#foo #foobar bar#foo #foo,," "foo" "bar"]
+    "#bar #foobar bar#foo #bar,,"
+
+    ["#foo #foobar bar#foo #foo #foo ball" "foo" "bar"]
+    "#bar #foobar bar#foo #bar #bar ball"
+
+    ["#foo #foobar bar#foo #foo\t#foo ball" "foo" "bar"]
+    "#bar #foobar bar#foo #bar\t#bar ball"
+
+    ["#foo #foobar bar#foo #foo" "foo" "new bar"]
+    "#[[new bar]] #foobar bar#foo #[[new bar]]"
+
+    ["#logseq/foo #logseq/foobar bar#logseq/foo #logseq/foo" "logseq/foo" "logseq/bar"]
+    "#logseq/bar #logseq/foobar bar#logseq/foo #logseq/bar"
+
+    ;; #6451
+    ["#中文" "中文" "中文2"] "#中文2"
+    ["#2中文" "2中文" "中文234"] "#中文234"
+    ["#2中文2" "2中文2" "中文1999"] "#中文1999"
+    ["#2中文,SLKDF" "2中文" "中文1999"] "#2中文,SLKDF"
+    ["#2中文, SLKDF" "2中文" "中文1999"] "#中文1999, SLKDF"
+    ["#2中文看来减肥了" "2中文" "中文1999"] "#2中文看来减肥了"
+    ["两份健康 #2中文 看来减肥了" "2中文" "中文1999"] "两份健康 #中文1999 看来减肥了"
+    ["sdaflk  #2中文   看asdf了" "2中文" "中文1999"] "sdaflk  #中文1999   看asdf了"
+    ["sdaflk  #2中文" "2中文" "中文1999"] "sdaflk  #中文1999"))
 
 (deftest test-replace-old-page!
   (are [x y] (= (let [[content old-name new-name] x]