Skip to content

Commit

Permalink
parse: allow multiple newlines between prose blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
mhuebert committed Aug 25, 2023
1 parent 510a638 commit 8ca06d5
Showing 1 changed file with 56 additions and 42 deletions.
98 changes: 56 additions & 42 deletions editor2/src/main/maria/editor/code/parse_clj.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,34 @@
(->> source
parse-clj
program-nodes
(map (fn [^js x] (j/!set x :source (subs source (.-from x) (.-to x)))))

;; lezer does not represent the space between nodes, eg. empty lines,
;; so add a ::line-gap marker in these cases
(partition 2 1 nil)
(mapcat (fn [[^js a ^js b]]
(if (and b (pos? (- (.-from b) (.-to a) 1)))
[a ::line-gap]
[a])))

(eduction
(map (fn [node]
(if (= node ::line-gap)
";"
(subs source (j/get node :from) (j/get node :to)))))
(partition-by comment?)
(mapcat
(fn [sources]
(if (comment? (first sources))
[{:type :prose
:source (->> sources
(map #(str/replace % #"^;+\s*" ""))
(str/join \newline))}]
(map (fn [source]
{:type :code
:source source}) sources)))))))
;; preserve newlines between prose blocks
(mapcat (fn [[^js a ^js b]]
(cond-> [(.-source a)]
(and b
(comment? (.-source a))
(comment? (.-source b)))
(into
(take (->> (subs source (.-to a) (.-from b))
(re-seq #"\n")
count
dec)
(repeat ";"))))))
(partition-by comment?)
(mapcat
(fn [sources]
(if (comment? (first sources))
[{:type :prose
:source (->> sources
(map #(str/replace % #"^;+\s*" ""))
(str/join \newline))}]
(map (fn [source]
{:type :code
:source source}) sources)))))))

(defn blocks->md [blocks]
(->> blocks
Expand All @@ -69,6 +72,10 @@

(def clojure->markdown (comp blocks->md clj->blocks))


;; - code blocks maintain a 1-line gap above & below
;; - consecutive prose blocks are separated by ;;-prefixed lines

(def sample-source
"(ns my.app)
Expand All @@ -81,30 +88,37 @@
;; Another paragraph.")

(comment
(= (vec (clj->blocks sample-source))
[{:type :code
:source "(ns my.app)"}
{:type :prose
:source "# Hello, world.\n\nThis is a paragraph."}
{:type :code
:source "(+ 1 2)"}
{:type :prose
:source "Another paragraph."}]))
(= (vec (clj->blocks sample-source))
[{:type :code
:source "(ns my.app)"}
{:type :prose
:source "# Hello, world.\n\nThis is a paragraph."}
{:type :code
:source "(+ 1 2)"}
{:type :prose
:source "Another paragraph."}]))

(comment
(= (-> sample-source
clj->blocks
blocks->md)
"```clj
(ns my.app)
```
(= (-> sample-source
clj->blocks
blocks->md)
"
```clj
(ns my.app)
```
# Hello, world.
# Hello, world.
This is a paragraph.
This is a paragraph.
```clj
(+ 1 2)
```
```clj
(+ 1 2)
```
Another paragraph."))
Another paragraph."))

(comment
(assert
(= (vec (clj->blocks ";; hello\n\n;; world"))
(vec (clj->blocks ";; hello\n;;\n;; world")))
"prose blocks are joined even if separated by non-;; lines"))

0 comments on commit 8ca06d5

Please sign in to comment.