<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Brett Terpstrajquery - Brett Terpstra</title>
	<atom:link href="http://brettterpstra.com/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://brettterpstra.com</link>
	<description>Elegant solutions to complex problems.</description>
	<lastBuildDate>Thu, 09 Feb 2012 15:01:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Word repetition checking with JavaScript</title>
		<link>http://brettterpstra.com/word-repetition-checking-with-javascript/</link>
		<comments>http://brettterpstra.com/word-repetition-checking-with-javascript/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 12:30:47 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3035</guid>
		<description><![CDATA[<p>Ok, I made something interesting (to me) last night. It’s probably not worth taking the time to write up, but someday someone might find it and think it useful. I apologize for the messiness of the code, if I take this further and clean it up, I’ll update this post. I was working on a few text-analysis features for Marked&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/word-repetition-checking-with-javascript/">Word repetition checking with JavaScript</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' display: block; margin-right: auto; margin-left: auto;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/11/Word-Repetition-Screenshot.png?9d7bd4" alt="Word Repetition Screenshot" width="650" height="132" class="aligncenter size-full wp-image-3042" /></p>

<p>Ok, I made something interesting (to me) last night. It’s probably not worth taking the time to write up, but someday someone might find it and think it useful. I apologize for the messiness of the code, if I take this further and clean it up, I’ll update this post.</p>

<p>I was working on a few text-analysis features for <a href="http://markedapp.com">Marked</a> and decided I wanted to be able to show repeated words on a per-paragraph basis. The following is the experiment I did as a proof-of-concept. I decided that I wanted to do this in JavaScript/jQuery for various reasons, so my existing Ruby scripts were mostly useless. Thus, I devised a way to handle it entirely in a WebKit browser.</p>

<h3>Demo</h3>

<p>For the purposes of demonstration, I set up a <a href="http://brettterpstra.com/share/word-repetition-check.php">single-page, dynamic version</a> of this. You can enter any article URL and see the processing take place. Hover over a bolded word to see where it repeats in the paragraph. Note that it’s pulling through a proxy of <a href="http://markdownrules.com/">Marky the Markdownifier</a>, and that some markup will return blanks. Obviously, it also helps to have a lot of text in the article you’re analyzing. Hard up for ideas? <a href="http://brettterpstra.com/share/word-repetition-check.php?url=http://en.wikipedia.org/wiki/Stemming">Try this</a>, or <a href="http://brettterpstra.com/share/word-repetition-check.php?url=http://www.engadget.com/2011/11/02/lenovo-posts-q2-earnings-sees-increase-in-profits-shipments-an/">this</a>. Give it a few seconds to load, it pulls in the content in the background and I haven’t put a progress indicator on it yet.</p>

<p><span id="more-3035"></span></p>

<h3>Breakdown</h3>

<p>I started with a <a href="http://tartarus.org/~martin/PorterStemmer/">Porter Stemmer</a> using a <a href="http://tartarus.org/~martin/PorterStemmer/js.txt">script from tartarus.org</a>. <a href="http://en.wikipedia.org/wiki/Stemming">Stemming</a> allows you to break a word down to a root form, so that all variations of a word can be boiled down and plurals, conjugations and various anomalous representations of a word will all match each other. From there, I do a frequency check to find word roots used more than once within the block being processed, creating an array of the repeated words. Then I re-parse the block, one word at a time, adding some markup to words whose root is found in the previously-created array.</p>

<p>Here’s the main script with a few comments. Until I get this prettied up, I won’t go into a step-by-step. Feel free to lift and improve as you like. Remember to include the <a href="http://tartarus.org/~martin/PorterStemmer/js.txt">porter-stemmer script</a> before this script. Oh, and because I’m lazy, you’ll need to include <a href="http://jquery.com/">jQuery</a> as well. The <code>in_array</code> function is stolen from <a href="http://phpjs.org/functions/in_array:432">php.js</a>.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="co1">// from php.js</span>
<span class="kw2">function</span> in_array <span class="br0">&#40;</span>needle<span class="sy0">,</span> haystack<span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="kw1">for</span> <span class="br0">&#40;</span>key <span class="kw1">in</span> haystack<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>haystack<span class="br0">&#91;</span>key<span class="br0">&#93;</span> <span class="sy0">==</span> needle<span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
  <span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="co1">// short, common words to skip when counting</span>
<span class="kw2">var</span> stopwords <span class="sy0">=</span> <span class="br0">&#91;</span><span class="st0">'1'</span><span class="sy0">,</span><span class="st0">'2'</span><span class="sy0">,</span><span class="st0">'3'</span><span class="sy0">,</span><span class="st0">'4'</span><span class="sy0">,</span><span class="st0">'5'</span><span class="sy0">,</span><span class="st0">'6'</span><span class="sy0">,</span><span class="st0">'7'</span><span class="sy0">,</span><span class="st0">'8'</span><span class="sy0">,</span><span class="st0">'9'</span><span class="sy0">,</span><span class="st0">'0'</span><span class="sy0">,</span><span class="st0">'one'</span><span class="sy0">,</span><span class="st0">'two'</span><span class="sy0">,</span><span class="st0">'three'</span><span class="sy0">,</span><span class="st0">'four'</span><span class="sy0">,</span><span class="st0">'five'</span><span class="sy0">,</span><span class="st0">'about'</span><span class="sy0">,</span><span class="st0">'actually'</span><span class="sy0">,</span><span class="st0">'always'</span><span class="sy0">,</span><span class="st0">'even'</span><span class="sy0">,</span><span class="st0">'given'</span><span class="sy0">,</span><span class="st0">'into'</span><span class="sy0">,</span><span class="st0">'just'</span><span class="sy0">,</span><span class="st0">'not'</span><span class="sy0">,</span><span class="st0">'Im'</span><span class="sy0">,</span><span class="st0">'thats'</span><span class="sy0">,</span><span class="st0">'its'</span><span class="sy0">,</span><span class="st0">'arent'</span><span class="sy0">,</span><span class="st0">'weve'</span><span class="sy0">,</span><span class="st0">'ive'</span><span class="sy0">,</span><span class="st0">'didnt'</span><span class="sy0">,</span><span class="st0">'dont'</span><span class="sy0">,</span><span class="st0">'the'</span><span class="sy0">,</span><span class="st0">'of'</span><span class="sy0">,</span><span class="st0">'to'</span><span class="sy0">,</span><span class="st0">'and'</span><span class="sy0">,</span><span class="st0">'a'</span><span class="sy0">,</span><span class="st0">'in'</span><span class="sy0">,</span><span class="st0">'is'</span><span class="sy0">,</span><span class="st0">'it'</span><span class="sy0">,</span><span class="st0">'you'</span><span class="sy0">,</span><span class="st0">'that'</span><span class="sy0">,</span><span class="st0">'he'</span><span class="sy0">,</span><span class="st0">'was'</span><span class="sy0">,</span><span class="st0">'for'</span><span class="sy0">,</span><span class="st0">'on'</span><span class="sy0">,</span><span class="st0">'are'</span><span class="sy0">,</span><span class="st0">'with'</span><span class="sy0">,</span><span class="st0">'as'</span><span class="sy0">,</span><span class="st0">'I'</span><span class="sy0">,</span><span class="st0">'his'</span><span class="sy0">,</span><span class="st0">'they'</span><span class="sy0">,</span><span class="st0">'be'</span><span class="sy0">,</span><span class="st0">'at'</span><span class="sy0">,</span><span class="st0">'one'</span><span class="sy0">,</span><span class="st0">'have'</span><span class="sy0">,</span><span class="st0">'this'</span><span class="sy0">,</span><span class="st0">'from'</span><span class="sy0">,</span><span class="st0">'or'</span><span class="sy0">,</span><span class="st0">'had'</span><span class="sy0">,</span><span class="st0">'by'</span><span class="sy0">,</span><span class="st0">'hot'</span><span class="sy0">,</span><span class="st0">'but'</span><span class="sy0">,</span><span class="st0">'some'</span><span class="sy0">,</span><span class="st0">'what'</span><span class="sy0">,</span><span class="st0">'there'</span><span class="sy0">,</span><span class="st0">'we'</span><span class="sy0">,</span><span class="st0">'can'</span><span class="sy0">,</span><span class="st0">'out'</span><span class="sy0">,</span><span class="st0">'were'</span><span class="sy0">,</span><span class="st0">'all'</span><span class="sy0">,</span><span class="st0">'your'</span><span class="sy0">,</span><span class="st0">'when'</span><span class="sy0">,</span><span class="st0">'up'</span><span class="sy0">,</span><span class="st0">'use'</span><span class="sy0">,</span><span class="st0">'how'</span><span class="sy0">,</span><span class="st0">'said'</span><span class="sy0">,</span><span class="st0">'an'</span><span class="sy0">,</span><span class="st0">'each'</span><span class="sy0">,</span><span class="st0">'she'</span><span class="sy0">,</span><span class="st0">'which'</span><span class="sy0">,</span><span class="st0">'do'</span><span class="sy0">,</span><span class="st0">'their'</span><span class="sy0">,</span><span class="st0">'if'</span><span class="sy0">,</span><span class="st0">'will'</span><span class="sy0">,</span><span class="st0">'way'</span><span class="sy0">,</span><span class="st0">'many'</span><span class="sy0">,</span><span class="st0">'then'</span><span class="sy0">,</span><span class="st0">'them'</span><span class="sy0">,</span><span class="st0">'would'</span><span class="sy0">,</span><span class="st0">'like'</span><span class="sy0">,</span><span class="st0">'so'</span><span class="sy0">,</span><span class="st0">'these'</span><span class="sy0">,</span><span class="st0">'her'</span><span class="sy0">,</span><span class="st0">'see'</span><span class="sy0">,</span><span class="st0">'him'</span><span class="sy0">,</span><span class="st0">'has'</span><span class="sy0">,</span><span class="st0">'more'</span><span class="sy0">,</span><span class="st0">'could'</span><span class="sy0">,</span><span class="st0">'go'</span><span class="sy0">,</span><span class="st0">'come'</span><span class="sy0">,</span><span class="st0">'did'</span><span class="sy0">,</span><span class="st0">'my'</span><span class="sy0">,</span><span class="st0">'no'</span><span class="sy0">,</span><span class="st0">'get'</span><span class="sy0">,</span><span class="st0">'me'</span><span class="sy0">,</span><span class="st0">'say'</span><span class="sy0">,</span><span class="st0">'too'</span><span class="sy0">,</span><span class="st0">'here'</span><span class="sy0">,</span><span class="st0">'must'</span><span class="sy0">,</span><span class="st0">'such'</span><span class="sy0">,</span><span class="st0">'try'</span><span class="sy0">,</span><span class="st0">'us'</span><span class="sy0">,</span><span class="st0">'own'</span><span class="sy0">,</span><span class="st0">'oh'</span><span class="sy0">,</span><span class="st0">'any'</span><span class="sy0">,</span><span class="st0">'youll'</span><span class="sy0">,</span><span class="st0">'youre'</span><span class="sy0">,</span><span class="st0">'also'</span><span class="sy0">,</span><span class="st0">'than'</span><span class="sy0">,</span><span class="st0">'those'</span><span class="sy0">,</span><span class="st0">'though'</span><span class="sy0">,</span><span class="st0">'thing'</span><span class="sy0">,</span><span class="st0">'things'</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// takes the text of a paragraph element as input</span>
<span class="co1">// returns marked up text with repeated words in 'b' tags with a class matching their &quot;stemmed&quot; root</span>
<span class="kw2">function</span> checkWords<span class="br0">&#40;</span>input<span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
  <span class="kw2">var</span> words <span class="sy0">=</span> input.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">' '</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="kw2">var</span> wordcount <span class="sy0">=</span> <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="sy0">;</span>
&nbsp;
  <span class="co1">// build an object to count word frequency</span>
  $.<span class="me1">each</span><span class="br0">&#40;</span>words<span class="sy0">,</span><span class="kw2">function</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="br0">&#123;</span>
    thisWord <span class="sy0">=</span> String<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/[\/\\]/</span><span class="sy0">,</span><span class="st0">' '</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/’/g</span><span class="sy0">,</span><span class="st0">&quot;'&quot;</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/[^a-z' ]/gi</span><span class="sy0">,</span><span class="st0">''</span><span class="br0">&#41;</span>.<span class="me1">toLowerCase</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>in_array<span class="br0">&#40;</span>thisWord<span class="sy0">,</span>stopwords<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="kw2">var</span> word <span class="sy0">=</span> stemmer<span class="br0">&#40;</span>thisWord<span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="kw1">if</span> <span class="br0">&#40;</span>wordcount<span class="br0">&#91;</span>word<span class="br0">&#93;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span> <span class="sy0">&amp;&amp;</span> word.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        wordcount<span class="br0">&#91;</span>word<span class="br0">&#93;</span> <span class="sy0">+=</span> <span class="nu0">1</span><span class="sy0">;</span>
      <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
        wordcount<span class="br0">&#91;</span>word<span class="br0">&#93;</span> <span class="sy0">=</span> <span class="nu0">1</span><span class="sy0">;</span>
      <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="co1">// convert the object to an object array</span>
  <span class="co1">// include only words repeated more than once within the paragraph</span>
  <span class="kw2">var</span> topwords <span class="sy0">=</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  $.<span class="me1">each</span><span class="br0">&#40;</span>wordcount<span class="sy0">,</span><span class="kw2">function</span><span class="br0">&#40;</span>w<span class="sy0">,</span>i<span class="br0">&#41;</span><span class="br0">&#123;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>i <span class="sy0">&gt;</span> <span class="nu0">1</span><span class="br0">&#41;</span>
      topwords.<span class="me1">push</span><span class="br0">&#40;</span><span class="br0">&#123;</span><span class="st0">'word'</span><span class="sy0">:</span>w<span class="sy0">,</span><span class="st0">'freq'</span><span class="sy0">:</span>i<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="co1">// convert the object array to a flat array</span>
  topwordsArr <span class="sy0">=</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    $.<span class="me1">each</span><span class="br0">&#40;</span>topwords<span class="sy0">,</span><span class="kw2">function</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    topwordsArr.<span class="me1">push</span><span class="br0">&#40;</span>String<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#91;</span><span class="st0">'word'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="co1">// re-parse the output, marking up repeated words based on their stems</span>
  <span class="kw2">var</span> output <span class="sy0">=</span> <span class="st0">''</span><span class="sy0">;</span>
  $.<span class="me1">each</span><span class="br0">&#40;</span>words<span class="sy0">,</span><span class="kw2">function</span><span class="br0">&#40;</span>w<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw2">var</span> aWord <span class="sy0">=</span> String<span class="br0">&#40;</span><span class="kw1">this</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw2">var</span> stripWord <span class="sy0">=</span> stemmer<span class="br0">&#40;</span>aWord.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/[\/\\]/</span><span class="sy0">,</span><span class="st0">' '</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/’/g</span><span class="sy0">,</span><span class="st0">&quot;'&quot;</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/[^a-z' ]/gi</span><span class="sy0">,</span><span class="st0">''</span><span class="br0">&#41;</span>.<span class="me1">toLowerCase</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>in_array<span class="br0">&#40;</span>stripWord<span class="sy0">,</span>topwordsArr<span class="br0">&#41;</span><span class="br0">&#41;</span>
      output <span class="sy0">+=</span> <span class="st0">' &lt;b class=&quot;'</span><span class="sy0">+</span>stripWord<span class="sy0">+</span><span class="st0">'&quot;&gt;'</span><span class="sy0">+</span>aWord<span class="sy0">+</span><span class="st0">'&lt;/b&gt;'</span><span class="sy0">;</span>
    <span class="kw1">else</span>
      output <span class="sy0">+=</span> <span class="st0">' '</span><span class="sy0">+</span>aWord<span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="kw1">return</span> output<span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>$<span class="br0">&#41;</span><span class="br0">&#123;</span>
  <span class="co1">// grab common top-level elements</span>
  grafs <span class="sy0">=</span> $<span class="br0">&#40;</span><span class="st0">'p,ul,ol,blockquote,h1,h2,h3,h4,h5,h6,pre code'</span><span class="sy0">,</span>$<span class="br0">&#40;</span><span class="st0">'#content'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="co1">// navigate each element found</span>
  $.<span class="me1">each</span><span class="br0">&#40;</span>grafs<span class="sy0">,</span><span class="kw2">function</span><span class="br0">&#40;</span>a<span class="sy0">,</span>g<span class="br0">&#41;</span><span class="br0">&#123;</span>
    <span class="co1">// if it's a paragraph, we'll process it</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>grafs<span class="br0">&#91;</span>a<span class="br0">&#93;</span>.<span class="me1">tagName</span> <span class="sy0">==</span> <span class="st0">&quot;P&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      $<span class="br0">&#40;</span><span class="st0">'#work'</span><span class="br0">&#41;</span>.<span class="me1">append</span><span class="br0">&#40;</span>$<span class="br0">&#40;</span><span class="st0">'&lt;p&gt;'</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span>checkWords<span class="br0">&#40;</span>$<span class="br0">&#40;</span>grafs<span class="br0">&#91;</span>a<span class="br0">&#93;</span><span class="br0">&#41;</span>.<span class="me1">text</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="co1">// if not, we just stick it back into the DOM</span>
    <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
      $<span class="br0">&#40;</span><span class="st0">'#work'</span><span class="br0">&#41;</span>.<span class="me1">append</span><span class="br0">&#40;</span>grafs<span class="br0">&#91;</span>a<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="co1">// set up hover listeners on the 'b' elements</span>
  <span class="co1">// the class is pulled from the hovered element</span>
  <span class="co1">// all similar words are highlighted on hover</span>
  $<span class="br0">&#40;</span><span class="st0">'b'</span><span class="sy0">,</span><span class="st0">'#work'</span><span class="br0">&#41;</span>.<span class="me1">hover</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    <span class="kw2">var</span> thisClass <span class="sy0">=</span> <span class="kw1">this</span>.<span class="me1">className</span><span class="sy0">;</span>
    $<span class="br0">&#40;</span><span class="st0">'.'</span><span class="sy0">+</span>thisClass<span class="br0">&#41;</span>.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">'highlight'</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="sy0">,</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    $<span class="br0">&#40;</span><span class="st0">'.highlight'</span><span class="br0">&#41;</span>.<span class="me1">removeClass</span><span class="br0">&#40;</span><span class="st0">'highlight'</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span>jQuery<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>


<p>This little bit of css will add the highlighting and a nice fade in compatible browsers:</p>


<div class="wp_syntax"><div class="code"><pre class="css">b <span class="br0">&#123;</span>
  <span class="kw1">font-weight</span><span class="sy0">:</span><span class="kw2">bold</span><span class="sy0">;</span>
  -webkit-transition<span class="sy0">:</span><span class="kw1">color</span> .2s ease-in-out<span class="sy0">;</span>
  -moz-transition<span class="sy0">:</span><span class="kw1">color</span> .2s ease-in-out<span class="sy0">;</span>
  -o-transition<span class="sy0">:</span><span class="kw1">color</span> .2s ease-in-out<span class="sy0">;</span>
  transition<span class="sy0">:</span><span class="kw1">color</span> .2s ease-in-out<span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="re1">.highlight</span> <span class="br0">&#123;</span> <span class="kw1">color</span><span class="sy0">:</span>rgba<span class="br0">&#40;</span><span class="nu0">207</span><span class="sy0">,</span> <span class="nu0">95</span><span class="sy0">,</span> <span class="nu0">205</span><span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span><span class="br0">&#125;</span></pre></div></div>


<p>If I decide to include this in Marked, it will definitely get some revamping. Like I said… proof-of-concept. Check out the demo, though, it’s kind of neat.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/a-simple-but-handy-bash-function-console/' rel='bookmark' title='A simple but handy Bash function: console'>A simple but handy Bash function: console</a></li>
<li><a href='http://brettterpstra.com/ampersands-javascript/' rel='bookmark' title='Ampersands &amp; Javascript'>Ampersands &amp; Javascript</a></li>
<li><a href='http://brettterpstra.com/quick-tip-this-command-line-trick-is-tops/' rel='bookmark' title='Quick Tip: This command line trick is tops'>Quick Tip: This command line trick is tops</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/word-repetition-checking-with-javascript/">Word repetition checking with JavaScript</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/word-repetition-checking-with-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Catching Markdown mistakes</title>
		<link>http://brettterpstra.com/catching-markdown-mistakes/</link>
		<comments>http://brettterpstra.com/catching-markdown-mistakes/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 11:58:39 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[marked]]></category>
		<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=2794</guid>
		<description><![CDATA[<p>I had an interesting idea this morning. At least I find it interesting, but I haven’t slept much lately. Either way, here it is: in Markdown, if you misname a reference link, forget to fill one in or have a malformed URL, your broken Markdown shows up in your output. Wouldn’t it be nice if your preview highlighted those for&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/catching-markdown-mistakes/">Catching Markdown mistakes</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' display: block; margin-right: auto; margin-left: auto;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/09/crazyones.txt.jpg?9d7bd4" alt="Markdown mistakes highlighted" title="crazyones.txt" width="650" height="136" class="aligncenter size-full wp-image-2795" /></p>

<p>I had an interesting idea this morning. At least <em>I</em> find it interesting, but I haven’t slept much lately. Either way, here it is: in Markdown, if you misname a reference link, forget to fill one in or have a malformed URL, your broken Markdown shows up in your output. Wouldn’t it be nice if your preview highlighted those for you <em>before</em> you went to publish?</p>

<p>Marked 1.3, which is coming along very nicely, has a few JavaScripts built in to the preview (which can be turned off in preferences). It provides a table of contents based on headers in your document, smooth scrolling, tool tips to show you where external links will go and, as of this morning, highlighting of broken links.</p>

<p>The code is simple. This version is jQuery, just because that was convenient, but you can pull this off in plain old JavaScript with barely any extra code:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="co1">// Scan for and highlight malformed/incomplete Markdown links</span>
$<span class="br0">&#40;</span><span class="st0">'#wrapper'</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span>$<span class="br0">&#40;</span><span class="st0">'#wrapper'</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="co2">/(\[.*?\][\[\(].*?[\]\)])/g</span><span class="sy0">,</span>
<span class="st0">&quot;&lt;span style=<span class="es0">\&quot;</span>color:rgba(152, 50, 63, 1)<span class="es0">\&quot;</span>&gt;$1&lt;/span&gt;&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>


<p>It just scans for Markdown-style links (<code>[text][title]</code> or <code>[text](link)</code>) that are still in your text after converting to HTML. If it finds them, it highlights them in red. Just thought I’d share.</p>

<p>By the way, in addition to the JavaScript fun, the next version of <a href="http://markedapp.com">Marked</a> has multiple custom styles (unlimited), can open any text file with any extension, can load MathJax for MathML rendering and much more. I’ll keep you posted on its release, but it should be soon.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/auto-convert-your-inline-markdown-links-to-references/' rel='bookmark' title='Auto-convert your inline Markdown links to references'>Auto-convert your inline Markdown links to references</a></li>
<li><a href='http://brettterpstra.com/markdown-quicktags-0-7/' rel='bookmark' title='Markdown QuickTags 0.7'>Markdown QuickTags 0.7</a></li>
<li><a href='http://brettterpstra.com/some-chrome-love-for-the-markdown-service-tools/' rel='bookmark' title='Some Chrome love for the Markdown Service Tools'>Some Chrome love for the Markdown Service Tools</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/catching-markdown-mistakes/">Catching Markdown mistakes</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/catching-markdown-mistakes/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Pully: jQuery plugin for automatic pull quotes</title>
		<link>http://brettterpstra.com/pully-jquery-plugin-for-automatic-pull-quotes/</link>
		<comments>http://brettterpstra.com/pully-jquery-plugin-for-automatic-pull-quotes/#comments</comments>
		<pubDate>Thu, 04 Nov 2010 15:30:39 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[experiments]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=1169</guid>
		<description><![CDATA[<p>: http://brettterpstra.com/share/pully/pully.jquery.js Demo &#124; [Download] Another quick experiment. Honestly, I don’t use pluggable functions in jQuery nearly as much as I should, so this is really just a brain exercise to get myself used to it. This one, called Pully, lets you specify a selector to have its contents cloned and inserted as a pull quote in your text. It&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/pully-jquery-plugin-for-automatic-pull-quotes/">Pully: jQuery plugin for automatic pull quotes</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://brettterpstra.com/share/pully/pullydemo.html">Demo</a> | <a href="http://brettterpstra.com/share/pully/pully.jquery.js?9d7bd4">Download</a></p>

<p><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/11/PullyDemoSection1ScreenCap.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/11/PullyDemoSection1ScreenCap-150x150.jpg?9d7bd4" alt="" title="PullyDemoSection1ScreenCap" width="150" height="150" class="shadow alignright size-thumbnail wp-image-1170" /></a>Another quick experiment. Honestly, I don’t use pluggable functions in jQuery nearly as much as I should, so this is really just a brain exercise to get myself used to it. This one, called Pully, lets you specify a selector to have its contents cloned and inserted as a <a href="http://en.wikipedia.org/wiki/Pull_quote">pull quote</a> in your text.</p>

<p>It seems to me that the average HTML pull quote, when you look at it from a source code or screen reader viewpoint, is redundant and/or confusing. They really only make sense when they’re visually styled. My thought is to use semantic markup within a block of content to emphasize pull-quotable text, and then unobtrusively create the pull quote from that text when it’s of use. I could be operating under faulty assumptions, but it makes sense to me tonight.</p>

<p>Pully has two options, <code>newclass</code> and <code>prependtoparent</code>. <code>newclass</code> determines the class that is added to the inserted pull quote element, and defaults to ‘pullyquote’. <code>prependtoparent</code> determines whether the pull quote element is inserted “inline” (directly before the selected source element) or moved up in the DOM and prepended to a parent element. It defaults to <code>false</code> (inline) and can be set to any element found upstream in the DOM from the source.</p>

<p>In its simplest usage, you can take a paragraph which contains a span with a class of .pullquote (for example) and call it like this:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript">$<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ready</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	$<span class="br0">&#40;</span><span class="st0">'.pullquote'</span><span class="br0">&#41;</span>.<span class="me1">pully</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>


<p>Here’s an example of Pully being run with all options. This call will take an <code>&lt;em&gt;</code> block inside of a <code>&lt;strong&gt;</code> element and turn it into the pullquote. It will insert the new element at the beginning of the enclosing paragraph and apply the class “ppullquote” to it:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript">$<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ready</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	$<span class="br0">&#40;</span><span class="st0">'p strong&gt;em'</span><span class="br0">&#41;</span>.<span class="me1">pully</span><span class="br0">&#40;</span><span class="br0">&#123;</span><span class="st0">'prependtoparent'</span><span class="sy0">:</span><span class="st0">'p'</span><span class="sy0">,</span><span class="st0">'newclass'</span><span class="sy0">:</span><span class="st0">'ppullquote'</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>


<p>You’ll need to provide your own CSS. Unless otherwise specified, your pullquote will have a class of “pullyquote,” to which you can apply whatever styles are most fitting. I borrowed some styles from <a href="http://type-a-file.com/">type-a-file</a> for the demo, the pertinent portions are included in the main source of the demo page.</p>

<p>You can <a href="http://brettterpstra.com/share/pully/pully.jquery.js?9d7bd4">download the plugin here</a>, and <a href="http://brettterpstra.com/share/pully/pullydemo.html">view it in action here</a>. Feel free to modify, repair or improve on the idea.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/desktop-quotes-geeklet/' rel='bookmark' title='Desktop Quotes Geeklet'>Desktop Quotes Geeklet</a></li>
<li><a href='http://brettterpstra.com/antique-1-6-final-release/' rel='bookmark' title='Antique 1.6, final release'>Antique 1.6, final release</a></li>
<li><a href='http://brettterpstra.com/quick-tip-extracting-mac-app-store-reviews-as-text/' rel='bookmark' title='Quick Tip: Extracting Mac App Store reviews as text'>Quick Tip: Extracting Mac App Store reviews as text</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/pully-jquery-plugin-for-automatic-pull-quotes/">Pully: jQuery plugin for automatic pull quotes</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/pully-jquery-plugin-for-automatic-pull-quotes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PromptDown for iOS: Mobile Markdown Teleprompter</title>
		<link>http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/</link>
		<comments>http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/#comments</comments>
		<pubDate>Tue, 12 Oct 2010 01:10:07 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[experiments]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[markdown]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=1083</guid>
		<description><![CDATA[<p>I recently wrote a tiny web app called PromptDown to let me drop in some Markdown (or plain text) and use it as a teleprompter for screencast voiceovers. this version works a little more smoothly as an iPhone/iPad web app.</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/">PromptDown for iOS: Mobile Markdown Teleprompter</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/PromptDownWebClipIcon.jpg?9d7bd4" alt="PromptDownWebClipIcon.jpg" border="0" width="250" height="250" class="alignright" />I recently wrote a tiny web app called <a href="http://brettterpstra.com/promptdown-markdown-teleprompter/">PromptDown</a> to let me drop in some Markdown (or plain text) and use it as a teleprompter for screencast voiceovers. I wasn’t going to put any more time into it, as it did what I needed. Then it started to bug me that it didn’t work on my iPad, which could actually be really handy. So my lunch break—fine, and an extra half an hour—went to making it work a little more smoothly as an iPhone/iPad app. It’s also ready to install as a web app, so you can go full-screen with it.</p>

<p>The concept is exactly the same: tap the main text field to clear it, type or paste your text, then tap the prompt button to open the prompt view. A single tap will start scrolling, a double tap will exit, and dragging up or down will allow you to fast forward or rewind. On the iPhone, it actually works best in landscape mode, allowing the words to be big enough to see while still fitting enough on the screen that it’s not ridiculously slow. I haven’t added any speed controls to it, which I may do at some point. For now, it’s on and off.</p>

<p>Point your mobile browser to <a href="http://brettterpstra.com/share/promptdown/mobile.html">http://brettterpstra.com/share/promptdown/mobile.html</a> and give it a try. Tap the plus button (on the iPhone) or the “send to” icon (on the iPad) to add the app to your homescreen and be able to use it full-screen. This version actually works well in Safari and Firefox on the desktop, too.</p>

<p>Neat.</p>

<p><div id="attachment_1084" class="wp-caption alignleft" style="width: 160px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; float: left;"><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/promptdownipadpromptscreen.jpg?9d7bd4"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/promptdownipadpromptscreen-150x150.jpg?9d7bd4" alt="" title="PromptDown prompt screen on iPad" width="150" height="150" class="size-thumbnail wp-image-1084" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">Prompt screen on iPad</p></div>
<div id="attachment_1085" class="wp-caption alignleft" style="width: 160px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; float: left;"><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/promptdowniphone4.jpg?9d7bd4"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/promptdowniphone4-150x150.jpg?9d7bd4" alt="Screenshot of PromptDown on iPhone 4" title="PromptDown on iPhone 4" width="150" height="150" class="size-thumbnail wp-image-1085" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">Edit screen on iPhone 4</p></div></p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/promptdown-markdown-teleprompter/' rel='bookmark' title='Look, I made you a Markdown teleprompter'>Look, I made you a Markdown teleprompter</a></li>
<li><a href='http://brettterpstra.com/ios-giveaway-writeup/' rel='bookmark' title='iOS App Giveaway: WriteUp'>iOS App Giveaway: WriteUp</a></li>
<li><a href='http://brettterpstra.com/ios-app-review-writeup/' rel='bookmark' title='iOS App Review: WriteUp'>iOS App Review: WriteUp</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/">PromptDown for iOS: Mobile Markdown Teleprompter</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Look, I made you a Markdown teleprompter</title>
		<link>http://brettterpstra.com/promptdown-markdown-teleprompter/</link>
		<comments>http://brettterpstra.com/promptdown-markdown-teleprompter/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 00:06:15 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[experiments]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=1071</guid>
		<description><![CDATA[<p>Be sure to check out version 2, with iOS support (iPhone/iPad)! Here’s my stupid trick of the day: a Markdown teleprompter called PromptDown (I see what you did there…). The idea was to create a teleprompter for recording screencast voiceovers that was cheap, fast and worked on plain text. I wanted to provide a non-WYSIWYG form field for typing or&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/promptdown-markdown-teleprompter/">Look, I made you a Markdown teleprompter</a></p>]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_1072" class="wp-caption alignleft" style="width: 160px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; float: left;"><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/PromptDownEditScreen.jpg?9d7bd4"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/PromptDownEditScreen-150x150.jpg?9d7bd4" alt="PromptDown Edit Screen" title="PromptDown Edit Screen" width="150" height="150" class="size-thumbnail wp-image-1072" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">PromptDown Edit Screen</p></div>
<div id="attachment_1074" class="wp-caption alignleft" style="width: 160px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; float: left;"><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/PromptDownPromptScreen.jpg?9d7bd4"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/PromptDownPromptScreen-150x150.jpg?9d7bd4" alt="PromptDown Prompt Screen" title="PromptDown Prompt Screen" width="150" height="150" class="size-thumbnail wp-image-1074" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">PromptDown Prompt Screen</p></div></p>

<p><strong><em>Be sure to <a href="http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/">check out version 2</a>, with iOS support (iPhone/iPad)!</em></strong></p>

<p>Here’s my stupid trick of the day: a Markdown teleprompter called <a href="http://brettterpstra.com/share/promptdown/">PromptDown</a> (I see what you did there…). The idea was to create a teleprompter for recording screencast voiceovers that was cheap, fast and worked on plain text. I wanted to provide a non-WYSIWYG form field for typing or pasting which still preserved paragraph breaks, so <a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a> (via <a href="http://attacklab.net/showdown/">Showdown</a>) was an ideal solution. I also included the <a href="http://teddevito.com/demos/textarea.html">jQuery “tabby” plugin</a> so you could use tabs in the textarea without jumping out of it, which is nice when editing Markdown, depending on your formatting habits. The rest is just CSS and quick-and-dirty tricks.</p>

<p><span id="more-1071"></span></p>

<h3>How to use it</h3>

<p>It takes input in standard Markdown format and, when you press the “Prompt” button or hit Shift-Enter, it blacks the screen and renders your Markdown in large, contrasting text. Then you can hit Spacebar or Enter to start and stop scrolling. Stopping auto-scroll and using your mouse’s scroll wheel will allow you to navigate. Escape (or a click on the background) will take you back to the editor.</p>

<p>There are a few more tricks listed in the text that initially populates the text area when the page loads. Among them is a note that entering a horizontal rule in Markdown syntax will give you a bright yellow marker at that point in your script, which is handy for longer work. The easiest format for a horizontal rule, for me, is <code>- - -</code>, three dashes with spaces between them on their own line.</p>

<h3>Why I made it</h3>

<p>Why did I spend an hour and a half making a cheap teleprompter with very few features? Because I just wanted to scroll some text, and the market for Mac-based teleprompters seemed to start around $65 and go up from there. I’m not one to complain about a price when there’s appropriate value, but I’m assuming that those $65–250 apps were doing magical things I just didn’t need. This is my solution, as hackish as it may be. As an aside, I used to have a license for <a href="http://www.telestream.net/video-cue/overview.htm">VideoCue</a>, which I loved, but I never upgraded it and now I’ve lost both it and my older version of VideoCue. Drat.</p>

<h3>Do it yourself</h3>

<p>Feel free to use it online, or feel free to borrow the code and build your own locally. It doesn’t require anything unusual, and will run right from a folder on your desktop if you point your browser there. I should note that it works much better in Safari 5 than in Firefox, at least in my quick testing (and hopefully not-at-all in Internet Explorer… I’m still carrying a grudge). I’m not really going for a fully cross-browser, all-purpose solution here. It fills a need for me, and if someone wants it to do something else, they can have at it. Here’s a zip of the code as of this evening: <a href="http://brettterpstra.com/share/promptdown.zip?9d7bd4">PromptDown.zip</a>. Try out the online version at <a href="http://brettterpstra.com/share/promptdown">http://brettterpstra.com/share/promptdown</a>.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/' rel='bookmark' title='PromptDown for iOS: Mobile Markdown Teleprompter'>PromptDown for iOS: Mobile Markdown Teleprompter</a></li>
<li><a href='http://brettterpstra.com/markdown-quicktags-makes-1000-people-happier-and-more-attractive/' rel='bookmark' title='Markdown QuickTags makes 1000 people happier and more attractive'>Markdown QuickTags makes 1000 people happier and more attractive</a></li>
<li><a href='http://brettterpstra.com/markdown-quicktags-wordpress-plugin/' rel='bookmark' title='Markdown QuickTags: WordPress plugin for Markdown lovers'>Markdown QuickTags: WordPress plugin for Markdown lovers</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/promptdown-markdown-teleprompter/">Look, I made you a Markdown teleprompter</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/promptdown-markdown-teleprompter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HomeControl: Local Mac control for iPhone</title>
		<link>http://brettterpstra.com/homecontrol-local-mac-control-for-iphone/</link>
		<comments>http://brettterpstra.com/homecontrol-local-mac-control-for-iphone/#comments</comments>
		<pubDate>Sun, 03 Oct 2010 02:31:37 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=1041</guid>
		<description><![CDATA[<p>I put together this little web app today as a proof of concept (that got a little out of hand). It basically provides a full interface for volume control, application starting and stopping and many iTunes functions, including volume and EQ. All features provide interface feedback and update you with current info from your Mac.</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/homecontrol-local-mac-control-for-iphone/">HomeControl: Local Mac control for iPhone</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/homecontrolpostimage.jpg?9d7bd4" alt="" title="homecontrolpostimage" width="300" height="264" class="alignright size-full wp-image-1047" />I tried out <a href="http://dashdingo.org/post/1075781336/mute-mac-osx-from-iphone">a tip</a> recently for controlling a Mac via Mobile Safari on your iPhone, and it got me thinking, which is often dangerous. I put together this little web app today as a proof of concept (that got a little out of hand). It basically provides a full interface for volume control, application starting and stopping and many iTunes functions, including volume and EQ. All features provide interface feedback and update you with current info from your Mac.</p>

<h3>Video preview</h3>

<p>httpv://www.youtube.com/watch?v=KTcISVU4Nf4</p>

<p><a href="http://www.youtube.com/watch?v=KTcISVU4Nf4&amp;fmt=21">YouTube Link…</a></p>

<p><span id="more-1041"></span></p>

<h3>Setting up your web server</h3>

<p>To run it, you need to run your local web server as your own user. This is, of course, a major security risk and completely inadvisable if your local web server is open to outsiders in any way. Mine’s not, so I didn’t put too much time into figuring out a more secure way to do this. If you have any clues in that area, let me know and I’ll post them.</p>

<p>To run your local web server as a different user, you need to edit <code>/etc/apache2/httpd.conf</code>. You’ll need to edit it as root, so use sudo to launch your text editor of choice (e.g. <code>sudo vi /etc/apache2/httpd.conf</code>). If you, like me, just use TextMate’s <code>mate</code> command, you’ll be prompted for a password when you save.</p>

<p>Locate the lines:</p>

<pre><code>User _www
Group _www
</code></pre>

<p>Change them to:</p>

<pre><code>User yourusername
Group staff
</code></pre>

<p>You’ll also need to enable PHP, if you haven’t already. If you haven’t, locate the line that starts with:</p>

<pre><code>#LoadModule php5_module
</code></pre>

<p>Just remove the hashmark at the beginning (#) to turn PHP on.</p>

<p>Now, at the command line, type <code>sudo apachectl graceful</code> to restart the server under the new user. If everything is in place, you’ll be able to run HomeControl without a hitch now. Turn on Web Sharing in System Preferences &gt; Sharing to keep the web server running through reboots and logouts.</p>

<h3>Installing HomeControl</h3>

<p>Just download the zip file at the end of this post and unzip it into your <code>~/Sites</code> folder. If you prefer to have it elsewhere, or have a custom folder set up for Apache, it will run just fine in any folder, as long as you can access it from a web browser on the local network.</p>

<p>Next, point your web browser to the folder. If you put the ‘homecontrol’ folder directly in <code>~/Sites</code>, you should be able to reach it at the url <code>http://computer_name.local/~Username/homecontrol</code>. You need to know the name of the computer it’s on (set in System Preferences &gt; Sharing, at the top), and your username on that system, substituting each in the appropriate place in the url.</p>

<p>Once you’ve loaded the page and tested it out, use the “+” icon at the bottom of Mobile Safari’s web browser to add an icon to your home screen which will take you directly there in the future, and will run the app full-screen.</p>

<h3>Customizing HomeControl</h3>

<p>Since I know not everybody who wants to try this out is going to be ready to hack into the jQuery and PHP, I made quite a few bits of the app modifiable with simple HTML edits. If you’re comfortable with that, you can change the list of applications and add iTunes features quite easily.</p>

<h4>Application launcher</h4>

<ul>
<li>Locate the div with the id “apps”</li>
<li>Find the unordered list (<code>&lt;ul&gt;</code>) inside of it</li>
<li>Edit or copy and edit existing lines by changing only the name of the application in the first span</li>
<li>Use the exact displayed name of the application you want to control, and HomeControl will pass it to the PHP exec function</li>
</ul>

<h4>iTunes functions</h4>

<ul>
<li>Locate the div with the id “itunes”</li>
<li>Find the unordered list inside of it with the id “itunescmd”</li>
<li>Add new features by copying an existing line and changing the rel attribute and the text of the link

<ul>
<li>The rel attribute passes the actual iTunes AppleScript command, which will be appended to a ‘<code>tell application "iTunes" to</code>’ line and passed to osascript</li>
<li>The text of the link is the title which will appear in the menu</li>
</ul></li>
</ul>

<h4>iTunes EQ Presets</h4>

<ul>
<li>Locate the div with the id “ituneseq”</li>
<li>Find the unordered list inside of it</li>
<li>Edit the text of the links in the list with the exact title of the preset you want to control</li>
<li>Add or remove list items as desired</li>
</ul>

<h4>Startup screen and icon</h4>

<ul>
<li>Edit <code>homecontrolicon.png</code> in the <code>homecontrol</code> folder to customize the app’s icon on the homescreen.</li>
<li>Edit <code>hc_startup.png</code> in the <code>homecontrol</code> folder to customize the startup screen.</li>
<li>If you’ve installed the web app, delete the icon and reinstall from Mobile Safari to see the new images.</li>
</ul>

<h4>Advanced customization</h4>

<p>If you’re handy with the jQuery, the PHP and the HTML, you can do a lot with the examples in the code. It’s very much a proof-of-concept, and intended to be a jumping point for more experimentation, so have at it.</p>

<p>The app currently uses the <a href="http://www.jqtouch.com/">jQTouch</a> library, but mostly for the CSS. It has very few dependencies on the API, so it should be a relatively trivial matter to switch to a different library. It does rely quite heavily on jQuery, though.</p>

<p>The main PHP/osascript calls are in <code>functions.php</code>. All functions are called using jQuery’s $.get function, which makes Ajax calls to the <code>functions.php</code> file in the background and receives updates on completion.</p>

<p>Have fun, hopefully my horrible waste of time will be someone else’s inspiration…</p>

<p><div id="attachment_1045" class="wp-caption alignleft" style="width: 160px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; float: left;"><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/homecontrolhomescreen.jpg?9d7bd4"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/homecontrolhomescreen-150x150.jpg?9d7bd4" alt="Screenshot of HomeControl Main Screen" title="HomeControl Main Screen" width="150" height="150" class="size-thumbnail wp-image-1045" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text"> Main Screen</p></div>
<div id="attachment_1042" class="wp-caption alignleft" style="width: 160px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; float: left;"><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/homecontrolapplications.jpg?9d7bd4"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/homecontrolapplications-150x150.jpg?9d7bd4" alt="Screenshot of HomeControl Applications Screen" title="HomeControl Applications Screen" width="150" height="150" class="size-thumbnail wp-image-1042" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">Applications Screen</p></div>
<div id="attachment_1046" class="wp-caption alignleft" style="width: 160px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; float: left;"><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/homecontrolitunes.jpg?9d7bd4"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/10/homecontrolitunes-150x150.jpg?9d7bd4" alt="Screenshot of HomeControl iTunes controls" title="HomeControl iTunes controls" width="150" height="150" class="size-thumbnail wp-image-1046" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">iTunes controls</p></div></p>

<h3>Download</h3>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/homecontrol.0.10.zip?9d7bd4" title="Download HomeControl (1350)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2010/10/homecontrolicon.png?9d7bd4" alt="download image for HomeControl" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/homecontrol.0.10.zip?9d7bd4" title="Download HomeControl (1350)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/homecontrol.0.10.zip?9d7bd4" title="Download HomeControl (1350)">HomeControl</a> — A web app—designed to run on a local server and be accessed over the local network—which provides control over volume, iTunes features and application launching. This is a skeleton for further experimentation. <a href="http://brettterpstra.com/homecontrol-local-mac-control-for-iphone">More Info</a></p></div>


<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/promptdown-for-ios-mobile-markdown-teleprompter/' rel='bookmark' title='PromptDown for iOS: Mobile Markdown Teleprompter'>PromptDown for iOS: Mobile Markdown Teleprompter</a></li>
<li><a href='http://brettterpstra.com/the-mac-and-ios-mind-mapping-app-extravaganza/' rel='bookmark' title='The Mac and iOS mind mapping app extravaganza'>The Mac and iOS mind mapping app extravaganza</a></li>
<li><a href='http://brettterpstra.com/promptdown-markdown-teleprompter/' rel='bookmark' title='Look, I made you a Markdown teleprompter'>Look, I made you a Markdown teleprompter</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/homecontrol-local-mac-control-for-iphone/">HomeControl: Local Mac control for iPhone</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/homecontrol-local-mac-control-for-iphone/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Antique 1.6, final release</title>
		<link>http://brettterpstra.com/antique-1-6-final-release/</link>
		<comments>http://brettterpstra.com/antique-1-6-final-release/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 15:24:57 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[antique]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[reader]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[safari 5]]></category>
		<category><![CDATA[typography]]></category>
		<category><![CDATA[widont]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=624</guid>
		<description><![CDATA[<p>"Antique" hack for Safari 5's Reader feature. Adds an antiqued theme and several new functions for typography, image handling and send-to applications.</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/antique-1-6-final-release/">Antique 1.6, final release</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/AntiqueImageLinking.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/AntiqueImageLinking-150x150.jpg?9d7bd4" alt="" title="AntiqueImageLinking" width="150" height="150" class="alignright size-thumbnail wp-image-628" /></a></p>

<p><strong>For a quick “how-to” on using the Antique (or any) Safari Reader hack, see the <a href="http://brettterpstra.com/howtos/install-a-safari-reader-hack/">related article</a> in the <a href="http://brettterpstra.com/howtos/">HowTo section</a>.</strong></p>

<p>This will be the last release of Antique, I think, barring a few minor fixes (follow <a href="http://twitter.com/ttscoff">@ttscoff</a> for updates on this and other projects). You can download it <a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Antique Reader 1.6">here</a>. The code is completely open source, if anyone wants to continue the project feel free (credit would be swell, where it’s due). I’ll be putting my free time into <a href="http://brettterpstra.com/2010/06/09/instapaper-beyond-for-safari/">Instapaper Beyond</a> and other more “legitimate” projects now (although I really would like to do a nice, high-contrast, Helvetica version…). In deference to <a href="http://farukat.es/journal/2010/06/456-stop-hacking-safari-reader">Faruk Ateş</a>, I’d like to clearly state that this <em>is</em> a hack, and you run a risk (albeit very minimal) of breaking your Safari install if you don’t know what you’re doing. I also won’t be posting further simplified instructions for installation, but they’re not hard to find. For advanced users, you simply need to know that you’re replacing <code>Reader.html</code> in <code>Contents/Resources</code>.</p>

<p><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/AntiqueHeadlineSplit.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/AntiqueHeadlineSplit-150x150.jpg?9d7bd4" alt="" title="AntiqueHeadlineSplit" width="150" height="150" class="alignright size-thumbnail wp-image-627" /></a></p>

<p>The coolest changes, in my opinion, are an <strong>amped-up Widon’t</strong> for headlines, and <strong>improved image linking</strong>. On the Widon’t end, if a title exceeds the width of the headline area, it’s actually split in the middle to provide more equal-length lines. It’s neat-o. And for the images: I had it only lightboxing images which were too large for the style and which <em>weren’t</em> already linked somewhere else, resulting in the user never knowing what would happen when they clicked an image. Now, if an image is linked to an external site, that link is extracted and placed on a line below the image. If an alt or title attribute are present in the image or the link, they’re preferred over the source attribute for naming the link, which should provide a decent idea of where you’re going, in most cases. Images which are linked, then, are always linked to the Colorbox effect, and will never take you out of the Reader page. Ah, consistency.</p>

<p>Here’s what else is new in this version.</p>

<ul>
<li>I swapped out the scrollbar images, shifted the colors a little, and included them in the HTML file.</li>
<li>Some style changes, including a darker background and slightly heavier gradient</li>
<li>Massively fixed up the <a href="http://brettterpstra.com/2010/06/14/ampersands-javascript/">ampersand code</a>. Also shifted ampersands 1 pixel left for better kerning within non-italicized text.</li>
<li>Improved smashing of empty paragraphs in bad markup to avoid huge spaces between paragraphs.</li>
<li>Fixed a CSS mistake I had introduced which caused the background and drop shadow to be visible before the content slid up from the bottom.</li>
<li>Set up an onscroll check for new elements. Every time the page is scrolled, Antique checks for new elements (i.e. additional pages that were inserted after initial load) and applies the default functions to them.</li>
<li>did I mention 12px Droid Sans Mono for code blocks? 12px seems reasonable, and doesn’t change when zooming/shrinking the rest of the text.</li>
</ul>

<!-- more -->

<p>Are there too many buttons in the HUD for your taste? They’re there as an example, but you can remove them easily by commenting out the “button” lines at the bottom of the Reader.html file. The HUD will adjust size and position automatically based on the number of buttons you have in there, so just remove the ones that aren’t of use to you.</p>

<p>If you’re playing with Reader styles, here’s a tip: you can set up a “sandbox” page to speed up development (at least with css). Once Reader has loaded a page that has elements you want to style, right click and choose “Inspect Element” (obviously, you have to have the developer menu enabled in preferences). Then, right click on the doctype declaration in the element inspector and choose “Copy as HTML.” That will give you the full HTML of the <em>rendered</em> document, which you can save to a new HTML file. Extract the inline stylesheets and link them into external stylesheets, and you can edit in CSSEdit or Firebug. It’s handy, given that, in order to change the live styles, you have to restart Safari every time you edit Reader.html.</p>

<p>I had started working on smart quotes and other javascript-based typography changes, but decided it wasn’t worth the time to try to come up with regular expressions that covered every possible circumstance. If anyone wants to pick up where I left off, I’d love to see what you come up with.</p>

<p><strong>For a quick “how-to” on using the Antique (or any) Safari Reader hack, see the <a href="http://brettterpstra.com/howtos/install-a-safari-reader-hack/">related article</a> in the <a href="http://brettterpstra.com/howtos/">HowTo section</a>.</strong></p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Download Antique 1.6 for Safari Reader (4517)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2010/11/safariiconantiqued.png?9d7bd4" alt="download image for Antique 1.6 for Safari Reader" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Download Antique 1.6 for Safari Reader (4517)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Download Antique 1.6 for Safari Reader (4517)">Antique 1.6 for Safari Reader</a> — Version 1.6 of the Antique hack for Safari 5. Adds pleasant styling to Reader, with many additional features. <a href="http://brettterpstra.com/2010/06/17/antique-1-6-final-release/">More Info</a></p></div>

<hr />
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/antique-is-back-baby/' rel='bookmark' title='Antique is back, baby'>Antique is back, baby</a></li>
<li><a href='http://brettterpstra.com/antique-safari-reader-hack-update-with-evernote-goodness/' rel='bookmark' title='Antique Safari Reader hack update with Evernote goodness'>Antique Safari Reader hack update with Evernote goodness</a></li>
<li><a href='http://brettterpstra.com/safari-reader-antique-hack/' rel='bookmark' title='Safari Reader Antique hack'>Safari Reader Antique hack</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/antique-1-6-final-release/">Antique 1.6, final release</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/antique-1-6-final-release/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Ampersands &amp; Javascript</title>
		<link>http://brettterpstra.com/ampersands-javascript/</link>
		<comments>http://brettterpstra.com/ampersands-javascript/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 16:18:31 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[antique]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[typography]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=613</guid>
		<description><![CDATA[<p>While playing around with Antique1, I decided I really wasn’t in love with the ampersands that were included in any of the fonts I was working with. Normally, I’d just run everything through Typogrify2 and get some handy CSS classes to work with. Working in Safari’s Reader, though, I only had access to Javascript (and jQuery, now). I set out&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/ampersands-javascript/">Ampersands &amp; Javascript</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' display:none'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/ampersandjavascriptheader.jpg?9d7bd4" alt="Ampersands and Javascript" border="0" width="650" height="187" class="headerimg" />While playing around with Antique<sup id="fnref:antique"><a href="#fn:antique" rel="footnote">1</a></sup>, I decided I really wasn’t in love with the ampersands that were included in any of the fonts I was working with. Normally, I’d just run everything through Typogrify<sup id="fnref:typogrify"><a href="#fn:typogrify" rel="footnote">2</a></sup> and get some handy CSS classes to work with. Working in Safari’s Reader, though, I only had access to Javascript (and jQuery, now).</p>

<p><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/AntiqueAmpersands.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/AntiqueAmpersands-300x58.jpg?9d7bd4" alt="" title="Antique - Ampersands" width="300" height="58" class="alignright size-medium wp-image-614" /></a>I set out on a search for an easy, all-purpose solution, but nothing worked as well as I wanted it to. So I did a little scavenging and put together a couple of functions that do the job pretty well. They use jQuery, but could just as easily be done with pure Javascript, if you really wanted to.</p>

<p><span id="more-613"></span></p>

<p>Here are the two functions I’m using in the latest (unreleased, at this moment) version of Antique:</p>

<div markdown=0>
<pre><code>
function fixAmpersands() {
    // entity encodes only ampersands that aren&#x27;t already encoded
    $(&quot;h1,h2,h3,p:contains(&#x27;&amp;&#x27;)&quot;, document.body).each(function() {
        if( this.nodeType == 3 ) {
            // regex from Stack Overflow http://bit.ly/aJZVCG
            $(this).html( $(this).html().replace( /&amp;(?![a-zA-Z]{2,6};|#[0-9]{2,4};)/g, &quot;&amp;amp;&quot; ) );
        }
    });
}
function dressUpAmpersands() {
    // adds a span with class &#x27;amp&#x27; to the entity-encoded ampersands
    $(&quot;h1,h2,h3,p:contains(&#x27;&amp;&#x27;)&quot;, document.body).each(function() {
        $(this).html( $(this).html().replace( /&amp;amp;/g, &quot;&lt;span class=&#x27;amp&#x27;&gt;&amp;amp;&lt;/span&gt;&quot; ) );
    });
}
$(document).ready(function() {
    fixAmpersands();
    dressUpAmpersands();
});
</code></pre>
</div>

<p>They seem to work pretty well, so far. I accompany them with some CSS I nicked from <a href="http://simplebits.com/notebook/2008/08/14/ampersands-2/">SimpleBits</a> and <a href="http://patrickhaney.com/thinktank/2008/08/19/automatic-awesompersands">Patrick Haney</a>:</p>

<div markdown=0>
<pre><code>
.page span.amp { 
    font-family: Baskerville, Palatino, Constantia, "Book Antiqua", "URW Palladio L", serif;
    font-style: italic;
}
</code></pre>
</div>

<p>In my situation, it doesn’t really matter if ampersands are captured within code blocks, but just to keep styling consistent, I also force any .amp-wrapped ampersands within pre and code blocks to match the pre/code styling:</p>

<div markdown=0>
<pre><code>
#article .page pre,#article .page code,.page code span.amp, .page pre span.amp {
    font-family: 'Droid Sans Mono', 'Andale Mono', 'Courier New', Courier, monospace !important;
    font-style: normal;
}
</code></pre>
</div>

<p>Of course, this is all really better handled server-side with, say, PHP, but if you’re looking for spicy typography and are limited to client-side solutions, give it a shot! I’m running these right before my rather wicked new version of widon’t which splits long titles into nearly equal-length lines… more on that soon.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:antique">
<p><a href="http://brettterpstra.com/2010/06/13/antique-1-5-for-safari-reader/">http://brettterpstra.com/2010/06/13/antique-1–5-for-safari-reader/</a> <a href="#fnref:antique" rev="footnote">↩</a></p>
</li>

<li id="fn:typogrify">
<p><a href="http://code.google.com/p/typogrify/">http://code.google.com/p/typogrify/</a> <a href="#fnref:typogrify" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/word-repetition-checking-with-javascript/' rel='bookmark' title='Word repetition checking with JavaScript'>Word repetition checking with JavaScript</a></li>
<li><a href='http://brettterpstra.com/catching-markdown-mistakes/' rel='bookmark' title='Catching Markdown mistakes'>Catching Markdown mistakes</a></li>
<li><a href='http://brettterpstra.com/antique-1-6-final-release/' rel='bookmark' title='Antique 1.6, final release'>Antique 1.6, final release</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/ampersands-javascript/">Ampersands &amp; Javascript</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/ampersands-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Antique 1.5 for Safari Reader</title>
		<link>http://brettterpstra.com/antique-1-5-for-safari-reader/</link>
		<comments>http://brettterpstra.com/antique-1-5-for-safari-reader/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 21:19:16 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[antique]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[safari 5]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=592</guid>
		<description><![CDATA[<p>There is a new version of Antique available! Check out version 1.6! Version 1.5 1.6 of Antique (originally posted here) is officially available for download. Here’s what’s new! jQuery: added the jQuery library via Google’s Ajax API to make some of the other additions much easier to implement. Colorbox: links to images are automatically opened in a “lightbox” so you&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/antique-1-5-for-safari-reader/">Antique 1.5 for Safari Reader</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>There is a new version of Antique available! <a href="http://brettterpstra.com/2010/06/17/antique-1-6-final-release/">Check out version 1.6</a>!</strong></p>

<p><a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Download Antique 1.6">Version <del datetime="2010-06-18T16:36:40+00:00">1.5</del> <ins datetime="2010-06-18T16:36:40+00:00">1.6</ins> of Antique</a> (<a href="http://brettterpstra.com/2010/06/12/safari-reader-antique-hack/">originally posted here</a>) is officially available for download. Here’s what’s new!</p>

<hr style="visibility:hidden;clear:both" />

<ul>
<li><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/Antique1.5.1screenshot.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/Antique1.5.1screenshot-150x150.jpg?9d7bd4" alt="" title="Antique1.5.1screenshot" width="150" height="150" class="alignright size-thumbnail wp-image-609" /></a> <strong>jQuery:</strong> added the <a href="http://jquery.com/">jQuery</a> library via Google’s Ajax API to make some of the other additions much easier to implement.</li>
<li><strong>Colorbox:</strong> links to images are automatically opened in a “lightbox” so you don’t have to leave the page. Uses jQuery <a href="http://colorpowered.com/colorbox/">Colorbox</a> and automatically applies the effect to links ending in ‘.jpg’ or ‘.png’.</li>
<li><strong>Widon’t:</strong> headlines and paragraphs have a widon’t function applied to them, preventing “widows” (short words alone on a line). This was mostly annoying me in the top-level headings of the page, but it’s a nice touch throughout. It ignores words longer than 8 characters. They’ll do just fine on their own.</li>
<li><strong>New HUD buttons:</strong> in addition to the Evernote web clipper button in the floating HUD, there are new buttons for <a href="http://www.devon-technologies.com/products/devonthink/devonthink2.html">DEVONthink</a>, <a href="http://delibarapp.com/">Delibar</a> and <a href="http://www.celmaro.com/webbla/">Webbla</a>. These are mostly to show how to pull it off, and are easily edited. See the instructions below to remove buttons from the HUD.</li>
<li><strong>Pass text selections:</strong> unlike using bookmarklets, clicking on a HUD icon makes you lose your text selection. Any service that accepts a selection as a note or description (Evernote, DEVONthink, Webbla, etc.) won’t normally work. By storing the selected text in an HTML5 sessionStorage key every time your mouse enters the HUD, Antique is able to pass what <em>was</em> selected before you clicked the button. <em>Still working on making this function with Evernote.</em></li>
<li><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/antiqueColorBoxScreenshot.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/antiqueColorBoxScreenshot-150x150.jpg?9d7bd4" alt="" title="Antique with ColorBox" width="150" height="150" class="alignright size-thumbnail wp-image-595" /></a> <strong>Smarter image resizing:</strong> when you load a page, Antique shrinks the larger images. It’s smarter now, though: wide, centered images are only reduced slightly and left centered, and any floated images that are reduced (and aren’t already linked somewhere) are now linked to the full size version of themselves, which will display in-page using Colorbox. Floated images also have bottom margin and clear:left applied to them to prevent horizontal stacking when images are close to each other in the layout.</li>
<li><strong><em>Minor Update:</em></strong> <em>(version 1.5.1)</em> I just swapped out Crimson Text for OFL Sorts Mill Goudy TT, primarily because I like the quotation marks much better. I also added hanging quotes (image-based) to blockquotes, and improved code blocks and bulleted lists wrapped around images.</li>
</ul>

<h3>Installation</h3>

<p>If you want to try out the style, <a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4">download it here</a> and open the archive. Inside you’ll find a file called Reader.html. The file you’re going to replace (back it up somewhere safe first) is <code>/Applications/Safari.app/Contents/Resources/Reader.html</code>. If you don’t know how to do this from Terminal, you can just do it in Finder: go to your Applications folder and locate Safari, then right click on it and choose “Show Package Contents.” That will open a new window with the inner workings of Safari inside it. Open the folder called Contents, and then the Resources folder inside of that. Locate the file Reader.html and drag it out to your desktop (that’s your original, keep it safe). Then drag the new Reader.html file you downloaded into the Resources folder. Restart Safari and try it out!</p>

<p>There are lots of minor efficiency and style tweaks, but those are the major changes. If you’re interested in modifying the HUD (removing unnecessary buttons), read on…</p>

<p><span id="more-592"></span></p>

<h3>Removing HUD buttons</h3>

<p>This part is a cinch, even if you don’t know anything about Javscript or HTML. The HUD buttons are in the HTML body section of the Reader.html file, and you can just edit them out in a text editor. If you open the file (Reader.html) in a your editor of choice (as plain text, not rich text), and scroll all the way to the bottom, you’ll see a series of “<code>&lt;button id="hud... &gt;</code>” lines. It will be pretty obvious what each one is for, and you can simply comment out or delete the lines for buttons you don’t need. Antique will automatically resize and reposition the HUD based on the number of buttons in it, so that’s all you have to worry about.</p>

<h3>Adding HUD buttons</h3>

<p>Adding buttons is a different story, depending on what you want the button to do. So far, I’ve mostly been converting existing bookmarklets. You can set the function to call right in the button definition (just copy an existing button and edit it), then add the appropriate function to the script section above. Note that any bookmarklet that uses <code>window.location</code>, <code>location.href</code> or any means of getting the page title attribute are going to break. Reader overrides all of that, but thankfully, it stores the info in an object called ReaderJS. You can access the original page url with <code>ReaderJS.originalURL</code> and the title with <code>ReaderJS.displayTitle</code>. Those two make it pretty easy to cover 90% of bookmarklets you’d want to use.</p>

<p>I’m including most external javascript plugins and libraries directly in the html page. Standard rules don’t apply, this is all being served locally and the fewer files you have to keep track of, the easier it is to distribute. If your needs are different, you can reference external files in the <code>Safari.app/Contents/Resources</code> folder with <code>safari-resource:/filename.ext</code>, where filename.ext is the name of the file.</p>

<p>Antique handles the resizing of the HUD automatically, but if you’re doing it from scratch you’ll need to adjust the width and left-margin of #hud in the css section. The buttons are 48x48px PNG files, with the icon occupying approximately 36x36px of that space. White and transparent pixels only, if you want to fit the aesthetic, and the “inactive” version should be saved at about 70% opacity. I’ve been encoding all of my PNG files in base64 and including them inline in the CSS to make it easier to distribute, but you can reference them as mentioned above.</p>

<p>You also can’t use <code>document.location</code> when Reader.html is loaded, so most bookmarklets need to be modified. You can use <code>window.open</code> and immediately close the new window, like this:</p>

<div markdown=0>
<pre><code>
function sendToWebbla() {
    var wlWindow = window.open(&#x27;webbla:url=&#x27;+encodeURIComponent(ReaderJS.originalURL)+&#x27;&amp;mode=modify&amp;title=&#x27;+encodeURIComponent(ReaderJS.displayTitle))+&#x27;&amp;textSelection=&#x27;+encodeURIComponent(sessionStorage.getItem(&#x27;textSelection&#x27;));
    wlWindow.close();
    self.focus();
}
</code></pre>
</div>

<p>I have the <code>self.focus()</code> in there because I have <a href="http://haoli.dnsalias.com/Saft/index.html">Saft</a> running and restoring focus to the last active tab, which somehow is missing and leaving me on the wrong tab when I execute the above sequence. So this just brings me back to the right tab. When it runs, you can just <em>barely</em> see that it’s even opening a new window/tab. Should be pretty seamless for most folks.</p>

<p>I think that covers the process in a general sense. Each button I’ve added has had its own quirks and issues, so it would take a lot longer to detail every possible problem you’d run in to.</p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Download Antique 1.6 for Safari Reader (4517)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2010/11/safariiconantiqued.png?9d7bd4" alt="download image for Antique 1.6 for Safari Reader" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Download Antique 1.6 for Safari Reader (4517)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/Antique1.6.zip?9d7bd4" title="Download Antique 1.6 for Safari Reader (4517)">Antique 1.6 for Safari Reader</a> — Version 1.6 of the Antique hack for Safari 5. Adds pleasant styling to Reader, with many additional features. <a href="http://brettterpstra.com/2010/06/17/antique-1-6-final-release/">More Info</a></p></div>

<hr style="visibility:hidden;clear:both" />
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/antique-safari-reader-hack-update-with-evernote-goodness/' rel='bookmark' title='Antique Safari Reader hack update with Evernote goodness'>Antique Safari Reader hack update with Evernote goodness</a></li>
<li><a href='http://brettterpstra.com/safari-reader-antique-hack/' rel='bookmark' title='Safari Reader Antique hack'>Safari Reader Antique hack</a></li>
<li><a href='http://brettterpstra.com/antique-1-6-final-release/' rel='bookmark' title='Antique 1.6, final release'>Antique 1.6, final release</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/antique-1-5-for-safari-reader/">Antique 1.5 for Safari Reader</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/antique-1-5-for-safari-reader/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Fun with MarsEdit, part I</title>
		<link>http://brettterpstra.com/fun-with-marsedit-part-i/</link>
		<comments>http://brettterpstra.com/fun-with-marsedit-part-i/#comments</comments>
		<pubDate>Sun, 06 Jun 2010 21:02:26 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[marsedit]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=533</guid>
		<description><![CDATA[<p>I’ll be the first to admit that I get a little obsessed with projects that aren’t really going to improve my life all that much. Those projects can be fun to blog about, though, so I present you my brief obsession for this Sunday afternoon. You may have noticed on this blog that some posts have header images, and some&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/fun-with-marsedit-part-i/">Fun with MarsEdit, part I</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' display:none'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/funwithmarseditheader.jpg?9d7bd4" alt="funwithmarseditheader.jpg" border="0" width="650" height="187" class="headerimg" /></p>

<p>I’ll be the first to admit that I get a little obsessed with projects that aren’t really going to improve my life all that much. Those projects can be fun to blog about, though, so I present you my brief obsession for this Sunday afternoon.</p>

<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2010/06/funwithmarseditbeforeafter.jpg?9d7bd4" alt="Template header before and after" border="0" width="298" height="202" class="alignright" />You may have noticed on this blog that some posts have header images, and some don’t, and that they get styled differently based on whether there’s an image or not. It pulls the header images from one of two places: the post thumbnail (which I can’t edit from MarsEdit) or the first image in the post content with a class of “headerimg”. As long as I’m blogging in <a href="http://​www​.red​-sweater​.com/​m​a​r​s​e​d​it/">MarsEdit</a> (or TextMate for that matter), I’m stuck with the latter option. Because the whole header image deal is handled through PHP in my functions.php file, I can’t really preview how it’s going to look; rather, I get a header image stuck somewhere before, in or after my content. In TextMate, I have a little more “scriptability” at my disposal, and the previews I’ve created there are quite accurate. As far as I can tell, I can’t pre-process content before the template is generated, so I had to try something else…
<span id="more-533"></span>My solution, for now, is jQuery in the preview template. I load the jQuery library up top (inside the header) using Google’s Ajax API:</p>

<div markdown=0>
<pre><code>
&lt;script src=&quot;http://www.google.com/jsapi&quot;&gt;&lt;/script&gt;
&lt;script&gt;google.load(&quot;jquery&quot;, &quot;1.4&quot;);&lt;/script&gt;
</code></pre>
</div>

<p>Then, at the bottom, I just start polling for an image with the right class to show up. I know it’s brute force, but this isn’t exactly public-facing, and it doesn’t seem to cause any hiccups in my writing. I have this right before my closing body tag:</p>

<div markdown=0>
<pre><code>
&lt;script&gt;
function fixHeader() {
    if ($(&#x27;img.headerimg&#x27;).attr(&#x27;src&#x27;) != undefined) {
        headerImg = $(&#x27;img.headerimg&#x27;).removeClass(&#x27;headerimg&#x27;).remove();
        postThumb = $(&#x27;.postthumb:first&#x27;);
        headerImg.prependTo(postThumb);
        postThumb.addClass(&#x27;hasimage&#x27;).removeClass(&#x27;noimage&#x27;);
    }
}
setInterval(fixHeader,2000);
&lt;/script&gt;
</code></pre>
</div>

<p>I’m sharing this just to toss the idea out there, not because I think there’s anyone else with the exact same template setup as mine.</p>

<p>In addition to having Javascript at my disposal, MarsEdit is also AppleScript-able. I haven’t looked very far into that yet, but I did whip up a quick script for adding the “headerimg” class to my images (because I always forget which class I assigned for this):</p>

<div markdown=0>
<pre><code>
tell application &quot;MarsEdit&quot;
    set selectionContents to selected text of document 1
    set {astid, AppleScript&#x27;s text item delimiters} to {AppleScript&#x27;s text item delimiters, &quot;/&gt;&quot;}
    if selectionContents is not &quot;&quot; then
        set textToInsert to (text item 1 of selectionContents) &amp; &quot;class=\&quot;headerimg\&quot; /&gt;&quot;
    end if
    set AppleScript&#x27;s text item delimiters to astid
    set selected text of document 1 to textToInsert
end tell
</code></pre>
</div>

<p>That lets me just select an image (or pending upload tag) and run the script to add the necessary class.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/multimarkdown-in-marsedit/' rel='bookmark' title='MultiMarkdown in MarsEdit'>MultiMarkdown in MarsEdit</a></li>
<li><a href='http://brettterpstra.com/instapaper-beyond-for-safari/' rel='bookmark' title='Instapaper Beyond for Safari'>Instapaper Beyond for Safari</a></li>
<li><a href='http://brettterpstra.com/marked-scripts-nvalt-evernote-marsedit-scrivener/' rel='bookmark' title='Marked scripts: nvALT, Evernote, MarsEdit, Scrivener'>Marked scripts: nvALT, Evernote, MarsEdit, Scrivener</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/fun-with-marsedit-part-i/">Fun with MarsEdit, part I</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/fun-with-marsedit-part-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Auto-lightboxing image links</title>
		<link>http://brettterpstra.com/auto-lightboxing-image-links/</link>
		<comments>http://brettterpstra.com/auto-lightboxing-image-links/#comments</comments>
		<pubDate>Wed, 26 May 2010 15:15:14 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[lightbox]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=492</guid>
		<description><![CDATA[<p>I ran into a problem recently. I wanted to have links to images be “lightboxed,” but I also wanted to blog in Markdown and not have to write out link tags with “rel” attributes for every image link. There are several existing plugins for WordPress that will do this automatically, but I’ve been sticking with the jQuery Lightbox plugin, which&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/auto-lightboxing-image-links/">Auto-lightboxing image links</a></p>]]></description>
			<content:encoded><![CDATA[<p>I ran into a problem recently. I wanted to have links to images be “lightboxed,” but I also wanted to blog in Markdown and not have to write out link tags with “rel” attributes for every image link. There are several existing plugins for WordPress that will do this automatically, but I’ve been sticking with the <a href="http://wordpress.org/extend/plugins/jquery-lightbox-balupton-edition/" title="jQuery Lightbox WordPress plugin">jQuery Lightbox plugin</a>, which handles WordPress galleries in this manner, but requires the “rel=lightbox” attribute to handle single image links.</p>

<p>I’m not a big fan of directly modifying plugins, primarily because it means that my changes will be scrapped if I ever automatically update the plugin. Since all I’m doing is adding a little jQuery to apply the effect to some additional selectors, I’ve just added it into an external Javascript file that I was already loading. Here’s what I did…</p>

<p><span id="more-492"></span>
The extra jQuery to run the lightbox effect on every link whose target ends with “jpg” is very simple:</p>

<div markdown=0>
<pre><code>
// Auto-handle direct jpeg links
$('a[href$="jpg"]').not('.gallery a').each(function() {
    $(this).lightbox();
});
</code></pre>
</div>

<p>It selects any link whose href value ends with ‘jpg’. I added a <code>.not()</code> selector to exclude the WordPress gallery links that the plugin already does a nice job of handling and turning into navigable lightbox galleries. This little bit of code will work with any flavor of the jQuery Lightbox plugin that uses “lightbox()” as its main function. Next I put this snippet into my js file, in the function that executes when the document is ready:</p>

<div markdown=0>
<pre><code>
jQuery(document).ready(function($) {
    // Auto-handle direct jpeg links
    $('a[href$="jpg"]').not('.gallery a').each(function() {
        $(this).lightbox();
    });
});
</code></pre>
</div>

<p>The “$” inside of the function’s parameters (<code>function($)</code>) lets us use the standard jQuery “$” inside of the function, instead of the no-conflict “jQuery.” Just a convenience, but if you don’t do this, and you have the default jQuery library loaded in WordPress, you’ll need to replace all of the “$” in the original snippet with “jQuery” to get it to work.</p>

<p>I add the external javascript to the queue in my theme’s functions.php file like this:</p>

<div markdown=0>
<pre><code>
function bt_load_scripts() {
    wp_enqueue_script('brettterpstra',TEMPLATEPATH.'/js/brettterpstra.js',array('jquery'),false,true);
}    

if (!is_admin()) {
    add_action('init', bt_load_scripts);
}
</code></pre>
</div>

<p>That did the trick, and any JPEG image I link to directly now gets the lightbox treatment. I haven’t run into any conflicts yet, but I’ll keep my eyes peeled and refine the selector if I need to.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/markdown-quicktags-0-7/' rel='bookmark' title='Markdown QuickTags 0.7'>Markdown QuickTags 0.7</a></li>
<li><a href='http://brettterpstra.com/auto-convert-your-inline-markdown-links-to-references/' rel='bookmark' title='Auto-convert your inline Markdown links to references'>Auto-convert your inline Markdown links to references</a></li>
<li><a href='http://brettterpstra.com/markdown-quicktags-wordpress-plugin/' rel='bookmark' title='Markdown QuickTags: WordPress plugin for Markdown lovers'>Markdown QuickTags: WordPress plugin for Markdown lovers</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/auto-lightboxing-image-links/">Auto-lightboxing image links</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/auto-lightboxing-image-links/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic (Feed is rejected)
Page Caching using disk: enhanced
Database Caching 24/134 queries in 0.306 seconds using xcache
Object Caching 3239/3389 objects using xcache
Content Delivery Network via cdn2.brettterpstra.com

Served from: brettterpstra.com @ 2012-02-09 17:22:27 -->
