<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Automatic HTML Summary / Teaser</title>
	<atom:link href="http://blog.stevenlevithan.com/archives/get-html-summary/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.stevenlevithan.com/archives/get-html-summary</link>
	<description>A JavaScript and regular expression centric blog</description>
	<lastBuildDate>Thu, 11 Mar 2010 18:49:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Max Paperno</title>
		<link>http://blog.stevenlevithan.com/archives/get-html-summary/comment-page-1#comment-46590</link>
		<dc:creator>Max Paperno</dc:creator>
		<pubDate>Wed, 27 Jan 2010 05:06:44 +0000</pubDate>
		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/get-html-summary#comment-46590</guid>
		<description>Here&#039;s a ColdFusion version of this function. Thanks Steve! Love the regex solution. 

Tested and working, but YMMV. Posted to CFLib.org but not up there yet.

&lt;pre class=&quot;code fixedHeight&quot;&gt;function getLeadingHtml(input, maxChars) {
	// token matches a word, tag, or special character
	var	token = &quot;[[:word:]]+&#124;[^[:word:]&lt;]&#124;(?:]*(\/)?&gt;)&#124;&lt;&quot;;
	var	selfClosingTag = &quot;^(?:[hb]r&#124;img)$&quot;;
	var	output = &quot;&quot;;
	var	charCount = 0;
	var	openTags = &quot;&quot;; var strPos = 0; var tag = &quot;&quot;;
	var i = 1;

	var	match = REFind(token, input, i, &quot;true&quot;);

	while ( (charCount LT maxChars) AND match.pos[1] ) {
		// If this is an HTML tag
		if (match.pos[3]) {
			output = output &amp; Mid(input, match.pos[1], match.len[1]);
			tag = Mid(input, match.pos[3], match.len[3]);
			// If this is not a self-closing tag
			if ( NOT ( match.pos[4] OR REFindNoCase(selfClosingTag, tag) ) ) {
				// If this is a closing tag
				if ( match.pos[2] AND ListFindNoCase(openTags, tag) ) {
					openTags = ListDeleteAt(openTags, ListFindNoCase(openTags, tag)); 
				} else {
					openTags = ListAppend(openTags, tag);
				}
			}
		} else {
			charCount = charCount +  match.len[1];
			if (charCount LTE maxChars) output = output &amp; Mid(input, match.pos[1], match.len[1]);
		}
		
		i = i + match.len[1];
		match = REFind(token, input, i, &quot;true&quot;);
	}

	// Close any tags which were left open
	while ( ListLen(openTags) ) {
		output = output &amp; &quot;&quot;;
		openTags = ListDeleteAt(openTags, ListLen(openTags));
	}

	if ( Len(input) GT Len(output) )
		output = output &amp; &quot;â€¦&quot;;
	
	return output;
}&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Here&#8217;s a ColdFusion version of this function. Thanks Steve! Love the regex solution. </p>
<p>Tested and working, but YMMV. Posted to CFLib.org but not up there yet.</p>
<pre class="code fixedHeight">function getLeadingHtml(input, maxChars) {
	// token matches a word, tag, or special character
	var	token = "[[:word:]]+|[^[:word:]< ]|(?:]*(\/)?>)|< ";
	var	selfClosingTag = "^(?:[hb]r|img)$";
	var	output = "";
	var	charCount = 0;
	var	openTags = ""; var strPos = 0; var tag = "";
	var i = 1;

	var	match = REFind(token, input, i, "true");

	while ( (charCount LT maxChars) AND match.pos[1] ) {
		// If this is an HTML tag
		if (match.pos[3]) {
			output = output &#038; Mid(input, match.pos[1], match.len[1]);
			tag = Mid(input, match.pos[3], match.len[3]);
			// If this is not a self-closing tag
			if ( NOT ( match.pos[4] OR REFindNoCase(selfClosingTag, tag) ) ) {
				// If this is a closing tag
				if ( match.pos[2] AND ListFindNoCase(openTags, tag) ) {
					openTags = ListDeleteAt(openTags, ListFindNoCase(openTags, tag));
				} else {
					openTags = ListAppend(openTags, tag);
				}
			}
		} else {
			charCount = charCount +  match.len[1];
			if (charCount LTE maxChars) output = output &#038; Mid(input, match.pos[1], match.len[1]);
		}

		i = i + match.len[1];
		match = REFind(token, input, i, "true");
	}

	// Close any tags which were left open
	while ( ListLen(openTags) ) {
		output = output &#038; "";
		openTags = ListDeleteAt(openTags, ListLen(openTags));
	}

	if ( Len(input) GT Len(output) )
		output = output &#038; "â€¦";

	return output;
}</pre>
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Maxime</title>
		<link>http://blog.stevenlevithan.com/archives/get-html-summary/comment-page-1#comment-43931</link>
		<dc:creator>Maxime</dc:creator>
		<pubDate>Mon, 23 Nov 2009 17:05:08 +0000</pubDate>
		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/get-html-summary#comment-43931</guid>
		<description>silent, I had the same problem. The solution is simple : just add this line 

token.lastIndex = 0;

before the while statement.</description>
		<content:encoded><![CDATA[<p>silent, I had the same problem. The solution is simple : just add this line </p>
<p>token.lastIndex = 0;</p>
<p>before the while statement.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: silent</title>
		<link>http://blog.stevenlevithan.com/archives/get-html-summary/comment-page-1#comment-41790</link>
		<dc:creator>silent</dc:creator>
		<pubDate>Tue, 13 Oct 2009 21:26:11 +0000</pubDate>
		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/get-html-summary#comment-41790</guid>
		<description>It doesnt work in firefox... When i call function for the first time - is OK, but for second time - &quot;match[&#039;index&#039;]&quot; doesnt resets, just continue from index number from last function call. 
Any help?</description>
		<content:encoded><![CDATA[<p>It doesnt work in firefox&#8230; When i call function for the first time &#8211; is OK, but for second time &#8211; &#8220;match['index']&#8221; doesnt resets, just continue from index number from last function call.<br />
Any help?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: trev</title>
		<link>http://blog.stevenlevithan.com/archives/get-html-summary/comment-page-1#comment-41497</link>
		<dc:creator>trev</dc:creator>
		<pubDate>Mon, 05 Oct 2009 21:42:29 +0000</pubDate>
		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/get-html-summary#comment-41497</guid>
		<description>Is there a coldfusion version of this function?</description>
		<content:encoded><![CDATA[<p>Is there a coldfusion version of this function?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: andrew cates</title>
		<link>http://blog.stevenlevithan.com/archives/get-html-summary/comment-page-1#comment-41180</link>
		<dc:creator>andrew cates</dc:creator>
		<pubDate>Wed, 23 Sep 2009 13:19:01 +0000</pubDate>
		<guid isPermaLink="false">http://blog.stevenlevithan.com/archives/get-html-summary#comment-41180</guid>
		<description>The above didn&#039;t work for me. Here&#039;s the working c# code

public string GetLeadingHtml(string input, int? maxChars) {
  // token matches a word, tag, or special character
  Regex token = new Regex(&quot;\\w+&#124;[^\\w&lt;]&#124;&lt;(/)?(\\w+)[^&gt;]*(/)?&gt;&#124;&lt;&quot;);
  Regex selfClosingTag = new Regex(&quot;^(?:[hb]r&#124;img)$&quot;, RegexOptions.IgnoreCase);
  string output = String.Empty;
  int charCount = 0;
  List&lt;string&gt; openTags = new List&lt;string&gt;();
  Match match;

  // Set the default for the max number of characters
  // (only counts characters outside of HTML tags)
  if(maxChars == null)
    maxChars = 250;

  MatchCollection matches = token.Matches(input);
  int matchCounter = 0;

  // (only counts characters outside of HTML tags)
  while (charCount &lt; maxChars &amp;&amp; matchCounter &lt; matches.Count)
  {
    match = matches[matchCounter];
    matchCounter++;
    // If this is an HTML tag
    if (match.Groups[2].Success)
    {
      output += match.Groups[0].Value;
      // If this is not a self-closing tag
      if (!(match.Groups[3].Success &#124;&#124; selfClosingTag.IsMatch(match.Groups[2].Value)))
      {
        // If this is a closing tag
        if (match.Groups[1].Success)
        {
          openTags.RemoveAt(openTags.Count - 1);
        }
        else
        {
          openTags.Add(match.Groups[2].Value);
        }
      }
    }
    else
    {
      charCount += match.Groups[0].Length;
      if (charCount &lt;= maxChars)
        output += match.Groups[0].Value;

    }
  }

  // Close any tags which were left open
  var i = openTags.Count;
  while (i-- &gt; 0) output += &quot;&lt;/&quot; + openTags[i] + &quot;&gt;&quot;;


  return output;
}</description>
		<content:encoded><![CDATA[<p>The above didn&#8217;t work for me. Here&#8217;s the working c# code</p>
<p>public string GetLeadingHtml(string input, int? maxChars) {<br />
  // token matches a word, tag, or special character<br />
  Regex token = new Regex(&#8220;\\w+|[^\\w&lt;]|&lt;(/)?(\\w+)[^&gt;]*(/)?&gt;|&lt;&#8221;);<br />
  Regex selfClosingTag = new Regex(&#8220;^(?:[hb]r|img)$&#8221;, RegexOptions.IgnoreCase);<br />
  string output = String.Empty;<br />
  int charCount = 0;<br />
  List&lt;string&gt; openTags = new List&lt;string&gt;();<br />
  Match match;</p>
<p>  // Set the default for the max number of characters<br />
  // (only counts characters outside of HTML tags)<br />
  if(maxChars == null)<br />
    maxChars = 250;</p>
<p>  MatchCollection matches = token.Matches(input);<br />
  int matchCounter = 0;</p>
<p>  // (only counts characters outside of HTML tags)<br />
  while (charCount &lt; maxChars &amp;&amp; matchCounter &lt; matches.Count)<br />
  {<br />
    match = matches[matchCounter];<br />
    matchCounter++;<br />
    // If this is an HTML tag<br />
    if (match.Groups[2].Success)<br />
    {<br />
      output += match.Groups[0].Value;<br />
      // If this is not a self-closing tag<br />
      if (!(match.Groups[3].Success || selfClosingTag.IsMatch(match.Groups[2].Value)))<br />
      {<br />
        // If this is a closing tag<br />
        if (match.Groups[1].Success)<br />
        {<br />
          openTags.RemoveAt(openTags.Count &#8211; 1);<br />
        }<br />
        else<br />
        {<br />
          openTags.Add(match.Groups[2].Value);<br />
        }<br />
      }<br />
    }<br />
    else<br />
    {<br />
      charCount += match.Groups[0].Length;<br />
      if (charCount &lt;= maxChars)<br />
        output += match.Groups[0].Value;</p>
<p>    }<br />
  }</p>
<p>  // Close any tags which were left open<br />
  var i = openTags.Count;<br />
  while (i&#8211; &gt; 0) output += &#8220;&lt;/&#8221; + openTags[i] + &#8220;&gt;&#8221;;</p>
<p>  return output;<br />
}</p>
]]></content:encoded>
	</item>
</channel>
</rss>
