<?xml version="1.0" encoding="utf-8"?> 
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
 <title type="text">SHRIPHANI PALAKODETY: Posts tagged 'enlive'</title>
 <link rel="self" href="http://blog.shriphani.com/feeds/enlive.atom.xml" />
 <link href="http://blog.shriphani.com/tags/enlive.html" />
 <id>urn:http-blog-shriphani-com:-tags-enlive-html</id>
 <updated>2014-05-16T05:14:56Z</updated>
 <entry>
  <title type="text">Augmenting enlive</title>
  <link rel="alternate" href="http://blog.shriphani.com/2014/05/16/augmenting-enlive/?utm_source=enlive&amp;utm_medium=Atom" />
  <id>urn:http-blog-shriphani-com:-2014-05-16-augmenting-enlive</id>
  <published>2014-05-16T05:14:56Z</published>
  <updated>2014-05-16T05:14:56Z</updated>
  <author>
   <name>SHRIPHANI PALAKODETY</name></author>
  <content type="html">&lt;html&gt;
&lt;p&gt;In manipulating HTML documents for features, I find myself needing to use some operations all the time - removing script tags, comments and the like. This feature-set is available in HtmlCleaner and I thus merged the two libraries to produce &lt;code&gt;enlive-helper&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now you can do:&lt;/p&gt;

&lt;div class="brush: clojure"&gt;
 &lt;table class="sourcetable"&gt;
  &lt;tbody&gt;
   &lt;tr&gt;
    &lt;td class="linenos"&gt;
     &lt;div class="linenodiv"&gt;
      &lt;pre&gt;1
2
3&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
    &lt;td class="code"&gt;
     &lt;div class="source"&gt;
      &lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;html-resource-steroids&lt;/span&gt; 
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;java.io.StringReader.&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;a&amp;gt;hi&amp;lt;/a&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
 &lt;span class="ss"&gt;:prune-tags&lt;/span&gt; &lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;And as a result the &lt;code&gt;a&lt;/code&gt; tag is not picked up:&lt;/p&gt;

&lt;div class="brush: clojure"&gt;
 &lt;table class="sourcetable"&gt;
  &lt;tbody&gt;
   &lt;tr&gt;
    &lt;td class="linenos"&gt;
     &lt;div class="linenodiv"&gt;
      &lt;pre&gt;1
2
3
4
5
6
7&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
    &lt;td class="code"&gt;
     &lt;div class="source"&gt;
      &lt;pre&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:tag&lt;/span&gt; &lt;span class="ss"&gt;:html&lt;/span&gt;,
  &lt;span class="ss"&gt;:attrs&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;,
  &lt;span class="ss"&gt;:content&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\n"&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:tag&lt;/span&gt; &lt;span class="ss"&gt;:head&lt;/span&gt;, &lt;span class="ss"&gt;:attrs&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;, &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="s"&gt;"\n"&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:tag&lt;/span&gt; &lt;span class="ss"&gt;:body&lt;/span&gt;, &lt;span class="ss"&gt;:attrs&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;, &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;})})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The options you can pass mirror those of &lt;a href="http://htmlcleaner.sourceforge.net/parameters.php"&gt;HtmlCleaner&lt;/a&gt;. Full docs available in &lt;a href="https://github.com/shriphani/enlive-helper"&gt;this github repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, the code is something I threw together from my research so it is released under &lt;a href="http://matt.might.net/articles/crapl/CRAPL-LICENSE.txt"&gt;Matt Might&amp;rsquo;s CRAPL license&lt;/a&gt;.&lt;/p&gt;&lt;/html&gt;</content></entry>
 <entry>
  <title type="text">clojure scraping overview</title>
  <link rel="alternate" href="http://blog.shriphani.com/2014/02/14/clojure-scraping-overview/?utm_source=enlive&amp;utm_medium=Atom" />
  <id>urn:http-blog-shriphani-com:-2014-02-14-clojure-scraping-overview</id>
  <published>2014-02-14T06:16:35Z</published>
  <updated>2014-02-14T06:16:35Z</updated>
  <author>
   <name>SHRIPHANI PALAKODETY</name></author>
  <content type="html">&lt;html&gt;
&lt;p&gt;Earlier this week I gave a talk on scraping with clojure - primarily using &lt;code&gt;clj-xpath&lt;/code&gt; and &lt;code&gt;enlive&lt;/code&gt; at the Pittsburgh clojure meetup group. Slides and code are linked to below.&lt;/p&gt;

&lt;script async="async" class="speakerdeck-embed" data-id="f0b571b0759a0131f0bd026a5a2b7ed1" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"&gt;&lt;/script&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/shriphani/clojure_scraping_overview"&gt;https://github.com/shriphani/clojure_scraping_overview&lt;/a&gt;&lt;/p&gt;&lt;/html&gt;</content></entry>
 <entry>
  <title type="text">Tree Edit Distance Enlive Version</title>
  <link rel="alternate" href="http://blog.shriphani.com/2013/12/09/tree-edit-distance-enlive-version/?utm_source=enlive&amp;utm_medium=Atom" />
  <id>urn:http-blog-shriphani-com:-2013-12-09-tree-edit-distance-enlive-version</id>
  <published>2013-12-09T08:52:34Z</published>
  <updated>2013-12-09T08:52:34Z</updated>
  <author>
   <name>SHRIPHANI PALAKODETY</name></author>
  <content type="html">&lt;html&gt;
&lt;p&gt;In my last post, I presented a code-dump that computed a restricted version of the tree edit distance algorithm. I was able to achieve a decent speed-up using enlive. Here&amp;rsquo;s a code-dump:&lt;/p&gt;
&lt;!-- more--&gt;

&lt;div class="brush: clojure"&gt;
 &lt;table class="sourcetable"&gt;
  &lt;tbody&gt;
   &lt;tr&gt;
    &lt;td class="linenos"&gt;
     &lt;div class="linenodiv"&gt;
      &lt;pre&gt;  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;
    &lt;td class="code"&gt;
     &lt;div class="source"&gt;
      &lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;ns &lt;/span&gt;&lt;span class="nv"&gt;tree-edit-distance.enlive-core&lt;/span&gt;
  &lt;span class="s"&gt;"A version of RTDM that operates on a tree produced by&lt;/span&gt;
&lt;span class="s"&gt;   enlive."&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:require&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;clj-http.client&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="nv"&gt;client&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;net.cgrand.enlive-html&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;init&lt;/span&gt;
  &lt;span class="s"&gt;"Perform the correct initialization"&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="nv"&gt;c1&lt;/span&gt; &lt;span class="nv"&gt;c2&lt;/span&gt; &lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;ins-cost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;make-array &lt;/span&gt;&lt;span class="nv"&gt;Integer/TYPE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;doseq &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
              &lt;span class="nv"&gt;j&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;aset &lt;/span&gt;&lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="nv"&gt;j&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;ins-cost&lt;/span&gt; &lt;span class="nv"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
      &lt;span class="nv"&gt;M&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;load-tree&lt;/span&gt;
  &lt;span class="s"&gt;"Fetches a link&amp;#39;s content and builds an enlive-tree with it"&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;a-link&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;a-link&lt;/span&gt;
       &lt;span class="nv"&gt;client/get&lt;/span&gt;
       &lt;span class="ss"&gt;:body&lt;/span&gt;
       &lt;span class="nv"&gt;java.io.StringReader.&lt;/span&gt;
       &lt;span class="nv"&gt;html/html-resource&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:tag&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="c1"&gt;; pick out the tree and not the docstring&lt;/span&gt;
       &lt;span class="nv"&gt;first&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;tree-children&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;a-tree&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;-&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;a-tree&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter &lt;/span&gt;&lt;span class="nv"&gt;map?&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;num-children&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;a-tree&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;a-tree&lt;/span&gt; &lt;span class="nv"&gt;tree-children&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;tree-descendants&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;a-tree&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;a-tree&lt;/span&gt; &lt;span class="nv"&gt;tree-children&lt;/span&gt; &lt;span class="nv"&gt;seq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;num-children&lt;/span&gt; &lt;span class="nv"&gt;a-tree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply + &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map &lt;/span&gt;&lt;span class="nv"&gt;tree-descendants&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-children&lt;/span&gt; &lt;span class="nv"&gt;a-tree&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;declare &lt;/span&gt;&lt;span class="nv"&gt;tree-edit-distance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;invert-cost&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;tree1&lt;/span&gt; &lt;span class="nv"&gt;tree2&lt;/span&gt; &lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;ins-cost&lt;/span&gt; &lt;span class="nv"&gt;sub-cost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;t1-desc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;tree1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;t2-desc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;tree2&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;t1-desc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;ins-cost&lt;/span&gt; &lt;span class="nv"&gt;t2-desc&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-edit-distance&lt;/span&gt; &lt;span class="nv"&gt;tree1&lt;/span&gt; &lt;span class="nv"&gt;tree2&lt;/span&gt; &lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;ins-cost&lt;/span&gt; &lt;span class="nv"&gt;sub-cost&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;tree-edit-distance&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;tree1&lt;/span&gt; &lt;span class="nv"&gt;tree2&lt;/span&gt; &lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;ins-cost&lt;/span&gt; &lt;span class="nv"&gt;sub-cost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;m&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;num-children&lt;/span&gt; &lt;span class="nv"&gt;tree1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;num-children&lt;/span&gt; &lt;span class="nv"&gt;tree2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nv"&gt;t1-children&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-children&lt;/span&gt; &lt;span class="nv"&gt;tree1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;t2-children&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-children&lt;/span&gt; &lt;span class="nv"&gt;tree2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nv"&gt;t1-desc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;tree1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;t2-desc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;tree2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="nv"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt; &lt;span class="nv"&gt;t1-desc&lt;/span&gt; &lt;span class="nv"&gt;t2-desc&lt;/span&gt; &lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;ins-cost&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;doseq &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range &lt;/span&gt;&lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nv"&gt;j&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range &lt;/span&gt;&lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; 
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;c-i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth &lt;/span&gt;&lt;span class="nv"&gt;t1-children&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nv"&gt;c-j&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth &lt;/span&gt;&lt;span class="nv"&gt;t2-children&lt;/span&gt; &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nv"&gt;c-i-desc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;c-i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nv"&gt;c-j-desc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;c-j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nv"&gt;del&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;aget &lt;/span&gt;&lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="nv"&gt;ins&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;aget &lt;/span&gt;&lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nv"&gt;sub-i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;aget &lt;/span&gt;&lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="nv"&gt;del-cost&lt;/span&gt;
                     &lt;span class="nv"&gt;ins-cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nv"&gt;sub&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="nv"&gt;c-i&lt;/span&gt; &lt;span class="nv"&gt;c-j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="nv"&gt;sub-i&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;ins-cost&lt;/span&gt; &lt;span class="nv"&gt;c-j-desc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;* &lt;/span&gt;&lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;c-i-desc&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cond&lt;/span&gt;
                   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;c-i&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter &lt;/span&gt;&lt;span class="nv"&gt;map?&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
                       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;c-j&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter &lt;/span&gt;&lt;span class="nv"&gt;map?&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
                   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="nv"&gt;sub-i&lt;/span&gt; &lt;span class="nv"&gt;sub-cost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;= &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;c-i&lt;/span&gt; &lt;span class="ss"&gt;:tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;-&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;c-j&lt;/span&gt; &lt;span class="ss"&gt;:tag&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
                   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="nv"&gt;sub-i&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;invert-cost&lt;/span&gt; &lt;span class="nv"&gt;c-i&lt;/span&gt; &lt;span class="nv"&gt;c-j&lt;/span&gt; &lt;span class="nv"&gt;del-cost&lt;/span&gt; &lt;span class="nv"&gt;ins-cost&lt;/span&gt; &lt;span class="nv"&gt;sub-cost&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

                   &lt;span class="ss"&gt;:else&lt;/span&gt;
                   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="nv"&gt;sub-i&lt;/span&gt; &lt;span class="nv"&gt;sub-cost&lt;/span&gt;&lt;span class="p"&gt;)))]&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;aset &lt;/span&gt;&lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc &lt;/span&gt;&lt;span class="nv"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min &lt;/span&gt;&lt;span class="nv"&gt;del&lt;/span&gt; &lt;span class="nv"&gt;ins&lt;/span&gt; &lt;span class="nv"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;aget &lt;/span&gt;&lt;span class="nv"&gt;M&lt;/span&gt; &lt;span class="nv"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;defn &lt;/span&gt;&lt;span class="nv"&gt;tree-edit-distance-link&lt;/span&gt;
  &lt;span class="s"&gt;"load trees and return their edit distance"&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;link1&lt;/span&gt; &lt;span class="nv"&gt;link2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;t1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;load-tree&lt;/span&gt; &lt;span class="nv"&gt;link1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;t2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;load-tree&lt;/span&gt; &lt;span class="nv"&gt;link2&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;- &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;/ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-edit-distance&lt;/span&gt; &lt;span class="nv"&gt;t1&lt;/span&gt; &lt;span class="nv"&gt;t2&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+ &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tree-descendants&lt;/span&gt; &lt;span class="nv"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;This is now a convenient implementation that you can use. The full source code is in this &lt;a href="https://github.com/shriphani/tree-edit-distance"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;&lt;/html&gt;</content></entry></feed>