Bläddra i källkod

fix #+keyword issues in orgmode (#4573)

* fix(orgmode): don't parse some in-file #+keyword as page properties

e.g. #+Name:, #+tblfm:, etc.

* enhance(orgmode): display image and table's caption keyword

https://orgmode.org/manual/Captions.html

* enhance(orgmode): ignore some #+keywords for parsing properties.

Orgmode uses lots of file level #+keyword: styled keywords[1].
Logseq parses their value as page references except `title` and
`filters`, which pollutes Logseq database.

Users can setup `:ignored-page-property-tags` in config.edn to
make Logseq not parsing those keywords.

[1]: https://orgmode.org/manual/In_002dbuffer-Settings.html.

* use take-while instead. Thanks tienson.

* comment out new settings

* revert some merge conflicts.
llcc 3 år sedan
förälder
incheckning
1361728457

+ 175 - 166
src/main/frontend/components/block.cljs

@@ -2674,173 +2674,182 @@
                    :markdown)]
     (try
       (match item
-        ["Drawer" name lines]
-        (when (or (not= name "logbook")
-                  (and
-                   (= name "logbook")
-                   (state/enable-timetracking?)
-                   (or  (get-in (state/get-config) [:logbook/settings :enabled-in-all-blocks])
-                        (when (get-in (state/get-config)
-                                      [:logbook/settings :enabled-in-timestamped-blocks] true)
-                          (or (:block/scheduled (:block config))
-                              (:block/deadline (:block config)))))))
-          [:div
-           [:div.text-sm
-            [:div.drawer {:data-drawer-name name}
-             (ui/foldable
-              [:div.opacity-50.font-medium.logbook
-               (util/format ":%s:" (string/upper-case name))]
-              [:div.opacity-50.font-medium
-               (if (= name "logbook")
-                 (logbook-cp lines)
-                 (apply str lines))
-               [:div ":END:"]]
-              {:default-collapsed? true
-               :title-trigger? true})]]])
-
-        ["Properties" m]
-        [:div.properties
-         (for [[k v] (dissoc m :roam_alias :roam_tags)]
-           (when (and (not (and (= k :macros) (empty? v))) ; empty macros
-                      (not (= k :title))
-                      (not (= k :filters)))
-             [:div.property
-              [:span.font-medium.mr-1 (str (name k) ": ")]
-              (if (coll? v)
-                (let [vals (for [item v]
-                             (if (coll? v)
-                               (let [config (when (= k :alias)
-                                              (assoc config :block/alias? true))]
-                                 (page-cp config {:block/name item}))
-                               (inline-text format item)))]
-                  (interpose [:span ", "] vals))
-                (inline-text format v))]))]
-
-        ["Paragraph" l]
-        ;; TODO: speedup
-        (if (util/safe-re-find #"\"Export_Snippet\" \"embed\"" (str l))
-          (->elem :div (map-inline config l))
-          (->elem :div.is-paragraph (map-inline config l)))
-
-        ["Horizontal_Rule"]
-        (when-not (:slide? config)
-          [:hr])
-        ["Heading" h]
-        (block-container config h)
-        ["List" l]
-        (let [lists (divide-lists l)]
-          (if (= 1 (count lists))
-            (let [l (first lists)]
-              (->elem
-               (list-element l)
-               (map #(list-item config %) l)))
-            [:div.list-group
-             (for [l lists]
-               (->elem
-                (list-element l)
-                (map #(list-item config %) l)))]))
-        ["Table" t]
-        (table config t)
-        ["Math" s]
-        (if html-export?
-          (latex/html-export s true true)
-          (latex/latex (str (d/squuid)) s true true))
-        ["Example" l]
-        [:pre.pre-wrap-white-space
-         (join-lines l)]
-        ["Quote" l]
-        (->elem
-         :blockquote
-         (markup-elements-cp config l))
-        ["Raw_Html" content]
-        (when (not html-export?)
-          [:div.raw_html {:dangerouslySetInnerHTML
-                          {:__html content}}])
-        ["Export" "html" _options content]
-        (when (not html-export?)
-          [:div.export_html {:dangerouslySetInnerHTML
-                             {:__html content}}])
-        ["Hiccup" content]
-        (ui/catch-error
-         [:div.warning {:title "Invalid hiccup"}
-          content]
-         (-> (safe-read-string content)
-             (security/remove-javascript-links-in-href)))
-
-        ["Export" "latex" _options content]
-        (if html-export?
-          (latex/html-export content true false)
-          (latex/latex (str (d/squuid)) content true false))
-
-        ["Custom" "query" _options _result content]
-        (try
-          (let [query (reader/read-string content)]
-            (custom-query config query))
-          (catch :default e
-            (log/error :read-string-error e)
-            (ui/block-error "Invalid query:" {:content content})))
-
-        ["Custom" "note" _options result _content]
-        (admonition config "note" result)
-
-        ["Custom" "tip" _options result _content]
-        (admonition config "tip" result)
-
-        ["Custom" "important" _options result _content]
-        (admonition config "important" result)
-
-        ["Custom" "caution" _options result _content]
-        (admonition config "caution" result)
-
-        ["Custom" "warning" _options result _content]
-        (admonition config "warning" result)
-
-        ["Custom" "pinned" _options result _content]
-        (admonition config "pinned" result)
-
-        ["Custom" "center" _options l _content]
-        (->elem
-         :div.text-center
-         (markup-elements-cp config l))
-
-        ["Custom" name _options l _content]
-        (->elem
-         :div
-         {:class name}
-         (markup-elements-cp config l))
-
-        ["Latex_Fragment" l]
-        [:p.latex-fragment
-         (inline config ["Latex_Fragment" l])]
-
-        ["Latex_Environment" name option content]
-        (let [content (latex-environment-content name option content)]
-          (if html-export?
-            (latex/html-export content true true)
-            (latex/latex (str (d/squuid)) content true true)))
-
-        ["Displayed_Math" content]
-        (if html-export?
-          (latex/html-export content true true)
-          (latex/latex (str (d/squuid)) content true true))
-
-        ["Footnote_Definition" name definition]
-        (let [id (util/url-encode name)]
-          [:div.footdef
-           [:div.footpara
-            (conj
-             (markup-element-cp config ["Paragraph" definition])
-             [:a.ml-1 {:id (str "fn." id)
-                       :style {:font-size 14}
-                       :class "footnum"
-                       :on-click #(route-handler/jump-to-anchor! (str "fnr." id))}
-              [:sup.fn (str name "↩︎")]])]])
-
-        ["Src" options]
-        (src-cp config options html-export?)
+             ["Drawer" name lines]
+             (when (or (not= name "logbook")
+                       (and
+                        (= name "logbook")
+                        (state/enable-timetracking?)
+                        (or  (get-in (state/get-config) [:logbook/settings :enabled-in-all-blocks])
+                             (when (get-in (state/get-config)
+                                           [:logbook/settings :enabled-in-timestamped-blocks] true)
+                               (or (:block/scheduled (:block config))
+                                   (:block/deadline (:block config)))))))
+               [:div
+                [:div.text-sm
+                 [:div.drawer {:data-drawer-name name}
+                  (ui/foldable
+                   [:div.opacity-50.font-medium.logbook
+                    (util/format ":%s:" (string/upper-case name))]
+                   [:div.opacity-50.font-medium
+                    (if (= name "logbook")
+                      (logbook-cp lines)
+                      (apply str lines))
+                    [:div ":END:"]]
+                   {:default-collapsed? true
+                    :title-trigger? true})]]])
+
+             ["Properties" m]
+             [:div.properties
+              (for [[k v] (dissoc m :roam_alias :roam_tags)]
+                (when (and (not (and (= k :macros) (empty? v))) ; empty macros
+                           (not (= k :title))
+                           (not (= k :filters)))
+                  [:div.property
+                   [:span.font-medium.mr-1 (str (name k) ": ")]
+                   (if (coll? v)
+                     (let [vals (for [item v]
+                                  (if (coll? v)
+                                    (let [config (when (= k :alias)
+                                                   (assoc config :block/alias? true))]
+                                      (page-cp config {:block/name item}))
+                                    (inline-text format item)))]
+                       (interpose [:span ", "] vals))
+                     (inline-text format v))]))]
+
+             ;; for file-level property in orgmode: #+key: value
+             ;; only display caption. https://orgmode.org/manual/Captions.html.
+             ["Directive" key value]
+             [:div.file-level-property
+              (when (contains? #{"caption"} (string/lower-case key))
+                [:span.font-medium
+                 [:span.font-bold (string/upper-case key)]
+                 (str ": " value)])]
+
+             ["Paragraph" l]
+             ;; TODO: speedup
+             (if (util/safe-re-find #"\"Export_Snippet\" \"embed\"" (str l))
+               (->elem :div (map-inline config l))
+               (->elem :div.is-paragraph (map-inline config l)))
+
+             ["Horizontal_Rule"]
+             (when-not (:slide? config)
+               [:hr])
+             ["Heading" h]
+             (block-container config h)
+             ["List" l]
+             (let [lists (divide-lists l)]
+               (if (= 1 (count lists))
+                 (let [l (first lists)]
+                   (->elem
+                    (list-element l)
+                    (map #(list-item config %) l)))
+                 [:div.list-group
+                  (for [l lists]
+                    (->elem
+                     (list-element l)
+                     (map #(list-item config %) l)))]))
+             ["Table" t]
+             (table config t)
+             ["Math" s]
+             (if html-export?
+               (latex/html-export s true true)
+               (latex/latex (str (d/squuid)) s true true))
+             ["Example" l]
+             [:pre.pre-wrap-white-space
+              (join-lines l)]
+             ["Quote" l]
+             (->elem
+              :blockquote
+              (markup-elements-cp config l))
+             ["Raw_Html" content]
+             (when (not html-export?)
+               [:div.raw_html {:dangerouslySetInnerHTML
+                               {:__html content}}])
+             ["Export" "html" _options content]
+             (when (not html-export?)
+               [:div.export_html {:dangerouslySetInnerHTML
+                                  {:__html content}}])
+             ["Hiccup" content]
+             (ui/catch-error
+              [:div.warning {:title "Invalid hiccup"}
+               content]
+              (-> (safe-read-string content)
+                  (security/remove-javascript-links-in-href)))
+
+             ["Export" "latex" _options content]
+             (if html-export?
+               (latex/html-export content true false)
+               (latex/latex (str (d/squuid)) content true false))
+
+             ["Custom" "query" _options _result content]
+             (try
+               (let [query (reader/read-string content)]
+                 (custom-query config query))
+               (catch :default e
+                 (log/error :read-string-error e)
+                 (ui/block-error "Invalid query:" {:content content})))
+
+             ["Custom" "note" _options result _content]
+             (admonition config "note" result)
+
+             ["Custom" "tip" _options result _content]
+             (admonition config "tip" result)
+
+             ["Custom" "important" _options result _content]
+             (admonition config "important" result)
+
+             ["Custom" "caution" _options result _content]
+             (admonition config "caution" result)
+
+             ["Custom" "warning" _options result _content]
+             (admonition config "warning" result)
+
+             ["Custom" "pinned" _options result _content]
+             (admonition config "pinned" result)
+
+             ["Custom" "center" _options l _content]
+             (->elem
+              :div.text-center
+              (markup-elements-cp config l))
 
-        :else
-        "")
+             ["Custom" name _options l _content]
+             (->elem
+              :div
+              {:class name}
+              (markup-elements-cp config l))
+
+             ["Latex_Fragment" l]
+             [:p.latex-fragment
+              (inline config ["Latex_Fragment" l])]
+
+             ["Latex_Environment" name option content]
+             (let [content (latex-environment-content name option content)]
+               (if html-export?
+                 (latex/html-export content true true)
+                 (latex/latex (str (d/squuid)) content true true)))
+
+             ["Displayed_Math" content]
+             (if html-export?
+               (latex/html-export content true true)
+               (latex/latex (str (d/squuid)) content true true))
+
+             ["Footnote_Definition" name definition]
+             (let [id (util/url-encode name)]
+               [:div.footdef
+                [:div.footpara
+                 (conj
+                  (markup-element-cp config ["Paragraph" definition])
+                  [:a.ml-1 {:id (str "fn." id)
+                            :style {:font-size 14}
+                            :class "footnum"
+                            :on-click #(route-handler/jump-to-anchor! (str "fnr." id))}
+                   [:sup.fn (str name "↩︎")]])]])
+
+             ["Src" options]
+             (src-cp config options html-export?)
+
+             :else
+             "")
       (catch js/Error e
         (println "Convert to html failed, error: " e)
         ""))))

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

@@ -115,10 +115,9 @@
   (if (seq ast)
     (let [original-ast ast
           ast (map first ast)           ; without position meta
-          directive?
-          (fn [[item _]] (= "directive" (string/lower-case (first item))))
+          directive? (fn [[item _]] (= "directive" (string/lower-case (first item))))
           grouped-ast (group-by directive? original-ast)
-          directive-ast (get grouped-ast true)
+          directive-ast (take-while directive? original-ast)
           [properties-ast other-ast] (if (= "Property_Drawer" (ffirst ast))
                                        [(last (first ast))
                                         (rest original-ast)]

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

@@ -2,7 +2,9 @@
   (:require [frontend.config :as config]
             [frontend.util :as util]
             [clojure.string :as string]
-            [frontend.format.mldoc :as mldoc]))
+            [frontend.format.mldoc :as mldoc]
+            [clojure.set :as set]
+            [frontend.state :as state]))
 
 (def page-ref-re-0 #"\[\[(.*)\]\]")
 (def org-page-ref-re #"\[\[(file:.*)\]\[.+?\]\]")
@@ -344,7 +346,9 @@
          v (if (or (symbol? v) (keyword? v)) (name v) (str v))
          v (string/trim v)]
      (cond
-       (contains? #{"title" "filters"} k)
+       (contains? (set/union
+                   #{"title" "filters"}
+                   (get (state/get-config) :ignored-page-references-keywords)) k)
        v
 
        (= v "true")

+ 3 - 0
templates/config.edn

@@ -189,4 +189,7 @@
 
  ;; Extra CodeMirror options
  ;; :editor/extra-codemirror-options {:keyMap "emacs" :lineWrapping true}
+
+ ;; ignore #+keyword: for parsing page references in orgmode
+ ;; :ignored-page-references-keywords #{"author" "startup"}
  }