Created
November 6, 2015 13:37
-
-
Save claj/a5cc452a12aa2880e0b5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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