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.
pull/4596/head
llcc 2022-03-16 17:10:49 +08:00 committed by GitHub
parent 96da98e5bd
commit 1361728457
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 168 additions and 153 deletions

View File

@ -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})]]])
["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))]))]
["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)))
;; 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)])]
["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)))
["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)))
["Export" "latex" _options content]
(if html-export?
(latex/html-export content true false)
(latex/latex (str (d/squuid)) content true false))
["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)))
["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})))
["Export" "latex" _options content]
(if html-export?
(latex/html-export content true false)
(latex/latex (str (d/squuid)) content true false))
["Custom" "note" _options result _content]
(admonition config "note" result)
["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" "tip" _options result _content]
(admonition config "tip" result)
["Custom" "note" _options result _content]
(admonition config "note" result)
["Custom" "important" _options result _content]
(admonition config "important" result)
["Custom" "tip" _options result _content]
(admonition config "tip" result)
["Custom" "caution" _options result _content]
(admonition config "caution" result)
["Custom" "important" _options result _content]
(admonition config "important" result)
["Custom" "warning" _options result _content]
(admonition config "warning" result)
["Custom" "caution" _options result _content]
(admonition config "caution" result)
["Custom" "pinned" _options result _content]
(admonition config "pinned" result)
["Custom" "warning" _options result _content]
(admonition config "warning" result)
["Custom" "center" _options l _content]
(->elem
:div.text-center
(markup-elements-cp config l))
["Custom" "pinned" _options result _content]
(admonition config "pinned" result)
["Custom" name _options l _content]
(->elem
:div
{:class name}
(markup-elements-cp config l))
["Custom" "center" _options l _content]
(->elem
:div.text-center
(markup-elements-cp config l))
["Latex_Fragment" l]
[:p.latex-fragment
(inline config ["Latex_Fragment" l])]
["Custom" name _options l _content]
(->elem
:div
{:class name}
(markup-elements-cp config 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)))
["Latex_Fragment" l]
[:p.latex-fragment
(inline config ["Latex_Fragment" l])]
["Displayed_Math" content]
(if html-export?
(latex/html-export content true true)
(latex/latex (str (d/squuid)) content true true))
["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)))
["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 "↩︎")]])]])
["Displayed_Math" content]
(if html-export?
(latex/html-export content true true)
(latex/latex (str (d/squuid)) content true true))
["Src" options]
(src-cp config options html-export?)
["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 "↩︎")]])]])
:else
"")
["Src" options]
(src-cp config options html-export?)
:else
"")
(catch js/Error e
(println "Convert to html failed, error: " e)
""))))

View File

@ -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)]

View File

@ -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")

View File

@ -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"}
}