1

我正在尝试在 clojure 中制作一个简单的文本编辑器,只是为了熟悉它。我正在考虑使用拉链来构建结构并导航和更新编辑器。

我正在考虑将编辑器的文本存储在文档中,例如:

(def document-test {
:id "doc1"
:info {
    :title "Moluctular bio"
    :description "Test document"
}
:nodes [{
        :type "header"
        :content "This is a header"
        :id "h1"
    }
    {
        :type "p"
        :content "this is a paragraph"
        :id "p1"
    }
    {
        :type "todo"
        :content "Todo list"
        :id "t1"
        :nodes [
            {
                :type "todoelement"
                :content "Do this"
                :id "td1"
            }
            {
                :type "todoelement"
                :content "Do that"
                :id "td2"
            }]}]})

所以我想制作一个能够轻松导航的拉链。也许拉链不是最好的?但我正在考虑从根开始。下去会带你到那个孩子的节点。所以文档的顶部是 id h1。

我有以下内容,但它不允许孩子成为一个数组:

(defn map-zip [m] 
  (zip/zipper 
    #(map? (second %)) 
        #(seq (second %)) 
       (fn [node children] [(first node) (into {} children)]) 
       [:root m])) 

它更期待类似的东西:

{:foo {:bar {:baz 2}}}

有什么想法吗?如果有人有任何建议,我愿意完全改变结构。

4

1 回答 1

1

您可以构建一个拉链来导航该结构,如下所示:

(def z (zip/zipper 
        (constantly true) ; a node can always have children
        :nodes ; child nodes in the :nodes key, and keywords are functions
        (fn [node children]
          (update-in node [:nodes] #(into (or % []) children)))
        document-test))

(-> z
    zip/down
    zip/right
    zip/right
    (zip/insert-child {:type "h3" :id "thing1" :content "It's a h3!"})
    zip/down
    zip/right
    zip/right
    zip/node)

您可能还想查看EnliveInstaparse的解析树格式,以了解有关结构的想法。重用它们的结构可能会为您提供一些您自己滚动无法获得的互操作性。

于 2013-09-27T22:47:34.177 回答