1
0

diff.cljs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. (ns frontend.diff
  2. (:require [clojure.string :as string]
  3. ["diff" :as jsdiff]
  4. [goog.object :as gobj]
  5. [lambdaisland.glogi :as log]
  6. [cljs-bean.core :as bean]
  7. [frontend.util :as util]
  8. [logseq.graph-parser.util :as gp-util]
  9. [frontend.util.text :as text-util]))
  10. (defn diff
  11. [s1 s2]
  12. (-> ((gobj/get jsdiff "diffLines") s1 s2 (clj->js {"newlineIsToken" true}))
  13. bean/->clj))
  14. (def inline-special-chars
  15. #{\* \_ \/ \` \+ \^ \~ \$})
  16. (defn- markdown-link?
  17. [markup current-line pos]
  18. (and current-line
  19. (= (util/nth-safe markup pos) "]")
  20. (= (util/nth-safe markup (inc pos)) "(")
  21. (string/includes? (subs current-line 0 pos) "[")
  22. (string/includes? (subs current-line pos) ")")))
  23. ;; (find-position "** hello _w_" "hello w")
  24. (defn find-position
  25. [markup text]
  26. (when (and (string? markup) (string? text))
  27. (try
  28. (let [pos (loop [t1 (-> markup string/lower-case seq)
  29. t2 (-> text string/lower-case seq)
  30. i1 0
  31. i2 0]
  32. (let [[h1 & r1] t1
  33. [h2 & r2] t2]
  34. (cond
  35. (or (empty? t1) (empty? t2))
  36. i1
  37. (= h1 h2)
  38. (recur r1 r2 (inc i1) (inc i2))
  39. (#{\[ \space \]} h2)
  40. (recur t1 r2 i1 (inc i2))
  41. :else
  42. (recur r1 t2 (inc i1) i2))))
  43. current-line (text-util/get-current-line-by-pos markup pos)]
  44. (cond
  45. (= (util/nth-safe markup pos)
  46. (util/nth-safe markup (inc pos))
  47. "]")
  48. (+ pos 2)
  49. (contains? inline-special-chars (util/nth-safe markup pos))
  50. (let [matched (->> (take-while inline-special-chars (gp-util/safe-subs markup pos))
  51. (apply str))
  52. matched? (and current-line (string/includes? current-line (string/reverse matched)))]
  53. (if matched?
  54. (+ pos (count matched))
  55. pos))
  56. (markdown-link? markup current-line pos)
  57. (let [idx (string/index-of (subs current-line pos) ")")]
  58. (+ pos (inc idx)))
  59. :else
  60. pos))
  61. (catch js/Error e
  62. (log/error :diff/find-position {:error e})
  63. (count markup)))))