Ver Fonte

feat(copy-as/export): add option: :newline-after-block

rcmerci há 2 anos atrás
pai
commit
bce6174b5a

+ 13 - 1
src/main/frontend/components/export.cljs

@@ -167,7 +167,19 @@
                                     (reset! *content (export-helper root-block-uuids-or-page-name)))})
 
          [:div {:style {:visibility (if (#{:text :html :opml} tp) "visible" "hidden")}}
-          "remove #tags"]]
+          "remove #tags"]
+
+         (ui/checkbox {:style {:margin-right 6
+                               :margin-left "1em"
+                               :visibility (if (#{:text} tp) "visible" "hidden")}
+                       :checked (boolean (:newline-after-block @*text-other-options))
+                       :on-change (fn [e]
+                                    (state/update-export-block-text-other-options!
+                                     :newline-after-block (boolean (util/echecked? e)))
+                                    (reset! *text-other-options (state/get-export-block-text-other-options))
+                                    (reset! *content (export-helper root-block-uuids-or-page-name)))})
+         [:div {:style {:visibility (if (#{:text} tp) "visible" "hidden")}}
+          "newline after block"]]
 
         [:div.flex.items-center
          [:label.mr-2 {:style {:visibility (if (#{:text :html :opml} tp) "visible" "hidden")}}

+ 23 - 10
src/main/frontend/handler/export/common.cljs

@@ -38,6 +38,10 @@
     :block-ref-replaced? false
     :block&page-embed-replaced? false}
 
+   ;; submap for :newline-after-block internal state
+   :newline-after-block
+   {:current-block-is-first-heading-block? true}
+
    ;; export-options submap
    :export-options
    {;; dashes, spaces, no-indent
@@ -45,7 +49,8 @@
     :remove-page-ref-brackets? false
     :remove-emphasis? false
     :remove-tags? false
-    :keep-only-level<=N :all}})
+    :keep-only-level<=N :all
+    :newline-after-block false}})
 
 ;;; internal utils
 (defn- get-blocks-contents
@@ -110,6 +115,10 @@
   [level & {:keys [spaces] :or {spaces "  "}}]
   ["Plain" (str (reduce str (repeat (dec level) "\t")) spaces)])
 
+(defn- mk-paragraph-ast
+  [inline-coll meta]
+  (with-meta ["Paragraph" inline-coll] meta))
+
 ;;; internal utils (ends)
 
 ;;; utils
@@ -291,7 +300,7 @@
       [ast-type (replace-block-reference-in-heading ast-content)]
 
       "Paragraph"
-      [ast-type (replace-block-reference-in-paragraph ast-content)]
+      (mk-paragraph-ast (replace-block-reference-in-paragraph ast-content) (meta block-ast))
 
       "List"
       [ast-type (replace-block-reference-in-list ast-content)]
@@ -382,17 +391,20 @@
             (recur other-inlines heading-exist? (conj current-paragraph-inlines* inline) r)))))))
 
 (defn- replace-block&page-embeds-in-paragraph
-  [inline-coll]
+  [inline-coll meta]
   (let [current-level (get-in *state* [:replace-ref-embed :current-level])]
     (loop [[inline & other-inlines] inline-coll
            current-paragraph-inlines []
            just-after-embed? false
            blocks (transient [])]
       (if-not inline
-        (persistent!
-         (if (seq current-paragraph-inlines)
-           (conj! blocks ["Paragraph" current-paragraph-inlines])
-           blocks))
+        (let [[first-block & other-blocks] (persistent!
+                                            (if (seq current-paragraph-inlines)
+                                              (conj! blocks ["Paragraph" current-paragraph-inlines])
+                                              blocks))]
+          (if first-block
+            (apply vector (with-meta first-block meta) other-blocks)
+            []))
         (match [inline]
           [["Macro" {:name "embed" :arguments [block-uuid-or-page-name]}]]
           (cond
@@ -448,7 +460,7 @@
       "Heading"
       (replace-block&page-embeds-in-heading ast-content)
       "Paragraph"
-      (replace-block&page-embeds-in-paragraph ast-content)
+      (replace-block&page-embeds-in-paragraph ast-content (meta block-ast))
       "List"
       (replace-block&page-embeds-in-list ast-content)
       "Quote"
@@ -514,6 +526,7 @@
   [[tp _]]
   (= tp "Properties"))
 
+
 (defn replace-Heading-with-Paragraph
   "works on block-ast
   replace all heading with paragraph when indent-style is no-indent"
@@ -526,7 +539,7 @@
               marker (cons ["Plain" (str marker " ")])
               size (cons ["Plain" (str (reduce str (repeat size "#")) " ")])
               true vec)]
-        ["Paragraph" inline-coll])
+        (mk-paragraph-ast inline-coll {:origin-ast heading-ast}))
       heading-ast)))
 
 (defn keep-only-level<=n
@@ -625,7 +638,7 @@
   (let [[ast-type ast-content] block-ast]
     (case ast-type
       "Paragraph"
-      ["Paragraph" (walk-block-ast-helper ast-content map-fns-on-inline-ast mapcat-fns-on-inline-ast)]
+      (mk-paragraph-ast (walk-block-ast-helper ast-content map-fns-on-inline-ast mapcat-fns-on-inline-ast) (meta block-ast))
       "Heading"
       (let [{:keys [title]} ast-content]
         ["Heading"

+ 12 - 12
src/main/frontend/handler/export/html.cljs

@@ -1,17 +1,17 @@
 (ns frontend.handler.export.html
   "export blocks/pages as html"
-  (:require
-   [clojure.edn :as edn]
-   [clojure.string :as string]
-   [clojure.zip :as z]
-   [frontend.db :as db]
-   [frontend.handler.export.common :as common :refer [*state*]]
-   [frontend.handler.export.zip-helper :refer [get-level goto-last goto-level]]
-   [frontend.state :as state]
-   [frontend.util :as util :refer [concatv mapcatv removev]]
-   [hiccups.runtime :as h]
-   [logseq.graph-parser.mldoc :as gp-mldoc]
-   [malli.core :as m]))
+  (:require [clojure.edn :as edn]
+            [clojure.string :as string]
+            [clojure.zip :as z]
+            [frontend.db :as db]
+            [frontend.handler.export.common :as common :refer [*state*]]
+            [frontend.handler.export.zip-helper :refer [get-level goto-last
+                                                        goto-level]]
+            [frontend.state :as state]
+            [frontend.util :as util :refer [concatv mapcatv removev]]
+            [hiccups.runtime :as h]
+            [logseq.graph-parser.mldoc :as gp-mldoc]
+            [malli.core :as m]))
 
 (def ^:private hiccup-malli-schema
   [:cat :keyword [:* :any]])

+ 13 - 13
src/main/frontend/handler/export/opml.cljs

@@ -1,20 +1,20 @@
 (ns frontend.handler.export.opml
   "export blocks/pages as opml"
   (:refer-clojure :exclude [map filter mapcat concat remove newline])
-  (:require
-   [clojure.string :as string]
-   [clojure.zip :as z]
-   [frontend.db :as db]
-   [frontend.extensions.zip :as zip]
-   [frontend.handler.export.common :as common :refer
+  (:require [clojure.string :as string]
+            [clojure.zip :as z]
+            [frontend.db :as db]
+            [frontend.extensions.zip :as zip]
+            [frontend.handler.export.common :as common :refer
              [*state* raw-text simple-asts->string space]]
-   [frontend.handler.export.zip-helper :refer [get-level goto-last goto-level]]
-   [frontend.state :as state]
-   [frontend.util :as util :refer [concatv mapcatv removev]]
-   [hiccups.runtime :as h]
-   [logseq.graph-parser.mldoc :as gp-mldoc]
-   [promesa.core :as p]
-   [goog.dom :as gdom]))
+            [frontend.handler.export.zip-helper :refer [get-level goto-last
+                                                        goto-level]]
+            [frontend.state :as state]
+            [frontend.util :as util :refer [concatv mapcatv removev]]
+            [goog.dom :as gdom]
+            [hiccups.runtime :as h]
+            [logseq.graph-parser.mldoc :as gp-mldoc]
+            [promesa.core :as p]))
 
 ;;; *opml-state*
 (def ^:private ^:dynamic

+ 76 - 64
src/main/frontend/handler/export/text.cljs

@@ -1,21 +1,18 @@
 (ns frontend.handler.export.text
   "export blocks/pages as text"
   (:refer-clojure :exclude [map filter mapcat concat remove newline])
-  (:require
-   [clojure.string :as string]
-   [frontend.db :as db]
-   [frontend.extensions.zip :as zip]
-   [frontend.handler.export.common :as common :refer
-    [*state*
-     simple-ast-malli-schema
-     raw-text space newline* indent simple-asts->string]]
-   [frontend.state :as state]
-   [frontend.util :as util :refer [mapcatv concatv removev]]
-   [goog.dom :as gdom]
-   [logseq.graph-parser.mldoc :as gp-mldoc]
-   [malli.core :as m]
-   [promesa.core :as p]))
-
+  (:require [clojure.string :as string]
+            [frontend.db :as db]
+            [frontend.extensions.zip :as zip]
+            [frontend.handler.export.common :as common :refer
+             [*state* indent newline* raw-text simple-ast-malli-schema
+              simple-asts->string space]]
+            [frontend.state :as state]
+            [frontend.util :as util :refer [concatv mapcatv removev]]
+            [goog.dom :as gdom]
+            [logseq.graph-parser.mldoc :as gp-mldoc]
+            [malli.core :as m]
+            [promesa.core :as p]))
 
 ;;; block-ast, inline-ast -> simple-ast
 
@@ -41,10 +38,17 @@
         size* (and size [space (raw-text (reduce str (repeat size "#")))])
         marker* (and marker (raw-text marker))]
     (set! *state* (assoc *state* :current-level level))
-    (removev nil? (concatv heading* size*
-                           [space marker* space priority* space]
-                           (mapcatv inline-ast->simple-ast title)
-                           [(newline* 1)]))))
+    (let [simple-asts
+          (removev nil? (concatv
+                         (when (and (get-in *state* [:export-options :newline-after-block])
+                                    (not (get-in *state* [:newline-after-block :current-block-is-first-heading-block?])))
+                           [(newline* 2)])
+                         heading* size*
+                         [space marker* space priority* space]
+                         (mapcatv inline-ast->simple-ast title)
+                         [(newline* 1)]))]
+      (set! *state* (assoc-in *state* [:newline-after-block :current-block-is-first-heading-block?] false))
+      simple-asts)))
 
 (declare block-list)
 (defn- block-list-item
@@ -309,52 +313,60 @@
 (m/=> block-ast->simple-ast [:=> [:cat [:sequential :any]] [:sequential simple-ast-malli-schema]])
 (defn- block-ast->simple-ast
   [block]
-  (removev
-   nil?
-   (let [[ast-type ast-content] block]
-     (case ast-type
-       "Paragraph"
-       (concatv (mapcatv inline-ast->simple-ast ast-content) [(newline* 1)])
-       "Paragraph_line"
-       (assert false "Paragraph_line is mldoc internal ast")
-       "Paragraph_Sep"
-       [(newline* ast-content)]
-       "Heading"
-       (block-heading ast-content)
-       "List"
-       (block-list ast-content)
-       ("Directive" "Results" "Property_Drawer" "Export" "CommentBlock" "Custom")
-       nil
-       "Example"
-       (block-example ast-content)
-       "Src"
-       (block-src ast-content)
-       "Quote"
-       (block-quote ast-content)
-       "Latex_Fragment"
-       (block-latex-fragment ast-content)
-       "Latex_Environment"
-       (block-latex-env (rest block))
-       "Displayed_Math"
-       (block-displayed-math ast-content)
-       "Drawer"
-       (block-drawer (rest block))
+  (let [newline-after-block? (get-in *state* [:export-options :newline-after-block])]
+    (removev
+     nil?
+     (let [[ast-type ast-content] block]
+       (case ast-type
+         "Paragraph"
+         (let [{:keys [origin-ast]} (meta block)
+               current-block-is-first-heading-block? (get-in *state* [:newline-after-block :current-block-is-first-heading-block?])]
+           (set! *state* (assoc-in *state* [:newline-after-block :current-block-is-first-heading-block?] false))
+           (concatv
+            (when (and origin-ast newline-after-block? (not current-block-is-first-heading-block?))
+              [(newline* 2)])
+            (mapcatv inline-ast->simple-ast ast-content)
+            [(newline* 1)]))
+         "Paragraph_line"
+         (assert false "Paragraph_line is mldoc internal ast")
+         "Paragraph_Sep"
+         [(newline* ast-content)]
+         "Heading"
+         (block-heading ast-content)
+         "List"
+         (block-list ast-content)
+         ("Directive" "Results" "Property_Drawer" "Export" "CommentBlock" "Custom")
+         nil
+         "Example"
+         (block-example ast-content)
+         "Src"
+         (block-src ast-content)
+         "Quote"
+         (block-quote ast-content)
+         "Latex_Fragment"
+         (block-latex-fragment ast-content)
+         "Latex_Environment"
+         (block-latex-env (rest block))
+         "Displayed_Math"
+         (block-displayed-math ast-content)
+         "Drawer"
+         (block-drawer (rest block))
        ;; TODO: option: toggle Property_Drawer
        ;; "Property_Drawer"
        ;; (block-property-drawer ast-content)
-       "Footnote_Definition"
-       (block-footnote-definition (rest block))
-       "Horizontal_Rule"
-       block-horizontal-rule
-       "Table"
-       (block-table ast-content)
-       "Comment"
-       (block-comment ast-content)
-       "Raw_Html"
-       (block-raw-html ast-content)
-       "Hiccup"
-       (block-hiccup ast-content)
-       (assert false (print-str :block-ast->simple-ast ast-type "not implemented yet"))))))
+         "Footnote_Definition"
+         (block-footnote-definition (rest block))
+         "Horizontal_Rule"
+         block-horizontal-rule
+         "Table"
+         (block-table ast-content)
+         "Comment"
+         (block-comment ast-content)
+         "Raw_Html"
+         (block-raw-html ast-content)
+         "Hiccup"
+         (block-hiccup ast-content)
+         (assert false (print-str :block-ast->simple-ast ast-type "not implemented yet")))))))
 
 (defn- inline-ast->simple-ast
   [inline]
@@ -410,7 +422,6 @@
 
 ;;; block-ast, inline-ast -> simple-ast (ends)
 
-
 ;;; export fns
 
 (defn- export-helper
@@ -423,7 +434,8 @@
                                :remove-emphasis? (contains? remove-options :emphasis)
                                :remove-page-ref-brackets? (contains? remove-options :page-ref)
                                :remove-tags? (contains? remove-options :tag)
-                               :keep-only-level<=N (:keep-only-level<=N other-options)}})]
+                               :keep-only-level<=N (:keep-only-level<=N other-options)
+                               :newline-after-block (:newline-after-block 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)