Структура молнии Clojure для текстового редактора (с картами и массивами)

Я пытаюсь сделать простой текстовый редактор в 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"
            }]}]})

Поэтому я хочу сделать молнию, которая сможет легко ориентироваться в этом. Может молния для этого не подойдет? Но я думал начать с корня. Спуск вниз приведет вас к узлам этих детей. Таким образом, верхняя часть документа имеет идентификатор h1.

У меня есть следующее, но это не позволяет детям быть массивом:

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

Ожидается что-то вроде:

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

Есть предположения? Я открыт для полного изменения структуры, если у кого-то есть предложения.


person Jonovono    schedule 27.09.2013    source источник


Ответы (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)

Вы также можете взглянуть на формат дерева синтаксического анализа Enlive или Instaparse для идей о структуре. Повторное использование их структуры может дать вам некоторую функциональную совместимость, которую вы не получите при развертывании своей собственной.

person Jared314    schedule 27.09.2013