Skip to content

Instantly share code, notes, and snippets.

@claj
Created November 6, 2015 13:37
Show Gist options
  • Save claj/a5cc452a12aa2880e0b5 to your computer and use it in GitHub Desktop.
Save claj/a5cc452a12aa2880e0b5 to your computer and use it in GitHub Desktop.
(ns path-with-enlive-example
(:require [net.cgrand.xml :as xml]
[clojure.zip :as z]))
;; This is meant to be answer to the question
;; "Enlive as a hammer" posted in the enlive mailing list:
;; https://groups.google.com/forum/#!topic/enlive-clj/Da0l_Vpu05U
;; div
;; | :content
;; [ ]
;; |---|---|
;; :p :p :p
(def simple-structure
(xml/xml-zip
{:tag :div :attrs {:id "the-table"} :content
[{:tag :p :attrs {:id "first-row"} :content ["alfa"]}
{:tag :p :attrs {:id "second-row"} :content ["bravo"]}
{:tag :p :attrs {:id "third-row"} :content ["charlie"]}]}))
;;the hidden zipper navigation functions:
(meta simple-structure)
{:zip/branch? #object[net.cgrand.xml$xml_zip$fn__10500 0x3a4ed857 "net.cgrand.xml$xml_zip$fn__10500@3a4ed857"]
:zip/children #object[clojure.core$comp$fn__4723 0x5014be2d "clojure.core$comp$fn__4723@5014be2d"]
:zip/make-node #object[net.cgrand.xml$xml_zip$fn__10503 0x61ef3ceb "net.cgrand.xml$xml_zip$fn__10503@61ef3ceb"]}
(-> simple-structure
z/down)
{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}
{:l [],
:pnodes
[{:tag :div,
:attrs {:id "the-table"},
:content
[{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}
{:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}
{:tag :p, :attrs {:id "third-row"}, :content ["charlie"]}]}],
:ppath nil,
:r
({:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}
{:tag :p, :attrs {:id "third-row"}, :content ["charlie"]})}]
(-> simple-structure
z/down
z/right)
:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}
{:l [{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}],
:pnodes
[{:tag :div,
:attrs {:id "the-table"},
:content
[{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}
{:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}
{:tag :p, :attrs {:id "third-row"}, :content ["charlie"]}]}],
:ppath nil,
:r ({:tag :p, :attrs {:id "third-row"}, :content ["charlie"]})}]
(-> simple-structure
z/down
z/right
z/down)
["bravo" ;;this can of course be any nested node content
{:l [],
:pnodes
[{:tag :div,
:attrs {:id "the-table"},
:content
[{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}
{:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}
{:tag :p, :attrs {:id "third-row"}, :content ["charlie"]}]}
{:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}],
:ppath
{:l [{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}],
:pnodes
[{:tag :div,
:attrs {:id "the-table"},
:content
[{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}
{:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}
{:tag :p, :attrs {:id "third-row"}, :content ["charlie"]}]}],
:ppath nil,
:r ({:tag :p, :attrs {:id "third-row"}, :content ["charlie"]})},
:r nil}]
(-> simple-structure
z/down
z/right
z/down
z/path)
;; the path is bisarre at first, but it really gives pointers:
[;;the pointer to the top of the tree
{:tag :div,
:attrs {:id "the-table"},
:content
[{:tag :p, :attrs {:id "first-row"}, :content ["alfa"]}
{:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}
{:tag :p, :attrs {:id "third-row"}, :content ["charlie"]}]}
;;the pointer to the second row
{:tag :p, :attrs {:id "second-row"}, :content ["bravo"]}]
(map (fn find-navigation [{tag :tag {id :id} :attrs}] [tag id])
(-> simple-structure
z/down
z/right
z/down
z/path))
([:div "the-table"] [:p "second-row"])
(def custom-path (flatten [[:div "the-table"] [:p "second-row"]]))
;; (:div "the-table" :p "second-row")
(def node-content
(-> simple-structure
z/down
z/right
z/down
z/node)) ;;=> "bravo"
(assoc-in {} custom-path node-content)
;; reduce
(reduce
(fn [coll [path val]]
(assoc-in coll path val))
{}
[[[:div "the-table" :p "second-row"] "bravo"]
[[:div "the-table" :p "third-row"] "charlie"]])
{:div {"the-table" {:p {"second-row" "bravo",
"third-row" "charlie"}}}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment