title: Best algorithm to highlight a list of given words in an HTML file
body: <p>I have some HTML files, upon which I have no control. Thus I can't change their structure or markup.</p>
  
  <p>For each of these HTML files, a list of words would be found based on another algorithm. These words should be highlighted in the text of HTML. For example if the HTML markup is:</p>
  
  <pre><code>&lt;p&gt;
  Monkeys are going to die soon, if we don't stop killing them. 
  So, we have to try hard to persuade hunters not to hunt monkeys. 
  Monkeys are very intelligent, and they should survive. 
  In fact, they deserve to survive.
  &lt;/p&gt;
  </code></pre>
  
  <p>and the list of the words is:</p>
  
  <pre><code>are, we, monkey
  </code></pre>
  
  <p>the result should be something like:</p>
  
  <pre><code>&lt;p&gt;
      &lt;span class='highlight'&gt;Monkeys&lt;/span&gt; 
      &lt;span class='highlight'&gt;are&lt;/span&gt; 
  going to die soon, if 
      &lt;span class='highlight'&gt;we&lt;/span&gt; 
  don't stop killing them. 
  So, 
      &lt;span class='highlight'&gt;we&lt;/span&gt; 
  have to try hard to persuade hunters 
  not to hunt 
      &lt;span class='highlight'&gt;monkeys&lt;/span&gt;
  . They 
      &lt;span class='highlight'&gt;are&lt;/span&gt; 
  very intelligent, and they should survive. 
  In fact, they deserve to survive.
  &lt;/p&gt;
  </code></pre>
  
  <p>The highlighting algorithm should:</p>
  
  <ol>
  <li>be case-insensitive</li>
  <li>be written in JavaScript (this happens inside browser) (jQuery is welcomed)</li>
  <li>be fast (be applicable for the text of a given book with almost 800 pages)</li>
  <li>not showing browser's famous "stop script" dialog</li>
  <li>be applicable for dirty HTML files (like supporting invalid HTML markup, say for example unclosed <p> elements) (some of these files are HTML export of MS Word, and I think you got what I mean by dirty!!!)</li>
  <li>should preserve original HTML markup (no markup deletion, no markup change except wrapping intended words inside an element, no nesting change. HTML should look the same before and after edit except highlighted words)</li>
  </ol>
  
  <p>What I've done till now:</p>
  
  <ol>
  <li>I get the list of words in JavaScript in an array like <code>["are", "we", "monkey"]</code></li>
  <li>I try to select text nodes in the browser (which is faulty now)</li>
  <li>I loop over each text node, and for each text node, I loop over each word in the list and try to find it and wrap it inside an element</li>
  </ol>
  
  <p>Please note that you can watch it online <a href="http://phis.ir/book-text/871" rel="noreferrer">here</a> (username: demo@phis.ir, pass: demo). Also current script could be seen at the end of the page's source.</p>