| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- (ns frontend.handler.block
- (:require [frontend.util :as util]
- [frontend.util.property :as property]
- [clojure.walk :as walk]
- [frontend.db :as db]
- [frontend.state :as state]
- [frontend.format.mldoc :as mldoc]
- [frontend.date :as date]
- [frontend.config :as config]
- [datascript.core :as d]
- [clojure.set :as set]
- [medley.core :as medley]
- [frontend.format.block :as block]
- [frontend.debug :as debug]
- [clojure.string :as string]
- [frontend.text :as text]
- [frontend.handler.common :as common-handler]))
- (defn get-block-ids
- [block]
- (let [ids (atom [])
- _ (walk/prewalk
- (fn [form]
- (when (map? form)
- (when-let [id (:block/uuid form)]
- (swap! ids conj id)))
- form)
- block)]
- @ids))
- ;; TODO: should we remove this dummy block and use the page's root block instead?
- (defn with-dummy-block
- ([blocks format]
- (with-dummy-block blocks format {} {}))
- ([blocks format default-option {:keys [journal? page-name]
- :or {journal? false}}]
- (let [format (or format (state/get-preferred-format) :markdown)
- blocks (vec blocks)]
- (if (seq blocks)
- blocks
- (let [page-block (when page-name (db/pull [:block/name (string/lower-case page-name)]))
- create-title-property? (and page-name (util/include-windows-reserved-chars? page-name))
- content (if create-title-property?
- (let [title (or (:block/original-name page-block)
- (:block/name page-block))
- properties (common-handler/get-page-default-properties title)]
- (property/build-properties-str format properties))
- "")
- page-id {:db/id (:db/id page-block)}
- dummy (merge {:block/uuid (db/new-block-id)
- :block/left page-id
- :block/parent page-id
- :block/page page-id
- :block/title ""
- :block/content content
- :block/format format
- :block/dummy? true}
- default-option)
- dummy (if (:db/id (:block/file dummy))
- dummy
- (dissoc dummy :block/file))]
- [dummy])))))
- (defn filter-blocks
- [repo ref-blocks filters group-by-page?]
- (let [ref-pages (->> (if group-by-page?
- (mapcat last ref-blocks)
- ref-blocks)
- (mapcat (fn [b] (concat (:block/refs b) (:block/children-refs b))))
- (concat (when group-by-page? (map first ref-blocks)))
- (distinct)
- (map :db/id)
- (db/pull-many repo '[:db/id :block/name]))
- ref-pages (zipmap (map :block/name ref-pages) (map :db/id ref-pages))
- exclude-ids (->> (map (fn [page] (get ref-pages page)) (get filters false))
- (remove nil?)
- (set))
- include-ids (->> (map (fn [page] (get ref-pages page)) (get filters true))
- (remove nil?)
- (set))]
- (if (empty? filters)
- ref-blocks
- (let [filter-f (fn [ref-blocks]
- (cond->> ref-blocks
- (seq exclude-ids)
- (remove (fn [block]
- (let [ids (set (concat (map :db/id (:block/refs block))
- (map :db/id (:block/children-refs block))
- [(:db/id (:block/page block))]))]
- (seq (set/intersection exclude-ids ids)))))
- (seq include-ids)
- (remove (fn [block]
- (let [page-block-id (:db/id (:block/page block))
- ids (set (concat (map :db/id (:block/refs block))
- (map :db/id (:block/children-refs block))))]
- (if (and (contains? include-ids page-block-id)
- (= 1 (count include-ids)))
- (not= page-block-id (first include-ids))
- (empty? (set/intersection include-ids (set (conj ids page-block-id))))))))))]
- (if group-by-page?
- (->> (map (fn [[p ref-blocks]]
- [p (filter-f ref-blocks)]) ref-blocks)
- (remove #(empty? (second %))))
- (->> (filter-f ref-blocks)
- (remove nil?)))))))
- ;; TODO: reduced version
- (defn walk-block
- [block check? transform]
- (let [result (atom nil)]
- (walk/postwalk
- (fn [x]
- (if (check? x)
- (reset! result (transform x))
- x))
- (:block/body block))
- @result))
- (defn get-timestamp
- [block typ]
- (walk-block block
- (fn [x]
- (and (block/timestamp-block? x)
- (= typ (first (second x)))))
- #(second (second %))))
- (defn get-scheduled-ast
- [block]
- (get-timestamp block "Scheduled"))
- (defn get-deadline-ast
- [block]
- (get-timestamp block "Deadline"))
|