Browse Source

fix: wrong indentation when extracting blocks

close #1785
Tienson Qin 4 years ago
parent
commit
66c0200b51

+ 16 - 10
src/main/frontend/format/block.cljs

@@ -526,26 +526,30 @@
 
 (defn with-parent-and-left
   [page-id blocks]
-  (loop [blocks blocks
+  (loop [blocks (map (fn [block] (assoc block :block/level-spaces (:block/level block))) blocks)
          parents [{:page/id page-id     ; db id or lookup ref [:block/name "xxx"]
-                   :block/level 0}]
+                   :block/level 0
+                   :block/level-spaces 0}]
          result []]
     (if (empty? blocks)
-      result
+      (map #(dissoc % :block/level-spaces) result)
       (let [[block & others] blocks
-            cur-level (:block/level block)
+            level-spaces (:block/level-spaces block)
             {:block/keys [uuid level parent unordered] :as last-parent} (last parents)
+            parent-spaces (:block/level-spaces last-parent)
             [blocks parents result]
             (cond
-              (= cur-level level)        ; sibling
+              (= level-spaces parent-spaces)        ; sibling
               (let [block (assoc block
                                  :block/parent parent
-                                 :block/left [:block/uuid uuid])
+                                 :block/left [:block/uuid uuid]
+                                 :block/level level
+                                 )
                     parents' (conj (vec (butlast parents)) block)
                     result' (conj result block)]
                 [others parents' result'])
 
-              (> cur-level level)         ; child
+              (> level-spaces parent-spaces)         ; child
               (let [parent (if uuid [:block/uuid uuid] (:page/id last-parent))
                     block (cond->
                             (assoc block
@@ -556,14 +560,16 @@
                             ;;   - a
                             ;; - b
                             ;; What if the input indentation is two spaces instead of 4 spaces
-                            (> (- cur-level level) (if unordered 4 1))
+                            (>= (- level-spaces parent-spaces) 1)
                             (assoc :block/level (inc level)))
                     parents' (conj parents block)
                     result' (conj result block)]
                 [others parents' result'])
 
-              (< cur-level level)         ; outdent
-              (let [parents' (vec (filter (fn [p] (<= (:block/level p) cur-level)) parents))]
+              (< level-spaces parent-spaces)         ; outdent
+              (let [parents' (vec (filter (fn [p] (<= (:block/level-spaces p) level-spaces)) parents))
+                    blocks (cons (assoc (first blocks) :block/level (dec level))
+                                 (rest blocks))]
                 [blocks parents' result]))]
         (recur blocks parents result)))))
 

+ 19 - 17
src/main/frontend/handler/extract.cljs

@@ -145,23 +145,25 @@
       (log/error :exception e))))
 
 (defn extract-blocks-pages
-  [repo-url file content utf8-content]
-  (if (string/blank? content)
-    []
-    (let [journal? (util/journal? file)
-          format (format/get-format file)
-          ast (mldoc/->edn content
-                           (mldoc/default-config format))
-          first-block (first ast)
-          properties (let [properties (and (seq first-block)
-                                           (= "Properties" (ffirst first-block))
-                                           (last (first first-block)))]
-                       (if (and properties (seq properties))
-                         properties))]
-      (extract-pages-and-blocks
-       repo-url
-       format ast properties
-       file content utf8-content journal?))))
+  ([repo-url file content]
+   (extract-blocks-pages repo-url file content (utf8/encode content)))
+  ([repo-url file content utf8-content]
+   (if (string/blank? content)
+     []
+     (let [journal? (util/journal? file)
+           format (format/get-format file)
+           ast (mldoc/->edn content
+                            (mldoc/default-config format))
+           first-block (first ast)
+           properties (let [properties (and (seq first-block)
+                                            (= "Properties" (ffirst first-block))
+                                            (last (first first-block)))]
+                        (if (and properties (seq properties))
+                          properties))]
+       (extract-pages-and-blocks
+        repo-url
+        format ast properties
+        file content utf8-content journal?)))))
 
 (defn with-block-uuid
   [pages]

+ 62 - 0
src/test/frontend/handler/extract_test.cljs

@@ -0,0 +1,62 @@
+(ns frontend.handler.extract-test
+  (:require [cljs.test :refer [deftest is are testing use-fixtures run-tests]]
+            [cljs-run-test :refer [run-test]]
+            [frontend.handler.extract :as extract]))
+
+(defn- extract-level-and-content
+  [text]
+  (->> (extract/extract-blocks-pages "repo" "a.md" text)
+       last
+       (mapv (juxt :block/level :block/content))))
+
+(deftest test-extract-blocks-pages
+  []
+  (are [x y] (= (extract-level-and-content x) y)
+    "- a
+  - b
+    - c"
+    [[1 "a"] [2 "b"] [3 "c"]]
+
+    "## hello
+    - world
+      - nice
+        - nice
+      - bingo
+      - world
+        - so good
+        - nice
+          - bingo
+           - test"
+    [[1 "## hello"]
+     [2 "world"]
+     [3 "nice"]
+     [4 "nice"]
+     [3 "bingo"]
+     [3 "world"]
+     [4 "so good"]
+     [4 "nice"]
+     [5 "bingo"]
+     [6 "test"]]
+
+    "# a
+## b
+### c
+#### d
+### e
+- f
+  - g
+    - h
+  - i
+- j"
+    [[1 "# a"]
+     [1 "## b"]
+     [1 "### c"]
+     [1 "#### d"]
+     [1 "### e"]
+     [1 "f"]
+     [2 "g"]
+     [3 "h"]
+     [2 "i"]
+     [1 "j"]]))
+
+#_(run-tests)

+ 8 - 8
src/test/frontend/text_test.cljs

@@ -31,7 +31,7 @@
     "[[foo]]" ["[[foo]]"]
     "[[nested [[foo]]]]" ["[[nested [[foo]]]]"]))
 
-(defn split-page-refs-without-brackets
+(deftest split-page-refs-without-brackets
   []
   (are [x y] (= (text/split-page-refs-without-brackets x) y)
     "foobar" "foobar"
@@ -49,7 +49,7 @@
     "#tag1,#tag2" #{"tag1" "tag2"}
     "[[Jan 26th, 2021]], hello" #{"hello" "Jan 26th, 2021"}))
 
-(defn extract-level-spaces
+(deftest extract-level-spaces
   []
   (testing "markdown"
     (are [x y] (= (text/extract-level-spaces x :markdown) y)
@@ -62,7 +62,7 @@
       "**   foobar" "**   "
       "*********************  foobar" "*********************  ")))
 
-(defn remove-level-spaces
+(deftest remove-level-spaces
   []
   (testing "markdown"
     (are [x y] (= (text/remove-level-spaces x :markdown true) y)
@@ -85,7 +85,7 @@
       "**foobar" "foobar"
       "*********************foobar" "foobar")))
 
-(defn append-newline-after-level-spaces
+(deftest append-newline-after-level-spaces
   []
   (are [x y] (= (text/append-newline-after-level-spaces x :markdown) y)
     "# foobar" "#\nfoobar"
@@ -97,7 +97,7 @@
     "* foobar\nfoo" "*\nfoobar\nfoo"
     "** foobar\nfoo" "**\nfoobar\nfoo"))
 
-(defn remove-id-property
+(deftest remove-id-property
   []
   (are [x y] (= (text/remove-id-property! :org x) y)
     "hello\n:PROPERTIES:\n:id: f9873a81-07b9-4246-b910-53a6f5ec7e04\n:END:\n"
@@ -106,7 +106,7 @@
     "hello\n:PROPERTIES:\n:id: f9873a81-07b9-4246-b910-53a6f5ec7e04\na: b\n:END:\n"
     "hello\n:PROPERTIES:\na: b\n:END:"))
 
-(defn test-remove-properties!
+(deftest test-remove-properties!
   []
   (testing "properties with non-blank lines"
     (are [x y] (= x y)
@@ -123,7 +123,7 @@
       (text/remove-properties! :org "** hello\n:PROPERTIES:\n:x: y\n\na:b\n:END:\n")
       "** hello")))
 
-(defn test-insert-property
+(deftest test-insert-property
   []
   (are [x y] (= x y)
     (text/insert-property! :org "hello" "a" "b")
@@ -138,7 +138,7 @@
     (text/insert-property! :org "hello\n:PROPERTIES:\n:a: b\n:END: world\n" "c" "d")
     "hello\n:PROPERTIES:\n:c: d\n:END:\n:PROPERTIES:\n:a: b\n:END: world\n"))
 
-(defn test->new-properties
+(deftest test->new-properties
   []
   (are [x y] (= (text/->new-properties x) y)
     ":PROPERTIES:\n:foo: bar\n:END:"