Pārlūkot izejas kodu

Merge pull request #6529 from logseq/refactor/refs-from-property-values

Refactor: extract references from property values
Gabriel Horner 3 gadi atpakaļ
vecāks
revīzija
4c3503ff1e
30 mainītis faili ar 509 papildinājumiem un 646 dzēšanām
  1. 5 1
      deps/db/src/logseq/db/schema.cljs
  2. 7 0
      deps/graph-parser/.carve/ignore
  3. 1 2
      deps/graph-parser/deps.edn
  4. 1 1
      deps/graph-parser/package.json
  5. 57 75
      deps/graph-parser/src/logseq/graph_parser/block.cljs
  6. 76 72
      deps/graph-parser/src/logseq/graph_parser/extract.cljc
  7. 38 87
      deps/graph-parser/src/logseq/graph_parser/mldoc.cljc
  8. 5 7
      deps/graph-parser/src/logseq/graph_parser/property.cljs
  9. 1 1
      deps/graph-parser/src/logseq/graph_parser/test/docs_graph_helper.cljs
  10. 87 161
      deps/graph-parser/src/logseq/graph_parser/text.cljs
  11. 0 8
      deps/graph-parser/src/logseq/graph_parser/util/page_ref.cljs
  12. 38 28
      deps/graph-parser/test/logseq/graph_parser/block_test.cljs
  13. 28 29
      deps/graph-parser/test/logseq/graph_parser/mldoc_test.cljs
  14. 1 14
      deps/graph-parser/test/logseq/graph_parser/property_test.cljs
  15. 44 54
      deps/graph-parser/test/logseq/graph_parser/text_test.cljs
  16. 68 52
      deps/graph-parser/test/logseq/graph_parser_test.cljs
  17. 4 4
      deps/graph-parser/yarn.lock
  18. 1 1
      package.json
  19. 11 10
      src/main/frontend/components/block.cljs
  20. 1 0
      src/main/frontend/db/model.cljs
  21. 8 3
      src/main/frontend/db/query_dsl.cljs
  22. 3 1
      src/main/frontend/format/block.cljs
  23. 5 5
      src/main/frontend/format/mldoc.cljs
  24. 3 4
      src/main/frontend/handler/editor.cljs
  25. 3 1
      src/main/frontend/handler/external.cljs
  26. 1 2
      src/main/frontend/handler/page.cljs
  27. 1 0
      src/main/frontend/modules/outliner/core.cljs
  28. 3 15
      src/test/frontend/db/query_dsl_test.cljs
  29. 4 4
      templates/config.edn
  30. 4 4
      yarn.lock

+ 5 - 1
deps/db/src/logseq/db/schema.cljs

@@ -52,10 +52,12 @@
    ;; "A", "B", "C"
    :block/priority {}
 
-   ;; block key value properties
+   ;; map, key -> set of refs in property value or full text if none are found
    :block/properties {}
    ;; vector
    :block/properties-order {}
+   ;; map, key -> original property value's content
+   :block/properties-text-values {}
 
    ;; first block that's not a heading or unordered list
    :block/pre-block? {}
@@ -118,6 +120,7 @@
     :block/type
     :block/properties
     :block/properties-order
+    :block/properties-text-values
     :block/invalid-properties
     :block/created-at
     :block/updated-at
@@ -136,6 +139,7 @@
     :block/content
     :block/properties
     :block/properties-order
+    :block/properties-text-values
     :block/invalid-properties
     :block/alias
     :block/tags})

+ 7 - 0
deps/graph-parser/.carve/ignore

@@ -3,6 +3,8 @@ logseq.graph-parser.cli/parse-graph
 ;; For CLI
 logseq.graph-parser.mldoc/ast-export-markdown
 ;; API
+logseq.graph-parser.mldoc/link?
+;; API
 logseq.graph-parser.property/register-built-in-properties
 ;; API
 logseq.graph-parser.util.block-ref/left-and-right-parens
@@ -20,6 +22,11 @@ logseq.graph-parser.util.page-ref/->page-ref
 logseq.graph-parser.util.page-ref/get-page-name!
 ;; API
 logseq.graph-parser.config/remove-asset-protocol
+;; API
+logseq.graph-parser.util/unquote-string
+;; API
+logseq.graph-parser.util.page-ref/page-ref-re
+;; API
 logseq.graph-parser.property/->block-content
 ;; API
 logseq.graph-parser.property/property-value-from-content

+ 1 - 2
deps/graph-parser/deps.edn

@@ -1,8 +1,7 @@
 {:paths ["src"]
  :deps
  ;; External deps should be kept in sync with https://github.com/logseq/nbb-logseq/blob/main/bb.edn
- {frankiesardo/linked {:mvn/version "1.3.0"}
-  com.andrewmcveigh/cljs-time {:git/url "https://github.com/logseq/cljs-time" ;; fork
+ {com.andrewmcveigh/cljs-time {:git/url "https://github.com/logseq/cljs-time" ;; fork
                                :sha     "5704fbf48d3478eedcf24d458c8964b3c2fd59a9"}
   ;; local dep
   logseq/db {:local/root "../db"}

+ 1 - 1
deps/graph-parser/package.json

@@ -6,7 +6,7 @@
     "@logseq/nbb-logseq": "^0.7.133"
   },
   "dependencies": {
-    "mldoc": "^1.3.9"
+    "mldoc": "^1.4.9"
   },
   "scripts": {
     "test": "nbb-logseq -cp src:test:../db/src -m logseq.graph-parser.nbb-test-runner/run-tests"

+ 57 - 75
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -146,99 +146,76 @@
 (defn- get-page-refs-from-property-names
   [properties {:property-pages/keys [enabled? excludelist]}]
   (if (contains? #{true nil} enabled?)
-    (some->> properties
-             (map (comp name first))
-             (remove string/blank?)
-             (remove (set (map name excludelist)))
-             ;; Remove built-in properties as we don't want pages
-             ;; created for them by default
-             (remove (set (map name (into (gp-property/editable-built-in-properties)
-                                          (gp-property/hidden-built-in-properties)))))
-             distinct)
+    (sequence
+     (comp (map (comp name first))
+           (remove string/blank?)
+           (remove (set (map name excludelist)))
+           ;; Remove built-in properties as we don't want pages
+           ;; created for them by default
+           (remove (into #{}
+                         (map name)
+                         (apply conj
+                                (gp-property/editable-built-in-properties)
+                                (gp-property/hidden-built-in-properties))))
+           (distinct))
+     properties)
     []))
 
-;; TODO: Use text/parse-property to determine refs rather than maintain this similar
-;; implementation to parse-property
 (defn- get-page-ref-names-from-properties
-  [format properties user-config]
+  [properties user-config]
   (let [page-refs (->>
                    properties
                    (remove (fn [[k _]]
                              (contains?
                               (set/union (apply disj
-                                           (gp-property/editable-built-in-properties)
-                                           gp-property/editable-linkable-built-in-properties)
+                                                (gp-property/editable-built-in-properties)
+                                                gp-property/editable-linkable-built-in-properties)
                                          (gp-property/hidden-built-in-properties))
                               (keyword k))))
+                   ;; get links ast
                    (map last)
-                   (map (fn [v]
-                          (cond
-                            (and (string? v)
-                                 (not (gp-mldoc/link? format v)))
-                            (let [v (string/trim v)
-                                  result (if (:rich-property-values? user-config)
-                                           (if (gp-util/wrapped-by-quotes? v)
-                                             []
-                                             (text/extract-page-refs-and-tags v))
-                                           (text/split-page-refs-without-brackets v {:un-brackets? false}))]
-                              (if (coll? result)
-                                (map text/page-ref-un-brackets! result)
-                                []))
-
-                            (coll? v)
-                            (map (fn [s]
-                                   (when-not (and (string? v)
-                                                  (gp-mldoc/link? format v))
-                                     (text/page-ref-un-brackets! s))) v)
-
-                            :else
-                            nil)))
-                   (apply concat))
+                   (mapcat (or (:extract-refs-from-property-value-fn user-config)
+                               text/extract-refs-from-mldoc-ast))
+                   ;; comma separated collections
+                   (concat (->> (map second properties)
+                                (filter coll?)
+                                (apply concat))))
         page-refs-from-property-names (get-page-refs-from-property-names properties user-config)]
     (->> (concat page-refs page-refs-from-property-names)
          (remove string/blank?)
          distinct)))
 
 (defn extract-properties
-  [format properties user-config]
+  [properties user-config]
   (when (seq properties)
     (let [properties (seq properties)
-          page-refs (get-page-ref-names-from-properties format properties user-config)
           *invalid-properties (atom #{})
           properties (->> properties
-                          (map (fn [[k v]]
-                                 (let [k (-> (string/lower-case (name k))
+                          (map (fn [[k v mldoc-ast]]
+                                 (let [k (if (or (keyword? k) (symbol? k))
+                                           (subs (str k) 1)
+                                           k)
+                                       k (-> (string/lower-case k)
                                              (string/replace " " "-")
-                                             (string/replace "_" "-")
-                                             (string/replace #"[\"|^|(|)|{|}]+" ""))]
+                                             (string/replace "_" "-"))]
                                    (if (gp-property/valid-property-name? (str ":" k))
-                                     (let [k (if (contains? #{"custom_id" "custom-id"} k)
-                                               "id"
-                                               k)
-                                           v (if (coll? v)
-                                               (remove string/blank? v)
-                                               (cond
-                                                 (string/blank? v)
-                                                 nil
-                                                 (and (= (keyword k) :file-path)
-                                                      (string/starts-with? v "file:"))
-                                                 v
-                                                 :else
-                                                 (text/parse-property format k v user-config)))
-                                           k (keyword k)
-                                           v (if (and
-                                                  (string? v)
-                                                  (contains? gp-property/editable-linkable-built-in-properties k))
-                                               (set [v])
-                                               v)
-                                           v (if (coll? v) (set v) v)]
-                                       [k v])
+                                     (let [k' (keyword
+                                               (if (contains? #{"custom_id" "custom-id"} k)
+                                                 "id"
+                                                 k))
+                                           v' (text/parse-property k v mldoc-ast user-config)]
+                                       [k' v' mldoc-ast v])
                                      (do (swap! *invalid-properties conj k)
                                          nil)))))
                           (remove #(nil? (second %))))
+          page-refs (get-page-ref-names-from-properties properties user-config)
+          properties-text-values (->> (map (fn [[k _v _refs original-text]] [k original-text]) properties)
+                                      (into {}))
+          properties (map (fn [[k v _]] [k v]) properties)
           properties' (into {} properties)]
       {:properties properties'
        :properties-order (map first properties)
+       :properties-text-values properties-text-values
        :invalid-properties @*invalid-properties
        :page-refs page-refs})))
 
@@ -444,8 +421,8 @@
       (d/squuid)))
 
 (defn get-page-refs-from-properties
-  [format properties db date-formatter user-config]
-  (let [page-refs (get-page-ref-names-from-properties format properties user-config)]
+  [properties db date-formatter user-config]
+  (let [page-refs (get-page-ref-names-from-properties properties user-config)]
     (map (fn [page] (page-name->map page true db true date-formatter)) page-refs)))
 
 (defn- with-page-block-refs
@@ -524,10 +501,9 @@
      ast)
     (mapv macro->block @*result)))
 
-(defn- with-pre-block-if-exists
+(defn with-pre-block-if-exists
   [blocks body pre-block-properties encoded-content {:keys [supported-formats db date-formatter user-config]}]
   (let [first-block (first blocks)
-        format (or (:block/format first-block) :markdown)
         first-block-start-pos (get-in first-block [:block/meta :start_pos])
 
         ;; Add pre-block
@@ -536,15 +512,22 @@
                  (cons
                   (merge
                    (let [content (utf8/substring encoded-content 0 first-block-start-pos)
-                         {:keys [properties properties-order invalid-properties]} pre-block-properties
+                         {:keys [properties properties-order properties-text-values invalid-properties]} pre-block-properties
                          id (get-custom-id-or-new-id {:properties properties})
-                         property-refs (->> (get-page-refs-from-properties format properties db date-formatter user-config)
+                         property-refs (->> (get-page-refs-from-properties
+                                             properties db date-formatter
+                                             (assoc user-config
+                                                    :extract-refs-from-property-value-fn
+                                                    (fn [refs]
+                                                      (when (coll? refs)
+                                                        refs))))
                                             (map :block/original-name))
                          block {:uuid id
                                 :content content
                                 :level 1
                                 :properties properties
                                 :properties-order (vec properties-order)
+                                :properties-text-values properties-text-values
                                 :invalid-properties invalid-properties
                                 :refs property-refs
                                 :pre-block? true
@@ -579,10 +562,9 @@
                        :format format
                        :meta pos-meta)
                 (seq (:properties properties))
-                (assoc :properties (:properties properties))
-
-                (seq (:properties-order properties))
-                (assoc :properties-order (vec (:properties-order properties)))
+                (assoc :properties (:properties properties)
+                       :properties-text-values (:properties-text-values properties)
+                       :properties-order (vec (:properties-order properties)))
 
                 (seq (:invalid-properties properties))
                 (assoc :invalid-properties (:invalid-properties properties)))
@@ -639,7 +621,7 @@
                   (recur headings (rest blocks) timestamps' properties body))
 
                 (gp-property/properties-ast? block)
-                (let [properties (extract-properties format (second block) user-config)]
+                (let [properties (extract-properties (second block) (assoc user-config :format format))]
                   (recur headings (rest blocks) timestamps properties body))
 
                 (heading-block? block)

+ 76 - 72
deps/graph-parser/src/logseq/graph_parser/extract.cljc

@@ -24,9 +24,10 @@
     (if (string/includes? file "pages/contents.")
       "Contents"
       (let [first-block (last (first (filter gp-block/heading-block? ast)))
-            property-name (when (and (contains? #{"Properties" "Property_Drawer"} (ffirst ast))
-                                     (not (string/blank? (:title (last (first ast))))))
-                            (:title (last (first ast))))
+            property-name (when (contains? #{"Properties" "Property_Drawer"} (ffirst ast))
+                            (let [properties-ast (second (first ast))
+                                  properties (zipmap (map (comp keyword first) properties-ast) (map second properties-ast))]
+                              (:title properties)))
             first-block-name (let [title (last (first (:title first-block)))]
                                (and first-block
                                     (string? title)
@@ -41,62 +42,69 @@
               (or first-block-name file-name)
               (or file-name first-block-name)))))))
 
-(defn- build-page-entity
-  [properties file page-name page ref-tags {:keys [date-formatter db from-page]}]
+(defn- extract-page-alias-and-tags
+  [page-m page page-name properties]
   (let [alias (:alias properties)
-        alias' (if (string? alias) [alias] alias)
+        alias' (if (coll? alias) alias [(str alias)])
         aliases (and alias'
                      (seq (remove #(or (= page-name (gp-util/page-name-sanity-lc %))
                                        (string/blank? %)) ;; disable blank alias
                                   alias')))
-        aliases' (->>
-                 (map
-                  (fn [alias]
-                    (let [page-name (gp-util/page-name-sanity-lc alias)
-                          aliases (distinct
-                                   (conj
-                                    (remove #{alias} aliases)
-                                    page))
-                          aliases (when (seq aliases)
-                                    (map
-                                     (fn [alias]
-                                       {:block/name (gp-util/page-name-sanity-lc alias)})
-                                     aliases))]
-                      (if (seq aliases)
-                        {:block/name page-name
-                         :block/alias aliases}
-                        {:block/name page-name})))
-                  aliases)
-                 (remove nil?))
-        [*valid-properties *invalid-properties]
+        aliases' (keep
+                   (fn [alias]
+                     (let [page-name (gp-util/page-name-sanity-lc alias)
+                           aliases (distinct
+                                    (conj
+                                     (remove #{alias} aliases)
+                                     page))
+                           aliases (when (seq aliases)
+                                     (map
+                                       (fn [alias]
+                                         {:block/name (gp-util/page-name-sanity-lc alias)})
+                                       aliases))]
+                       (if (seq aliases)
+                         {:block/name page-name
+                          :block/original-name alias
+                          :block/alias aliases}
+                         {:block/name page-name
+                          :block/original-name alias})))
+                   aliases)
+        result (cond-> page-m
+                 (seq aliases')
+                 (assoc :block/alias aliases')
+
+                 (:tags properties)
+                 (assoc :block/tags (let [tags (:tags properties)
+                                          tags (if (coll? tags) tags [(str tags)])
+                                          tags (remove string/blank? tags)]
+                                      (map (fn [tag] {:block/name (gp-util/page-name-sanity-lc tag)
+                                                      :block/original-name tag})
+                                        tags))))]
+    (update result :block/properties #(apply dissoc % gp-property/editable-linkable-built-in-properties))))
+
+(defn- build-page-map
+  [properties invalid-properties file page page-name {:keys [date-formatter db from-page]}]
+  (let [[*valid-properties *invalid-properties]
         ((juxt filter remove)
          (fn [[k _v]] (gp-property/valid-property-name? (str k))) properties)
         valid-properties (into {} *valid-properties)
-        invalid-properties (set (map (comp name first) *invalid-properties))]
+        invalid-properties (set (->> (map (comp name first) *invalid-properties)
+                                     (concat invalid-properties)))
+        page-m (->
+                (gp-util/remove-nils
+                 (assoc
+                  (gp-block/page-name->map page false db true date-formatter
+                                           :from-page from-page)
+                  :block/file {:file/path (gp-util/path-normalize file)}))
+                (extract-page-alias-and-tags page page-name properties))]
     (cond->
-     (gp-util/remove-nils
-      (assoc
-       (gp-block/page-name->map page false db true date-formatter
-                                :from-page from-page)
-       :block/file {:file/path (gp-util/path-normalize file)}))
-
-     (seq valid-properties)
-     (assoc :block/properties valid-properties)
+      page-m
 
-     (seq invalid-properties)
-     (assoc :block/invalid-properties invalid-properties)
+      (seq valid-properties)
+      (assoc :block/properties valid-properties)
 
-     (seq aliases')
-     (assoc :block/alias aliases')
-
-     (:tags properties)
-     (assoc :block/tags (let [tags (:tags properties)
-                              tags (if (string? tags) [tags] tags)
-                              tags (remove string/blank? tags)]
-                          (swap! ref-tags set/union (set tags))
-                          (map (fn [tag] {:block/name (gp-util/page-name-sanity-lc tag)
-                                          :block/original-name tag})
-                               tags))))))
+      (seq invalid-properties)
+      (assoc :block/invalid-properties invalid-properties))))
 
 ;; TODO: performance improvement
 (defn- extract-pages-and-blocks
@@ -104,10 +112,14 @@
   (try
     (let [page (get-page-name file ast page-name-order)
           [page page-name _journal-day] (gp-block/convert-page-if-journal page date-formatter)
-          blocks (->> (gp-block/extract-blocks ast content false format (dissoc options :page-name-order))
-                      (gp-block/with-parent-and-left {:block/name page-name}))
+          options' (-> options
+                       (assoc :page-name page-name
+                              :original-page-name page)
+                       (dissoc :page-name-order))
+          blocks (->> (gp-block/extract-blocks ast content false format options')
+                      (gp-block/with-parent-and-left {:block/name page-name})
+                      (vec))
           ref-pages (atom #{})
-          ref-tags (atom #{})
           blocks (map (fn [block]
                         (if (contains? #{"macro"} (:block/type block))
                           block
@@ -124,22 +136,20 @@
                                        :block/refs block-ref-pages
                                        :block/path-refs block-path-ref-pages)))))
                    blocks)
-          page-entity (build-page-entity properties file page-name page ref-tags
-                                         (assoc options :from-page page))
-          namespace-pages (let [page (:block/original-name page-entity)]
+          [properties invalid-properties] (if (:block/pre-block? (first blocks))
+                                            [(:block/properties (first blocks))
+                                             (:block/invalid-properties (first blocks))]
+                                            [properties []])
+          page-map (build-page-map properties invalid-properties file page page-name (assoc options' :from-page page))
+          namespace-pages (let [page (:block/original-name page-map)]
                             (when (text/namespace-page? page)
                               (->> (gp-util/split-namespace-pages page)
                                    (map (fn [page]
                                           (-> (gp-block/page-name->map page true db true date-formatter)
                                               (assoc :block/format format)))))))
           pages (->> (concat
-                      [page-entity]
+                      [page-map]
                       @ref-pages
-                      (map
-                       (fn [page]
-                         {:block/original-name page
-                          :block/name (gp-util/page-name-sanity-lc page)})
-                       @ref-tags)
                       namespace-pages)
                      ;; remove block references
                      (remove vector?)
@@ -162,18 +172,16 @@
           _ (when verbose (println "Parsing start: " file))
           ast (gp-mldoc/->edn content (gp-mldoc/default-config format
                                         ;; {:parse_outline_only? true}
-                                        )
-                              user-config)]
+                                        ))]
       (when verbose (println "Parsing finished: " file))
       (let [first-block (ffirst ast)
             properties (let [properties (and (gp-property/properties-ast? first-block)
                                              (->> (last first-block)
-                                                  (map (fn [[x y]]
-                                                         [x (if (and (string? y)
-                                                                     (not (and (= (keyword x) :file-path)
-                                                                               (string/starts-with? y "file:"))))
-                                                              (text/parse-property format x y user-config)
-                                                              y)]))
+                                                  (map (fn [[x y mldoc-ast]]
+                                                         (let [k (if (keyword? x)
+                                                                   (subs (str x) 1)
+                                                                   x)]
+                                                           [(string/lower-case k) (text/parse-property k y mldoc-ast (assoc user-config :format format))])))
                                                   (into {})
                                                   (walk/keywordize-keys)))]
                          (when (and properties (seq properties))
@@ -204,7 +212,3 @@
          vals
          (map (partial apply merge))
          (with-block-uuid))))
-
-;; TODO: Properly fix this circular dependency:
-;; mldoc/->edn > text/parse-property > mldoc/link? ->mldoc/inline->edn + mldoc/default-config
-(set! gp-mldoc/parse-property text/parse-property)

+ 38 - 87
deps/graph-parser/src/logseq/graph_parser/mldoc.cljc

@@ -12,13 +12,13 @@
             [cljs-bean.core :as bean]
             [logseq.graph-parser.utf8 :as utf8]
             [clojure.string :as string]
-            [linked.core :as linked]
             [logseq.graph-parser.util :as gp-util]
             [logseq.graph-parser.config :as gp-config]))
 
 (defonce parseJson (gobj/get Mldoc "parseJson"))
 (defonce parseInlineJson (gobj/get Mldoc "parseInlineJson"))
 (defonce astExportMarkdown (gobj/get Mldoc "astExportMarkdown"))
+(defonce getReferences (gobj/get Mldoc "getReferences"))
 
 (def default-references
   (js/JSON.stringify
@@ -42,6 +42,11 @@
   [text config]
   (parseInlineJson text config))
 
+(defn get-references
+  [text config]
+  (when-not (string/blank? text)
+    (gp-util/json->clj (getReferences text config))))
+
 (defn ast-export-markdown
   [ast config references]
   (astExportMarkdown ast
@@ -95,85 +100,27 @@
               [block pos-meta])
             [block pos-meta])) ast)))
 
-(defn- ->vec
-  [s]
-  (if (string? s) [s] s))
-
-(defn- ->vec-concat
-  [& coll]
-  (->> (map ->vec coll)
-       (remove nil?)
-       (apply concat)
-       (distinct)))
-
 (defn collect-page-properties
-  [ast parse-property config-state]
-  (if (seq ast)
+  [ast config]
+  (when (seq ast)
     (let [original-ast ast
-          ast (map first ast)           ; without position meta
           directive? (fn [[item _]] (= "directive" (string/lower-case (first item))))
           grouped-ast (group-by directive? original-ast)
-          directive-ast (take-while directive? original-ast)
-          [properties-ast other-ast] (if (= "Property_Drawer" (ffirst ast))
-                                       [(last (first ast))
-                                        (rest original-ast)]
-                                       [(->> (map first directive-ast)
-                                             (map rest))
-                                        (get grouped-ast false)])
-          properties (->>
-                      properties-ast
-                      (map (fn [[k v]]
-                             (let [k (keyword (string/lower-case k))
-                                   v (if (contains? #{:title :description :filters :macro} k)
-                                       v
-                                       (parse-property k v config-state))]
-                               [k v]))))
-          properties (into (linked/map) properties)
-          macro-properties (filter (fn [x] (= :macro (first x))) properties)
-          macros (if (seq macro-properties)
-                   (->>
-                    (map
-                     (fn [[_ v]]
-                       (let [[k v] (gp-util/split-first " " v)]
-                         (mapv
-                          string/trim
-                          [k v])))
-                     macro-properties)
-                    (into {}))
-                   {})
-          properties (->> (remove (fn [x] (= :macro (first x))) properties)
-                          (into (linked/map)))
-          properties (cond-> properties
-                             (seq macros)
-                             (assoc :macros macros))
-          alias (:alias properties)
-          alias (when alias
-                  (if (coll? alias)
-                    (remove string/blank? alias)
-                    [alias]))
-          filetags (when-let [org-file-tags (:filetags properties)]
-                     (->> (string/split org-file-tags ":")
-                          (remove string/blank?)))
-          tags (:tags properties)
-          tags (->> (->vec-concat tags filetags)
-                    (remove string/blank?)
-                    vec)
-          properties (assoc properties :tags tags :alias alias)
-          properties (-> properties
-                         (update :filetags (constantly filetags)))
-          properties (into (linked/map)
-                           (remove (fn [[_k v]]
-                                     (or (nil? v) (and (coll? v) (empty? v))))
-                                   properties))]
+          [properties-ast other-ast] [(->> (get grouped-ast true)
+                                           (map first))
+                                      (get grouped-ast false)]
+          properties (map (fn [[_directive k v]]
+                            (let [kname (string/lower-case k)
+                                  k (keyword kname)
+                                  mldoc-ast (get-references v config)]
+                              [k v mldoc-ast]))
+                       properties-ast)]
       (if (seq properties)
         (cons [["Properties" properties] nil] other-ast)
-        original-ast))
-    ast))
-
-(def parse-property nil)
+        original-ast))))
 
 (defn ->edn
-  [content config config-state]
+  [content config]
   (if (string? content)
     (try
       (if (string/blank? content)
@@ -182,7 +129,7 @@
             (parse-json config)
             (gp-util/json->clj)
             (update-src-full-content content)
-            (collect-page-properties parse-property config-state)))
+            (collect-page-properties config)))
       (catch :default e
         (log/error :unexpected-error e)
         []))
@@ -199,20 +146,24 @@
     (catch :default _e
       [])))
 
+(defn ast-link?
+  [[type link]]
+  (let [[ref-type ref-value] (:url link)]
+    (and (= "Link" type)
+         (or
+          ;; 1. url
+          (not (contains? #{"Page_ref" "Block_ref"} ref-type))
+
+          (and (contains? #{"Page_ref"} ref-type)
+               (or
+                ;; 2. excalidraw link
+                (gp-config/draw? ref-value)
+
+                ;; 3. local asset link
+                (boolean (gp-config/local-asset? ref-value))))))))
+
 (defn link?
   [format link]
   (when (string? link)
-    (let [[type link] (first (inline->edn link (default-config format)))
-          [ref-type ref-value] (:url link)]
-      (and (= "Link" type)
-           (or
-            ;; 1. url
-            (not (contains? #{"Page_ref" "Block_ref"} ref-type))
-
-            (and (contains? #{"Page_ref"} ref-type)
-                 (or
-                  ;; 2. excalidraw link
-                  (gp-config/draw? ref-value)
-
-                  ;; 3. local asset link
-                  (boolean (gp-config/local-asset? ref-value)))))))))
+    (some-> (first (inline->edn link (default-config format)))
+            ast-link?)))

+ 5 - 7
deps/graph-parser/src/logseq/graph_parser/property.cljs

@@ -15,13 +15,11 @@
        (map #(str (name (key %)) (str colons " ") (val %)))
        (string/join "\n")))
 
-(defn property-value-from-content
-  "Extracts full property value from block content"
-  [property content]
-  (second (re-find (re-pattern (str property colons "\\s+(.*)"))
-                   content)))
-
-(def valid-property-name? gp-util/valid-edn-keyword?)
+(defn valid-property-name?
+  [s]
+  [:pre (string? s)]
+  (and (gp-util/valid-edn-keyword? s)
+       (not (re-find #"[\"|^|(|)|{|}]+" s))))
 
 (defn properties-ast?
   [block]

+ 1 - 1
deps/graph-parser/src/logseq/graph_parser/test/docs_graph_helper.cljs

@@ -142,7 +142,7 @@
   ;; only increase over time as the docs graph rarely has deletions
   (testing "Counts"
     (is (= 211 (count files)) "Correct file count")
-    (is (= 41776 (count (d/datoms db :eavt))) "Correct datoms count")
+    (is (= 42070 (count (d/datoms db :eavt))) "Correct datoms count")
 
     (is (= 3600
            (ffirst

+ 87 - 161
deps/graph-parser/src/logseq/graph_parser/text.cljs

@@ -4,10 +4,10 @@
             [goog.string :as gstring]
             [clojure.string :as string]
             [clojure.set :as set]
+            [logseq.graph-parser.property :as gp-property]
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [logseq.graph-parser.util :as gp-util]
-            [logseq.graph-parser.property :as gp-property]
-            [logseq.graph-parser.util.page-ref :as page-ref :refer [right-brackets]]))
+            [logseq.graph-parser.util.page-ref :as page-ref]))
 
 (defn get-file-basename
   [path]
@@ -37,131 +37,11 @@
   [s]
   (or (get-page-name s) s))
 
-;; E.g "Foo Bar"
-(defn sep-by-comma
-  [s]
-  (when s
-    (some->>
-     (string/split s #"[\,|,]{1}")
-     (remove string/blank?)
-     (map string/trim))))
-
-(defn sep-by-hashtag
-  [s]
-  (when s
-    (some->>
-     (string/split s #"#")
-     (remove string/blank?)
-     (map string/trim))))
-
-(defn- not-matched-nested-pages
-  [s]
-  (and (string? s)
-       (> (count (re-seq page-ref/left-brackets-re s))
-          (count (re-seq page-ref/right-brackets-re s)))))
-
-(defn- ref-matched?
-  [s]
-  (let [x (re-seq page-ref/left-brackets-re s)
-        y (re-seq page-ref/right-brackets-re s)]
-    (and (> (count x) 0) (= (count x) (count y)))))
-
 (defn get-nested-page-name
   [page-name]
   (when-let [first-match (re-find page-ref/page-ref-without-nested-re page-name)]
     (second first-match)))
 
-(defn- concat-nested-pages
-  [coll]
-  (first
-   (reduce (fn [[acc not-matched-s] s]
-             (cond
-               (and not-matched-s (= s right-brackets))
-               (let [s' (str not-matched-s s)]
-                 (if (ref-matched? s')
-                   [(conj acc s') nil]
-                   [acc s']))
-
-               not-matched-s
-               [acc (str not-matched-s s)]
-
-               (not-matched-nested-pages s)
-               [acc s]
-
-               :else
-               [(conj acc s) not-matched-s])) [[] nil] coll)))
-
-(defn- sep-by-quotes
-  [s]
-  (string/split s #"(\"[^\"]*\")"))
-
-(def markdown-link #"\[([^\[]+)\](\(.*\))")
-
-(defn split-page-refs-without-brackets
-  ([s]
-   (split-page-refs-without-brackets s {}))
-  ([s {:keys [un-brackets?]
-       :or {un-brackets? true}}]
-   (cond
-     (and (string? s) (gp-util/wrapped-by-quotes? s))
-     (gp-util/unquote-string s)
-
-     (and (string? s) (re-find markdown-link s))
-     s
-
-     (and (string? s)
-            ;; Either a page ref, a tag or a comma separated collection
-            (or (re-find page-ref/page-ref-re s)
-                (re-find #"[\,|,|#|\"]+" s)))
-     (let [result (->> (sep-by-quotes s)
-                       (mapcat
-                        (fn [s]
-                          (when-not (gp-util/wrapped-by-quotes? (string/trim s))
-                            (string/split s page-ref/page-ref-outer-capture-re))))
-                       (mapcat (fn [s]
-                                 (cond
-                                   (gp-util/wrapped-by-quotes? s)
-                                   nil
-
-                                   (string/includes? (string/trimr s)
-                                                     (str right-brackets ","))
-                                   (let [idx (string/index-of s (str right-brackets ","))]
-                                     [(subs s 0 idx)
-                                      right-brackets
-                                      (subs s (+ idx 3))])
-
-                                   :else
-                                   [s])))
-                       (remove #(= % ""))
-                       (mapcat (fn [s] (if (string/ends-with? s right-brackets)
-                                         [(subs s 0 (- (count s) 2))
-                                          right-brackets]
-                                         [s])))
-                       concat-nested-pages
-                       (remove string/blank?)
-                       (mapcat (fn [s]
-                                 (cond
-                                   (gp-util/wrapped-by-quotes? s)
-                                   nil
-
-                                   (page-ref/page-ref? s)
-                                   [(if un-brackets? (page-ref-un-brackets! s) s)]
-
-                                   :else
-                                   (->> (sep-by-comma s)
-                                        (mapcat sep-by-hashtag)))))
-                       (distinct))]
-       (if (or (coll? result)
-               (and (string? result)
-                    (string/starts-with? result "#")))
-         (let [result (if coll? result [result])
-               result (map (fn [s] (string/replace s #"^#+" "")) result)]
-           (set result))
-         (first result)))
-
-     :else
-     s)))
-
 (defn- remove-level-space-aux!
   [text pattern space? trim-left?]
   (let [pattern (gstring/format
@@ -214,49 +94,95 @@
     (re-find #"^\d+$" v)
     (parse-long v)))
 
-(def ^:private page-ref-or-tag-re
-  (re-pattern (str "#?" (page-ref/->page-ref-re-str "(.*?)") "|"
-                   ;; Don't capture punctuation at end of a tag
-                   "#([\\S]+[^\\s.!,])")))
+(defn- get-ref-from-ast
+  [[typ data]]
+  (case typ
+    "Link"
+    (case (first (:url data))
+      "Page_ref"
+      (second (:url data))
 
-(defn extract-page-refs-and-tags
-  "Returns set of page-refs and tags in given string or returns string if none
-  are found"
-  [string]
-  (let [refs (map #(or (second %) (get % 2))
-                  (re-seq page-ref-or-tag-re string))]
-    (if (seq refs) (set refs) string)))
+      "Search"
+      (second (:url data))
 
-(defn parse-property
-  "Property value parsing that takes into account built-in properties, format
-  and user config"
-  ([k v config-state]
-   (parse-property :markdown k v config-state))
-  ([format k v config-state]
-   (let [k (name k)
-         v (if (or (symbol? v) (keyword? v)) (name v) (str v))
-         v (string/trim v)]
-     (cond
-       (contains? (set/union
-                   #{"title" "filters"}
-                   (get config-state :ignored-page-references-keywords)) k)
-       v
+      nil)
 
-       (gp-util/wrapped-by-quotes? v) ; wrapped in ""
-       v
+    "Nested_link"
+    (page-ref/get-page-name (:content data))
 
-       (contains? @non-parsing-properties (string/lower-case k))
-       v
+    "Tag"
+    (if (= "Plain" (ffirst data))
+      (second (first data))
+      (get-ref-from-ast (first data)))
 
-       (gp-mldoc/link? format v)
-       v
+    nil))
 
-       (contains? gp-property/editable-linkable-built-in-properties (keyword k))
-       (split-page-refs-without-brackets v)
+(defn extract-refs-from-mldoc-ast
+  [v]
+  (into #{}
+        (comp
+         (remove gp-mldoc/ast-link?)
+         (keep get-ref-from-ast)
+         (map string/trim))
+        v))
+
+(defn- sep-by-comma
+  [s]
+  {:pre (string? s)}
+  (->>
+   (string/split s #"[\,,]{1}")
+   (map string/trim)
+   (remove string/blank?)
+   (set)))
+
+(defn separated-by-commas?
+  [config-state k]
+  (let [k' (if (keyword? k) k (keyword k))]
+    (contains? (set/union gp-property/editable-linkable-built-in-properties
+                          (set (get config-state :property/separated-by-commas)))
+               k')))
+
+(defn- extract-refs-by-commas
+  [v format]
+  (let [plains (->> (map first (gp-mldoc/->edn v (gp-mldoc/default-config format)))
+                    first
+                    second
+                    (filter #(and (vector? %) (= "Plain" (first %))))
+                    (map second))]
+    (set (mapcat sep-by-comma plains))))
 
-       :else
-       (if-some [res (parse-non-string-property-value v)]
-         res
-         (if (:rich-property-values? config-state)
-           (extract-page-refs-and-tags v)
-           (split-page-refs-without-brackets v)))))))
+(defn parse-property
+  "Property value parsing that takes into account built-in properties, and user config"
+  [k v mldoc-references-ast config-state]
+  (let [refs (extract-refs-from-mldoc-ast mldoc-references-ast)
+        property-separated-by-commas? (separated-by-commas? config-state k)
+        refs' (if property-separated-by-commas?
+                (->> (extract-refs-by-commas v (get config-state :format :markdown))
+                     (set/union refs))
+                refs)
+        k (if (or (symbol? k) (keyword? k)) (subs (str k) 1) k)
+        v (string/trim (str v))
+        non-string-property (parse-non-string-property-value v)]
+    (cond
+      (contains? (set/union
+                  #{"filters" "macro"}
+                  (get config-state :ignored-page-references-keywords)) k)
+      v
+
+      (@non-parsing-properties k)
+      v
+
+      (string/blank? v)
+      nil
+
+      (and (string? v) (gp-util/wrapped-by-quotes? v))
+      v
+
+      (seq refs')
+      refs'
+
+      (some? non-string-property)
+      non-string-property
+
+      :else
+      v)))

+ 0 - 8
deps/graph-parser/src/logseq/graph_parser/util/page_ref.cljs

@@ -9,10 +9,7 @@
   (str left-brackets right-brackets))
 
 ;; common regular expressions
-(def left-brackets-re #"\[\[")
-(def right-brackets-re #"\]\]")
 (def page-ref-re "Inner capture and doesn't match nested brackets" #"\[\[(.*?)\]\]")
-(def page-ref-outer-capture-re #"(\[\[.*?\]\])")
 (def page-ref-without-nested-re "Matches most inner nested brackets" #"\[\[([^\[\]]+)\]\]")
 (def page-ref-any-re "Inner capture that matches anything between brackets" #"\[\[(.*)\]\]")
 
@@ -27,11 +24,6 @@
   [page-name]
   (str left-brackets page-name right-brackets))
 
-(defn ->page-ref-re-str
-  "Create a page ref regex escaped string given a page name"
-  [page-name]
-  (string/replace (->page-ref page-name) #"([\[\]])" "\\$1"))
-
 (defn get-page-name
   "Extracts page-name from page-ref string"
   [s]

+ 38 - 28
deps/graph-parser/test/logseq/graph_parser/block_test.cljs

@@ -1,72 +1,82 @@
 (ns logseq.graph-parser.block-test
   (:require [logseq.graph-parser.block :as gp-block]
+            [logseq.graph-parser.mldoc :as gp-mldoc]
             [cljs.test :refer [deftest are testing is]]))
 
+(defn- extract-properties
+  [properties user-config]
+  (gp-block/extract-properties
+   (map
+    (fn [[k v]]
+      (let [mldoc-ast (gp-mldoc/get-references v (gp-mldoc/default-config :markdown))]
+        [k v mldoc-ast]))
+    properties)
+   user-config))
+
 (deftest test-extract-properties
-  (are [x y] (= (:properties (gp-block/extract-properties :markdown x {})) y)
+  (are [x y] (= (:properties (extract-properties x {})) y)
        ;; Built-in properties
        [["background-color" "#000000"]] {:background-color "#000000"}
-       [["alias" "name/with space"]] {:alias #{"name/with space"}}
-       [["tags" "foo, bar"]] {:tags #{"foo" "bar"}}
-       [["tags" "'bar'"]] {:tags #{"'bar'"}}
+       [["alias" "[[name/with space]]"]] {:alias #{"name/with space"}}
+       [["tags" "[[foo]], [[bar]]"]] {:tags #{"foo" "bar"}}
+       [["tags" "[[foo]] [[bar]]"]] {:tags #{"foo" "bar"}}
+       [["tags" "bar"]] {:tags #{"bar"}}
        [["file-path" "file:///home/x, y.pdf"]] {:file-path "file:///home/x, y.pdf"}
 
        ;; User properties
        [["year" "1000"]] {:year 1000}
        [["year" "\"1000\""]] {:year "\"1000\""}
-       [["year" "1000"] ["alias" "name/with space"]] {:year 1000, :alias #{"name/with space"}}
-       [["year" "1000"] ["tags" "name/with space"]] {:year 1000, :tags #{"name/with space"}}
-       [["year" "1000"] ["tags" "name/with space, another"]] {:year 1000, :tags #{"name/with space" "another"}}
-       [["year" "1000"] ["alias" "name/with space, another"]] {:year 1000, :alias #{"name/with space" "another"}}
-       [["year" "1000"] ["alias" "name/with space, [[another [[nested]]]]"]] {:year 1000, :alias #{"name/with space" "another [[nested]]"}}
-       [["year" "1000"] ["alias" "name/with space, [[[[nested]] another]]"]] {:year 1000, :alias #{"name/with space" "[[nested]] another"}}
+       [["year" "1000"] ["alias" "[[name/with space]]"]] {:year 1000, :alias #{"name/with space"}}
+       [["year" "1000"] ["tags" "[[name/with space]]"]] {:year 1000, :tags #{"name/with space"}}
+       [["year" "1000"] ["tags" "[[name/with space]], [[another]]"]] {:year 1000, :tags #{"name/with space" "another"}}
+       [["year" "1000"] ["alias" "[[name/with space]], [[another]]"]] {:year 1000, :alias #{"name/with space" "another"}}
+       [["year" "1000"] ["alias" "[[name/with space]], [[another [[nested]]]]"]] {:year 1000, :alias #{"name/with space" "another [[nested]]"}}
+       [["year" "1000"] ["alias" "[[name/with space]], [[[[nested]] another]]"]] {:year 1000, :alias #{"name/with space" "[[nested]] another"}}
        [["foo" "bar"]] {:foo "bar"}
-       [["foo" "bar, baz"]] {:foo #{"bar" "baz"}}
-       [["foo" "bar, [[baz]]"]] {:foo #{"bar" "baz"}}
+       [["foo" "[[bar]], [[baz]]"]] {:foo #{"bar" "baz"}}
+       [["foo" "[[bar]], [[baz]]"]] {:foo #{"bar" "baz"}}
        [["foo" "[[bar]], [[baz]]"]] {:foo #{"bar" "baz"}}
        [["foo" "[[bar]], [[nested [[baz]]]]"]] {:foo #{"bar" "nested [[baz]]"}}
        [["foo" "[[bar]], [[nested [[baz]]]]"]] {:foo #{"bar" "nested [[baz]]"}}
-       [["foo" "bar, [[baz, test]]"]] {:foo #{"bar" "baz, test"}}
-       [["foo" "bar, [[baz, test, [[nested]]]]"]] {:foo #{"bar" "baz, test, [[nested]]"}})
+       [["foo" "[[bar]], [[baz, test]]"]] {:foo #{"bar" "baz, test"}}
+       [["foo" "[[bar]], [[baz, test, [[nested]]]]"]] {:foo #{"bar" "baz, test, [[nested]]"}})
 
   (testing "page-refs"
     (are [x y] (= (vec (:page-refs
-                        (gp-block/extract-properties :markdown x {:property-pages/enabled? true}))) y)
+                        (extract-properties x {:property-pages/enabled? true}))) y)
          [["year" "1000"]] ["year"]
          [["year" "\"1000\""]] ["year"]
          [["year" "1000"] ["month" "12"]] ["year" "month"]
-         [["foo" "[[bar]] test"]] ["bar" "test" "foo"]
-         [["foo" "[[bar]] test [[baz]]"]] ["bar" "test" "baz" "foo"]
-         [["foo" "[[bar]] test [[baz]] [[nested [[baz]]]]"]] ["bar" "test" "baz" "nested [[baz]]" "foo"]
+         [["foo" "[[bar]] test"]] ["bar" "foo"]
+         [["foo" "[[bar]] test [[baz]]"]] ["bar" "baz" "foo"]
+         [["foo" "[[bar]] test [[baz]] [[nested [[baz]]]]"]] ["bar" "baz" "nested [[baz]]" "foo"]
          [["foo" "#bar, #baz"]] ["bar" "baz" "foo"]
-         [["foo" "[[nested [[page]]]], test"]] ["nested [[page]]" "test" "foo"])
+         [["foo" "[[nested [[page]]]], test"]] ["nested [[page]]" "foo"])
 
 
     (are [x y] (= (vec (:page-refs
-                        (gp-block/extract-properties :markdown x {:property-pages/enabled? false}))) y)
+                        (extract-properties x {:property-pages/enabled? false}))) y)
          [["year" "1000"]] []
          [["year" "1000"] ["month" "12"]] []
-         [["foo" "[[bar]] test"]] ["bar" "test"])
+         [["foo" "[[bar]] test"]] ["bar"])
 
     (is (= ["year"]
            (:page-refs
-            (gp-block/extract-properties :markdown
-                                         [["year" "1000"] ["month" "12"]]
+            (extract-properties [["year" "1000"] ["month" "12"]]
                                          {:property-pages/enabled? true
                                           :property-pages/excludelist #{:month :day}})))
         ":property-pages/exclude-list excludes specified properties")
 
     (is (= ["year"]
            (:page-refs
-            (gp-block/extract-properties :markdown
-                                         [["year" "1000"]]
+            (extract-properties [["year" "1000"]]
                                          {})))
         "Default to enabled when :property-pages/enabled? is not in config")
 
     (is (= ["foo" "bar"]
            (:page-refs
-            (gp-block/extract-properties :markdown
-                                         ;; tags is linkable and background-color is not
-                                         [["tags" "foo, bar"] ["background-color" "#008000"]]
+            (extract-properties
+             ;; tags is linkable and background-color is not
+             [["tags" "[[foo]], [[bar]]"] ["background-color" "#008000"]]
                                          {:property-pages/enabled? true})))
         "Only editable linkable built-in properties have page-refs in property values")))

+ 28 - 29
deps/graph-parser/test/logseq/graph_parser/mldoc_test.cljs

@@ -1,5 +1,6 @@
 (ns logseq.graph-parser.mldoc-test
   (:require [logseq.graph-parser.mldoc :as gp-mldoc]
+            [logseq.graph-parser.text :as text]
             [clojure.string :as string]
             [logseq.graph-parser.test.docs-graph-helper :as docs-graph-helper]
             [logseq.graph-parser.cli :as gp-cli]
@@ -51,41 +52,40 @@
           {:start_pos 0, :end_pos 15}]
          (first (gp-mldoc/->edn "```
 : hello
-```" md-config {})))
+```" md-config)))
       "Basic src example")
 
   (is (= [["Src"
-            {:lines ["  hello" "\n" "  world" "\n"],
-             :pos_meta {:start_pos 7, :end_pos 25},
-             :full_content "```\nhello\nworld\n```"}]
-           {:start_pos 1, :end_pos 29}]
+           {:lines ["  hello" "\n" "  world" "\n"],
+            :pos_meta {:start_pos 7, :end_pos 25},
+            :full_content "```\nhello\nworld\n```"}]
+          {:start_pos 1, :end_pos 29}]
          (second (gp-mldoc/->edn "
   ```
   hello
   world
   ```
-" md-config {})))
+" md-config)))
       "Src example with leading whitespace"))
 
-(deftest md-properties-test
-  (are [x y] (= [["Properties" y] nil]
-                (first (gp-mldoc/->edn x md-config {})))
-
-       ;; comma separates values
-       "property:: foo, bar"
-       {:property #{"foo" "bar"}}
+(defn- get-properties
+  [x]
+  (->> (gp-mldoc/->edn x md-config)
+       ffirst second
+       (map (fn [[k v ast]]
+              [(keyword k) (text/parse-property k v ast {})]))
+       (into {})))
 
-       ;; alias property
-       "alias:: foo,, bar"
-       {:alias ["foo" "bar"]}
+(deftest md-properties-test
+  (are [x y] (= y (get-properties x))
 
-       ;; tags property
-       "tags:: foo,bar,foo"
-       {:tags ["foo" "bar"]}
+    ;; reference values
+    "property:: [[foo]], [[bar]]"
+    {:property #{"foo" "bar"}}
 
-       ;; title property
-       "title:: comma, is ok"
-       {:title "comma, is ok"}))
+    ;; comma separated
+    "tags:: foo, bar, foo"
+    {:tags #{"foo" "bar"}}))
 
 (deftest name-definition-test
   (is (= [["List"
@@ -96,11 +96,11 @@
              :ordered false}]]
           {:start_pos 0, :end_pos 17}]
          (first (gp-mldoc/->edn "term
-: definition" md-config {})))))
+: definition" md-config)))))
 
 (defn- parse-properties
   [text]
-  (->> (gp-mldoc/->edn text (gp-mldoc/default-config :org) {})
+  (->> (gp-mldoc/->edn text (gp-mldoc/default-config :org))
        (filter #(= "Properties" (ffirst %)))
        ffirst
        second))
@@ -110,7 +110,7 @@
   (testing "just title"
     (let [content "#+TITLE:   some title   "
           props (parse-properties content)]
-      (is (= "some title   " (:title props)))))
+      (is (= "some title   " (second (first props))))))
 
   (testing "filetags"
     (let [content "#+FILETAGS:   :tag1:tag2:@tag:
@@ -130,8 +130,7 @@ body"
                                                 :org :markdown)]
                                    [path
                                     (gp-mldoc/->edn content
-                                                    (gp-mldoc/default-config format)
-                                                    {})])))
+                                                    (gp-mldoc/default-config format))])))
                           (into {}))]
     (is (= {"CommentBlock" 1,
             "Custom" 41,
@@ -143,8 +142,8 @@ body"
             "Hiccup" 15,
             "List" 37,
             "Paragraph" 417,
-            "Properties" 104,
-            "Property_Drawer" 188,
+            "Properties" 91,
+            "Property_Drawer" 201,
             "Quote" 9,
             "Raw_Html" 12,
             "Src" 56,

+ 1 - 14
deps/graph-parser/test/logseq/graph_parser/property_test.cljs

@@ -1,5 +1,5 @@
 (ns logseq.graph-parser.property-test
-  (:require [cljs.test :refer [are deftest is]]
+  (:require [cljs.test :refer [are deftest]]
             [logseq.graph-parser.property :as gp-property]))
 
 (deftest test->new-properties
@@ -24,16 +24,3 @@
 
     "hello\n:PROPERTIES:\n:foo: bar\n:nice\n:END:\nnice"
     "hello\nfoo:: bar\n:nice\nnice"))
-
-(deftest property-value-from-content
-  (is (= "62b38254-4be7-4627-a2b7-6d9ee20999e5"
-         (gp-property/property-value-from-content
-          "id"
-          "type:: blog-posting\ndesc:: nice walkthrough on creating a blog with #nbb\nid:: 62b38254-4be7-4627-a2b7-6d9ee20999e5"))
-      "Pulls value from end of block content")
-
-  (is (= "nice walkthrough on creating a blog with #nbb"
-         (gp-property/property-value-from-content
-          "desc"
-          "type:: blog-posting\ndesc:: nice walkthrough on creating a blog with #nbb\nid:: 62b38254-4be7-4627-a2b7-6d9ee20999e5"))
-      "Pulls value from middle of block content"))

+ 44 - 54
deps/graph-parser/test/logseq/graph_parser/text_test.cljs

@@ -1,6 +1,7 @@
 (ns logseq.graph-parser.text-test
-  (:require [cljs.test :refer [are deftest testing is]]
-            [logseq.graph-parser.text :as text]))
+  (:require [cljs.test :refer [are deftest testing]]
+            [logseq.graph-parser.text :as text]
+            [logseq.graph-parser.mldoc :as gp-mldoc]))
 
 (deftest test-get-page-name
   []
@@ -35,37 +36,6 @@
     "[single bracket]" "[single bracket]"
     "no brackets" "no brackets"))
 
-(deftest sep-by-comma
-  []
-  (are [x y] (= (text/sep-by-comma x) y)
-    "foo,bar" ["foo" "bar"]
-    "foo, bar" ["foo" "bar"]
-    "foo bar" ["foo bar"]
-    "[[foo]] [[bar]]" ["[[foo]] [[bar]]"]
-    "[[foo]],[[bar]]" ["[[foo]]", "[[bar]]"]
-    "[[foo]], [[bar]]" ["[[foo]]", "[[bar]]"]
-    "[[foo]]" ["[[foo]]"]
-    "[[nested [[foo]]]]" ["[[nested [[foo]]]]"]))
-
-(deftest split-page-refs-without-brackets
-  []
-  (are [x y] (= (text/split-page-refs-without-brackets x) y)
-    "foobar" "foobar"
-    "foo bar" "foo bar"
-    "foo, bar" #{"foo" "bar"}
-    "[[foo]] [[bar]]" #{"foo" "bar"}
-    "[[foo]],[[bar]]" #{"foo", "bar"}
-    "[[foo]], [[bar]]" #{"foo", "bar"}
-    "[[foo]]" #{"foo"}
-    "[[nested [[foo]]]]" #{"nested [[foo]]"}
-    "[[nested [[foo]]]], [[foo]]" #{"nested [[foo]]" "foo"}
-    "[[nested [[foo]] [[bar]]]], [[foo]]" #{"nested [[foo]] [[bar]]" "foo"}
-    "[[nested [[foo]], [[bar]]]], [[foo]]" #{"nested [[foo]], [[bar]]" "foo"}
-    "#tag," #{"tag"}
-    "#tag" #{"tag"}
-    "#tag1,#tag2" #{"tag1" "tag2"}
-    "[[Jan 26th, 2021]], hello" #{"hello" "Jan 26th, 2021"}))
-
 (def block-patterns
   {:markdown "-"
    :org "*"})
@@ -90,28 +60,48 @@
       "**foobar" "foobar"
       "*********************foobar" "foobar")))
 
+(defn- parse-property
+  [k v user-config]
+  (let [references (gp-mldoc/get-references v (gp-mldoc/default-config :markdown))]
+    (text/parse-property k v references user-config)))
+
 (deftest test-parse-property
-  (testing "parse-property"
-    (are [k v y] (= (text/parse-property k v {}) y)
-      :tags "foo" "foo"
-      :tags "foo, bar" #{"foo" "bar"}
-      :tags "foo,bar" #{"foo" "bar"}
-      :tags "[[foo]]" #{"foo"}
-      :tags "[[foo]] [[bar]]" #{"foo" "bar"}
-      :tags "[[foo]], [[bar]]" #{"foo" "bar"}
-      :tags "[[foo]], [[bar]], #baz" #{"foo" "bar" "baz"}
-      :tags "#baz, [[foo]], [[bar]]" #{"foo" "bar" "baz"}
-      :tags "[[foo [[bar]]]]" #{"foo [[bar]]"}
-      :tags "[[foo [[bar]]]], baz" #{"baz" "foo [[bar]]"}))
+  (testing "for default comma separated properties"
+    (are [k v y] (= (parse-property k v {}) y)
+         :tags "foo" #{"foo"}
+         :tags "comma, separated" #{"comma" "separated"}
+         :alias "one, two, one" #{"one" "two"}))
+
+  (testing "for user comma separated properties"
+    (are [k v y] (= (parse-property k v {:property/separated-by-commas #{:comma-prop}}) y)
+         :comma-prop "foo" #{"foo"}
+         :comma-prop "comma, separated" #{"comma" "separated"}
+         :comma-prop "one, two, one" #{"one" "two"}))
+
+  (testing "for user comma separated properties with mixed values"
+    (are [k v y] (= (parse-property k v {:property/separated-by-commas #{:comma-prop}}) y)
+      :comma-prop "foo, #bar" #{"foo", "bar"}
+      :comma-prop "comma, separated, [[page ref]], [[nested [[page]]]], #[[nested [[tag]]]], end" #{"page ref" "nested [[page]]" "nested [[tag]]" "comma" "separated" "end"}))
+
+  (testing "for normal properties"
+    (are [k v y] (= (parse-property k v {}) y)
+         :normal "[[foo]] [[bar]]" #{"foo" "bar"}
+         :normal "[[foo]], [[bar]]" #{"foo" "bar"}
+         :normal "[[foo]]" #{"foo"}
+         :normal "[[foo]], [[bar]], #baz" #{"foo" "bar" "baz"}
+         :normal "[[foo [[bar]]]]" #{"foo [[bar]]"}
+         :normal "[[foo [[bar]]]], [[baz]]" #{"baz" "foo [[bar]]"}
+         :title "comma, is ok" "comma, is ok"))
+
+  (testing "for tags in properties with punctuation"
+    (are [k v y] (= (parse-property k v {}) y)
+         :prop "#foo, #bar. #baz!" #{"foo" "bar" "baz"}
+         :prop "#foo: '#bar'" #{"foo" "bar"}))
+
   (testing "parse-property with quoted strings"
-    (are [k v y] (= (text/parse-property k v {}) y)
-      :tags "\"foo, bar\"" "\"foo, bar\""
-      :tags "\"[[foo]], [[bar]]\"" "\"[[foo]], [[bar]]\""
-      :tags "baz, \"[[foo]], [[bar]]\"" #{"baz"})))
-
-(deftest extract-page-refs-and-tags
-  (is (= #{"cljs" "nbb" "js" "amazing"}
-       (text/extract-page-refs-and-tags "This project is written with #cljs, #nbb and #js. #amazing!"))
-      "Don't extract punctation at end of a tag"))
+    (are [k v y] (= (parse-property k v {}) y)
+         :tags "\"foo, bar\"" "\"foo, bar\""
+         :tags "\"[[foo]], [[bar]]\"" "\"[[foo]], [[bar]]\"")))
+
 
 #_(cljs.test/test-ns 'logseq.graph-parser.text-test)

+ 68 - 52
deps/graph-parser/test/logseq/graph_parser_test.cljs

@@ -3,6 +3,7 @@
             [clojure.string :as string]
             [logseq.graph-parser :as graph-parser]
             [logseq.db :as ldb]
+            [logseq.db.default :as default-db]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.property :as gp-property]
             [datascript.core :as d]))
@@ -70,13 +71,12 @@
   (testing "Sort order and persistence of 10 properties"
     (test-property-order 10)))
 
-(defn- quoted-property-values-test
-  [user-config]
+(deftest quoted-property-values
   (let [conn (ldb/start-conn)
         _ (graph-parser/parse-file conn
                                    "foo.md"
                                    "- desc:: \"#foo is not a ref\""
-                                   {:extract-options {:user-config user-config}})
+                                   {:extract-options {:user-config {}}})
         block (->> (d/q '[:find (pull ?b [* {:block/refs [*]}])
                        :in $
                        :where [?b :block/properties]]
@@ -90,47 +90,55 @@
            (map :block/original-name (:block/refs block)))
         "No refs from property value")))
 
-(deftest quoted-property-values
-  (testing "With default config"
-    (quoted-property-values-test {}))
-  (testing "With :rich-property-values config"
-    (quoted-property-values-test {:rich-property-values? true})))
+(deftest non-string-property-values
+  (let [conn (ldb/start-conn)]
+    (graph-parser/parse-file conn
+                             "lythe-of-heaven.md"
+                             "rating:: 8\nrecommend:: true\narchive:: false"
+                             {})
+    (is (= {:rating 8 :recommend true :archive false}
+           (->> (d/q '[:find (pull ?b [*])
+                       :in $
+                       :where [?b :block/properties]]
+                     @conn)
+                (map (comp :block/properties first))
+                first)))))
 
-(deftest page-properties-persistence
-  (testing "Non-string property values"
-    (let [conn (ldb/start-conn)]
-      (graph-parser/parse-file conn
-                               "lythe-of-heaven.md"
-                               "rating:: 8\nrecommend:: true\narchive:: false"
-                               {})
-      (is (= {:rating 8 :recommend true :archive false}
-             (->> (d/q '[:find (pull ?b [*])
-                         :in $
-                         :where [?b :block/properties]]
-                       @conn)
-                  (map (comp :block/properties first))
-                  first)))))
+(deftest linkable-built-in-properties
+  (let [conn (ldb/start-conn)
+        _ (graph-parser/parse-file conn
+                                   "lol.md"
+                                   (str "alias:: 233\ntags:: fun, facts"
+                                        "\n- "
+                                        "alias:: 666\ntags:: block, facts")
+                                   {})
+        page-block (->> (d/q '[:find (pull ?b [:block/properties {:block/alias [:block/name]} {:block/tags [:block/name]}])
+                               :in $
+                               :where [?b :block/name "lol"]]
+                             @conn)
+                        (map first)
+                        first)
+        block (->> (d/q '[:find (pull ?b [:block/properties])
+                          :in $
+                          :where
+                          [?b :block/properties]
+                          [(missing? $ ?b :block/pre-block?)]
+                          [(missing? $ ?b :block/name)]]
+                        @conn)
+                   (map first)
+                   first)]
 
-  (testing "Linkable built-in properties"
-    (let [conn (ldb/start-conn)
-          _ (graph-parser/parse-file conn
-                                     "lol.md"
-                                     "alias:: 233\ntags:: fun, facts"
-                                     {})
-          block (->> (d/q '[:find (pull ?b [:block/properties {:block/alias [:block/name]} {:block/tags [:block/name]}])
-                            :in $
-                            :where [?b :block/name "lol"]]
-                          @conn)
-                     (map first)
-                     first)]
-
-      (is (= {:block/alias [{:block/name "233"}]
-              :block/tags [{:block/name "fun"} {:block/name "facts"}]
-              :block/properties {:alias ["233"] :tags ["fun" "facts"]}}
-             block))
-
-      (is (every? vector? (vals (:block/properties block)))
-          "Linked built-in property values as vectors provides for easier transforms"))))
+    (is (= {:block/alias [{:block/name "233"}]
+            :block/tags [{:block/name "fun"} {:block/name "facts"}]
+            :block/properties {:alias #{"233"} :tags #{"fun" "facts"}}}
+           page-block)
+        "page properties, alias and tags are correct")
+    (is (every? set? (vals (:block/properties page-block)))
+        "Linked built-in property values as sets provides for easier transforms")
+
+    (is (= {:block/properties {:alias #{"666"} :tags #{"block" "facts"}}}
+           block)
+        "block properties are correct")))
 
 (defn- property-relationships-test
   "Runs tests on page properties and block properties. file-properties is what is
@@ -189,22 +197,13 @@
                     :desc "This is a multiple sentence description. It has one [[link]]"
                     :comma-prop "one, two,three"}]
     (testing "With default config"
-      (property-relationships-test
-       properties
-       {:single-link #{"bar"}
-        :multi-link #{"Logseq" "is the fastest" "triples" "text editor"}
-        :desc #{"This is a multiple sentence description. It has one" "link"}
-        :comma-prop #{"one" "two" "three"}}
-       {}))
-
-    (testing "With :rich-property-values config"
       (property-relationships-test
        properties
        {:single-link #{"bar"}
         :multi-link #{"Logseq" "triples" "text editor"}
         :desc #{"link"}
         :comma-prop "one, two,three"}
-       {:rich-property-values? true}))))
+       {}))))
 
 (deftest invalid-properties
   (let [conn (ldb/start-conn)
@@ -237,3 +236,20 @@
                 (map first)
                 (map #(select-keys % [:block/properties :block/invalid-properties]))))
         "Has correct (in)valid page properties")))
+
+(deftest correct-page-names-created
+  (testing "from title"
+    (let [conn (ldb/start-conn)
+          built-in-pages (set (map string/lower-case default-db/built-in-pages-names))]
+      (graph-parser/parse-file conn
+                               "foo.md"
+                               "title:: core.async"
+                               {})
+      (is (= #{"core.async"}
+             (->> (d/q '[:find (pull ?b [*])
+                         :in $
+                         :where [?b :block/name]]
+                       @conn)
+                  (map (comp :block/name first))
+                  (remove built-in-pages)
+                  set))))))

+ 4 - 4
deps/graph-parser/yarn.lock

@@ -177,10 +177,10 @@ mimic-fn@^2.0.0:
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
 
-mldoc@^1.3.9:
-  version "1.3.9"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.3.9.tgz#9e45a25ba79596f3b0b0eace65f651a4c5a0c30a"
-  integrity sha512-UfqNuBphOj7paSBvozTdin5BLB5+W2tr2SGKTfp5eae6VQPx23oICx6RPQprft7KGFtn8T3rpM1YMUN8FaJLhg==
+mldoc@^1.4.9:
+  version "1.4.9"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.4.9.tgz#a61d93e98f19bf4ec6303810cc3573c5e14eab44"
+  integrity sha512-rroc1tWJnNm2n33MYk+sWgLjGWmP93Am+6zvpBe0BGEyccHQT3AxHHv8fNpF7HVvT7YPtU/dtHWTh6nE2n7vPA==
   dependencies:
     yargs "^12.0.2"
 

+ 1 - 1
package.json

@@ -110,7 +110,7 @@
         "ignore": "5.1.8",
         "is-svg": "4.3.0",
         "jszip": "3.7.0",
-        "mldoc": "1.4.0",
+        "mldoc": "^1.4.9",
         "path": "0.12.7",
         "pixi-graph-fork": "0.2.0",
         "pixi.js": "6.2.0",

+ 11 - 10
src/main/frontend/components/block.cljs

@@ -1912,13 +1912,14 @@
   [config block k value]
   (let [date (and (= k :date) (date/get-locale-string (str value)))
         user-config (state/get-config)
-        ;; In this mode and when value is a set of refs, display full property text
+        ;; When value is a set of refs, display full property text
         ;; because :block/properties value only contains refs but user wants to see text
-        v (if (and (:rich-property-values? user-config)
-                   (coll? value)
-                   (not (contains? gp-property/editable-linkable-built-in-properties k)))
-            (gp-property/property-value-from-content (name k) (:block/content block))
-            value)
+        property-separated-by-commas? (text/separated-by-commas? (state/get-config) k)
+        v (or
+           (when (and (coll? value) (seq value)
+                      (not property-separated-by-commas?))
+             (get (:block/properties-text-values block) k))
+           value)
         property-pages-enabled? (contains? #{true nil} (:property-pages/enabled? user-config))]
     [:div
      (if property-pages-enabled?
@@ -1935,7 +1936,10 @@
        date
        date
 
-       (coll? v)
+       (and (string? v) (gp-util/wrapped-by-quotes? v))
+       (gp-util/unquote-string v)
+
+       (and property-separated-by-commas? (coll? v))
        (let [v (->> (remove string/blank? v)
                     (filter string?))
              vals (for [v-item v]
@@ -1944,9 +1948,6 @@
          (for [elem elems]
            (rum/with-key elem (str (random-uuid)))))
 
-       (and (string? v) (gp-util/wrapped-by-quotes? v))
-       (gp-util/unquote-string v)
-
        :else
        (inline-text config (:block/format block) (str v)))]))
 

+ 1 - 0
src/main/frontend/db/model.cljs

@@ -46,6 +46,7 @@
     :block/marker
     :block/priority
     :block/properties
+    :block/properties-text-values
     :block/pre-block?
     :block/scheduled
     :block/deadline

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

@@ -237,9 +237,14 @@
 (defn parse-property-value
   "Parses non-string property values or any page-ref like values"
   [v]
-  (if-some [res (text/parse-non-string-property-value v)]
-    res
-    (text/split-page-refs-without-brackets v)))
+  (let [result (if-some [res (text/parse-non-string-property-value v)]
+                 res
+                 (if (string/starts-with? v "#")
+                   (subs v 1)
+                   (or (page-ref/get-page-name v) v)))]
+    (if (string? result)
+      (string/trim result)
+      result)))
 
 (defn- build-property-two-arg
   [e]

+ 3 - 1
src/main/frontend/format/block.cljs

@@ -11,8 +11,9 @@
             [frontend.state :as state]
             [logseq.graph-parser.block :as gp-block]
             [logseq.graph-parser.config :as gp-config]
+            [logseq.graph-parser.property :as gp-property]
             [logseq.graph-parser.mldoc :as gp-mldoc]
-            [logseq.graph-parser.property :as gp-property]))
+            [lambdaisland.glogi :as log]))
 
 (defn extract-blocks
   "Wrapper around logseq.graph-parser.block/extract-blocks that adds in system state
@@ -27,6 +28,7 @@ and handles unexpected failure."
                               :db (db/get-db (state/get-current-repo))
                               :date-formatter (state/get-date-formatter)})
     (catch :default e
+      (log/error :exception e)
       (Sentry/captureException e)
       (notification/show! "An unexpected error occurred during block extraction." :error)
       [])))

+ 5 - 5
src/main/frontend/format/mldoc.cljs

@@ -2,7 +2,6 @@
   "Mldoc code needed by app but not graph-parser"
   (:require [clojure.string :as string]
             [frontend.format.protocol :as protocol]
-            [frontend.state :as state]
             [goog.object :as gobj]
             [lambdaisland.glogi :as log]
             ["mldoc" :as mldoc :refer [Mldoc]]
@@ -40,20 +39,21 @@
                "Heading"} type))
 
 (defn opml->edn
-  [content]
+  [config content]
   (try
     (if (string/blank? content)
       {}
       (let [[headers blocks] (-> content (parse-opml) (gp-util/json->clj))]
-        [headers (gp-mldoc/collect-page-properties blocks gp-mldoc/parse-property (state/get-config))]))
+        [headers (gp-mldoc/collect-page-properties blocks config)]))
     (catch js/Error e
       (log/error :edn/convert-failed e)
       [])))
 
 (defn ->edn
-  "Wrapper around gp-mldoc/->edn which provides config state"
+  "Alias to gp-mldoc/->edn but could serve as a wrapper e.g. handle
+  gp-mldoc/default-config"
   [content config]
-  (gp-mldoc/->edn content config (state/get-config)))
+  (gp-mldoc/->edn content config))
 
 (defrecord MldocMode []
   protocol/Format

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

@@ -633,8 +633,7 @@
 (defn properties-block
   [properties format page]
   (let [content (property/insert-properties format "" properties)
-        refs (gp-block/get-page-refs-from-properties format
-                                                     properties
+        refs (gp-block/get-page-refs-from-properties properties
                                                      (db/get-db (state/get-current-repo))
                                                      (state/get-date-formatter)
                                                      (state/get-config))]
@@ -2726,11 +2725,11 @@
             (autopair input-id "(" format nil))
 
         ;; If you type `xyz`, the last backtick should close the first and not add another autopair
-        ;; If you type several backticks in a row, each one should autopair to accommodate multiline code (```)        
+        ;; If you type several backticks in a row, each one should autopair to accommodate multiline code (```)
         (contains? (set (keys autopair-map)) key)
         (let [curr (get-current-input-char input)
                   prev (util/nth-safe value (dec pos))]
-            (util/stop e) 
+            (util/stop e)
             (if (and (= key "`") (= "`" curr) (not= "`" prev))
               (cursor/move-cursor-forward input)
               (autopair input-id key format nil)))

+ 3 - 1
src/main/frontend/handler/external.cljs

@@ -11,6 +11,7 @@
             [frontend.db :as db]
             [frontend.format.mldoc :as mldoc]
             [frontend.format.block :as block]
+            [logseq.graph-parser.mldoc :as gp-mldoc]
             [logseq.graph-parser.util :as gp-util]
             [logseq.graph-parser.date-time-util :as date-time-util]
             [frontend.handler.page :as page]
@@ -79,7 +80,8 @@
   [data finished-ok-handler]
   #_:clj-kondo/ignore
   (when-let [repo (state/get-current-repo)]
-    (let [[headers parsed-blocks] (mldoc/opml->edn data)
+    (let [config (gp-mldoc/default-config :markdown)
+          [headers parsed-blocks] (mldoc/opml->edn config data)
           parsed-blocks (->>
                          (block/extract-blocks parsed-blocks "" :markdown {})
                          (mapv editor/wrap-parse-block))

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

@@ -76,8 +76,7 @@
    (let [p (common-handler/get-page-default-properties title)
          ps (merge p properties)
          content (page-property/insert-properties format "" ps)
-         refs (gp-block/get-page-refs-from-properties format
-                                                      properties
+         refs (gp-block/get-page-refs-from-properties properties
                                                       (db/get-db (state/get-current-repo))
                                                       (state/get-date-formatter)
                                                       (state/get-config))]

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

@@ -212,6 +212,7 @@
                       (let [id (:db/id (:block/page block))]
                         [[:db/retract id :block/properties]
                          [:db/retract id :block/properties-order]
+                         [:db/retract id :block/properties-text-values]
                          [:db/retract id :block/alias]
                          [:db/retract id :block/tags]])))]
       (swap! txs-state concat txs page-tx)

+ 3 - 15
src/test/frontend/db/query_dsl_test.cljs

@@ -116,12 +116,6 @@ prop-d:: nada"}])
 (deftest block-property-queries
   (testing "block property tests with default config"
     (test-helper/with-config {}
-      (block-property-queries-test)))
-
-  (test-helper/start-test-db!) ;; reset db
-
-  (testing "block property tests with rich-property-values? config"
-    (test-helper/with-config {:rich-property-values? true}
       (block-property-queries-test))))
 
 (defn- page-property-queries-test
@@ -187,12 +181,6 @@ prop-d:: nada"}])
 (deftest page-property-queries
   (testing "page property tests with default config"
     (test-helper/with-config {}
-      (page-property-queries-test)))
-
-  (test-helper/start-test-db!) ;; reset db
-
-  (testing "page property tests with rich-property-values? config"
-    (test-helper/with-config {:rich-property-values? true}
       (page-property-queries-test))))
 
 (deftest task-queries
@@ -310,15 +298,15 @@ prop-d:: nada"}])
   (load-test-files
    [{:file/path "pages/page1.md"
      :file/content "---
-tags: [[page-tag-1]], page-tag-2
+tags: [[page-tag-1]], [[page-tag-2]]
 ---"}
     {:file/path "pages/page2.md"
      :file/content "---
-tags: page-tag-2, [[page-tag-3]]
+tags: [[page-tag-2]], [[page-tag-3]]
 ---"}
     {:file/path "pages/page3.md"
      :file/content "---
-tags: other
+tags: [[other]]
 ---"}])
 
   (are [x y] (= (set y) (set (map :block/name (dsl-query x))))

+ 4 - 4
templates/config.edn

@@ -232,10 +232,10 @@
  ;; E.g.:property-pages/excludelist #{:duration :author}
  ;; :property-pages/excludelist
 
- ;; Enables property values to contain a mix of tags, page-refs, special
- ;; punctuation and free-form text.
- ;; Re-index current graph for config to take effect
- ;; :rich-property-values? true
+ ;; By default, property value separated by commas will not be treated as
+ ;; page references. You can add properties to enable it.
+ ;; E.g. :property/separated-by-commas #{:alias :tags}
+ ;; :property/separated-by-commas #{}
 
  ;; logbook setup
  ;; :logbook/settings

+ 4 - 4
yarn.lock

@@ -4702,10 +4702,10 @@ mkdirp@^1.0.3:
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
   integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
 
-mldoc@1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.4.0.tgz#10dd8b57b1941a66b3d30fd031881ad31d499edb"
-  integrity sha512-6s1utUm03SCR1XH2EnHD3s0qAd+RLLGRc+1qb4SuHIjjmT5HMWbWGP+vADBLHKQKP6nwYCKsUJkiwLFjOXfP6w==
+mldoc@^1.4.9:
+  version "1.4.9"
+  resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.4.9.tgz#a61d93e98f19bf4ec6303810cc3573c5e14eab44"
+  integrity sha512-rroc1tWJnNm2n33MYk+sWgLjGWmP93Am+6zvpBe0BGEyccHQT3AxHHv8fNpF7HVvT7YPtU/dtHWTh6nE2n7vPA==
   dependencies:
     yargs "^12.0.2"