<?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>Joe Maller &#187; Web Development</title>
	<atom:link href="http://joemaller.com/category/projects/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://joemaller.com</link>
	<description>.com</description>
	<lastBuildDate>Tue, 15 May 2012 03:40:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Fixing a quarter million misnested HTML tags</title>
		<link>http://joemaller.com/1567/fixing-a-quarter-million-misnested-html-tags/</link>
		<comments>http://joemaller.com/1567/fixing-a-quarter-million-misnested-html-tags/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 04:01:42 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[misc.]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[Regular Expressions]]></category>

		<guid isPermaLink="false">http://joemaller.com/?p=1567</guid>
		<description><![CDATA[These things just seem to find me, this time it was a very large database dump for a media site which was plagued with misnested HTML tags. Seriously. Just shy of 250,000 misnested pairs. Here&#8217;s the pattern I came up with to fix it: Find: &#60;(([^ &#62;]+)(?:[^&#62;]*))&#62;(.*)&#60;(([^ &#62;]+)(?:[^&#62;]*))&#62;(.*)&#60;/\2&#62;(.*)&#60;/\5&#62; Replace with: &#60;$1&#62;$3&#60;$4&#62;$6&#60;/$5&#62;$7&#60;/$2&#62; or, depending on your [...]]]></description>
			<content:encoded><![CDATA[<p>These things just seem to find me, this time it was a very large database dump for a media site which was plagued with misnested HTML tags. Seriously. Just shy of 250,000 misnested pairs. </p>
<p>Here&#8217;s the pattern I came up with to fix it:</p>
<p>Find:</p>
<pre><code>&lt;(([^ &gt;]+)(?:[^&gt;]*))&gt;(.*)&lt;(([^ &gt;]+)(?:[^&gt;]*))&gt;(.*)&lt;/\2&gt;(.*)&lt;/\5&gt;</code></pre>
<p>Replace with:<br />
<code>&lt;$1&gt;$3&lt;$4&gt;$6&lt;/$5&gt;$7&lt;/$2&gt;</code><br />
or, depending on your regex engine, your replace string might look like this:<br />
<code>&lt;\1&gt;\3&lt;\4&gt;\6&lt;/\5&gt;\7&lt;/\2&gt;</code></p>
<p>That handles all of the following cases:</p>
<pre><code>&lt;b&gt;&lt;i&gt;text&lt;/b&gt;&lt;/i&gt;
&lt;b&gt;text&lt;i&gt;text&lt;/b&gt;text&lt;/i&gt;
&lt;b&gt;&lt;a href="#" target="_new"&gt;link&lt;/b&gt;text&lt;/a&gt;
&lt;a href="#"&gt;&lt;h2&gt;text&lt;/a&gt;&lt;/h2&gt;</code></pre>
<p>Running the final substitution was ridiculously fast, <a href="http://xkcd.com/208/">Regular Expressions are magic</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/1567/fixing-a-quarter-million-misnested-html-tags/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Django via CGI on shared hosting</title>
		<link>http://joemaller.com/1467/django-via-cgi-on-shared-hosting/</link>
		<comments>http://joemaller.com/1467/django-via-cgi-on-shared-hosting/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 03:40:33 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[shared hosting]]></category>

		<guid isPermaLink="false">http://joemaller.com/?p=1467</guid>
		<description><![CDATA[Django just isn&#8217;t designed to run under CGI. It won&#8217;t run under OS/2, either.* Well ok, but running Django under CGI is not impossible. It just kind of really sucks. But anyway, to prove it&#8217;s possible if not workable, here&#8217;s how I got it running on two standard cPanel shared hosts using plain old slow [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Django just isn&#8217;t designed to run under CGI.<br />
It won&#8217;t run under OS/2, either.<a href="http://code.djangoproject.com/ticket/2407#comment:21">*</a>
</p></blockquote>
<p>Well ok, but running Django under CGI is not <em>impossible</em>. It just kind of really sucks. But anyway, to prove it&#8217;s possible if not workable, here&#8217;s how I got it running on two standard cPanel shared hosts using plain old slow and clunky CGI.</p>
<h3> virtualenv</h3>
<p>First, install <a href="http://virtualenv.openplans.org/">virtualenv</a>. This makes locally managing modules fantastically easy by creating self-contained Python virtual environments. Installing couldn&#8217;t be simpler: Get the script, run the script, source your environment. </p>
<pre><code>$ mkdir ~/src &amp;&amp; cd ~/src
$ curl -LO http://bitbucket.org/ianb/virtualenv/get/tip.gz
$ tar -xvzf tip.gz
$ python virtualenv/virtualenv.py --distribute ~/python_virtualenv
<span class="output">New python executable in /home/joe/python_virtualenv/bin/python
Installing distribute.............................................
..................................................done.
</span>
$ source ~/python_virtualenv/bin/activate </code></pre>
<p>Now, install Django using <a href="http://pip.openplans.org/">pip</a>, which was automatically installed by virtualenv. After sourcing the virtual environment, this works from anywhere. </p>
<pre><code>$ pip install Django
<span class="output">Downloading/unpacking Django
  Downloading Django-1.1.1.tar.gz (5.6Mb): 5.6Mb downloaded
  Running setup.py egg_info for package Django
Installing collected packages: Django
  Running setup.py install for Django
    changing mode of build/scripts-2.4/django-admin.py from 664 to 775
    changing mode of /home/joe/python_virtualenv/bin/django-admin.py to 775
Successfully installed Django</span></code></pre>
<p>If your host doesn&#8217;t block GCC, use pip to be sure your MySQL interface (MySQLdb) is up to date:</p>
<pre><code>$ pip install -U MySQL-python
<span class="output">...
Successfully installed MySQL-python
</span></code></pre>
<p>Django requires MySQLdb version <a href='http://docs.djangoproject.com/en/dev/topics/install/#get-your-database-running'>1.2.1p2 or higher</a>.</p>
<p><a href="http://tools.assembla.com/yolk/">Yolk</a> prints a nice, clean list of everything installed in your Python environment, install and run:</p>
<pre><code>$ pip install yolk
$ yolk -l
<span class="output">
Django          - 1.1.1        - active
MySQL-python    - 1.2.3c1      - active
pip             - 0.6.1        - active
setuptools      - 0.6c11       - active
yolk            - 0.4.1        - active
</span></code></pre>
<p>At this point, I started a new Django project, assigned a database and filled in the necessary values in settings.py. I put the Django project files into the virtual environment to keep everything in the same place. This might not be the best practice, but it makes sense to me.</p>
<pre><code>$ cd ~/python_virtualenv/
$ django-admin.py startproject testproject</code></pre>
<p>The sane part is finished, now onto the kludgery.</p>
<h3>Django.cgi</h3>
<p>All the CGI shim solutions I found pointed back to a script Paul Sargent uploaded to ticket 2407 back in summer of 2006. It still works: <a href="http://code.djangoproject.com/attachment/ticket/2407/django.cgi">django.cgi</a></p>
<p>Three lines need editing:</p>
<p><strong>Line 1:</strong> Point the CGI&#8217;s shebang to the virtualenv Python binary.</p>
<pre><code>#!<strong>/home/joe/python_virtualenv/bin/python</strong></code></pre>
<p><strong>Line 95:</strong> Add the directory above the Django project directory to Python&#8217;s sys.path. </p>
<pre><code>sys.path.append("<strong>/home/joe/python_virtualenv</strong>")</code></pre>
<p><strong>Line 97:</strong> Add the project&#8217;s settings to os.environ.</p>
<pre><code>os.environ['DJANGO_SETTINGS_MODULE'] = '<strong>testproject.settings</strong>'</code></pre>
<h3>htaccess</h3>
<p>For Django to respond to URL requests, those urls need to be fed into the django.cgi script. For testing I routed everything from /django to the cgi script by adding the following lines to my top-level htaccess file:</p>
<pre><code>RewriteEngine on
RewriteRule ^cgi-bin/ - [L]
RewriteRule ^django/(.*)$ /cgi-bin/django.cgi/$1 [QSA,L]</code></pre>
<p>The second line isn&#8217;t necessary unless pulling Django urls from the webroot, without it, the redirects would loop.</p>
<p>At this point, the Django site should load from /django/&#8230; urls.</p>
<p>Finally, as a quick fix for admin media files, I symlinked Django&#8217;s admin media directory from my web root:</p>
<pre><code>ln -s ~/python_virtualenv/lib/python2.4/site-packages/django/contrib/admin/media ~/www/media</code></pre>
<h3>Conclusion</h3>
<p>I spent quite a few hours spread across a couple days researching and figuring out how to get the first install working. The second installation only took about 5 minutes from start until editing Django&#8217;s admin pages.</p>
<p>Running Django through CGI is possible, but it is <em>dog slow</em>. There appears to be some caching after the first request, but that first page load often takes an excruciatingly long time.</p>
<h3>Further reading, possible improvements</h3>
<ul>
<li><a href='http://docs.python.org/library/wsgiref.html'>21.4. wsgiref — WSGI Utilities and Reference Implementation — Python v2.6.4 documentation</a></li>
<li><a href='http://www.djangosnippets.org/snippets/1307/'>Django snippets: django under apache / mod_fcgid</a></li>
</ul>
<p>The servers I was working with are both running the almost six year old <a href="http://www.python.org/download/releases/2.4.3/NEWS.txt">Python 2.4.3</a>. The wsigref  module was introduced with Python 2.5. My goal was to get Django running without compiling anything since some hosts deny access to GCC.</p>
<h3>References</h3>
<p>These sites were helpful in figuring this out.
<ul>
<li><a href='http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/'>Notes on using pip and virtualenv with Django « SaltyCrane Blog </a></li>
<li><a href='http://jeffcroft.com/blog/2006/may/11/django-dreamhost/'>JeffCroft.com: Setting up Django on Dreamhost</a></li>
<li><a href='http://seamusc.com/blog/2007/jun/11/how-get-django-working-digiwebie-using-djangocgi/'>seamusc.com &#8211; How to get Django working on digiweb.ie using django.cgi</a></li>
<li><a href='https://www.lithiumhosting.com/billing/knowledgebase/18/How-to-install-Django-on-a-basic-shared-hosting-plan-with-plain-CGI.html'>Lithium Hosting &#8211; Knowledgebase &#8211; How to install Django on a basic shared hosting plan with plain CGI</a></li>
<li><a href='http://www.petersmith.org/blog/archives/2007/09/some-time-ago-i-played.html'>Django revisited &#8211; PeterSmith: Blog</a></li>
</ul>
<p>The two hosts I tested on were <a href="http://www.liquidweb.com/?RID=joemaller">LiquidWeb</a> and <a href="http://www.a2hosting.com/1482.html">A2Hosting</a>. Both have been excellent, dependable hosts. Neither has any Python support to speak of on their shared plans. A2 blocks access to GCC.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/1467/django-via-cgi-on-shared-hosting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to install Git on a shared host</title>
		<link>http://joemaller.com/908/how-to-install-git-on-a-shared-host/</link>
		<comments>http://joemaller.com/908/how-to-install-git-on-a-shared-host/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 01:45:00 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[shared host]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://joemaller.com/?p=908</guid>
		<description><![CDATA[(regularly updated) Installing Git on a shared hosting account is simple, the installation is fast and like most things Git, it just works. This is a basic install without documentation. My main goal is to be able to push changes from remote repositories into the hosted repository, which also serves as the source directory of [...]]]></description>
			<content:encoded><![CDATA[<p><em>(regularly updated)</em></p>
<p>Installing <a href="http://git-scm.com">Git</a> on a shared hosting account is simple, the installation is fast and like most things Git, it just works.</p>
<p>This is a basic install without documentation. My main goal is to be able to push changes from remote repositories into the hosted repository, which also serves as the source directory of the live website. <a href="http://joemaller.com/990/a-web-focused-git-workflow/">Like this</a>.</p>
<h3>Prerequisites</h3>
<p>The only two things you absolutely must have are shell access to the account and permission to use GCC on the server. Check both with the following command:</p>
<pre><code>$ ssh joe@webserver 'gcc --version'
<span class="output">gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-50)
[...]</span></code></pre>
<p>If GCC replies with a version number, you should be able to install Git. SSH into your server and let&#8217;s get started!</p>
<p>If you see something like <em>/usr/bin/gcc: Permission denied</em> you don&#8217;t have access to the GCC compiler and <strong>will not</strong> be able to build the Git binaries from source. <a href="#hosting">Find another hosting company</a>.</p>
<h3>Update your $PATH</h3>
<p>None of this will work if you don&#8217;t update the $PATH environment variable. In most cases, this is set in <strong>.bashrc</strong>. Using <strong>.bashrc</strong> instead of <strong>.bash_profile</strong> updates $PATH for interactive and non-interactive sessions&#8211;which is necessary for remote Git commands. Edit <strong>.bashrc</strong> and add the following line:</p>
<pre><code>export PATH=$HOME/bin:$PATH</code></pre>
<p>Be sure &#8216;~/bin&#8217; is at the beginning since $PATH is searched from left to right; to execute local binaries first, their location has to appear first. Depending on your server&#8217;s configuration there could be a lot of other stuff in there, including duplicates.</p>
<p>Double-check this by sourcing the file and echoing $PATH:</p>
<pre><code>$ source ~/.bashrc
$ echo $PATH
<span class="output">/home/joe/bin:/usr/local/bin:/bin:/usr/bin</span></code></pre>
<p>Verify that the remote path was updated by sending a remote command like this (from another connection):</p>
<pre><code>$ ssh joe@webserver 'echo $PATH'
<span class="output">/home/joe/bin:/usr/local/bin:/bin:/usr/bin</span></code></pre>
<p>Note: Previous iterations of this page installed into the ~/opt directory. Following current Git conventions, I&#8217;m now installing into the default <code>~/bin</code>.</p>
<h3>Installing Git</h3>
<p>SSH into your webserver. I created a source directory to hold the files and make cleanup easier:</p>
<pre><code>$ cd
$ mkdir src
$ cd src</code></pre>
<p>Grab the most recent source tarball from <a href="https://github.com/git/git/tags/">Github</a>. When this post was updated, the current Git release was version 1.7.10.1:</p>
<pre><code>$ curl -LO https://github.com/git/git/tarball/v1.7.10.1</code></pre>
<p>Untar the archive and cd into the new directory:</p>
<pre><code>$ tar -xzvf v1.7.10.1
$ cd git-git-9dfad1a</code></pre>
<p>By default, Git installs into <code>~/bin</code> which is perfect for shared hosting. Earlier versions required adding a prefix to the configure script (<a href="http://joemaller.com/881/how-to-install-subversion-on-a-shared-host/">like this</a>), but none of that is necessary anymore. If you do need to change the install location of Git, just specify a prefix to the Make command as described in Git&#8217;s INSTALL file.</p>
<p>With all that taken care of, installation is simple:</p>
<pre><code>$ make
$ make install
<span class="response">[lots of words...]</span></code></pre>
<p></code></pre>
<p>That should be it, check your installed version like this:</p>
<pre><code>$ git --version
<span class="response">git version 1.7.10.1</span></code></pre>
<p>It's now safe to delete the src folder containing the downloaded tarball and source files.</p>
<p><a name="hosting"></a>My preferred shared hosting providers are <a href="http://www.a2hosting.com/1482.html">A2 Hosting</a> and <a href="http://www.webfaction.com/signup?affiliate=joemaller">WebFaction</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/908/how-to-install-git-on-a-shared-host/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Tabbed clipboard to HTML Table</title>
		<link>http://joemaller.com/887/tabbed-clipboard-to-html-table/</link>
		<comments>http://joemaller.com/887/tabbed-clipboard-to-html-table/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 21:00:23 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[numbers]]></category>

		<guid isPermaLink="false">http://joemaller.com/2008/02/13/tabbed-clipboard-to-html-table/</guid>
		<description><![CDATA[I was looking for a quick way to get a structured table from some data I had in Numbers. Unfortunately Numbers isn&#8217;t scriptable and doesn&#8217;t seem to offer plain HTML export. After a little poking around, I just ended up writing a script to do what I wanted. This little AppleScript will convert anything text [...]]]></description>
			<content:encoded><![CDATA[<p>I was looking for a quick way to get a structured table from some data I had in <a href="http://www.apple.com/iwork/numbers/">Numbers</a>. Unfortunately Numbers isn&#8217;t scriptable and doesn&#8217;t seem to offer plain HTML export. After a little poking around, I just ended up writing a script to do what I wanted.</p>
<p>This little AppleScript will convert anything text in the clipboard into a simple, unstyled HTML table. <a href="applescript://com.apple.scripteditor?action=new&#038;script=%0Aset%20oldDelims%20to%20AppleScript%27s%20text%20item%20delimiters%0Aset%20AppleScript%27s%20text%20item%20delimiters%20to%20return%0Aset%20TRs%20to%20every%20text%20item%20of%20%28the%20clipboard%20as%20text%29%0A%0Aset%20AppleScript%27s%20text%20item%20delimiters%20to%20tab%0Aset%20theTable%20to%20%22%3Ctable%3E%22%20%26%20return%0A%0Arepeat%20with%20TR%20in%20TRs%0A%09copy%20theTable%20%26%20%22%3Ctr%3E%22%20%26%20return%20to%20theTable%0A%09repeat%20with%20TD%20in%20text%20items%20of%20TR%0A%09%09copy%20theTable%20%26%20%22%3Ctd%3E%22%20%26%20TD%20%26%20%22%3C%2Ftd%3E%22%20%26%20return%20to%20theTable%0A%09end%20repeat%0A%09copy%20theTable%20%26%20%22%3C%2Ftr%3E%22%20%26%20return%20to%20theTable%0Aend%20repeat%0A%0Acopy%20theTable%20%26%20%22%3C%2Ftable%3E%22%20to%20theTable%0A%0Aset%20AppleScript%27s%20text%20item%20delimiters%20to%20oldDelims%0A%0Aset%20the%20clipboard%20to%20theTable%0A%0A">View the script in Script Editor</a></p>
<p>Just save it into your Scripts folder and call it after copying some data to the clipboard. Any text on your clipboard will be converted to a basic, un-styled HTML table, ready to paste.</p>
<style type="text/css">
    p.p1 {margin: 0.0px 0.0px 0.0px 32.7px; text-indent: -32.8px; font: 10.0px Verdana; min-height: 12.0px}
    p.p2 {margin: 0.0px 0.0px 0.0px 34.7px; text-indent: -34.7px; font: 10.0px Verdana; color: #0000ff}
    p.p3 {margin: 0.0px 0.0px 0.0px 32.7px; text-indent: -32.8px; font: 12.0px Helvetica; min-height: 14.0px}
    p.p4 {margin: 0.0px 0.0px 0.0px 34.7px; text-indent: -34.7px; font: 10.0px Verdana}
    p.p5 {margin: 0.0px 0.0px 0.0px 56.0px; text-indent: -56.1px; font: 10.0px Verdana}
    p.p6 {margin: 0.0px 0.0px 0.0px 56.0px; text-indent: -56.1px; font: 10.0px Verdana; color: #0000ff}
    p.p7 {margin: 0.0px 0.0px 0.0px 84.1px; text-indent: -84.1px; font: 10.0px Verdana}
    p.p8 {margin: 0.0px 0.0px 0.0px 34.7px; text-indent: -34.7px; font: 12.0px Helvetica; min-height: 14.0px}
    span.s1 {font: 12.0px Helvetica; color: #000000}
    span.s2 {color: #408000}
    span.s3 {color: #000000}
    span.s4 {color: #0000ff}
    span.s5 {font: 12.0px Helvetica}
    span.Apple-tab-span {white-space:pre}
  </style>
<p class="p1"></p>
<p class="p2"><b>set</b><span class="s1"> </span><span class="s2">oldDelims</span><span class="s1"> </span><b>to</b><span class="s1"> </span>AppleScript<span class="s3">&#8216;s</span><span class="s1"> </span>text item delimiters</p>
<p class="p2"><b>set</b><span class="s1"> </span>AppleScript<span class="s3">&#8216;s</span><span class="s1"> </span>text item delimiters<span class="s1"> </span><b>to</b><span class="s1"> </span>return</p>
<p class="p2"><b>set</b><span class="s1"> </span><span class="s2">TRs</span><span class="s1"> </span><b>to</b><span class="s1"> </span><b>every</b><span class="s1"> </span>text item<span class="s1"> </span><b>of</b><span class="s1"> </span><span class="s3">(</span>the clipboard<span class="s1"> </span>as<span class="s1"> </span>text<span class="s3">)</span></p>
<p class="p3"></p>
<p class="p2"><b>set</b><span class="s1"> </span>AppleScript<span class="s3">&#8216;s</span><span class="s1"> </span>text item delimiters<span class="s1"> </span><b>to</b><span class="s1"> </span>tab</p>
<p class="p4"><span class="s4"><b>set</b></span><span class="s5"> </span><span class="s2">theTable</span><span class="s5"> </span><span class="s4"><b>to</b></span><span class="s5"> </span>&#8220;&lt;table&gt;&#8221;<span class="s5"> </span>&amp;<span class="s5"> </span><span class="s4">return</span></p>
<p class="p3"></p>
<p class="p2"><b>repeat</b><span class="s1"> </span><b>with</b><span class="s1"> </span><span class="s2">TR</span><span class="s1"> </span><b>in</b><span class="s1"> </span><span class="s2">TRs</span></p>
<p class="p5"><span class="s5"><span class="Apple-tab-span">	</span></span><span class="s4"><b>copy</b></span><span class="s5"> </span><span class="s2">theTable</span><span class="s5"> </span>&amp;<span class="s5"> </span>&#8220;&lt;tr&gt;&#8221;<span class="s5"> </span>&amp;<span class="s5"> </span><span class="s4">return</span><span class="s5"> </span><span class="s4"><b>to</b></span><span class="s5"> </span><span class="s2">theTable</span></p>
<p class="p6"><span class="s1"><span class="Apple-tab-span">	</span></span><b>repeat</b><span class="s1"> </span><b>with</b><span class="s1"> </span><span class="s2">TD</span><span class="s1"> </span><b>in</b><span class="s1"> </span>text items<span class="s1"> </span><b>of</b><span class="s1"> </span><span class="s2">TR</span></p>
<p class="p7"><span class="s5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span><span class="s4"><b>copy</b></span><span class="s5"> </span><span class="s2">theTable</span><span class="s5"> </span>&amp;<span class="s5"> </span>&#8220;&lt;td&gt;&#8221;<span class="s5"> </span>&amp;<span class="s5"> </span><span class="s2">TD</span><span class="s5"> </span>&amp;<span class="s5"> </span>&#8220;&lt;/td&gt;&#8221;<span class="s5"> </span>&amp;<span class="s5"> </span><span class="s4">return</span><span class="s5"> </span><span class="s4"><b>to</b></span><span class="s5"> </span><span class="s2">theTable</span></p>
<p class="p6"><span class="s1"><span class="Apple-tab-span">	</span></span><b>end</b><span class="s1"> </span><b>repeat</b></p>
<p class="p5"><span class="s5"><span class="Apple-tab-span">	</span></span><span class="s4"><b>copy</b></span><span class="s5"> </span><span class="s2">theTable</span><span class="s5"> </span>&amp;<span class="s5"> </span>&#8220;&lt;/tr&gt;&#8221;<span class="s5"> </span>&amp;<span class="s5"> </span><span class="s4">return</span><span class="s5"> </span><span class="s4"><b>to</b></span><span class="s5"> </span><span class="s2">theTable</span></p>
<p class="p2"><b>end</b><span class="s1"> </span><b>repeat</b></p>
<p class="p8"></p>
<p class="p4"><span class="s4"><b>copy</b></span><span class="s5"> </span><span class="s2">theTable</span><span class="s5"> </span>&amp;<span class="s5"> </span>&#8220;&lt;/table&gt;&#8221;<span class="s5"> </span><span class="s4"><b>to</b></span><span class="s5"> </span><span class="s2">theTable</span></p>
<p class="p8"></p>
<p class="p2"><b>set</b><span class="s1"> </span>AppleScript<span class="s3">&#8216;s</span><span class="s1"> </span>text item delimiters<span class="s1"> </span><b>to</b><span class="s1"> </span><span class="s2">oldDelims</span></p>
<p class="p8"></p>
<p class="p2">set the clipboard to<span class="s1"> </span><span class="s2">theTable</span></p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/887/tabbed-clipboard-to-html-table/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to install Subversion on a shared host</title>
		<link>http://joemaller.com/881/how-to-install-subversion-on-a-shared-host/</link>
		<comments>http://joemaller.com/881/how-to-install-subversion-on-a-shared-host/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 04:04:43 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[64 bit]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[liquidweb]]></category>
		<category><![CDATA[shared hosting]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[wget]]></category>

		<guid isPermaLink="false">http://joemaller.com/2008/01/29/how-to-install-subversion-on-a-shared-host/</guid>
		<description><![CDATA[I&#8217;ve hosted this site and several others LiquidWeb&#8217;s shared servers for probably eight years. They are without question, the most dependable host I&#8217;ve ever used. [see update] But LiquidWeb doesn&#8217;t offer Subversion. And I will no longer do web work without it. For some time I&#8217;d been considering leaving LiquidWeb because the lack of svn [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve hosted this site and several others <a href="http://www.liquidweb.com/">LiquidWeb&#8217;s shared servers</a> for probably eight years. They are without question, the most dependable host I&#8217;ve ever used. <em>[<a href="http://joemaller.com/881/how-to-install-subversion-on-a-shared-host/#lwupdate">see update</a>]</em></p>
<p>But LiquidWeb doesn&#8217;t offer <a href="http://subversion.tigris.org/">Subversion</a>. And I will no longer do web work without it.</p>
<p>For some time I&#8217;d been considering leaving LiquidWeb because the lack of svn was now hindering work on my own sites. For the same reason, I&#8217;ve had to pass them over several times when clients asked for hosting recommendations. Then the other night, I stumbled across a discussion about installing Subversion on a shared host. Why didn&#8217;t I  try that years ago? </p>
<p><span id="more-881"></span></p>
<h3>Installation Instructions</h3>
<p>These instructions assume basic proficiency with the Unix command line. Note that the goal is to install the SVN client, plan on hosting your repositories somewhere else.</p>
<p>Connect to  your account with ssh and create a working directory, mine&#8217;s called _src:</p>
<pre><code>cd
mkdir _src
cd _src</code></pre>
<p>Next, use <a href="http://linux.die.net/man/1/wget">wget</a> to pull down the subversion sources. You could also use curl, but wget does the same with less typing. Choose a version from this <a href="http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=260&#038;expandFolder=74">list of Subversion sources</a>. The parallel &#8220;subversion-deps&#8221; download includes all dependent sources required to build Subversion.</p>
<pre><code>wget http://subversion.tigris.org/downloads/subversion-1.4.6.tar.gz
wget http://subversion.tigris.org/downloads/subversion-deps-1.4.6.tar.gz</code></pre>
<p>Next, untar the sources and dive into the directory:</p>
<pre><code>tar -xzvf subversion-1.4.6.tar.gz
tar -xzvf subversion-deps-1.4.6.tar.gz
cd subversion-1.4.6</code></pre>
<h3>One step, maybe (32-bit?)</h3>
<p>At this point, depending on your server configuration, you might be able to install with the following two commands:</p>
<pre><code>./configure --prefix=$HOME --without-berkeley-db \
     --with-ssl --with-editor=/usr/bin/vim \
     --without-apxs --without-apache
make &amp;&amp; make install</code></pre>
<p>That worked on some servers but not others, I spent many hours clumsily trying to figure out why. I found that the build process was linking to external libraries instead of the ones in subversion-deps, despite the configure directives.</p>
<p>On the 64-bit server (x86_64) this was a big problem, even though everything worked normally on two 32-bit (i686/i386) servers.  Check server architecture with either <code>arch</code>, <code>uname -a</code> or <code>cat /proc/cpuinfo</code>. The solution for 64-bit machines is to build the three main components beforehand and then tell Subversion where to find them.</p>
<h3>Build them, use them  (64-bit?)</h3>
<p>The following commands systematically build each of the three shared libraries from the Subversion-deps sources. This should guarantee that the files Subversion links to will be compatible. In each step, we explicitly enable compilation of shared libraries and prefix the files into our home directory. This looks worse than it is.</p>
<p>Build <a href="http://apr.apache.org/">apr</a>, apr-util and <a href="http://www.webdav.org/neon/">neon</a>, in that order:</p>
<pre><code>cd apr
./configure --enable-shared --prefix=$HOME
make &amp;&amp; make install

cd ../apr-util
./configure --enable-shared --prefix=$HOME \
     --with-expat=builtin --with-apr=$HOME \
     --without-berkeley-db
make &amp;&amp; make install

cd ../neon
./configure --enable-shared --prefix=$HOME \
     --with-libs=$HOME --with-ssl
make &amp;&amp; make install</code></pre>
<p>With those out of the way, we can now configure and build Subversion. According to the notes in Subversion&#8217;s configure file, the <code>--with-ssl</code> flag is not necessary since it&#8217;s just passed to neon and we already built neon.  <code>--without-apxs</code> and <code>--without-apache</code> prevent Subversion from trying to install its Apache modules. Remember to point to the libraries we just built (in $HOME): (note: you may need to add the <code>--without-serf</code> flag as well, <a href="#comment-50835">see this comment</a>)</p>
<pre><code>cd ../
./configure --prefix=$HOME --without-berkeley-db \
     --with-editor=/usr/bin/vim --with-apr=$HOME \
     --with-apr-util=$HOME --with-neon=$HOME \
     --without-apxs --without-apache
make &amp;&amp; make install</code></pre>
<p>Subversion should now be installed! It&#8217;s likely you already have <code>:~/bin</code> in your user $PATH, if so, you can try it out right away:</p>
<pre><code>svn --version

   svn, version 1.4.6 (r28521)
      compiled Jan 29 2008, 11:05:47</code></pre>
<p>So far, I&#8217;ve run this against two LiquidWeb shared accounts, one LiquidWeb CPanel container on a VPS and a <a href="http://www.hostmatters.com/">HostingMatters</a> shared account running JailShell. After some limited testing accessing different repositories with https and svn+ssh, everything seems to be working.</p>
<p>Now I just need to figure out where to put my repositories, here are some free Subversion hosts I&#8217;ve used or are considering:</p>
<ul>
<li><a href="http://www.beanstalkapp.com/pricing.html">Beanstalk</a> 20 MB free</li>
<li><a href="http://www.assembla.com">Assembla</a> 500 MB free?! really?</li>
<li><a href='http://unfuddle.com/home'>Unfuddle</a> 15 MB free</li>
<li><a href="http://code.google.com/hosting/">Google Code</a> 100 MB free, must be open source</li>
</ul>
<p>Two other sites which aren&#8217;t free, but I&#8217;m keeping in mind for the future: <a href="http://wush.net/">Wush</a> and  <a href="http://www.projectlocker.com/scenario/startup">Project Locker</a>.</p>
<h3>The getting there was the hardest part</h3>
<p>While I was finally able to streamline this down to a fairly simple process, it was not easy to get there.  I don&#8217;t do much compiling from source, so I&#8217;m very clumsy about troubleshooting. If any of these steps can be simplified, please leave a note.</p>
<pre><code>Here are some of the errors I saw along the way:
/usr/lib/libexpat.so: could not read symbols: File in wrong format
/usr/lib/libexpat.so: could not read symbols: Invalid operation
/home/joe/_src/subversion-1.4.6/neon/src/.libs/libneon.a: could not read symbols: Bad value </code></pre>
<p>The first two errors indicate that the build had grabbed the 32-bit libexpat from /usr/lib instead of the 64-bit version from /usr/lib64. However, redirecting to the 64-bit libraries introduced other problems such as the libneon.a bad value error. As mentioned above, what I needed to do was pull libraries from the subverson-deps code. To use those, I needed to compile each one first. </p>
<h3>Resources:</h3>
<ul>
<li><a href="http://svn.collab.net/repos/svn/trunk/INSTALL">Subversion&#8217;s INSTALL file</a></li>
<li>./configure -help</li>
<li><a href="http://pastie.caboo.se/99618">These commands</a>, from <a href="http://forum.activereload.net/forums/8/topics/241#post_934">this original post</a> almost worked.</li>
<li><a href='http://www.apdz.com/phpbb/viewtopic.php?t=369&#038;;sid=cbd15a9447f96cf9eb5000c4efb1b167'>Installing Mephisto and Subversion on a Shared Host</a>, first inkling this was possible</li>
<li>similar problem with with <a href="http://svn.haxx.se/users/archive-2005-05/0284.shtml">/usr/lib instead of /usr/lib64.</a></li>
<li><a href="http://www.linuxquestions.org/questions/showthread.php?t=563541">GATTAGA&#8217;s post</a> was the first clue about working around the libexpat problem.</li>
<li><a href="http://www.svnforum.org/2017/viewtopic.php?t=1940&#038;;sid=1d48a79776ec72bfbb719b91beb274ba">SVNforum: libneon.a: could not read symbols: Bad value</a> This was the post that gave me the final bit of information I needed</li>
</ul>
<p><strong>Related:</strong> <a href="http://joemaller.com/2008/08/13/how-to-install-git-on-a-shared-host/">How to install Git on a shared host</a></p>
<p><strong id="lwupdate">Update, November 2010:</strong> Sometime this year Liquid Web disallowed compiler access.  I now host my sites at <a href="http://www.webfaction.com/signup?affiliate=joemaller">WebFaction</a> and <a href="http://www.a2hosting.com/1482.html">A2 Hosting</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/881/how-to-install-subversion-on-a-shared-host/feed/</wfw:commentRss>
		<slash:comments>58</slash:comments>
		</item>
		<item>
		<title>iTransmogrify update</title>
		<link>http://joemaller.com/879/itransmogrify-update/</link>
		<comments>http://joemaller.com/879/itransmogrify-update/#comments</comments>
		<pubDate>Wed, 23 Jan 2008 21:17:27 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[itransmogrify]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://joemaller.com/2008/01/23/itransmogrify-update/</guid>
		<description><![CDATA[The main iTransmogrify! script has been updated with a bunch of new functionality: YouTube.com pages are now supported (see notes) Daily Motion videos are supported for new-style urls (see notes) Kink.fm player and listings page are now supported Sideload.com play links are now supported WordPress Blogs using Viper Video QuickTags are supported for YouTube All [...]]]></description>
			<content:encoded><![CDATA[<p>The main <a href="http://itransmogrify.googlecode.com">iTransmogrify!</a> script has been updated with a bunch of new functionality:</p>
<ul>
<li>YouTube.com pages are now supported (see <a href="#notes">notes</a>)</li>
<li>Daily Motion videos are supported for new-style urls (see <a href="#notes">notes</a>)</li>
<li><a href="http://www.kink.fm">Kink.fm</a> player and listings page are now supported</li>
<li><a href="http://www.sideload.com">Sideload.com</a> play links are now supported</li>
<li>WordPress Blogs using <a href="http://wordpress.org/extend/plugins/vipers-video-quicktags">Viper Video QuickTags</a> are supported for YouTube</li>
<li>All media links now open into new windows, so you won&#8217;t have to re-transmogrify a page with several media files after playing one. Note that this is dependent on the iPhone, sometimes it will blank other windows)</li>
<li>Some content in iframes will now be converted.</li>
<li>MotionBox, Viddler and Vimeo embedded videos, while not supporting iPod/iPhone alternate content, now link to their respective detail pages.</li>
</ul>
<p>The main bookmarklet code was updated. This was necessary to workaround a <a href="http://joemaller.com/2008/01/22/itransmogrify-update-ready-but/">frustrating oversight with Google Code hosting</a>. Everyone will need to update their bookmarklet, in the future all updates will be automatic.</p>
<p>This has turned out to be far bigger than I ever imagined. Thank you to everyone for the links, feedback, compliments and ideas.</p>
<h3 id="known_issues">Known issues</h3>
<p>LiveJournal pages redefine a bunch of core JavaScript functionality, breaking all kinds of stuff including jQuery. Additionally, they&#8217;re serving media in an iframe from a different domain, meaning JavaScript couldn&#8217;t access the frame even if they hadn&#8217;t broken it.</p>
<h3 id="notes">Notes</h3>
<p><strong>YouTube Internal pages </strong ><br />
Because of a strange iPhone quirk, these links all need to go through the Google redirector, otherwise they bounce back to uk.youtube.com instead of playing.</p>
<p><strong>DailyMotion</strong><br />
DailyMotion videos using new-style urls, which are usually about six digits long, work correctly. Videos using the old-style alphanumeric ID do not work yet. I&#8217;m probably just going to resort to building a simple web-service to grab those. Additionally, there is no way to programatically access the mp4 alternate content url, so I just linked to their iPhone pages. I&#8217;d prefer embedding QuickTime directly, but it&#8217;s just not possible yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/879/itransmogrify-update/feed/</wfw:commentRss>
		<slash:comments>87</slash:comments>
		</item>
		<item>
		<title>iTransmogrify update ready, but&#8230;</title>
		<link>http://joemaller.com/880/itransmogrify-update-ready-but/</link>
		<comments>http://joemaller.com/880/itransmogrify-update-ready-but/#comments</comments>
		<pubDate>Tue, 22 Jan 2008 16:41:00 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[googlecode]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[itransmogrify]]></category>

		<guid isPermaLink="false">http://joemaller.com/2008/01/22/itransmogrify-update-ready-but/</guid>
		<description><![CDATA[So I&#8217;ve got a big update ready to go for iTransmogrify!. Except there&#8217;s a problem with Google Code. Google Code doesn&#8217;t allow downloads to be renamed or deleted after they&#8217;re 2 days old or have 50+ downloads. That nugget of critical information is buried deep in their FAQ. I posted this in Google Code Support, [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve got a big update ready to go for <a href="http://itransmogrify.googlecode.com">iTransmogrify!</a>. Except there&#8217;s a problem with Google Code.</p>
<p>Google Code doesn&#8217;t allow downloads to be renamed or deleted after they&#8217;re 2 days old or have 50+ downloads. That nugget of <em>critical</em> information is <a href="http://code.google.com/support/bin/answer.py?answer=56626&#038;topic=10456">buried deep in their FAQ</a>.</p>
<p>I posted this in Google Code Support, <strong><a href="http://groups.google.com/group/google-code-hosting/browse_thread/thread/f89cee035752a335">Rename or replace download</a></strong> and commented on issue 417, <strong><a href="http://code.google.com/p/support/issues/detail?id=417">Need a stable link to the latest version of a download</a></strong>. A &#8216;latest version&#8217; link on Google Code would solve this completely, but it&#8217;s been almost four months since they tagged the issue, so who knows when or if that feature will ever exist.</p>
<p>I&#8217;m not expecting any help from Google, so I&#8217;m considering the following two options:</p>
<ol>
<li>Link files directly from svn trunk.</li>
<li>Set up externally-hosted http redirect.</li>
</ol>
<p>Neither is ideal and both would require users to update their bookmarks or miss out on updates. Additionally the main script file would be outside of stats collection, so no one would know how many times iTransmogrify has been used, when I hit publish on this post, that number was just under 279,000 times.</p>
<h3>My solution</h3>
<p>After a day of thinking about it and discussing things with a few people, I&#8217;ve decided to go with a locally-hosted redirect for the main JavaScript file. Going forward I&#8217;ll just manually update the redirect to point to the latest version. This is an acceptable outcome for an imperfect situation.</p>
<p>The update will unfortunately require action on the users&#8217; part, something I had intended never to happen: <em>Users will need to update the bookmarklet.</em> From here forward, all updates will just happen, as I&#8217;d planned from the beginning.</p>
<p>Once this update is known to be working, I will modify the graphics seen by the old script file to announce the changes. Hopefully that last step will get most everyone moved to the newer bookmarklet.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/880/itransmogrify-update-ready-but/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>iTransmogrify!</title>
		<link>http://joemaller.com/873/itransmogrify/</link>
		<comments>http://joemaller.com/873/itransmogrify/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 05:43:10 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[itransmogrify]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://joemaller.com/2008/01/12/itransmogrify/</guid>
		<description><![CDATA[iTransmogrify! is a bookmarklet for iPhone which transforms embedded Flash content into direct links to natively supported formats. That means YouTube videos and MP3s can now be played from the iPhone&#8217;s Safari web browser with just a few clicks. Seeing it work is the best explanation: On an iPhone? Try it now: iTransmogrify! (works in [...]]]></description>
			<content:encoded><![CDATA[<div style="float:right"><script type="text/javascript">digg_url='http://digg.com/apple/iTransmogrify_embedded_Flash_converter_for_iPhone';</script><script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script></div>
<p>iTransmogrify! is a bookmarklet for iPhone which transforms embedded Flash content into direct links to natively supported formats. That means YouTube videos and MP3s can now be played from the iPhone&#8217;s Safari web browser with just a few clicks. </p>
<p>Seeing it work is the best explanation:</p>
<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/djkYrLoZBb0&#038;rel=1"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/djkYrLoZBb0&#038;rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p>
<p>On an iPhone? Try it now: <strong><a href="javascript:if%28typeof%28iTransmogrify%29%3D%3D%27undefined%27%29%7Bvar%20s%3Ddocument.createElement%28%27script%27%29%3Bs.src%3D%27http%3A%2F%2Fjoemaller.com%2FiTransmogrify-latest.js%3Fq%3D%27%2B%28new%20Date%29.getTime%28%29%3Bdocument.getElementsByTagName%28%27head%27%29%5B0%5D.appendChild%28s%29%7Dvoid%280%29">iTransmogrify!</a></strong> (works in Safari and Firefox too)</p>
<blockquote><p>Sorry, it took YouTube a long time to re-encode that for iPhone, here&#8217;s a baby panda:</p></blockquote>
<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/ysTmUTQ5wZE&#038;rel=1"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/ysTmUTQ5wZE&#038;rel=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p>
<h3>Installation</h3>
<p>To install the bookmarklet, just drag the link to your Safari or Firefox Bookmarks, IE users should right click and choose &#8220;Add To Favorites&#8230;&#8221; After adding the link, sync your iPhone. </p>
<p>Grab it now: <b><a href="javascript:if%28typeof%28iTransmogrify%29%3D%3D%27undefined%27%29%7Bvar%20s%3Ddocument.createElement%28%27script%27%29%3Bs.src%3D%27http%3A%2F%2Fjoemaller.com%2FiTransmogrify-latest.js%3Fq%3D%27%2B%28new%20Date%29.getTime%28%29%3Bdocument.getElementsByTagName%28%27head%27%29%5B0%5D.appendChild%28s%29%7Dvoid%280%29">iTransmogrify!</a></b></p>
<p>You can also <a href="http://joemaller.com/___?javascript:if%28typeof%28iTransmogrify%29%3D%3D%27undefined%27%29%7Bvar%20s%3Ddocument.createElement%28%27script%27%29%3Bs.src%3D%27http%3A%2F%2Fjoemaller.com%2FiTransmogrify-latest.js%3Fq%3D%27%2B%28new%20Date%29.getTime%28%29%3Bdocument.getElementsByTagName%28%27head%27%29%5B0%5D.appendChild%28s%29%7Dvoid%280%29">add iTransmogrify from your iPhone</a>!</p>
<p>More information, source code and bug-tracking is available on the <a href="http://itransmogrify.googlecode.com/">iTransmogrify Google Code page</a>.</p>
<ul>Currently supported content:</p>
<li>Default YouTube Object-Embed code</li>
<li>YouTube bare Embed</li>
<li>YouTube bare Object</li>
<li>A variety of Flash-based MP3 players including <a href="http://digg.com/podcasts">Digg Podcasts</a></li>
</ul>
<p><em>Lots more added: <a href='http://joemaller.com/2008/01/23/itransmogrify-update/'>iTransmogrify update</a></em></p>
<p>Support for other embedded media sites will be added as I figure them out. Please report broken sites or suggest additional sources using <a href="http://code.google.com/p/itransmogrify/issues/list">Google Code issue tracker</a>.</p>
<h3>Acknowledgements</h3>
<p>The first robust, script insertion bookmarklets I ever saw was Sumaato&#8217;s original <a href="http://sumaato.typolis.net/stories/4323/">Flickr GeoCoding bookmarklet</a>.</p>
<p>Other sites also deserving links:
<ul>
<li>Jan Wolter&#8217;s <a href='http://unixpapa.com/js/dyna.html'>Dynamic Script Loading</a></li>
<li>Andrew Sumin&#8217;s <a href="http://jsx.ru/Texts/ModulesInJS/indexeng.html">Modularity in JavaScript</a></li>
<li>Mike West&#8217;s <a href='http://www.digital-web.com/articles/scope_in_javascript'>Scope in JavaScript</a> was the refresher I needed to resolve one especially annoying object-scope bug.</li>
</ul>
<p>iPhone graphic reference: </p>
<ul>
<li><a href='http://www.hackthatphone.com/112/iphone_graphics_locations.html'>iPhone Graphics locations</a></li>
<li><a href='http://www.flickr.com/photos/34818713@N00/sets/72157601845495751/'>Huge iPhone icons</a></li>
</ul>
<p>Also, John Resig&#8217;s amazing <a href="http://jquery.com/">jQuery JavaScript library</a>. This project was the excuse I&#8217;d been looking for to finally dig in and learn it. </p>
<p>The name came from a late-night brainstorming chat with <a href="http://movielibrary.lynda.com/authors/author/?aid=1">Bruce</a> and was far more fun and interesting than the utilitarian ones I was thinking of. So thank you Bruce, and of course,  Bill Watterson.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemaller.com/873/itransmogrify/feed/</wfw:commentRss>
		<slash:comments>306</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced
Database Caching 4/11 queries in 0.008 seconds using disk: basic
Object Caching 618/627 objects using disk: basic

Served from: joemaller.com @ 2012-05-23 06:41:03 -->
