Bladeren bron

Move first batch of util fns to graph-parser.util

Still need to fix external.roam
Gabriel Horner 3 jaren geleden
bovenliggende
commit
85bd1fecb2
43 gewijzigde bestanden met toevoegingen van 211 en 166 verwijderingen
  1. 2 1
      .clj-kondo/config.edn
  2. 4 3
      src/main/frontend/commands.cljs
  3. 9 8
      src/main/frontend/components/block.cljs
  4. 2 1
      src/main/frontend/components/content.cljs
  5. 4 3
      src/main/frontend/components/page.cljs
  6. 2 1
      src/main/frontend/components/page_menu.cljs
  7. 2 1
      src/main/frontend/components/reference.cljs
  8. 2 1
      src/main/frontend/components/search.cljs
  9. 4 3
      src/main/frontend/config.cljs
  10. 2 1
      src/main/frontend/db/conn.cljs
  11. 4 3
      src/main/frontend/db/model.cljs
  12. 3 2
      src/main/frontend/db/query_dsl.cljs
  13. 3 2
      src/main/frontend/db/query_react.cljs
  14. 2 1
      src/main/frontend/db/react.cljs
  15. 3 2
      src/main/frontend/db/utils.cljs
  16. 2 1
      src/main/frontend/extensions/html_parser.cljs
  17. 2 1
      src/main/frontend/external/roam.cljc
  18. 7 6
      src/main/frontend/format/block.cljs
  19. 2 1
      src/main/frontend/format/mldoc.cljs
  20. 3 3
      src/main/frontend/fs/watcher_handler.cljs
  21. 13 12
      src/main/frontend/handler/editor.cljs
  22. 4 3
      src/main/frontend/handler/extract.cljs
  23. 3 2
      src/main/frontend/handler/file.cljs
  24. 3 2
      src/main/frontend/handler/graph.cljs
  25. 3 2
      src/main/frontend/handler/page.cljs
  26. 2 1
      src/main/frontend/handler/repo.cljs
  27. 2 1
      src/main/frontend/handler/route.cljs
  28. 2 2
      src/main/frontend/handler/shell.cljs
  29. 2 1
      src/main/frontend/handler/ui.cljs
  30. 4 3
      src/main/frontend/handler/web/nfs.cljs
  31. 2 1
      src/main/frontend/modules/outliner/core.cljs
  32. 2 2
      src/main/frontend/modules/outliner/datascript.cljc
  33. 2 2
      src/main/frontend/modules/outliner/tree.cljs
  34. 2 2
      src/main/frontend/security.cljs
  35. 2 1
      src/main/frontend/state.cljs
  36. 6 5
      src/main/frontend/text.cljs
  37. 20 61
      src/main/frontend/util.cljc
  38. 3 2
      src/main/frontend/util/drawer.cljs
  39. 4 3
      src/main/frontend/util/marker.cljs
  40. 3 2
      src/main/frontend/util/priority.cljs
  41. 10 9
      src/main/frontend/util/property.cljs
  42. 3 2
      src/main/logseq/api.cljs
  43. 50 0
      src/main/logseq/graph_parser/util.cljs

+ 2 - 1
.clj-kondo/config.edn

@@ -19,7 +19,8 @@
              frontend.db.react react
              frontend.db.query-react query-react
              frontend.util util
-             frontend.config config}}}
+             frontend.config config
+             logseq.graph-parser.util gp-util}}}
 
  :hooks {:analyze-call {rum.core/defc hooks.rum/defc
                          rum.core/defcs hooks.rum/defcs}}

+ 4 - 3
src/main/frontend/commands.cljs

@@ -15,6 +15,7 @@
             [frontend.util.marker :as marker]
             [frontend.util.priority :as priority]
             [frontend.util.property :as property]
+            [logseq.graph-parser.util :as gp-util]
             [goog.dom :as gdom]
             [goog.object :as gobj]
             [promesa.core :as p]))
@@ -515,7 +516,7 @@
 
 (defn compute-pos-delta-when-change-marker
   [edit-content marker pos]
-  (let [old-marker (some->> (first (util/safe-re-find marker/bare-marker-pattern edit-content))
+  (let [old-marker (some->> (first (gp-util/safe-re-find marker/bare-marker-pattern edit-content))
                             (string/trim))
         pos-delta (- (count marker)
                      (count old-marker))
@@ -540,7 +541,7 @@
                   (if-let [matches (seq (util/re-pos new-line-re-pattern prefix))]
                     (let [[start-pos content] (last matches)]
                       (+ start-pos (count content)))
-                    (count (util/safe-re-find re-pattern prefix))))
+                    (count (gp-util/safe-re-find re-pattern prefix))))
             new-value (str (subs edit-content 0 pos)
                            (string/replace-first (subs edit-content pos)
                                                  (marker/marker-pattern format)
@@ -581,7 +582,7 @@
       (let [edit-content (gobj/get current-input "value")
             heading-pattern #"^#+\s+"
             new-value (cond
-                        (util/safe-re-find heading-pattern edit-content)
+                        (gp-util/safe-re-find heading-pattern edit-content)
                         (string/replace-first edit-content
                                               heading-pattern
                                               (str heading " "))

+ 9 - 8
src/main/frontend/components/block.cljs

@@ -51,6 +51,7 @@
             [frontend.util.clock :as clock]
             [frontend.util.property :as property]
             [frontend.util.drawer :as drawer]
+            [logseq.graph-parser.util :as gp-util]
             [goog.dom :as gdom]
             [goog.object :as gobj]
             [lambdaisland.glogi :as log]
@@ -647,7 +648,7 @@
   [config id label]
   (when (and
          (not (string/blank? id))
-         (util/uuid-string? id))
+         (gp-util/uuid-string? id))
     (let [block-id (uuid id)
           block (db/pull-block block-id)
           block-type (keyword (get-in block [:block/properties :ls-type]))
@@ -919,7 +920,7 @@
                (= "Complex" protocol)
                (= (string/lower-case (:protocol path)) "id")
                (string? (:link path))
-               (util/uuid-string? (:link path))) ; org mode id
+               (gp-util/uuid-string? (:link path))) ; org mode id
           (let [id (uuid (:link path))
                 block (db/entity [:block/uuid id])]
             (if (:block/pre-block? block)
@@ -1035,7 +1036,7 @@
                        string/trim)]
         (when-let [id (and s
                            (let [s (string/trim s)]
-                             (and (util/uuid-string? s)
+                             (and (gp-util/uuid-string? s)
                                   (uuid s))))]
           (block-embed (assoc config :link-depth (inc link-depth)) id)))
 
@@ -1046,7 +1047,7 @@
   [_config arguments]
   (when-let [url (first arguments)]
     (let [Vimeo-regex #"^((?:https?:)?//)?((?:www).)?((?:player.vimeo.com|vimeo.com)?)((?:/video/)?)([\w-]+)(\S+)?$"]
-      (when-let [vimeo-id (nth (util/safe-re-find Vimeo-regex url) 5)]
+      (when-let [vimeo-id (nth (gp-util/safe-re-find Vimeo-regex url) 5)]
         (when-not (string/blank? vimeo-id)
           (let [width (min (- (util/get-width) 96)
                            560)
@@ -1067,7 +1068,7 @@
       (when-let [id (cond
                       (<= (count url) 15) url
                       :else
-                      (last (util/safe-re-find id-regex url)))]
+                      (last (gp-util/safe-re-find id-regex url)))]
         (when-not (string/blank? id)
           (let [width (min (- (util/get-width) 96)
                            560)
@@ -1197,7 +1198,7 @@
           (when-let [youtube-id (cond
                                   (== 11 (count url)) url
                                   :else
-                                  (nth (util/safe-re-find YouTube-regex url) 5))]
+                                  (nth (gp-util/safe-re-find YouTube-regex url) 5))]
             (when-not (string/blank? youtube-id)
               (youtube/youtube-video youtube-id)))))
 
@@ -1228,7 +1229,7 @@
           (when-let [id (cond
                           (<= (count url) 15) url
                           :else
-                          (last (util/safe-re-find id-regex url)))]
+                          (last (gp-util/safe-re-find id-regex url)))]
             (ui/tweet-embed id))))
 
       (= name "embed")
@@ -2757,7 +2758,7 @@
 
         ["Paragraph" l]
              ;; TODO: speedup
-        (if (util/safe-re-find #"\"Export_Snippet\" \"embed\"" (str l))
+        (if (gp-util/safe-re-find #"\"Export_Snippet\" \"embed\"" (str l))
           (->elem :div (map-inline config l))
           (->elem :div.is-paragraph (map-inline config l)))
 

+ 2 - 1
src/main/frontend/components/content.cljs

@@ -21,6 +21,7 @@
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.util.url :as url-util]
             [goog.dom :as gdom]
             [goog.object :as gobj]
@@ -364,7 +365,7 @@
                            e
                            (custom-context-menu-content))
 
-                          (and block-id (util/uuid-string? block-id))
+                          (and block-id (gp-util/uuid-string? block-id))
                           (let [block (.closest target ".ls-block")]
                             (when block
                               (util/select-highlight! [block]))

+ 4 - 3
src/main/frontend/components/page.cljs

@@ -34,6 +34,7 @@
             [reitit.frontend.easy :as rfe]
             [medley.core :as medley]
             [rum.core :as rum]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.mobile.util :as mobile-util]))
 
 (defn- get-page-name
@@ -114,7 +115,7 @@
   (when page-e
     (let [page-name (or (:block/name page-e)
                         (str (:block/uuid page-e)))
-          block? (util/uuid-string? page-name)
+          block? (gp-util/uuid-string? page-name)
           block-id (and block? (uuid page-name))
           page-blocks (get-blocks repo page-name block-id)]
       (if (empty? page-blocks)
@@ -310,7 +311,7 @@
     (let [current-repo (state/sub :git/current-repo)
           repo (or repo current-repo)
           page-name (util/page-name-sanity-lc path-page-name)
-          block? (util/uuid-string? page-name)
+          block? (gp-util/uuid-string? page-name)
           block-id (and block? (uuid page-name))
           format (let [page (if block-id
                               (:block/name (:block/page (db/entity [:block/uuid block-id])))
@@ -633,7 +634,7 @@
               (date/today))
         theme (:ui/theme @state/state)
         dark? (= theme "dark")
-        graph (if (util/uuid-string? page)
+        graph (if (gp-util/uuid-string? page)
                 (graph-handler/build-block-graph (uuid page) theme)
                 (graph-handler/build-page-graph page theme))]
     (when (seq (:nodes graph))

+ 2 - 1
src/main/frontend/components/page_menu.cljs

@@ -14,6 +14,7 @@
             [frontend.handler.shell :as shell]
             [frontend.handler.plugin :as plugin-handler]
             [frontend.mobile.util :as mobile-util]
+            [logseq.graph-parser.util :as gp-util]
             [electron.ipc :as ipc]
             [frontend.config :as config]
             [frontend.handler.user :as user-handler]
@@ -63,7 +64,7 @@
           repo (state/sub :git/current-repo)
           page (db/entity repo [:block/name page-name])
           page-original-name (:block/original-name page)
-          block? (and page (util/uuid-string? page-name))
+          block? (and page (gp-util/uuid-string? page-name))
           contents? (= page-name "contents")
           properties (:block/properties page)
           public? (true? (:public properties))

+ 2 - 1
src/main/frontend/components/reference.cljs

@@ -12,6 +12,7 @@
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [medley.core :as medley]
             [rum.core :as rum]))
 
@@ -84,7 +85,7 @@
           default-collapsed? (>= (count refed-blocks-ids) threshold)
           filters-atom (get state ::filters)
           filter-state (rum/react filters-atom)
-          block? (util/uuid-string? page-name)
+          block? (gp-util/uuid-string? page-name)
           block-id (and block? (uuid page-name))
           page-name (string/lower-case page-name)
           journal? (date/valid-journal-title? (string/capitalize page-name))

+ 2 - 1
src/main/frontend/components/search.cljs

@@ -20,6 +20,7 @@
             [clojure.string :as string]
             [frontend.context.i18n :refer [t]]
             [frontend.date :as date]
+            [logseq.graph-parser.util :as gp-util]
             [reitit.frontend.easy :as rfe]
             [frontend.modules.shortcut.core :as shortcut]))
 
@@ -32,7 +33,7 @@
             lc-content (util/search-normalize content)
             lc-q (util/search-normalize q)]
         (if (and (string/includes? lc-content lc-q)
-                 (not (util/safe-re-find #" " q)))
+                 (not (gp-util/safe-re-find #" " q)))
           (let [i (string/index-of lc-content lc-q)
                 [before after] [(subs content 0 i) (subs content (+ i (count q)))]]
             [:div

+ 4 - 3
src/main/frontend/config.cljs

@@ -4,6 +4,7 @@
             [frontend.state :as state]
             [frontend.util :as util]
             [shadow.resource :as rc]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.mobile.util :as mobile-util]))
 
 (goog-define DEV-RELEASE false)
@@ -105,7 +106,7 @@
 
 (def mobile?
   (when-not util/node-test?
-    (util/safe-re-find #"Mobi" js/navigator.userAgent)))
+    (gp-util/safe-re-find #"Mobi" js/navigator.userAgent)))
 
 ;; TODO: protocol design for future formats support
 
@@ -301,7 +302,7 @@
 
 (defn local-asset?
   [s]
-  (util/safe-re-find (re-pattern (str "^[./]*" local-assets-dir)) s))
+  (gp-util/safe-re-find (re-pattern (str "^[./]*" local-assets-dir)) s))
 
 (defn get-local-asset-absolute-path
   [s]
@@ -368,7 +369,7 @@
 
                  :else
                  relative-path)]
-      (util/path-normalize path))))
+      (gp-util/path-normalize path))))
 
 (defn get-config-path
   ([]

+ 2 - 1
src/main/frontend/db/conn.cljs

@@ -8,6 +8,7 @@
             [frontend.state :as state]
             [frontend.config :as config]
             [frontend.text :as text]
+            [logseq.graph-parser.util :as gp-util]
             [datascript.core :as d]))
 
 (defonce conns (atom {}))
@@ -69,7 +70,7 @@
 
 (defn me-tx
   [_db {:keys [name email avatar]}]
-  (util/remove-nils {:me/name name
+  (gp-util/remove-nils {:me/name name
                      :me/email email
                      :me/avatar avatar}))
 

+ 4 - 3
src/main/frontend/db/model.cljs

@@ -15,6 +15,7 @@
             [frontend.format :as format]
             [frontend.state :as state]
             [frontend.util :as util :refer [react]]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.db.rules :refer [rules]]
             [frontend.db.default :as default-db]
             [frontend.util.drawer :as drawer]))
@@ -61,7 +62,7 @@
    (db-utils/transact! (state/get-current-repo) tx-data))
   ([repo-url tx-data]
    (when-not config/publishing?
-     (let [tx-data (->> (util/remove-nils tx-data)
+     (let [tx-data (->> (gp-util/remove-nils tx-data)
                         (remove nil?)
                         (map #(dissoc % :file/handle :file/type)))]
        (when (seq tx-data)
@@ -894,7 +895,7 @@
 
 (defn get-page
   [page-name]
-  (if (util/uuid-string? page-name)
+  (if (gp-util/uuid-string? page-name)
     (db-utils/entity [:block/uuid (uuid page-name)])
     (db-utils/entity [:block/name (util/page-name-sanity-lc page-name)])))
 
@@ -1252,7 +1253,7 @@
 
 (defn get-referenced-blocks-ids
   [page-name-or-block-uuid]
-  (if (util/uuid-string? (str page-name-or-block-uuid))
+  (if (gp-util/uuid-string? (str page-name-or-block-uuid))
     (let [id (uuid page-name-or-block-uuid)]
       (get-block-referenced-blocks-ids id))
     (get-page-referenced-blocks-ids page-name-or-block-uuid)))

+ 3 - 2
src/main/frontend/db/query_dsl.cljs

@@ -13,7 +13,8 @@
             [frontend.db.rules :as rules]
             [frontend.template :as template]
             [frontend.text :as text]
-            [frontend.util :as util]))
+            [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]))
 
 
 ;; Query fields:
@@ -447,7 +448,7 @@ Some bindings in this fn:
                                                  (remove string/blank?)
                                                  (map (fn [x]
                                                         (if (or (contains? #{"+" "-"} (first x))
-                                                                (and (util/safe-re-find #"\d" (first x))
+                                                                (and (gp-util/safe-re-find #"\d" (first x))
                                                                      (some #(string/ends-with? x %) ["y" "m" "d" "h" "min"])))
                                                           (keyword (name x))
                                                           x)))

+ 3 - 2
src/main/frontend/db/query_react.cljs

@@ -12,6 +12,7 @@
             [frontend.state :as state]
             [frontend.text :as text]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [lambdaisland.glogi :as log]))
 
 (defn resolve-input
@@ -31,12 +32,12 @@
     ;; This sometimes runs when there isn't a current page e.g. :home route
     (some-> (state/get-current-page) string/lower-case)
     (and (keyword? input)
-         (util/safe-re-find #"^\d+d(-before)?$" (name input)))
+         (gp-util/safe-re-find #"^\d+d(-before)?$" (name input)))
     (let [input (name input)
           days (util/parse-int (subs input 0 (dec (count input))))]
       (date->int (t/minus (t/today) (t/days days))))
     (and (keyword? input)
-         (util/safe-re-find #"^\d+d(-after)?$" (name input)))
+         (gp-util/safe-re-find #"^\d+d(-after)?$" (name input)))
     (let [input (name input)
           days (util/parse-int (subs input 0 (dec (count input))))]
       (date->int (t/plus (t/today) (t/days days))))

+ 2 - 1
src/main/frontend/db/react.cljs

@@ -10,6 +10,7 @@
             [frontend.db.utils :as db-utils]
             [frontend.state :as state]
             [frontend.util :as util :refer [react]]
+            [logseq.graph-parser.util :as gp-util]
             [cljs.spec.alpha :as s]
             [clojure.core.async :as async]))
 
@@ -227,7 +228,7 @@
         affected-keys (concat
                        (mapcat
                         (fn [block-id]
-                          (let [block-id (if (and (string? block-id) (util/uuid-string? block-id))
+                          (let [block-id (if (and (string? block-id) (gp-util/uuid-string? block-id))
                                            [:block/uuid block-id]
                                            block-id)]
                             (when-let [block (db-utils/entity block-id)]

+ 3 - 2
src/main/frontend/db/utils.cljs

@@ -7,7 +7,8 @@
             [frontend.util :as util]
             [frontend.date :as date]
             [frontend.db.conn :as conn]
-            [frontend.config :as config]))
+            [frontend.config :as config]
+            [logseq.graph-parser.util :as gp-util]))
 
 ;; transit serialization
 
@@ -88,7 +89,7 @@
    (transact! repo-url tx-data nil))
   ([repo-url tx-data tx-meta]
    (when-not config/publishing?
-     (let [tx-data (->> (util/remove-nils tx-data)
+     (let [tx-data (->> (gp-util/remove-nils tx-data)
                         (remove nil?))]
        (when (seq tx-data)
          (when-let [conn (conn/get-db repo-url false)]

+ 2 - 1
src/main/frontend/extensions/html_parser.cljs

@@ -4,6 +4,7 @@
             [clojure.walk :as walk]
             [frontend.config :as config]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [hickory.core :as hickory]))
 
 (defonce *inside-pre? (atom false))
@@ -74,7 +75,7 @@
                                 :h6 (block-transform 6 children)
                                 :a (let [href (:href attrs)
                                          label (map-join children)
-                                         has-img-tag? (util/safe-re-find #"\[:img" (str x))]
+                                         has-img-tag? (gp-util/safe-re-find #"\[:img" (str x))]
                                      (if has-img-tag?
                                        (export-hiccup x)
                                        (case format

+ 2 - 1
src/main/frontend/external/roam.cljc

@@ -10,6 +10,7 @@
             [clojure.walk :as walk]
             [clojure.string :as string]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.text :as text]))
 
 (defonce all-refed-uids (atom #{}))
@@ -39,7 +40,7 @@
 (defn macro-transform
   [text]
   (string/replace text macro-pattern (fn [[original text]]
-                                       (let [[name arg] (util/split-first ":" text)]
+                                       (let [[name arg] (gp-util/split-first ":" text)]
                                          (if name
                                            ;; TODO: Why unresolved var
                                            #_:clj-kondo/ignore

+ 7 - 6
src/main/frontend/format/block.cljs

@@ -11,6 +11,7 @@
             [frontend.utf8 :as utf8]
             [frontend.util :as util]
             [frontend.util.property :as property]
+            [logseq.graph-parser.util :as gp-util]
             [lambdaisland.glogi :as log]
             [medley.core :as medley]
             [frontend.format.mldoc :as mldoc]))
@@ -136,7 +137,7 @@
                         :else
                         nil)]
     (when (and block-id
-               (util/uuid-string? block-id))
+               (gp-util/uuid-string? block-id))
       block-id)))
 
 (defn paragraph-block?
@@ -265,7 +266,7 @@
             {}
             {:block/uuid (db/new-block-id)}))
         (when namespace?
-          (let [namespace (first (util/split-last "/" original-page-name))]
+          (let [namespace (first (gp-util/split-last "/" original-page-name))]
             (when-not (string/blank? namespace)
               {:block/namespace {:block/name (util/page-name-sanity-lc namespace)}})))
         (when (and with-timestamp? (not page-entity)) ;; Only assign timestamp on creating new entity
@@ -302,7 +303,7 @@
            (swap! refs conj page))
          (when-let [tag (get-tag form)]
            (let [tag (text/page-ref-un-brackets! tag)]
-             (when (util/tag-valid? tag)
+             (when (gp-util/tag-valid? tag)
                (swap! refs conj tag))))
          form))
      (concat title body))
@@ -333,7 +334,7 @@
        form)
      (concat title body))
     (let [ref-blocks (->> @ref-blocks
-                          (filter util/uuid-string?))
+                          (filter gp-util/uuid-string?))
           ref-blocks (map
                        (fn [id]
                          [:block/uuid (medley/uuid id)])
@@ -354,7 +355,7 @@
   [blocks]
   (map (fn [block]
          (if (map? block)
-           (block-keywordize (util/remove-nils block))
+           (block-keywordize (gp-util/remove-nils block))
            block))
        blocks))
 
@@ -437,7 +438,7 @@
                                (get-in properties [:properties :custom_id])
                                (get-in properties [:properties :id]))]
         (let [custom-id (and (string? custom-id) (string/trim custom-id))]
-          (when (and custom-id (util/uuid-string? custom-id))
+          (when (and custom-id (gp-util/uuid-string? custom-id))
             (uuid custom-id))))
       (db/new-block-id)))
 

+ 2 - 1
src/main/frontend/format/mldoc.cljs

@@ -9,6 +9,7 @@
             [medley.core :as medley]
             ["mldoc" :as mldoc :refer [Mldoc]]
             [linked.core :as linked]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.config :as config]))
 
 (defonce parseJson (gobj/get Mldoc "parseJson"))
@@ -138,7 +139,7 @@
                    (->>
                     (map
                      (fn [[_ v]]
-                       (let [[k v] (util/split-first " " v)]
+                       (let [[k v] (gp-util/split-first " " v)]
                          (mapv
                           string/trim
                           [k v])))

+ 3 - 3
src/main/frontend/fs/watcher_handler.cljs

@@ -9,13 +9,13 @@
             [frontend.handler.page :as page-handler]
             [frontend.handler.repo :as repo-handler]
             [frontend.handler.ui :as ui-handler]
-            [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [lambdaisland.glogi :as log]
             [electron.ipc :as ipc]
             [promesa.core :as p]
             [frontend.state :as state]))
 
-;; all IPC paths must be normalized! (via util/path-normalize)
+;; all IPC paths must be normalized! (via gp-util/path-normalize)
 
 (defn- set-missing-block-ids!
   [content]
@@ -42,7 +42,7 @@
 (defn handle-changed!
   [type {:keys [dir path content stat] :as payload}]
   (when dir
-    (let [path (util/path-normalize path)
+    (let [path (gp-util/path-normalize path)
           repo (config/get-local-repo dir)
           pages-metadata-path (config/get-pages-metadata-path)
           {:keys [mtime]} stat

+ 13 - 12
src/main/frontend/handler/editor.cljs

@@ -52,6 +52,7 @@
             [medley.core :as medley]
             [promesa.core :as p]
             [frontend.util.keycode :as keycode]
+            [logseq.graph-parser.util :as gp-util]
             ["path" :as path]))
 
 ;; FIXME: should support multiple images concurrently uploading
@@ -255,7 +256,7 @@
 (defn- another-block-with-same-id-exists?
   [current-id block-id]
   (and (string? block-id)
-       (util/uuid-string? block-id)
+       (gp-util/uuid-string? block-id)
        (not= current-id (cljs.core/uuid block-id))
        (db/entity [:block/uuid (cljs.core/uuid block-id)])))
 
@@ -336,7 +337,7 @@
   (if (and (state/enable-timetracking?)
            (not= (:block/content block) value))
     (let [format (:block/format block)
-          new-marker (last (util/safe-re-find (marker/marker-pattern format) (or value "")))
+          new-marker (last (gp-util/safe-re-find (marker/marker-pattern format) (or value "")))
           new-value (with-marker-time value block format
                       new-marker
                       (:block/marker block))]
@@ -480,10 +481,10 @@
   (let [current-page (state/get-current-page)
         block-id (or
                   (and (:id config)
-                       (util/uuid-string? (:id config))
+                       (gp-util/uuid-string? (:id config))
                        (:id config))
                   (and current-page
-                       (util/uuid-string? current-page)
+                       (gp-util/uuid-string? current-page)
                        current-page))]
     (= uuid (and block-id (medley/uuid block-id)))))
 
@@ -1139,7 +1140,7 @@
   []
   (when-let [page (get-nearest-page)]
     (let [page-name (string/lower-case page)
-          block? (util/uuid-string? page-name)]
+          block? (gp-util/uuid-string? page-name)]
       (when-let [page (db/get-page page-name)]
         (if block?
           (state/sidebar-add-block!
@@ -1171,7 +1172,7 @@
     (let [page (state/get-current-page)
           block-id (and
                     (string? page)
-                    (util/uuid-string? page)
+                    (gp-util/uuid-string? page)
                     (medley/uuid page))]
       (when block-id
         (let [block-parent (db/get-block-parent block-id)]
@@ -2008,7 +2009,7 @@
 (defn- last-top-level-child?
   [{:keys [id]} current-node]
   (when id
-    (when-let [entity (if (util/uuid-string? (str id))
+    (when-let [entity (if (gp-util/uuid-string? (str id))
                         (db/entity [:block/uuid (uuid id)])
                         (db/entity [:block/name (util/page-name-sanity-lc id)]))]
       (= (:block/uuid entity) (tree/-get-parent-id current-node)))))
@@ -2835,7 +2836,7 @@
         (string/join "\n"
                      (mapv (fn [p] (->> (string/trim p)
                                         ((fn [p]
-                                           (if (util/safe-re-find (if (= format :org)
+                                           (if (gp-util/safe-re-find (if (= format :org)
                                                                     #"\s*\*+\s+"
                                                                     #"\s*-\s+") p)
                                              p
@@ -2898,9 +2899,9 @@
       ;; from external
       (let [format (or (db/get-page-format (state/get-current-page)) :markdown)]
         (match [format
-                (nil? (util/safe-re-find #"(?m)^\s*(?:[-+*]|#+)\s+" text))
-                (nil? (util/safe-re-find #"(?m)^\s*\*+\s+" text))
-                (nil? (util/safe-re-find #"(?:\r?\n){2,}" text))]
+                (nil? (gp-util/safe-re-find #"(?m)^\s*(?:[-+*]|#+)\s+" text))
+                (nil? (gp-util/safe-re-find #"(?m)^\s*\*+\s+" text))
+                (nil? (gp-util/safe-re-find #"(?:\r?\n){2,}" text))]
           [:markdown false _ _]
           (paste-text-parseable format text)
 
@@ -3185,7 +3186,7 @@
     :or {collapse? false expanded? false incremental? true root-block nil}}]
   (when-let [page (or (state/get-current-page)
                       (date/today))]
-    (let [block? (util/uuid-string? page)
+    (let [block? (gp-util/uuid-string? page)
           block-id (or root-block (and block? (uuid page)))
           blocks (if block-id
                    (db/get-block-and-children (state/get-current-repo) block-id)

+ 4 - 3
src/main/frontend/handler/extract.cljs

@@ -11,6 +11,7 @@
             [frontend.state :as state]
             [frontend.text :as text]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.util.property :as property]
             [lambdaisland.glogi :as log]))
 
@@ -29,7 +30,7 @@
                                     (string? title)
                                     title))
             file-name (when-let [file-name (last (string/split file #"/"))]
-                        (let [result (first (util/split-last "." file-name))]
+                        (let [result (first (gp-util/split-last "." file-name))]
                           (if (config/mldoc-support? (string/lower-case (util/get-file-ext file)))
                             (string/replace result "." "/")
                             result)))]
@@ -90,10 +91,10 @@
                                        aliases)
                                      (remove nil?))]
                         (cond->
-                          (util/remove-nils
+                          (gp-util/remove-nils
                            (assoc
                             (block/page-name->map page false)
-                            :block/file {:file/path (util/path-normalize file)}))
+                            :block/file {:file/path (gp-util/path-normalize file)}))
                           (seq properties)
                           (assoc :block/properties properties)
 

+ 3 - 2
src/main/frontend/handler/file.cljs

@@ -16,6 +16,7 @@
             [frontend.handler.ui :as ui-handler]
             [frontend.state :as state]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]  
             [lambdaisland.glogi :as log]
             [promesa.core :as p]
             [frontend.mobile.util :as mobile]
@@ -75,7 +76,7 @@
                                         (seq images)
                                         (merge (zipmap images (repeat (count images) ""))))
                         file-contents (for [[file content] file-contents]
-                                        {:file/path (util/path-normalize file)
+                                        {:file/path (gp-util/path-normalize file)
                                          :file/content content})]
                     (ok-handler file-contents))))
         (p/catch (fn [error]
@@ -115,7 +116,7 @@
 
                 :else
                 file)
-         file (util/path-normalize file)
+         file (gp-util/path-normalize file)
          new? (nil? (db/entity [:file/path file]))]
      (db/set-file-content! repo-url file content)
      (let [format (format/get-format file)

+ 3 - 2
src/main/frontend/handler/graph.cljs

@@ -4,7 +4,8 @@
             [frontend.db :as db]
             [frontend.db.default :as default-db]
             [frontend.state :as state]
-            [frontend.util :as util]))
+            [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]))
 
 (defn- build-links
   [links]
@@ -45,7 +46,7 @@
                   ;; slow
 (defn- uuid-or-asset?
   [id]
-  (or (util/uuid-string? id)
+  (or (gp-util/uuid-string? id)
       (string/starts-with? id "../assets/")
       (= id "..")
       (string/starts-with? id "assets/")

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

@@ -33,6 +33,7 @@
             [lambdaisland.glogi :as log]
             [promesa.core :as p]
             [frontend.mobile.util :as mobile-util]
+            [logseq.graph-parser.util :as gp-util]
             [goog.functions :refer [debounce]]))
 
 (defn- get-directory
@@ -625,7 +626,7 @@
   (->> (db/get-all-pages repo)
        (remove (fn [p]
                  (let [name (:block/name p)]
-                   (or (util/uuid-string? name)
+                   (or (gp-util/uuid-string? name)
                        (config/draw? name)
                        (db/built-in-pages-names (string/upper-case name))))))
        (common-handler/fix-pages-timestamps)))
@@ -679,7 +680,7 @@
               chosen (if (string/starts-with? chosen "New page: ") ;; FIXME: What if a page named "New page: XXX"?
                        (subs chosen 10)
                        chosen)
-              chosen (if (and (util/safe-re-find #"\s+" chosen) (not wrapped?))
+              chosen (if (and (gp-util/safe-re-find #"\s+" chosen) (not wrapped?))
                        (util/format "[[%s]]" chosen)
                        chosen)
               q (if @editor-handler/*selected-text "" q)

+ 2 - 1
src/main/frontend/handler/repo.cljs

@@ -22,6 +22,7 @@
             [promesa.core :as p]
             [shadow.resource :as rc]
             [frontend.db.persist :as db-persist]
+            [logseq.graph-parser.util :as gp-util]
             [electron.ipc :as ipc]
             [clojure.set :as set]
             [clojure.core.async :as async]))
@@ -300,7 +301,7 @@
                              [])
               add-or-modify-files (some->>
                                    (concat modify-files add-files)
-                                   (util/remove-nils))
+                                   (gp-util/remove-nils))
               options {:delete-files (concat delete-files delete-pages)
                        :delete-blocks delete-blocks
                        :re-render? true}]

+ 2 - 1
src/main/frontend/handler/route.cljs

@@ -8,6 +8,7 @@
             [frontend.state :as state]
             [frontend.text :as text]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [medley.core :as medley]
             [reitit.frontend.easy :as rfe]))
 
@@ -77,7 +78,7 @@
     "Create a new page"
     :page
     (let [name (:name path-params)
-          block? (util/uuid-string? name)]
+          block? (gp-util/uuid-string? name)]
       (if block?
         (if-let [block (db/entity [:block/uuid (medley/uuid name)])]
           (let [content (text/remove-level-spaces (:block/content block)

+ 2 - 2
src/main/frontend/handler/shell.cljs

@@ -1,7 +1,7 @@
 (ns frontend.handler.shell
   (:require [electron.ipc :as ipc]
             [clojure.string :as string]
-            [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.handler.notification :as notification]
             [promesa.core :as p]
             [frontend.db :as db]
@@ -34,7 +34,7 @@
 
 (defn run-command!
   [command]
-  (let [[command args] (util/split-first " " command)
+  (let [[command args] (gp-util/split-first " " command)
         command (and command (string/lower-case command))]
     (when (and (not (string/blank? command)) (not (string/blank? args)))
       (let [args (string/trim args)]

+ 2 - 1
src/main/frontend/handler/ui.cljs

@@ -14,6 +14,7 @@
             [clojure.string :as string]
             [rum.core :as rum]
             [frontend.mobile.util :as mobile]
+            [logseq.graph-parser.util :as gp-util]
             [electron.ipc :as ipc]))
 
 (defn- get-css-var-value
@@ -111,7 +112,7 @@
   (let [id (and
             (> (count fragment) 36)
             (subs fragment (- (count fragment) 36)))]
-    (if (and id (util/uuid-string? id))
+    (if (and id (gp-util/uuid-string? id))
       (let [elements (array-seq (js/document.getElementsByClassName id))]
         (when (first elements)
           (util/scroll-to-element (gobj/get (first elements) "id")))

+ 4 - 3
src/main/frontend/handler/web/nfs.cljs

@@ -20,6 +20,7 @@
             [lambdaisland.glogi :as log]
             [promesa.core :as p]
             [frontend.mobile.util :as mobile-util]
+            [logseq.graph-parser.util :as gp-util]
             [clojure.core.async :as async]))
 
 (defn remove-ignore-files
@@ -48,7 +49,7 @@
    (cond
      mobile-native?
      (map (fn [{:keys [uri content size mtime]}]
-            {:file/path             (util/path-normalize uri)
+            {:file/path             (gp-util/path-normalize uri)
              :file/last-modified-at mtime
              :file/size             size
              :file/content content})
@@ -57,7 +58,7 @@
      electron?
      (map (fn [{:keys [path stat content]}]
             (let [{:keys [mtime size]} stat]
-              {:file/path             (util/path-normalize path)
+              {:file/path             (gp-util/path-normalize path)
                :file/last-modified-at mtime
                :file/size             size
                :file/content content}))
@@ -71,7 +72,7 @@
                     path (-> (get-attr "webkitRelativePath")
                              (string/replace-first (str dir-name "/") ""))]
                 {:file/name             (get-attr "name")
-                 :file/path             (util/path-normalize path)
+                 :file/path             (gp-util/path-normalize path)
                  :file/last-modified-at (get-attr "lastModified")
                  :file/size             (get-attr "size")
                  :file/type             (get-attr "type")

+ 2 - 1
src/main/frontend/modules/outliner/core.cljs

@@ -12,6 +12,7 @@
             [frontend.modules.outliner.utils :as outliner-u]
             [frontend.state :as state]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [cljs.spec.alpha :as s]))
 
 (s/def ::block-map (s/keys :req [:db/id :block/uuid]
@@ -135,7 +136,7 @@
     (let [m (-> (:data this)
                 (dissoc :block/children :block/meta :block/top? :block/bottom?
                         :block/title :block/body :block/level)
-                (util/remove-nils))
+                (gp-util/remove-nils))
           m (if (state/enable-block-timestamps?) (block-with-timestamps m) m)
           other-tx (:db/other-tx m)
           id (:db/id (:data this))

+ 2 - 2
src/main/frontend/modules/outliner/datascript.cljc

@@ -7,8 +7,8 @@
                      [frontend.modules.editor.undo-redo :as undo-redo]
                      [frontend.state :as state]
                      [frontend.config :as config]
+                     [logseq.graph-parser.util :as gp-util]
                      [lambdaisland.glogi :as log]
-                     [frontend.util :as util]
                      [medley.core :as medley])))
 
 #?(:cljs
@@ -30,7 +30,7 @@
 #?(:cljs
    (defn- remove-nil-from-transaction
      [txs]
-     (some->> (util/remove-nils txs)
+     (some->> (gp-util/remove-nils txs)
               (map (fn [x]
                      (if (map? x)
                        (medley/map-vals (fn [v] (if (vector? v)

+ 2 - 2
src/main/frontend/modules/outliner/tree.cljs

@@ -1,6 +1,6 @@
 (ns frontend.modules.outliner.tree
   (:require [frontend.db :as db]
-            [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [clojure.string :as string]
             [frontend.state :as state]))
 
@@ -45,7 +45,7 @@
 (defn- get-root-and-page
   [repo root-id]
   (if (string? root-id)
-    (if (util/uuid-string? root-id)
+    (if (gp-util/uuid-string? root-id)
       [false (db/entity repo [:block/uuid (uuid root-id)])]
       [true (db/entity repo [:block/name (string/lower-case root-id)])])
     [false root-id]))

+ 2 - 2
src/main/frontend/security.cljs

@@ -1,6 +1,6 @@
 (ns frontend.security
   (:require [clojure.walk :as walk]
-            [frontend.util :as util]))
+            [logseq.graph-parser.util :as gp-util]))
 
 ;; To prevent from cross-site scripting vulnerability, we should add security checks for both hiccup and raw html.
 ;; Hiccup: [:a {:href "javascript:alert('hei')"} "click me"]
@@ -12,7 +12,7 @@
    (= :a (first f))
    (:href (second f))
    (:href (second f))
-   (util/safe-re-find #"(?i)javascript" (:href (second f)))))
+   (gp-util/safe-re-find #"(?i)javascript" (:href (second f)))))
 
 (defn remove-javascript-links-in-href
   [hiccup]

+ 2 - 1
src/main/frontend/state.cljs

@@ -13,6 +13,7 @@
             [goog.object :as gobj]
             [promesa.core :as p]
             [rum.core :as rum]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.mobile.util :as mobile-util]))
 
 (defonce ^:large-vars/data-var state
@@ -447,7 +448,7 @@
     (or
       (when-let [workflow (:preferred-workflow (get-config))]
         (let [workflow (name workflow)]
-          (if (util/safe-re-find #"now|NOW" workflow)
+          (if (gp-util/safe-re-find #"now|NOW" workflow)
             :now
             :todo)))
       (get-in @state [:me :preferred_workflow] :now))))

+ 6 - 5
src/main/frontend/text.cljs

@@ -4,6 +4,7 @@
             [clojure.string :as string]
             [frontend.format.mldoc :as mldoc]
             [clojure.set :as set]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.state :as state]))
 
 (def page-ref-re-0 #"\[\[(.*)\]\]")
@@ -136,8 +137,8 @@
 
      (and (string? s)
             ;; Either a page ref, a tag or a comma separated collection
-            (or (util/safe-re-find page-ref-re s)
-                (util/safe-re-find #"[\,|,|#|\"]+" s)))
+            (or (gp-util/safe-re-find page-ref-re s)
+                (gp-util/safe-re-find #"[\,|,|#|\"]+" s)))
      (let [result (->> (sep-by-quotes s)
                        (mapcat
                         (fn [s]
@@ -192,7 +193,7 @@
     (let [pattern (util/format
                    "^[%s]+\\s?"
                    (config/get-block-pattern format))]
-      (util/safe-re-find (re-pattern pattern) text))
+      (gp-util/safe-re-find (re-pattern pattern) text))
     ""))
 
 (defn- remove-level-space-aux!
@@ -231,7 +232,7 @@
 
 (defn media-link?
   [media-formats s]
-  (some (fn [fmt] (util/safe-re-find (re-pattern (str "(?i)\\." fmt "(?:\\?([^#]*))?(?:#(.*))?$")) s)) media-formats))
+  (some (fn [fmt] (gp-util/safe-re-find (re-pattern (str "(?i)\\." fmt "(?:\\?([^#]*))?(?:#(.*))?$")) s)) media-formats))
 
 (defn namespace-page?
   [p]
@@ -356,7 +357,7 @@
        (= v "false")
        false
 
-       (and (not= k "alias") (util/safe-re-find #"^\d+$" v))
+       (and (not= k "alias") (gp-util/safe-re-find #"^\d+$" v))
        (util/safe-parse-int v)
 
        (util/wrapped-by-quotes? v) ; wrapped in ""

+ 20 - 61
src/main/frontend/util.cljc

@@ -14,6 +14,7 @@
             [cljs-time.core :as t]
             [dommy.core :as d]
             [frontend.mobile.util :refer [is-native-platform?]]
+            [logseq.graph-parser.util :as gp-util]
             [goog.dom :as gdom]
             [goog.object :as gobj]
             [goog.string :as gstring]
@@ -52,20 +53,11 @@
        (and (string/includes? ua "webkit")
             (not (string/includes? ua "chrome"))))))
 
-(defn safe-re-find
-  [pattern s]
-  #?(:cljs
-     (when-not (string? s)
-       ;; TODO: sentry
-       (js/console.trace)))
-  (when (string? s)
-    (re-find pattern s)))
-
 #?(:cljs
    (defn mobile?
      []
      (when-not node-test?
-       (safe-re-find #"Mobi" js/navigator.userAgent))))
+       (gp-util/safe-re-find #"Mobi" js/navigator.userAgent))))
 
 #?(:cljs
    (defn electron?
@@ -162,16 +154,6 @@
           (cske/transform-keys csk/->kebab-case-keyword m)
           m)))))
 
-(defn remove-nils
-  "remove pairs of key-value that has nil value from a (possibly nested) map."
-  [nm]
-  (walk/postwalk
-   (fn [el]
-     (if (map? el)
-       (into {} (remove (comp nil? second)) el)
-       el))
-   nm))
-
 (defn remove-nils-non-nested
   [nm]
   (into {} (remove (comp nil? second)) nm))
@@ -381,7 +363,7 @@
 #?(:cljs
    (defn scroll-to-element
      [elem-id]
-     (when-not (safe-re-find #"^/\d+$" elem-id)
+     (when-not (gp-util/safe-re-find #"^/\d+$" elem-id)
        (when elem-id
          (when-let [elem (gdom/getElement elem-id)]
            (.scroll (app-scroll-container-node)
@@ -525,16 +507,6 @@
   (if (string? s)
     (string/lower-case s) s))
 
-(defn split-first [pattern s]
-  (when-let [first-index (string/index-of s pattern)]
-    [(subs s 0 first-index)
-     (subs s (+ first-index (count pattern)) (count s))]))
-
-(defn split-last [pattern s]
-  (when-let [last-index (string/last-index-of s pattern)]
-    [(subs s 0 last-index)
-     (subs s (+ last-index (count pattern)) (count s))]))
-
 (defn trim-safe
   [s]
   (when s
@@ -770,12 +742,6 @@
      ([s html?]
       (utils/writeClipboard s html?))))
 
-(def uuid-pattern "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}")
-(defonce exactly-uuid-pattern (re-pattern (str "(?i)^" uuid-pattern "$")))
-(defn uuid-string?
-  [s]
-  (safe-re-find exactly-uuid-pattern s))
-
 (defn drop-nth [n coll]
   (keep-indexed #(when (not= %1 n) %2) coll))
 
@@ -882,11 +848,6 @@
   []
   (str (rand-str 6) (rand-str 3)))
 
-(defn tag-valid?
-  [tag-name]
-  (when (string? tag-name)
-    (not (safe-re-find #"[# \t\r\n]+" tag-name))))
-
 (defn pp-str [x]
   #_:clj-kondo/ignore
   (with-out-str (clojure.pprint/pprint x)))
@@ -905,8 +866,8 @@
      []
      (let [user-agent js/navigator.userAgent
            vendor js/navigator.vendor]
-       (and (safe-re-find #"Chrome" user-agent)
-            (safe-re-find #"Google Inc" vendor)))))
+       (and (gp-util/safe-re-find #"Chrome" user-agent)
+            (gp-util/safe-re-find #"Google Inc" vendor)))))
 
 #?(:cljs
    (defn indexeddb-check?
@@ -947,24 +908,26 @@
      [block-id]
      (when block-id
        (let [block-id (str block-id)]
-         (when (uuid-string? block-id)
+         (when (gp-util/uuid-string? block-id)
            (first (array-seq (js/document.getElementsByClassName block-id))))))))
 
 (def windows-reserved-chars #"[:\\*\\?\"<>|]+")
 
-(defn include-windows-reserved-chars?
-  [s]
-  (safe-re-find windows-reserved-chars s))
+#?(:cljs
+   (do
+     (defn include-windows-reserved-chars?
+      [s]
+       (gp-util/safe-re-find windows-reserved-chars s))
 
-(defn create-title-property?
-  [s]
-  (and (string? s)
-       (or (include-windows-reserved-chars? s)
-           (string/includes? s "_")
-           (string/includes? s "/")
-           (string/includes? s ".")
-           (string/includes? s "%")
-           (string/includes? s "#"))))
+     (defn create-title-property?
+       [s]
+       (and (string? s)
+            (or (include-windows-reserved-chars? s)
+                (string/includes? s "_")
+                (string/includes? s "/")
+                (string/includes? s ".")
+                (string/includes? s "%")
+                (string/includes? s "#"))))))
 
 (defn remove-boundary-slashes
   [s]
@@ -979,10 +942,6 @@
 (defn normalize
   [s]
   (.normalize s "NFC"))
-(defn path-normalize
-  "Normalize file path (for reading paths from FS, not required by writting)"
-  [s]
-  (.normalize s "NFC"))
 
 #?(:cljs
    (defn search-normalize

+ 3 - 2
src/main/frontend/util/drawer.cljs

@@ -1,6 +1,7 @@
 (ns frontend.util.drawer
   (:require [clojure.string :as string]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.util.property :as property]
             [frontend.format.mldoc :as mldoc]))
 
@@ -86,8 +87,8 @@
 
 (defn contains-logbook?
   [content]
-  (and (util/safe-re-find (re-pattern (str "(?i)" logbook-start)) content)
-       (util/safe-re-find (re-pattern (str "(?i)" drawer-end)) content)))
+  (and (gp-util/safe-re-find (re-pattern (str "(?i)" logbook-start)) content)
+       (gp-util/safe-re-find (re-pattern (str "(?i)" drawer-end)) content)))
 
 ;; TODO: DRY
 (defn remove-logbook

+ 4 - 3
src/main/frontend/util/marker.cljs

@@ -1,6 +1,7 @@
 (ns frontend.util.marker
   (:require [clojure.string :as string]
-            [frontend.util :as util]))
+            [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]))
 
 (defn marker-pattern [format]
   (re-pattern
@@ -20,7 +21,7 @@
         (if-let [matches (seq (util/re-pos new-line-re-pattern content))]
           (let [[start-pos content] (last matches)]
             (+ start-pos (count content)))
-          (count (util/safe-re-find re-pattern content)))
+          (count (gp-util/safe-re-find re-pattern content)))
         new-content
         (str (subs content 0 pos)
              (string/replace-first (subs content pos)
@@ -59,6 +60,6 @@
   (let [content    (string/triml content)
         new-marker (or new-marker
                        (cycle-marker-state (or marker
-                                               (last (util/safe-re-find (marker-pattern format) content))) ; Returns the last matching group (last vec)
+                                               (last (gp-util/safe-re-find (marker-pattern format) content))) ; Returns the last matching group (last vec)
                                            preferred-workflow))]
     [(add-or-update-marker content format new-marker) new-marker]))

+ 3 - 2
src/main/frontend/util/priority.cljs

@@ -1,12 +1,13 @@
 (ns frontend.util.priority
   (:require [clojure.string :as string]
             [frontend.util :as util]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.util.marker :as marker]))
 
 (defn cycle-priority-state
   [content]
   (let [priority-reg #"\[#([ABC]{1})\]\s{1}"
-        priority (last (util/safe-re-find priority-reg content))
+        priority (last (gp-util/safe-re-find priority-reg content))
         next-priority (case priority
                         "A" "B"
 
@@ -28,7 +29,7 @@
         (if-let [matches (seq (util/re-pos new-line-re-pattern content))]
           (let [[start-pos content] (last matches)]
             (+ start-pos (count content)))
-          (count (util/safe-re-find re-pattern content)))
+          (count (gp-util/safe-re-find re-pattern content)))
         skip-marker-pos
         (if-let [matches (seq (util/re-pos marker/bare-marker-pattern (subs content skip-hash-pos)))]
           (let [[start-pos content] (last matches)]

+ 10 - 9
src/main/frontend/util/property.cljs

@@ -4,6 +4,7 @@
             [clojure.set :as set]
             [frontend.config :as config]
             [medley.core :as medley]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.format.mldoc :as mldoc]
             [frontend.text :as text]
             [frontend.util.cursor :as cursor]))
@@ -38,7 +39,7 @@
   [content]
   (when content
     (and (string/includes? content properties-start)
-         (util/safe-re-find properties-end-pattern content))))
+         (gp-util/safe-re-find properties-end-pattern content))))
 
 (defn remove-empty-properties
   [content]
@@ -52,28 +53,28 @@
   [line]
   (boolean
    (and (string? line)
-        (util/safe-re-find #"^\s?[^ ]+:: " line))))
+        (gp-util/safe-re-find #"^\s?[^ ]+:: " line))))
 
 (defn front-matter-property?
   [line]
   (boolean
    (and (string? line)
-        (util/safe-re-find #"^\s*[^ ]+: " line))))
+        (gp-util/safe-re-find #"^\s*[^ ]+: " line))))
 
 (defn get-property-key
   [line format]
   (and (string? line)
        (when-let [key (last
                        (if (= format :org)
-                         (util/safe-re-find #"^\s*:([^: ]+): " line)
-                         (util/safe-re-find #"^\s*([^ ]+):: " line)))]
+                         (gp-util/safe-re-find #"^\s*:([^: ]+): " line)
+                         (gp-util/safe-re-find #"^\s*([^ ]+):: " line)))]
          (keyword key))))
 
 (defn org-property?
   [line]
   (boolean
    (and (string? line)
-        (util/safe-re-find #"^\s*:[^: ]+: " line)
+        (gp-util/safe-re-find #"^\s*:[^: ]+: " line)
         (when-let [key (get-property-key line :org)]
           (not (contains? #{:PROPERTIES :END} key))))))
 
@@ -265,7 +266,7 @@
                           middle (doall
                                   (->> (subvec lines (inc start-idx) end-idx)
                                        (mapv (fn [text]
-                                               (let [[k v] (util/split-first ":" (subs text 1))]
+                                               (let [[k v] (gp-util/split-first ":" (subs text 1))]
                                                  (if (and k v)
                                                    (let [key-exists? (= k key)
                                                          _ (when key-exists? (reset! exists? true))
@@ -288,7 +289,7 @@
                                                     (if (property-f (first lines))
                                                       (let [lines (doall
                                                                    (mapv (fn [text]
-                                                                           (let [[k v] (util/split-first sym text)]
+                                                                           (let [[k v] (gp-util/split-first sym text)]
                                                                              (if (and k v)
                                                                                (let [key-exists? (= k key)
                                                                                      _ (when key-exists? (reset! exists? true))
@@ -375,7 +376,7 @@
         (let [before (subvec lines 0 start-idx)
               middle (->> (subvec lines (inc start-idx) end-idx)
                           (map (fn [text]
-                                 (let [[k v] (util/split-first ":" (subs text 1))]
+                                 (let [[k v] (gp-util/split-first ":" (subs text 1))]
                                    (if (and k v)
                                      (let [k (string/replace k "_" "-")
                                            compare-k (keyword (string/lower-case k))

+ 3 - 2
src/main/logseq/api.cljs

@@ -36,6 +36,7 @@
             [promesa.core :as p]
             [reitit.frontend.easy :as rfe]
             [sci.core :as sci]
+            [logseq.graph-parser.util :as gp-util]
             [frontend.version :as fv]
             [frontend.handler.shell :as shell]
             [frontend.modules.layout.core]))
@@ -636,7 +637,7 @@
 
 (defn ^:export prepend_block_in_page
   [uuid-or-page-name content ^js opts]
-  (let [page? (not (util/uuid-string? uuid-or-page-name))
+  (let [page? (not (gp-util/uuid-string? uuid-or-page-name))
         page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
         _ (and page-not-exist? (page-handler/create! uuid-or-page-name
                                  {:redirect? false
@@ -652,7 +653,7 @@
 
 (defn ^:export append_block_in_page
   [uuid-or-page-name content ^js opts]
-  (let [page? (not (util/uuid-string? uuid-or-page-name))
+  (let [page? (not (gp-util/uuid-string? uuid-or-page-name))
         page-not-exist? (and page? (nil? (db-model/get-page uuid-or-page-name)))
         _ (and page-not-exist? (page-handler/create! uuid-or-page-name
                                  {:redirect? false

+ 50 - 0
src/main/logseq/graph_parser/util.cljs

@@ -0,0 +1,50 @@
+(ns logseq.graph-parser.util
+  "Util fns shared between graph-parser and rest of app. Util fns only rely on
+  clojure standard libraries."
+  (:require [clojure.walk :as walk]
+            [clojure.string :as string]))
+
+(def uuid-pattern "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}")
+(defonce exactly-uuid-pattern (re-pattern (str "(?i)^" uuid-pattern "$")))
+
+(defn safe-re-find
+  [pattern s]
+  (when-not (string? s)
+    ;; TODO: sentry
+    (js/console.trace))
+  (when (string? s)
+    (re-find pattern s)))
+
+(defn uuid-string?
+  [s]
+  (safe-re-find exactly-uuid-pattern s))
+
+(defn path-normalize
+  "Normalize file path (for reading paths from FS, not required by writting)"
+  [s]
+  (.normalize s "NFC"))
+
+(defn remove-nils
+  "remove pairs of key-value that has nil value from a (possibly nested) map."
+  [nm]
+  (walk/postwalk
+   (fn [el]
+     (if (map? el)
+       (into {} (remove (comp nil? second)) el)
+       el))
+   nm))
+
+(defn split-first [pattern s]
+  (when-let [first-index (string/index-of s pattern)]
+    [(subs s 0 first-index)
+     (subs s (+ first-index (count pattern)) (count s))]))
+
+(defn split-last [pattern s]
+  (when-let [last-index (string/last-index-of s pattern)]
+    [(subs s 0 last-index)
+     (subs s (+ last-index (count pattern)) (count s))]))
+
+(defn tag-valid?
+  [tag-name]
+  (when (string? tag-name)
+    (not (safe-re-find #"[# \t\r\n]+" tag-name))))