Browse Source

only copy-as/export level<N blocks for text export

rcmerci 2 years ago
parent
commit
5efbd125de

+ 24 - 4
src/main/frontend/components/export.cljs

@@ -62,30 +62,34 @@
   (let [current-repo (state/get-current-repo)
         text-indent-style (state/get-export-block-text-indent-style)
         text-remove-options (set (state/get-export-block-text-remove-options))
+        text-other-options (state/get-export-block-text-other-options)
         tp @*export-block-type]
     (case tp
       :text (export-text/export-blocks-as-markdown
              current-repo block-uuids-or-page-name
-             {:indent-style text-indent-style :remove-options text-remove-options})
+             {:indent-style text-indent-style :remove-options text-remove-options :other-options text-other-options})
       :opml (export-opml/export-blocks-as-opml
-             current-repo block-uuids-or-page-name {:remove-options text-remove-options})
+             current-repo block-uuids-or-page-name {:remove-options text-remove-options :other-options text-other-options})
       :html (export-html/export-blocks-as-html
-             current-repo block-uuids-or-page-name {:remove-options text-remove-options})
+             current-repo block-uuids-or-page-name {:remove-options text-remove-options :other-options text-other-options})
       "")))
 
 (rum/defcs export-blocks < rum/static
   (rum/local false ::copied?)
   (rum/local nil ::text-remove-options)
   (rum/local nil ::text-indent-style)
+  (rum/local nil ::text-other-options)
   (rum/local nil ::content)
   {:will-mount (fn [state]
                  (let [content (export-helper (last (:rum/args state)))]
                    (reset! (::content state) content)
                    (reset! (::text-remove-options state) (set (state/get-export-block-text-remove-options)))
                    (reset! (::text-indent-style state) (state/get-export-block-text-indent-style))
+                   (reset! (::text-other-options state) (state/get-export-block-text-other-options))
                    state))}
   [state root-block-uuids-or-page-name]
   (let [tp @*export-block-type
+        *text-other-options (::text-other-options state)
         *text-remove-options (::text-remove-options state)
         *text-indent-style (::text-indent-style state)
         *copied? (::copied? state)
@@ -163,7 +167,23 @@
                                     (reset! *content (export-helper root-block-uuids-or-page-name)))})
 
          [:div {:style {:visibility (if (#{:text :html :opml} tp) "visible" "hidden")}}
-          "remove #tags"]]])
+          "remove #tags"]]
+
+        [:div.flex.items-center
+         [:label.mr-2 {:style {:visibility (if (#{:text :html :opml} tp) "visible" "hidden")}}
+          "level <="]
+         [:select.block.my-2.text-lg.rounded.border
+          {:style {:padding "0 0 0 12px"
+                   :visibility (if (#{:text :html :opml} tp) "visible" "hidden")}
+           :value (or (:keep-only-level<=N @*text-other-options) :all)
+           :on-change (fn [e]
+                        (let [value (util/evalue e)
+                              level (if (= "all" value) :all (util/safe-parse-int value))]
+                          (state/update-export-block-text-other-options! :keep-only-level<=N level)
+                          (reset! *text-other-options (state/get-export-block-text-other-options))
+                          (reset! *content (export-helper root-block-uuids-or-page-name))))}
+          (for [n (cons "all" (range 1 10))]
+            [:option {:key n :value n} n])]]])
 
      [:div.mt-4
       (ui/button (if @*copied? "Copied to clipboard!" "Copy to clipboard")

+ 25 - 1
src/main/frontend/handler/export/common.cljs

@@ -44,7 +44,8 @@
     :indent-style "dashes"
     :remove-page-ref-brackets? false
     :remove-emphasis? false
-    :remove-tags? false}})
+    :remove-tags? false
+    :keep-only-level<=N :all}})
 
 ;;; internal utils
 (defn- get-blocks-contents
@@ -528,6 +529,29 @@
         ["Paragraph" inline-coll])
       heading-ast)))
 
+(defn keep-only-level<=n
+  [block-ast-coll n]
+  (-> (reduce
+       (fn [{:keys [result-ast-tcoll accepted-heading] :as r} ast]
+         (let [[heading-type {level :level}] ast
+               is-heading?                   (= heading-type "Heading")]
+           (cond
+             (and (not is-heading?) accepted-heading)
+             {:result-ast-tcoll (conj! result-ast-tcoll ast) :accepted-heading accepted-heading}
+
+             (and (not is-heading?) (not accepted-heading))
+             r
+
+             (and is-heading? (<= level n))
+             {:result-ast-tcoll (conj! result-ast-tcoll ast) :accepted-heading true}
+
+             (and is-heading? (> level n))
+             {:result-ast-tcoll result-ast-tcoll :accepted-heading false})))
+       {:result-ast-tcoll  (transient []) :accepted-heading false}
+       block-ast-coll)
+      :result-ast-tcoll
+      persistent!))
+
 ;;; inline transformers
 
 (defn remove-emphasis

+ 8 - 2
src/main/frontend/handler/export/text.cljs

@@ -415,16 +415,22 @@
 
 (defn- export-helper
   [content format options]
-  (let [remove-options (set (:remove-options options))]
+  (let [remove-options (set (:remove-options options))
+        other-options (:other-options options)]
     (binding [*state* (merge *state*
                              {:export-options
                               {:indent-style (or (:indent-style options) "dashes")
                                :remove-emphasis? (contains? remove-options :emphasis)
                                :remove-page-ref-brackets? (contains? remove-options :page-ref)
-                               :remove-tags? (contains? remove-options :tag)}})]
+                               :remove-tags? (contains? remove-options :tag)
+                               :keep-only-level<=N (:keep-only-level<=N other-options)}})]
       (let [ast (gp-mldoc/->edn content (gp-mldoc/default-config format))
             ast (mapv common/remove-block-ast-pos ast)
             ast (removev common/Properties-block-ast? ast)
+            keep-level<=n (get-in *state* [:export-options :keep-only-level<=N])
+            ast (if (= :all keep-level<=n)
+                  ast
+                  (common/keep-only-level<=n ast keep-level<=n))
             ast* (common/replace-block&page-reference&embed ast)
             ast** (if (= "no-indent" (get-in *state* [:export-options :indent-style]))
                     (mapv common/replace-Heading-with-Paragraph ast*)

+ 2 - 0
src/main/frontend/spec/storage.cljc

@@ -25,6 +25,7 @@
 (s/def :ui/shortcut-tooltip? boolean?)
 (s/def :copy/export-block-text-indent-style string?)
 (s/def :copy/export-block-text-remove-options set?)
+(s/def :copy/export-block-text-other-options map?)
 ;; Dynamic keys which aren't as easily validated:
 ;; :ls-pdf-last-page-*
 ;; :ls-js-allowed-*
@@ -58,4 +59,5 @@
             :ui/shortcut-tooltip?
             :copy/export-block-text-indent-style
             :copy/export-block-text-remove-options
+            :copy/export-block-text-other-options
             :file-sync/onboarding-state]))

+ 9 - 0
src/main/frontend/state.cljs

@@ -227,6 +227,8 @@
                                                 "dashes")
      :copy/export-block-text-remove-options (or (storage/get :copy/export-block-text-remove-options)
                                                 #{})
+     :copy/export-block-text-other-options  (or (storage/get :copy/export-block-text-other-options)
+                                                {})
      :date-picker/date                      nil
 
      :youtube/players                       {}
@@ -1756,6 +1758,13 @@ Similar to re-frame subscriptions"
     (storage/set :copy/export-block-text-remove-options
                  (get-export-block-text-remove-options))))
 
+(defn get-export-block-text-other-options []
+  (:copy/export-block-text-other-options @state))
+
+(defn update-export-block-text-other-options!
+  [k v]
+  (update-state! :copy/export-block-text-other-options #(assoc % k v)))
+
 (defn set-editor-args!
   [args]
   (set-state! :editor/args args))