<?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>W-Shadow.com &#187; Programming</title>
	<atom:link href="http://w-shadow.com/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://w-shadow.com</link>
	<description>Slightly Advanced Computer Stuff (and some magic)</description>
	<lastBuildDate>Thu, 02 Sep 2010 11:04:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Automatic Updates For Private And Commercial Plugins</title>
		<link>http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/</link>
		<comments>http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 11:04:00 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[automatic updates]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[update notifications]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress plugins]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=2045</guid>
		<description><![CDATA[Since time immemorial, only plugins hosted in the official WordPress.org plugin directory have supported automatic updates. Now, I&#8217;ve written a PHP library that you can use to add automatic update capabilities to any plugin. Public, private and commercial plugins alike &#8211; all can now enjoy the benefits of automatic update notifications and one-click upgrades. The [...]]]></description>
			<content:encoded><![CDATA[<p>Since <abbr title="December 10th, 2008 - WordPress 2.7">time immemorial</abbr>, only plugins hosted in the official WordPress.org plugin directory have supported automatic updates. Now, I&#8217;ve written a PHP library that you can use to add automatic update capabilities to any plugin. Public, private and commercial plugins alike &#8211; all can now enjoy the benefits of automatic update notifications and one-click upgrades.</p>
<p>The custom update checker integrates closely with the upgrade system already built into WordPress, producing a seamless user experience. Observe : </p>
<div id="attachment_2064" class="wp-caption aligncenter" style="width: 500px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; display: block; margin-right: auto; margin-left: auto;"><a href="http://w-shadow.com/wp-content/uploads/2010/09/external-upgrade-notice.png"><img src="http://w-shadow.com/wp-content/uploads/2010/09/external-upgrade-notice-490x56.png" alt="" title="Upgrade notice generated by an external plugin update" width="490" height="56" class="size-large wp-image-2064" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">An upgrade notice for a privately hosted plugin.</p></div>
<div id="attachment_2065" class="wp-caption aligncenter" style="width: 500px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; display: block; margin-right: auto; margin-left: auto;"><a href="http://w-shadow.com/wp-content/uploads/2010/09/external-update-plugin-information.png"><img src="http://w-shadow.com/wp-content/uploads/2010/09/external-update-plugin-information-490x290.png" alt="" title="The &quot;Plugin Information&quot; window with placeholder data" width="490" height="290" class="size-large wp-image-2065" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">The 'Plugin Information' window with placeholder data.</p></div>
<p><em>(Excuse my marketing-speak. It&#8217;s a thing. On with the practicalities of the matter.)</em></p>
<h3>Download</h3>
<ul>
<li><strong><a href="http://w-shadow.com/files/plugin-updates.zip">Client library</a></strong> (requires PHP5 and WP 2.8 or later)</li>
<li><strong><a href="http://w-shadow.com/files/external-update-example/external-update-example.zip">Example plugin</a></strong></li>
<li><strong><a href="http://w-shadow.com/files/external-update-example/info.json">Example metadata file</a></strong></li>
</ul>
<h3>Quick-start Guide</h3>
<p>This section describes the quickest way to get automatic updates working for your plugin. Here&#8217;s what you&#8217;ll need to do: create a metadata file for your plugin, host it somewhere publicly accessible, and tell the update checker where to find it.</p>
<p>Lets start with the metadata. Copy the <a href="http://www.json.org/">JSON</a> code below into a new file and replace the placeholder values with your plugin&#8217;s info.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;name&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;My Cool Plugin&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;slug&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;my-cool-plugin&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;download_url&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://example.com/plugins/my-cool-plugin.zip&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;version&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;2.0&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;author&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;John Smith&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;sections&quot;</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;description&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Plugin description here. Basic HTML allowed.&quot;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>(This is the <em>minimal</em> amount data required to make automatic updates work. In most cases, you will probably want to add a couple more fields. See the metadata docs below for details.)</p>
<p>Most of the fields should be pretty self-explanatory, with one possible exception &#8211; the &#8220;slug&#8221;. WordPress expects all plugins that support automatic updates to have a unique textual identifier called the &#8220;slug&#8221;. Normally, slugs are assigned by the official plugin directory. For a private/commercial plugin that&#8217;s hosted elsewhere you&#8217;ll have to make something up. If unsure, just use the plugin&#8217;s file name without the &#8220;.php&#8221; extension (my-cool-plugin/my-cool-plugin.php becomes my-cool-plugin).</p>
<p>Upload the metadata file you just created to your web server. It doesn&#8217;t matter where exactly you put the file or how you name it. The important thing is for its URL to be accessible from wherever someone might install your plugin.</p>
<p>Next, copy the &#8220;update-checker&#8221; directory from the <a href="http://w-shadow.com/files/plugin-updates.zip">client library archive</a> to your plugin&#8217;s directory. Then fire up your favourite code editor and add the following lines to the top of your plugin file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'plugin-updates/plugin-update-checker.php'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$MyUpdateChecker</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PluginUpdateChecker<span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'http://example.com/path/to/metadata.json'</span><span style="color: #339933;">,</span>
    <span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'your-chosen-slug'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>(If you followed my advice and used the plugin&#8217;s file name as the slug, you can omit the third parameter of the PluginUpdateChecker constructor.)</p>
<p>And that, believe it or not, is it. </p>
<p>The PluginUpdateChecker class will handle the rest. It&#8217;ll check the metadata file every 12 hours and, if it discovers that a new version has been released, twiddle the right bits in the undocumented WP API to make it show up as a standard upgrade notification in the &#8220;Plugins&#8221; tab. Assuming you&#8217;ve set up the download_url correctly, users will be able to install the update with a single click.</p>
<p>The rest of this post will be devoted to a more in-depth discussion of the update checker class and the metadata format.</p>
<h3>The PluginUpdateChecker class</h3>
<p>This class is the core of the update checker. It&#8217;s also the only part of the updater that you should need to deal with unless you decide to  extend the library yourself.</p>
<p><strong>Class constructor</strong></p>
<p>All configuration settings should be specified by passing them to the PluginUpdateChecker constructor. It takes the following parameters :</p>
<ul>
<li><code>$metadataUrl</code> &#8211; The full URL of the plugin&#8217;s metadata file.</li>
<li><code>$pluginFile</code> &#8211; The fully qualified path to the plugin file. In most cases you can simply use the __FILE__ constant here.</li>
<li><code>$slug</code> &#8211; The plugin&#8217;s &#8216;slug&#8217;. If not specified, the filename part of $pluginFile (sans &#8220;.php&#8221;) will be used as the slug.</li>
<li><code>$checkPeriod</code> &#8211; How often to check for updates (in hours). Defaults to checking every 12 hours. Set to zero to disable automatic update checks.</li>
<li><code>$optionName</code> &#8211; Where to store book-keeping info about updates. Defaults to &#8220;external_updates-$slug&#8221;.</li>
</ul>
<p><strong>checkForUpdates()</strong></p>
<p>Manually trigger an update check. This is especially useful when you&#8217;ve disabled automatic checks by setting $checkPeriod (above) to zero. This method takes no parameters and returns nothing.</p>
<p><strong>addQueryArgFilter($callback)</strong></p>
<p>Register a callback for filtering query arguments. Whenever the update checker needs to retrieve the metadata file, it will first run each filter callback and attach the query arguments that they return to the metadata URL. This lets you pass arbitrary data to the server hosting the metadata. For example, commercial plugins could use it to implement some kind of authorization scheme where only users that have the right &#8220;key&#8221; get automatic updates.</p>
<p>The callback function will be passed an associative array of query arguments and should return a modified array. By default, the update checker will add these arguments to the metadata URL:</p>
<ul>
<li><code>installed_version</code> &#8211; set to the currently installed version of the plugin.</li>
<li><code>checking_for_updates</code> &#8211; set to 1 if checking for updates, absent otherwise (i.e. when loading data for the &#8220;Plugin Information&#8221; box).</li>
</ul>
<p>This method takes one parameter &#8211; the callback function.</p>
<p><strong>addHttpRequestArgFilter($callback)</strong></p>
<p>Register a callback for filtering the various options passed to the built-in helper function <a href="http://codex.wordpress.org/HTTP_API#Helper_Functions">wp_remote_get</a> that the update checker uses to periodically download plugin metadata. The callback function should take one argument &#8211; an associative array of arguments &#8211; and return a modified array or arguments. See the WP documentation on wp_remote_get for details about what arguments are available and how they work.</p>
<p>This method takes one parameter &#8211; the callback function.</p>
<p><strong>addResultFilter($callback)</strong></p>
<p>Register a callback for filtering plugin info retrieved from the metadata URL.</p>
<p>The callback function should take two arguments. If the metadata was retrieved successfully, the first argument passed will be an instance of  PluginInfo (see the source for a description of this class). Otherwise, it will be NULL. The second argument will be the corresponding return value of wp_remote_get (see WP docs for details). The callback function should return a new or modified instance of PluginInfo or NULL.</p>
<p>This method takes one parameter &#8211; the callback function.</p>
<h3>Metadata format</h3>
<p>The automatic update system uses a JSON-based file format to describe plugins.  Essentially, the entire file is one big JSON-encoded object (<em>AKA</em> hash-table or associative array). Each field &#8211; or array key &#8211; represents a piece of information about the latest version of the plugin. <a href="https://spreadsheets.google.com/pub?key=0AqP80E74YcUWdEdETXZLcXhjd2w0cHMwX2U1eDlWTHc&amp;authkey=CK7h9toK&amp;hl=en&amp;single=true&amp;gid=0&amp;output=html">The full description of all available fields is here.</a></p>
<p>For the sake of simplicity, both general metadata and update-related information are stored in the same file. If this is undesirable, you can replace the plain JSON file with a script that checks for the presence of the the &#8220;checking_for_updates&#8221; query parameter and emits just the update-related fields if its set to &#8220;1&#8243;.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/09/02/automatic-updates-for-any-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Towards a Better dbDelta</title>
		<link>http://w-shadow.com/blog/2010/07/29/towards-a-better-dbdelta/</link>
		<comments>http://w-shadow.com/blog/2010/07/29/towards-a-better-dbdelta/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 14:17:27 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[database schema]]></category>
		<category><![CDATA[dbDelta]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[php classes]]></category>
		<category><![CDATA[table diff]]></category>
		<category><![CDATA[update tables]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1954</guid>
		<description><![CDATA[When it comes to creating and updating database tables, WordPress has what appears to be a very handy utility function &#8211; dbDelta. In theory, this function can take one or more CREATE TABLE queries, compare them to the tables already in the database and automatically figure out how to bring them up to date, adding [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to creating and updating database tables, WordPress has what appears to be a very handy utility function &#8211; <a href="http://codex.wordpress.org/Creating_Tables_with_Plugins#Creating_or_Updating_the_Table">dbDelta</a>. In theory, this function can take one or more CREATE TABLE queries, compare them to the tables already in the database and automatically figure out how to bring them up to date, adding or modifying columns and indexes as necessary.</p>
<p>In practice, <code>dbDelta</code> is fragile, undocumented and prone to fail silently when something goes wrong. It can only parse queries tailored to its idiosyncratic requirements, doesn&#8217;t know how to drop obsolete columns, isn&#8217;t aware of character sets and collation, chokes on extra whitespace&#8230; Nasty, but evidently <em>Good Enough™ </em> for most plugins, even for WordPress itself. It&#8217;s still better than doing schema updates manually, and in most cases you can work around the limitations.</p>
<p>Then again, sometimes you can&#8217;t. Just a few days ago I ran into a situation that <code>dbDelta</code> just couldn&#8217;t handle (due to the aforementioned lack of collation awareness). This prompted me to refactor dbDelta into something more flexible. The result was the <code>blcTableDelta</code> class &#8211; still somewhat finicky with regards to query syntax, but much more flexible otherwise. </p>
<p>In the remainder of this post discuss how my version compares to the built-in dbDelta function, explain how to use it, and provide the source code.</p>
<h3>Advantages</h3>
<p>My version of dbDelta is by no means perfect &#8211; or, for that matter, even particularly <em>good</em>. That would require implementing a full-blown SQL parser, which is clearly overkill for a utility function that gets called only once or twice per install. Instead, it&#8217;s just <em>Better Enough<em>™</em></em>. Here&#8217;s how blcTableDelta fares when compared to dbDelta :</p>
<ul>
<li>More lenient with whitespace &#8211; no more ridiculous requirements like &#8220;there must be exactly two spaces between the words PRIMARY KEY and the definition of your primary key&#8221;.</li>
<li>Detects changes not just in column data type, but also in collation settings and NULL/NOT NULL/AUTO INCREMENT flags.</li>
<li>Can optionally remove obsolete columns and indexes.</li>
<li>Returns a complete query log, including execution status and any MySQL error messages.</li>
<li>Doesn&#8217;t choke on &#8220;IF NOT EXISTS&#8221;.</li>
<li>Has slightly better documentation.</li>
</ul>
<p>The downside is that this class isn&#8217;t nearly as battle-tested as the native dbDelta function. It also doesn&#8217;t support INSERT queries.</p>
<h3>Usage</h3>
<p>Here&#8217;s a simple example of how to use the <code>blcTableDelta</code> class :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Define the table structure you want to achieve.</span>
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000cc; font-style: italic;">&lt;&lt;&lt;EOM
prefix}example_table` (
	`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
	`name` varchar(100) NOT NULL DEFAULT '',
	`another_field` text  COLLATE latin1_general_cs    not null,
&nbsp;
	PRIMARY    KEY   ( `id` ),
	INDEX named_index(name)
);
EOM</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Call the static delta() method</span>
<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$messages</span><span style="color: #339933;">,</span> <span style="color: #000088;">$query_log</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> blcTableDelta<span style="color: #339933;">::</span><span style="color: #004000;">delta</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Output the execution log</span>
<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$messages</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query_log</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The static delta() method can take up to four arguments :</p>
<ul>
<li><strong>$queries </strong>- a string containing one or more CREATE TABLE queries, separated by semicolons.</li>
<li><strong>$execute</strong> &#8211; whether to apply the required schema changes (True) or just return the generated queries (False). Defaults to executing the queries right away.</li>
<li><strong>$drop_columns</strong> &#8211; whether to remove columns that are present in the current table but not in the corresponding CREATE TABLE query (True), or leave them alone (False). Defaults to removing the columns.</li>
<li><strong>$drop_indexes</strong> &#8211; same as the previous argument, except for indexes.</li>
</ul>
<p>The function returns an array with two elements. The first element is a list of human-readable messages explaining what schema changes would need to be performed to update the database. The second returned value is the query log. Each item of the query log array is also an array, with up to three keys :</p>
<ul>
<li><strong>&#8220;query&#8221;</strong> &#8211; the generated SQL query.</li>
<li><strong>&#8220;success&#8221;</strong> &#8211; a True/False flag indicating whether the query was executed successfully. Present only if the $execute argument was set to True.</li>
<li><strong>&#8220;error_message&#8221; </strong> &#8211; the MySQL error that occurred when executing the query. Only meaningful when &#8220;success&#8221; = False.</li>
</ul>
<h3>Source Code</h3>
<p>The source code is too long to include in the post, so I&#8217;ve placed it in a separate .zip archive. <a href="http://w-shadow.com/files/db-upgrade.zip">Download it here.</a> Just place the .php file found therein somewhere inside your plugin&#8217;s directory and <code>include</code> it before calling <code>blcTableDelta::delta</code>.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/07/29/towards-a-better-dbdelta/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Pure CSS Perversion</title>
		<link>http://w-shadow.com/blog/2010/06/16/pure-css-perversion/</link>
		<comments>http://w-shadow.com/blog/2010/06/16/pure-css-perversion/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 16:47:44 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[CSS hack]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[image converter]]></category>
		<category><![CDATA[image handling]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[pure CSS image]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1876</guid>
		<description><![CDATA[Sometimes it seems that not a month goes by without another &#8220;Pure CSS Something&#8221; project. Most recently, it was the Pure CSS Twitter &#8220;Fail Whale&#8221; page that has been making the rounds on Twitter and social news sites for the last few days. Before that, we had the Opera logo made in CSS, and many, [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes it seems that not a month goes by without another <em>&#8220;Pure CSS Something&#8221;</em> project. Most recently, it was the <a href="http://www.subcide.com/experiments/fail-whale/">Pure CSS Twitter &#8220;Fail Whale&#8221;</a> page that has been making the rounds on Twitter and social news sites for the last few days. Before that, we had the <a href="http://desandro.com/articles/opera-logo-css/">Opera logo made in CSS</a>, and many, many others.</p>
<p>It got me wondering &#8211; could one write a program that converts <em>any</em> image into pure CSS &amp; HTML?</p>
<p>As it turns out, <a href="http://elliottback.com/wp/convert-image-to-css/">that&#8217;s already been done</a>. However, I was pretty sure it could be done <em>better</em> &#8211; despite limiting the maximum output resolution to 100&#215;100, the CSS/HTML code produced by the aforementioned converter was truly humongous. Surely I could improve on that. Thus I went ahead and wrote my own image to CSS converter anyway.</p>
<p>The result, lovingly code-named &#8220;Pure CSS Perversion&#8221;, produces remarkably space-efficient* HTML and CSS code for a wide range of input images. You can <a href="http://w-shadow.com/css-anything/">try it out here</a>. </p>
<p><em>*Only in the context of image-to-CSS conversion. It&#8217;s laughably inefficient when compared to most image file formats.</em></p>
<h3>Awesome Features</h3>
<ul>
<li><strong>Highly perverse HTML/CSS coding</strong><br />
Almost as space-efficient as storing your images in uncompressed bitmaps!</li>
<li><strong>Glorious 256 color palette<br />
</strong>Evokes fond memories of DOS and VGA.<strong><br />
</strong></li>
<li><strong>Dithering support<br />
</strong>Greatly improves image quality with only an enormous increase in file size.<strong><br />
</strong></li>
<li><strong>Cross-browser compatibility</strong><br />
Tested in Firefox 3.6, Opera 10.53, Chrome 6.0, and even Internet Explorer 8.</li>
<li><strong>Supports JPG, PNG and GIF<br />
</strong>Also supports PCX, ARJ and ponies. Okay, not really.</li>
</ul>
<h3>Examples</h3>
<p>Click a screenshot to go to the corresponding converter results page.</p>
<p><a href="http://w-shadow.com/css-anything/process.php?url=http%3A%2F%2Fw-shadow.com%2Fcss-anything%2Fexamples%2FMona_Lisa.jpg&amp;submit=Go&amp;max_width=300&amp;max_height=270&amp;max_colors=256&amp;box_size=1&amp;rle=50"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1880" title="Pure CSS Mona Lisa" src="http://w-shadow.com/wp-content/uploads/2010/06/converted-image-2.png" alt="" width="298" height="425" /></a></p>
<h3><a href="http://w-shadow.com/css-anything/process.php?url=http%3A%2F%2Fw-shadow.com%2Fcss-anything%2Fexamples%2F%2527Recycle%25202%2527%2520by%2520jaylopez%2520%2528sxc.hu%2529.jpg&amp;submit=Go&amp;max_width=300&amp;max_height=250&amp;max_colors=256&amp;box_size=1&amp;rle=50&amp;dither=on"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1879" title="Pure CSS &quot;Recycle&quot; tag" src="http://w-shadow.com/wp-content/uploads/2010/06/converted-image-1.png" alt="" width="319" height="375" /></a></h3>
<h3><a href="http://w-shadow.com/css-anything/process.php?url=http%3A%2F%2Fw-shadow.com%2Fcss-anything%2Fexamples%2FCornell_box.png&amp;max_width=300&amp;max_height=300&amp;max_colors=256&amp;box_size=auto&amp;rle=50&amp;dither=0"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-full wp-image-1878" title="Some boxes?... But hey, it's pure CSS and HTML!" src="http://w-shadow.com/wp-content/uploads/2010/06/converted-image-3.png" alt="" width="326" height="455" /></a></h3>
<p>You can find more examples on the <a href="http://w-shadow.com/css-anything/">converter&#8217;s homepage</a>.</p>
<h3>Descent Into Optimization</h3>
<p>For those interested in such things, here is a detailed explanation of how the converter works, including a tedious step-by-step account of how I arrived to the current algorithm. You can also <a href="http://w-shadow.com/files/css-anything.rar">download the source code</a>.</p>
<p><strong>1. Starting Simple</strong><br />
The simplest way to encode an image as HTML/CSS is to convert each image pixel to a separate &lt;div&gt; element 1&#215;1 pixels in size and use an inline style attribute set the div&#8217;s background color to that of the pixel. Example :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;css-image&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;row&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;background: #abcdef; width: 1px; height: 1px;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;background: #abcdef; width: 1px; height: 1px;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #808080; font-style: italic;">&lt;!-- more pixels --&gt;</span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;row&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;background: #abcdef; width: 1px; height: 1px;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;background: #abcdef; width: 1px; height: 1px;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #808080; font-style: italic;">&lt;!-- more pixels --&gt;</span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #808080; font-style: italic;">&lt;!-- more rows/scanlines --&gt;</span></pre></div></div>

<p>This produces good-looking results, but the amount of HTML code quickly balloons out of control. Even a modest 200&#215;200 picture would result take up over 1 MB when encoded in this way, which is wasteful and can even crash some browsers.</p>
<p><strong>2. Palletise and Cassify</strong><br />
The easiest way to reduce the file size of the &#8220;pure CSS&#8221; image is to convert it to a palette-based format and create a new CSS class for each palette color. This is what my first version of the image-to-CSS converter did.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
div { width: 1px; height: 1px; float: left; }
.color1 { background: #abcdef; }
.color2 { background: #f00000; }
/*....*/
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;color1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;color2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>As you can see, I&#8217;ve also moved the rules that apply to all DIVs to a separate CSS block.</p>
<p><strong>3. Run-Length Encoding</strong><br />
To further reduce the code size, we can detect continuous runs of the same color and encode each of them using only a single, wider &lt;div&gt;. To avoid explicitly writing out the width of each element, lets generate CSS classes for widths :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
.width2 { width: 2px; }
.width3 { width: 3px; }
.width4 { width: 4px; }
.width5 { width: 5px; }
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
...
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;color1 width3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>All &lt;div&gt;&#8217;s have a 1-pixel width by default, so we don&#8217;t need a &#8220;width1&#8243; class.</p>
<p><strong>4. Shorter Class Names</strong><br />
All those &#8220;colorA&#8221; and &#8220;widthB&#8221; class names are wastefully long. Lets shorten them to a single-letter prefix and a hex-encoded index.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
.c1 { background: #abcdef; }
.c2 { background: #f00000; }
/* ... */
.w9 { width: 9px; }
.wa { width: 10px; }
.wb { width: 11px; }
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c2a wf&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c2 wa2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>...</pre></div></div>

<p><strong>5. Default Colors</strong><br />
We can squeeze out a few more bytes by determining the color that&#8217;s most frequently used in a given row and adding it as the background color to the container element. Then we can omit the color class from those elements that match the most common color.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><span style="color: #808080; font-style: italic;">&lt;!-- matches the row's background color --&gt;</span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>6. Perversion Begins</strong><br />
Hmm, look at all those byte-hogging &lt;div&gt; elements &#8211; each eating up 3 bytes on tag name alone. Plus, we&#8217;re forced to waste another 6 bytes on the completely useless closing tag! That will not do. </p>
<p>Luckily, the closing tags are optional for &lt;p&gt; and &lt;li&gt; elements. We can rework our HTML structure to make use of this.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;css-image&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c1 w2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;cba w5&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #808080; font-style: italic;">&lt;!-- more pixels --&gt;</span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c1 w2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;c3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;cba w5&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #808080; font-style: italic;">&lt;!-- more pixels --&gt;</span>
&nbsp;
   <span style="color: #808080; font-style: italic;">&lt;!-- more rows --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>7. Going Classless</strong><br />
We&#8217;re also wasting 5 bytes/div on the &#8220;class&#8221; attribute, so lets get rid of it and use custom attributes instead.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
p[c=&quot;1&quot;],li[c=&quot;1&quot;]{ background: #abcdef; }
p[c=&quot;2&quot;],li[c=&quot;2&quot;]{ background: #f00000; }
/*...*/
p[w=&quot;9&quot;]{ width: 9px; }
p[w=&quot;a&quot;]{ width: 10px; }
p[w=&quot;b&quot;]{ width: 11px; }
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/stlye<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #808080; font-style: italic;">&lt;!-- ... --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">c</span>=<span style="color: #ff0000;">&quot;1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">c</span>=<span style="color: #ff0000;">&quot;16&quot;</span> <span style="color: #000066;">w</span>=<span style="color: #ff0000;">&quot;5&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> <span style="color: #000066;">c</span>=<span style="color: #ff0000;">&quot;ab&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></div></div>

<p>It may not validate, but it works. Who cares about validation anyway? <img src='http://w-shadow.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>8. Even More Perversion</strong><br />
Well, that&#8217;s probably the limit of size optimization. We need to specify the background color and width <em>somehow</em>, so we can&#8217;t completely eliminate the attributes. We could remove the quotes from attribute values and format our output like &#8220;&lt;p c=1 w=ab&gt;&#8221;, but that&#8217;s it. Right?</p>
<p>Actually, there <em>is</em> a way to compress the output even more. We can use the attribute name itself to specify pixel color and width. Observe :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
p[c1],li[c1]{ background: #abcdef; }
p[c2],li[c2]{ background: #f00000; }
/*...*/
p[w9]{ width: 9px; }
p[wa]{ width: 10px; }
p[wb]{ width: 11px; }
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/stlye<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #808080; font-style: italic;">&lt;!-- ... --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> c1<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> c16 w5<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> cab<span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></div></div>

<p>Yes, that actually works. It even works in Internet Explorer 8 (when in standards mode).</p>
<p><strong>9. Huffman And Friends</strong><br />
In any given image, some colors are more common than others. For example, a picture of a lush countryside might have a lot of greens, whereas a beach photo would be predominantly blue and yellow. Our current algorithm is not aware of that &#8211; it simply enumerates all colors in sequential order, assigning attribute names as it goes. There&#8217;s no relation between the color and the codename it gets.</p>
<p>We can reduce output size by assigning shorter attribute names to more common colors. This is known as <a href="http://en.wikipedia.org/wiki/Huffman_coding">Huffman coding</a>, and is one of the simplest algorithms used for lossless data compression.</p>
<p>The general idea is thus : </p>
<ul>
<li>Iterate over the image and record how many times each color is seen.</li>
<li>Sort the list of colors by their frequency.</li>
<li>Assign shorter names to more common colors, longer ones to rare ones.</li>
</ul>
<p>In fact, we can use this idea to eliminate the color vs. width attribute distinction completely. Lets look at our HTML stucture again :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p</span> c1<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> c16 w5<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> cab<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> ce2<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> c1 w12<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #808080; font-style: italic;">&lt;!-- ... --&gt;</span></pre></div></div>

<p>If we forget the &#8220;&lt;p &#8230;&gt;&#8221; wrappers for a moment&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">c1 c16 w5 cab ce2 c1 w12</pre></div></div>

<p>&#8230;it&#8217;s just a string of codes! Some more common, some less. We don&#8217;t need to know what each of them means to assign a optimally short and unique name to each one.</p>
<p>The actual implementation is somewhat complicated, but the HTML/CSS it produces is very space-efficient. This is what the output of my final algorithm looks like (line breaks inserted for clarity) :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
p[a]{width:6px;}
p[b],li[b]{background:#dfdbda;}
p[c]{width:9px;}
p[d],li[d]{background:#dfe3e8;}
p[e],li[e]{background:#d4d5dc;}
/*...*/
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #808080; font-style: italic;">&lt;!-- ... --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;css-image&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;li</span> y<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> d f<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> b c<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> d a<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> b xb<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> o<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> b _g<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> e<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;p</span> b l<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #808080; font-style: italic;">&lt;!-- etc --&gt;</span></pre></div></div>

<h3>Improve On <em>That</em></h3>
<p>Unbelievable though it may seem, this is <em>still</em> not the limit of size optimization for &#8220;pure CSS&#8221; images. For example, you could use variable-width right and left borders on the &lt;p&gt; element to encode additional pixels in a single element. This would decrease the HTML size at least by another 20%. You could also replace the primitive RLE algorithm I used in my converter with something more advanced. There might also be some interesting HTML hacks I haven&#8217;t even thought about.</p>
<p>I&#8217;ll leave that as an exercise to the reader <img src='http://w-shadow.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/06/16/pure-css-perversion/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Showing Different Ads To Different Visitors</title>
		<link>http://w-shadow.com/blog/2010/03/09/showing-different-ads-to-different-visitors/</link>
		<comments>http://w-shadow.com/blog/2010/03/09/showing-different-ads-to-different-visitors/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 16:38:42 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[a/b testing]]></category>
		<category><![CDATA[adsense]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Making Money]]></category>
		<category><![CDATA[online advertising]]></category>
		<category><![CDATA[referrer]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1740</guid>
		<description><![CDATA[Just today, I decided to run an impromptu experiment to test if visitors who come from search engines are really more likely to click on ads. It&#8217;s considered  &#8221;common knowledge&#8221; by many bloggers who advise everyone to only show ads to search engine visitors (as a quick Google search will illustrate), but my own AdSense [...]]]></description>
			<content:encoded><![CDATA[<p>Just today, I decided to run an impromptu experiment to test if visitors who come from search engines are really more likely to click on ads. It&#8217;s considered  &#8221;common knowledge&#8221; by many bloggers who advise everyone to only show ads to search engine visitors (as a <a href="http://www.google.com/search?q=show+ads+search+engine+visitors">quick Google search</a> will illustrate), but my own AdSense stats made me doubt that particular piece of advice. Hence the experiment.</p>
<p>So how does one show different ads to different visitors? Normally you could use the excellent <a href="http://planetozh.com/blog/my-projects/wordpress-plugin-who-sees-ads-control-adsense-display/">Who Sees Ads</a> plugin, but that doesn&#8217;t work for my site. I&#8217;m using the <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP-SuperCache</a> caching plugin which is incompatible with Who Sees Ads.</p>
<p>Instead, I wrote a JavaScript function that can analyse the HTTP referrer to distinguish between four types of visitors :</p>
<ul>
<li>People who accessed your page directly, e.g. by typing in the URL (no referrer).</li>
<li>People who clicked an internal link to access the page (referrer from the same domain).</li>
<li>Search engine visitors; people who arrived via Google or Yahoo! (referrer matches one of the most popular search engines).</li>
<li>External visitors. This is basically a catch-all category for everyone who found your link on a third-party site that&#8217;s not a search engine. For example, this would include external forums and web directories.</li>
</ul>
<p>Here&#8217;s the script :</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> get_referrer_type<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> ref <span style="color: #339933;">=</span> document.<span style="color: #660066;">referrer</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> ref.<span style="color: #660066;">length</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">function</span> getHostname<span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> re <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^(?:f|ht)tp(?:s)?\:\/\/([^\/]+)/im</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> matches <span style="color: #339933;">=</span> str.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span> re <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> matches <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">return</span> matches<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> getHostname<span style="color: #009900;">&#40;</span>ref<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> document.<span style="color: #660066;">location</span>.<span style="color: #660066;">host</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'internal'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> SE <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'/search?'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'.google.'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'web.info.com'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'search.'</span><span style="color: #339933;">,</span> 
		<span style="color: #3366CC;">'del.icio.us/search'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'soso.com'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'/search/'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'.yahoo.'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'.ask.'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> source <span style="color: #000066; font-weight: bold;">in</span> SE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ref.<span style="color: #660066;">indexOf</span><span style="color: #009900;">&#40;</span>SE<span style="color: #009900;">&#91;</span>source<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'search'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'external'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The function <code>get_referrer_type()</code> returns one of &#8220;none&#8221;, &#8220;internal&#8221;, &#8220;search&#8221; or &#8220;external&#8221; based on the referrer info.</p>
<p>And here&#8217;s the script that I used to show different  AdSense ads to different people :</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> get_top_adsense_ad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> default_slot <span style="color: #339933;">=</span> <span style="color: #3366CC;">'1111111111'</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> code <span style="color: #339933;">=</span> <span style="color: #3366CC;">'&lt;'</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'script type=&quot;text/javascript&quot;&gt;&lt;!--<span style="color: #000099; font-weight: bold;">\n</span>google_ad_client = &quot;pub-0000000000000000&quot;;google_ad_slot = &quot;%ad_slot%&quot;;google_ad_width = 336;google_ad_height = 280;<span style="color: #000099; font-weight: bold;">\n</span>//--&gt;&lt;'</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'/script&gt;&lt;'</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;&lt;/'</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'script&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> slots <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #3366CC;">'none'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'2222222222'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'internal'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'3333333333'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'external'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'4444444444'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'search'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'5555555555'</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> ref_type <span style="color: #339933;">=</span> get_referrer_type<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>slots<span style="color: #009900;">&#91;</span>ref_type<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		code <span style="color: #339933;">=</span> code.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'%ad_slot%'</span><span style="color: #339933;">,</span> slots<span style="color: #009900;">&#91;</span>ref_type<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
		code <span style="color: #339933;">=</span> code.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'%ad_slot%'</span><span style="color: #339933;">,</span> default_slot<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">return</span> code<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span>get_top_adsense_ad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Unlike <code>get_referrer_type()</code>, this script is optimized for my site/AdSense account. Don&#8217;t try using it without modification <img src='http://w-shadow.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  If you want to use it, replace &#8220;pub-XXXXXXXX&#8221;, the ad slot IDs and ad width/height settings with your own values (you can find them in your AdSense ad code).</p>
<p>As for the experiment, I&#8217;ll post the results sometime next week.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/03/09/showing-different-ads-to-different-visitors/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>12 Invisible But Invaluable jQuery Plugins</title>
		<link>http://w-shadow.com/blog/2010/03/05/12-invisible-but-invaluable-jquery-plugins/</link>
		<comments>http://w-shadow.com/blog/2010/03/05/12-invisible-but-invaluable-jquery-plugins/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 20:28:02 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[jQuery plugins]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[keyboard shortcuts]]></category>
		<category><![CDATA[lists]]></category>
		<category><![CDATA[mouse wheel]]></category>
		<category><![CDATA[utilities]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1729</guid>
		<description><![CDATA[Not all jQuery plugins are about UI and eye-candy. There&#8217;s also a class of plugins that aim to make web development itself easier, either by acting as convenient wrappers around hard-to-use JavaScript functionality, simplifying cross-browser compatibility, or providing small but useful utilities and APIs. Below you&#8217;ll find a list of 12 great utility-style jQuery plugins. [...]]]></description>
			<content:encoded><![CDATA[<p>Not all jQuery plugins are about UI and eye-candy. There&#8217;s also a class of plugins that aim to make web development itself easier, either by acting as convenient wrappers around hard-to-use JavaScript functionality, simplifying cross-browser compatibility, or providing small but useful utilities and APIs.</p>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1734" title="JQuery logo" src="http://w-shadow.com/wp-content/uploads/2010/03/JQuery_logo_color_onwhite-200.png" alt="" width="200" height="49" />Below you&#8217;ll find a list of 12 great utility-style jQuery plugins. While invisible to the user, they can be invaluable to the developer.</p>
<h3>1. <a href="http://code.google.com/p/js-hotkeys/">Hotkeys</a></h3>
<p>The <a href="http://code.google.com/p/js-hotkeys/">HotKeys plugin</a> makes it very easy to hook almost any key or key combination. Great for adding keyboard shortcuts to your web-app.</p>
<h3>2. <a href="http://brandonaaron.net/code/mousewheel/docs">Mouse Wheel</a></h3>
<p>Detect when the user scrolls the <a href="http://brandonaaron.net/code/mousewheel/docs">mouse wheel</a>. Note : In theory, the plugin supports all major browsers. However, the current version may report inconsistent scroll deltas in different browsers.</p>
<h3>3. <a href="http://www.fyneworks.com/jquery/xml-to-json/">XML to JSON</a></h3>
<p><a href="http://www.fyneworks.com/jquery/xml-to-json/">XML to JSON</a> lets you convert XML documents to JSON. Handy if you find plain JS objects easier to use than the XML DOM, or if you&#8217;re building a mashup with heterogeneous data coming in from a bunch of APIs and you want to convert it all to JSON for simplicity.</p>
<h3>4. <a href="http://projects.allmarkedup.com/jquery_url_parser/">URL Parser</a></h3>
<p><a href="http://projects.allmarkedup.com/jquery_url_parser/">jQuery URL parser</a> processes URLs and provides you with easy access to info about their components &#8211; the protocol, host, path, query string, and so on. On top of that, it also has some neat extra features, like the ability access query parameter values by parameter name.</p>
<h3>5. <a href="http://www.malsup.com/jquery/taconite/">Taconite</a></h3>
<p>With <a href="http://www.malsup.com/jquery/taconite/">Taconite</a>, you can update multiple DOM elements with a single AJAX request. This can considerably simplify your client-side code and helps cut down on bandwidth use.</p>
<h3>6. <a href="http://www.protofunc.com/scripts/jquery/ajaxManager3/">AJAX Manager</a></h3>
<p>Queue, order, abort, block, cache and otherwise manipulate your AJAX requests with the <a href="http://www.protofunc.com/scripts/jquery/ajaxManager3/">AJAX manager</a> plugin.</p>
<h3>7. <a href="http://www.pengoworks.com/workshop/jquery/calculation/calculation.plugin.htm">Calculation</a></h3>
<p>The <a href="http://www.pengoworks.com/workshop/jquery/calculation/calculation.plugin.htm">jQuery Calculation Plugin</a> lets you extract numeric data from HTML elements and apply a number of common mathematical operations to the results. It includes typical aggregation functions like sum(), avg(), min() and max() and also lets you define your own equations.</p>
<h3>8. <a href="http://stackoverflow.com/questions/1809275/suppress-jquery-event-handling-temporarily/1810532#1810532">Freeze/Unfreeze Events</a></h3>
<p><a href="http://stackoverflow.com/questions/1809275/suppress-jquery-event-handling-temporarily/1810532#1810532">This mini-plugin</a> can be used to temporarily stop all jQuery events assigned to a specific element (or a group of elements) from firing.</p>
<h3>9. <a href="http://plugins.jquery.com/project/cookie">Cookie </a><a href="http://code.google.com/p/cookies/">Handling</a></h3>
<p>When it comes to cookies, there are <em>two</em> jQuery plugins that stand out :</p>
<ul>
<li><a href="http://plugins.jquery.com/project/cookie">Cookie</a> is simple and light-weight. Just the bare essentials  &#8211; you can read/write/delete cookies, and that&#8217;s it.</li>
<li><a href="http://code.google.com/p/cookies/">Cookies</a> is the advanced option. It can filter cookies using regexps, test if the browser is set to accept cookies, bind DOM element contents to cookies, and do automatic JSON serialization.</li>
</ul>
<h3>10. <a href="http://plugins.jquery.com/project/metadata">Metadata</a></h3>
<p>The <a href="http://plugins.jquery.com/project/metadata">Metadata</a> plugin provides a unified way to extract different formats of metadata from the DOM. It can extract metadata from classes, attributes, child elements or HTML5 data- attributes.</p>
<h3>11. <a href="http://www.asual.com/jquery/address/">Navigation History For AJAX Pages</a></h3>
<p>Add the coveted back-button support to your AJAX apps with the powerful <a href="http://www.asual.com/jquery/address/">Address</a> plugin. There&#8217;s a number of other plugins that deal with #anchor-based navigation, but <a href="http://www.asual.com/jquery/address/">Address</a> is a clear winner &#8211; it has the cleanest API and the best documentation.</p>
<h3>12. <a href="http://plugins.jquery.com/project/timers">Timers</a></h3>
<p><a href="http://plugins.jquery.com/project/timers">jQuery Timers</a> provides a more elegant, jQuery-flavoured way to deal with setTimetout() and setInterval(). You can apply timers to DOM elements, set the number of times a given timer will execute, create named timers, and more.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/03/05/12-invisible-but-invaluable-jquery-plugins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making The Web More Readable For Everyone</title>
		<link>http://w-shadow.com/blog/2010/01/18/making-the-web-more-readable-for-everyone/</link>
		<comments>http://w-shadow.com/blog/2010/01/18/making-the-web-more-readable-for-everyone/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 17:59:19 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[News and Rants]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bookmarklet]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[readability]]></category>
		<category><![CDATA[reddit]]></category>
		<category><![CDATA[web page layout]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1612</guid>
		<description><![CDATA[In a recent Reddit thread, one commenter made a casual remark : There needs to be a way to link to a page on Reddit and automatically apply Readability. That seemed like an excellent idea to me. In case you haven&#8217;t heard about it yet, Readability is a bookmarklet that can take an article or [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent Reddit thread, one commenter made a casual remark :</p>
<blockquote><p>There needs to be a way to link to a page on Reddit and automatically apply <a href="http://lab.arc90.com/experiments/readability/">Readability</a>.</p></blockquote>
<p>That seemed like an excellent idea to me. In case you haven&#8217;t heard about it yet, <a href="http://lab.arc90.com/experiments/readability/">Readability</a> is a bookmarklet that can take an article or blog post with even the most cluttered, ad-infested and eye-bleedingly ugly design and turn it into a clean and readable work of art. As a side-effect, it also removes most kinds of ads.</p>
<p>Of course, you could just install the bookmarklet for your own use and have that be the end of it. But if you regularly share links to interesting articles with friends, or post them to social bookmarking sites, it would sure be handy to have a way give others the benefit of Readability without forcing them to install anything.</p>
<p>So I went ahead and created a website that lets you do just that &#8211; <a href="http://makereadable.com/">MakeReadable.com</a>. Go <a href="http://makereadable.com/">check it out</a>.</p>
<p>Here&#8217;s how to use it :</p>
<ol>
<li>Enter a URL of the page  that you want to make more readable. Pages with lots of text &#8211; like news articles or blog posts &#8211; work best.</li>
<li>Click the &#8220;Make Readable&#8221; button (or press Enter).</li>
<li>Wait a few seconds while the server processes the page and redirects you to a new URL that already has Readability applied.</li>
<li>Share the URL of the new page with your friends, etc.</li>
</ol>
<p>An even easier way to use this service is to simply append the URL of the page you want processed after <code>http://makereadable.com/</code>, like this :</p>
<p><code>http://makereadable.com/example.com/someblog/article-123.htm</code></p>
<p>Behind the scenes, <a href="http://makereadable.com/">MakeReadable.com</a> also performs several other optimizations, like normalizing the HTML and stripping out all other scripts and most CSS. Since Readability completely restyles the page anyway, this post-processing makes the resulting page smaller and faster-loading (in theory) without hurting its looks.</p>
<p>Thoughts? Feature suggestions? Leave a comment below.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/01/18/making-the-web-more-readable-for-everyone/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>15+ Useful Firefox Addons For Web Developers</title>
		<link>http://w-shadow.com/blog/2009/11/27/15-useful-firefox-addons-for-web-developers/</link>
		<comments>http://w-shadow.com/blog/2009/11/27/15-useful-firefox-addons-for-web-developers/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 17:08:07 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[firefox addon]]></category>
		<category><![CDATA[firefox extension]]></category>
		<category><![CDATA[lists]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1479</guid>
		<description><![CDATA[Everyone already knows and loves Firebug and Web Developer. So instead of another redundant &#8220;Top 10&#8243; list, here&#8217;s a collection of 15+ great add-ons that you might not have heard about yet. Dust-Me Selectors Dust-Me Selectors helps you find unused CSS selectors. You can use it to test an individual page, or let it spider [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone already knows and loves <a href="http://getfirebug.com/">Firebug</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/60">Web Developer</a>. So instead of another redundant &#8220;Top 10&#8243; list, here&#8217;s a collection of 15+ great add-ons that you might not have heard about yet.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/5392">Dust-Me Selectors</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/5392"><img class="size-full wp-image-1496 alignnone" title="Dust-Me Selectors" src="http://w-shadow.com/wp-content/uploads/2009/11/Dust-Me-Selectors.png" alt="Dust-Me Selectors" width="401" height="211" /></a></p>
<p>Dust-Me Selectors helps you find unused CSS selectors. You can use it to test an individual page, or let it spider your entire site. Results are presented in a nice color-coded report and can be exported as CSV.</p>
<p><em>Alternative</em> :  <a href="https://addons.mozilla.org/en-US/firefox/addon/10704">CSS Usage</a></p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/9641">Inline Code Finder for Firebug</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/9641"><img class="size-full wp-image-1498 alignnone" title="Inline Code Finder" src="http://w-shadow.com/wp-content/uploads/2009/11/Inline-Code-Finder2.jpg" alt="Inline Code Finder" width="500" height="200" /></a></p>
<p>Finds and highlights HTML elements with suspicious hacks like inline JavaScript events, inline styles and javascript: links. It also presents a summary report and calculates an overall score based on how many such elements were encountered on the page.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/1985">Window Resizer</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/1985"><img class="alignnone size-full wp-image-1508" title="Window Resizer" src="http://w-shadow.com/wp-content/uploads/2009/11/Window-Resizer-ready.png" alt="Window Resizer" width="517" height="197" /></a></p>
<p>Lets you quickly resize your browser window to a number of common screen sizes so that you can see how you page would look at a different display resolution.</p>
<p><em>Alternative</em> : <a href="https://addons.mozilla.org/en-US/firefox/addon/5792">FireSizer</a></p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/9780">RESTClient</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/9780"><img class="alignnone size-full wp-image-1507" title="RESTClient" src="http://w-shadow.com/wp-content/uploads/2009/11/RESTClient-ready.png" alt="RESTClient" width="400" height="293" /></a></p>
<p>RESTClient is a very handy tool for web service developers, allowing you to directly test and analyze RESTful APIs. It also includes partial support for the WebDAV protocol.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/10869">JSONView</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/10869"><img class="alignnone size-full wp-image-1506" title="JSONView" src="http://w-shadow.com/wp-content/uploads/2009/11/JSONView-ready.png" alt="JSONView-ready" width="290" height="278" /></a></p>
<p>Lets you view JSON data directly in the browser and supports syntax highlighting and code folding. Overall, it&#8217;s another simple yet useful extension for developers working with WEB APIs.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/1595">Remove Cookie(s) for Site</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/1595"><img class="alignnone size-full wp-image-1482" title="Remove Cookie(s)" src="http://w-shadow.com/wp-content/uploads/2009/11/Remove-Cookies.png" alt="Remove Cookie(s)" width="320" height="280" /></a></p>
<p>Remove all cookies from the current site with a single click. If you need something more advanced, check out the alternatives below.</p>
<p><em>Alternatives</em> : <a href="https://addons.mozilla.org/en-US/firefox/addon/573">Add N Edit Cookies</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/6683">FireCookie</a></p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/3255">CookieSwap</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/3255"><img class="alignnone size-full wp-image-1501" title="CookieSwap" src="http://w-shadow.com/wp-content/uploads/2009/11/CookieSwap-ready.png" alt="CookieSwap" width="276" height="192" /></a></p>
<p>Lets you quickly swap all your cookies so that you can easily switch between different user accounts without logging in/out all the time. While this add-on is primarily advertised as a way to manage multiple webmail/Amazon/Google accounts, it can also be useful to web developers &#8211; e.g. for testing how your site behaves from the point of view of normal visitors vs. logged-in users, or users with different privilege levels.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/966">TamperData</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/966"><img class="alignnone size-full wp-image-1483" title="TamperData" src="http://w-shadow.com/wp-content/uploads/2009/11/TamperData.png" alt="TamperData" width="500" height="220" /></a></p>
<p>With TamperData, you can intercept HTTP(S) requests made by Firefox and view/modify their headers and POST data. All requests are logged and can also be exported as XML or displayed on a graph. Handy for security testing and catching certain breeds of elusive server-side bugs.</p>
<p><em>Alternatives</em> : <a href="https://addons.mozilla.org/en-US/firefox/addon/967">Modify Header</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/1290">UrlParams</a></p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/2214">View Dependencies</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/2214"><img class="alignnone size-full wp-image-1502" title="View Dependencies" src="http://w-shadow.com/wp-content/uploads/2009/11/View-Dependencies-ready-2.png" alt="View Dependencies" width="538" height="323" /></a></p>
<p>Essentially a simpler alternative to <a href="https://addons.mozilla.org/firefox/addon/5369">YSlow</a>, View Dependencies adds a new tab to the <em>Page Info</em> window, listing all the files that were loaded to display the current page.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/3899">HackBar</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/3899"><img class="alignnone size-full wp-image-1504" title="HackBar" src="http://w-shadow.com/wp-content/uploads/2009/11/HackBar-screenshot-ready.png" alt="HackBar" width="490" height="228" /></a></p>
<p>HackBar is a large collection of simple penetration testing tools, useful for security-auditing your site and testing it for common vulnerabilities. You can convert strings to hex and back, encrypt text with SHA-1, SHA-256 or ROT13 (if only just for fun), try a number of typical SQL injection/XSS tricks, manipulate POST data, spoof the referer, and much more.</p>
<p><em>Related</em> : <a href="https://addons.mozilla.org/en-US/firefox/addon/7595">Access Me</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/7598">XSS Me</a></p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/3863">iMacros for Firefox</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/3863"><img class="alignnone size-full wp-image-1486" title="iMacros" src="http://w-shadow.com/wp-content/uploads/2009/11/iMacros.png" alt="iMacros" width="519" height="211" /></a></p>
<p>&#8220;Whatever you do with Firefox, iMacros can automate it.&#8221; It can automatically fill forms, download &amp; upload files, scrape web pages, memorize passwords, and so on. iMacros really makes tasks like web application testing, data mining and mashup creation much easier.</p>
<h3><a href="http://mingyi.org/T2F3/">TableTools</a></h3>
<p><a href="http://mingyi.org/T2F3/"><img class="alignnone size-full wp-image-1487" title="TableTools" src="http://w-shadow.com/wp-content/uploads/2009/11/TableTools.png" alt="TableTools" width="487" height="161" /></a></p>
<p>Sort, filter or copy any HTML table. You can filter each column either by selecting a value from a drop-down menu or by searching for a specific keyword (regular expressions are also supported). TableTools will automatically recognize frequently used data types like numbers, timestamps and IP addresses, and sort/filter them intelligently.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/5817">SQLite Manager</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/5817"><img class="alignnone size-full wp-image-1489" title="SQLite Manager" src="http://w-shadow.com/wp-content/uploads/2009/11/SQLite-Manager.png" alt="SQLite Manager" width="400" height="232" /></a></p>
<p>Manage any SQLite database on your computer. This add-on has all the features you would expect from a full-featured DB manager &#8211; you can view the database structure, create, modify and search tables and views, manage indexes, export and import data, and manipulate pretty much any other aspect of the database.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/8487">Pencil</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/8487"><img class="alignnone size-full wp-image-1490" title="Pencil" src="http://w-shadow.com/wp-content/uploads/2009/11/Pencil.jpg" alt="Pencil" width="329" height="250" /></a></p>
<p>Make diagrams, build GUI prototypes and sketch website mockups with this awesome Firefox add-on!</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/14465">Flashbug</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/14465"><img class="alignnone size-full wp-image-1493" title="Flashbug" src="http://w-shadow.com/wp-content/uploads/2009/11/Flashbug-ready-2.png" alt="Flashbug" width="489" height="205" /></a></p>
<p>A Firebug extension that logs all the SWF trace output to the Firebug console. Can be invaluable for debugging Flash-based applications and games.</p>
<h3><a href="https://addons.mozilla.org/en-US/firefox/addon/11090">FireLogger</a></h3>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/11090"><img class="alignnone size-full wp-image-1494" title="FireLogger" src="http://w-shadow.com/wp-content/uploads/2009/11/FireLogger-ready-1.png" alt="FireLogger" width="500" height="198" /></a></p>
<p>Debug your server-side Python and PHP code from within the browser. After installing this Firebug extension and the appropriate Python/PHP library, you will be able to send logging information from your server-side scripts directly to the FireBug console.</p>
<p><em>Alternative</em> : <a href="https://addons.mozilla.org/en-US/firefox/addon/6149">FirePHP</a></p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/11/27/15-useful-firefox-addons-for-web-developers/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How To Extract HTML Tags And Their Attributes With PHP</title>
		<link>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/</link>
		<comments>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 14:35:03 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[extract attributes]]></category>
		<category><![CDATA[extract tags]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP script]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1375</guid>
		<description><![CDATA[There are several ways to extract specific tags from an HTML document. The one that most people will think of first is probably regular expressions. However, this is not always &#8211; or, as some would insist, ever &#8211; the best approach. Regular expressions can be handy for small hacks, but using a real HTML parser [...]]]></description>
			<content:encoded><![CDATA[<p>There are several ways to extract specific tags from an HTML document. The one that most people will think of first is probably regular expressions. However, this is not always &#8211; or, as some would insist, <em>ever</em> &#8211; the best approach. Regular expressions can be handy for small hacks, but using a real HTML parser will usually lead to simpler and more robust code. Complex queries, like &#8220;find all rows with the class .foo of the second table of this document and return all links contained in those rows&#8221;, can also be done much easier with a decent parser.</p>
<p>There are <em>some</em> (though very few they may be) edge case where regular expressions might work better, so I will discuss both approaches in this post.</p>
<h3>Extracting Tags With DOM</h3>
<p>PHP 5 comes with a usable <a href="http://php.net/manual/en/book.dom.php">DOM API</a> built-in that you can use to parse and manipulate (X)HTML documents. For example, here&#8217;s how you could use it to extract all link URLs from a HTML file :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Load the HTML page</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page.htm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Create a new DOM document</span>
<span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Parse the HTML. The @ is used to suppress any parsing errors</span>
<span style="color: #666666; font-style: italic;">//that will be thrown if the $html string isn't valid XHTML.</span>
<span style="color: #339933;">@</span><span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadHTML</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Get all links. You could also use any other tag name here,</span>
<span style="color: #666666; font-style: italic;">//like 'img' or 'table', to extract other tags.</span>
<span style="color: #000088;">$links</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Iterate over the extracted links and display their URLs</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$links</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//Extract and show the &quot;href&quot; attribute. </span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In addition to <code>getElementsByTagName()</code> you can also use <code>$dom-&gt;getElementById()</code> to find tags with a specific id. For more complex tasks, like extracting deeply nested tags, <a href="http://www.php.net/manual/en/class.domxpath.php">XPath</a> is probably the way to go. For example, to find all list items with the class &#8220;foo&#8221; containing links with the class &#8220;bar&#8221; and display the link URLs :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Load the HTML page</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page.htm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Parse it. Here we use loadHTML as a static method</span>
<span style="color: #666666; font-style: italic;">//to parse the HTML and create the DOM object in one go.</span>
<span style="color: #339933;">@</span><span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> DOMDocument<span style="color: #339933;">::</span><span style="color: #004000;">loadHTML</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Init the XPath object</span>
<span style="color: #000088;">$xpath</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMXpath<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Query the DOM</span>
<span style="color: #000088;">$links</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'//li[contains(@class, &quot;foo&quot;)]//a[@class = &quot;bar&quot;]'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Display the results as in the previous example</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$links</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>For more information about DOM and XPath see these resources : </p>
<ul>
<li><a href="http://www.php.net/manual/en/book.dom.php">DOM API documentation</a></li>
<li><a href="http://www.w3schools.com/Xpath/">W3Schools XPath tutorial</a></li>
<li><a href="http://www.w3.org/TR/xpath">XPath language specification</a></li>
</ul>
<p>Honourable mention : <a href="http://simplehtmldom.sourceforge.net/">Simple HTML DOM Parser</a> is a popular alternative HTML parser for PHP 5 that lets you manipulate HTML pages with jQuery-like ease. However, I personally wouldn&#8217;t recommend using it if you care about your script&#8217;s performance, as in my tests Simple HTML DOM was about 30 times slower than DOMDocument.</p>
<h3>Extracting Tags &#038; Attributes With Regular Expressions</h3>
<p>There are only two advantages to processing HTML with regular expressions &#8211; availability and edge-case performance. While most parsers require PHP 5 or later, regular expressions are available pretty much anywhere. Also, they are a little bit faster than real parsers when you need to extract something from a <em>very</em> large document (on the order of 400 KB or more). Still, in most cases you&#8217;re better off using the PHP DOM extension or even Simple HTML DOM, not messing with convoluted regexps.</p>
<p>That said, here&#8217;s a PHP function that can extract any HTML tags and their attributes from a given string :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * extract_tags()
 * Extract specific HTML tags and their attributes from a string.
 *
 * You can either specify one tag, an array of tag names, or a regular expression that matches the tag name(s). 
 * If multiple tags are specified you must also set the $selfclosing parameter and it must be the same for 
 * all specified tags (so you can't extract both normal and self-closing tags in one go).
 * 
 * The function returns a numerically indexed array of extracted tags. Each entry is an associative array
 * with these keys :
 * 	tag_name	- the name of the extracted tag, e.g. &quot;a&quot; or &quot;img&quot;.
 *	offset		- the numberic offset of the first character of the tag within the HTML source.
 *	contents	- the inner HTML of the tag. This is always empty for self-closing tags.
 *	attributes	- a name -&gt; value array of the tag's attributes, or an empty array if the tag has none.
 *	full_tag	- the entire matched tag, e.g. '&lt;a href=&quot;http://example.com&quot;&gt;example.com&lt;/a&gt;'. This key 
 *		          will only be present if you set $return_the_entire_tag to true.	   
 *
 * @param string $html The HTML code to search for tags.
 * @param string|array $tag The tag(s) to extract.							 
 * @param bool $selfclosing	Whether the tag is self-closing or not. Setting it to null will force the script to try and make an educated guess. 
 * @param bool $return_the_entire_tag Return the entire matched tag in 'full_tag' key of the results array.  
 * @param string $charset The character set of the HTML code. Defaults to ISO-8859-1.
 *
 * @return array An array of extracted tags, or an empty array if no matching tags were found. 
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">,</span> <span style="color: #000088;">$selfclosing</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$return_the_entire_tag</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$charset</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ISO-8859-1'</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tag</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'|'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tag</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//If the user didn't specify if $tag is a self-closing tag we try to auto-detect it</span>
	<span style="color: #666666; font-style: italic;">//by checking against a list of known self-closing tags.</span>
	<span style="color: #000088;">$selfclosing_tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'area'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'base'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'basefont'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'br'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'hr'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'input'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'img'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'link'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'meta'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'col'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'param'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$selfclosing</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$selfclosing</span> <span style="color: #339933;">=</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">,</span> <span style="color: #000088;">$selfclosing_tags</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//The regexp is different for normal and self-closing tags because I can't figure out </span>
	<span style="color: #666666; font-style: italic;">//how to make a sufficiently robust unified one.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$selfclosing</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag_pattern</span> <span style="color: #339933;">=</span> 
			<span style="color: #0000ff;">'@&lt;(?P&lt;tag&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$tag</span><span style="color: #339933;">.</span><span style="color: #0000ff;">')			# &lt;tag
			(?P&lt;attributes&gt;\s[^&gt;]+)?		# attributes, if any
			\s*/?&gt;					# /&gt; or just &gt;, being lenient here 
			@xsi'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag_pattern</span> <span style="color: #339933;">=</span> 
			<span style="color: #0000ff;">'@&lt;(?P&lt;tag&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$tag</span><span style="color: #339933;">.</span><span style="color: #0000ff;">')			# &lt;tag
			(?P&lt;attributes&gt;\s[^&gt;]+)?		# attributes, if any
			\s*&gt;					# &gt;
			(?P&lt;contents&gt;.*?)			# tag contents
			&lt;/(?P=tag)&gt;				# the closing &lt;/tag&gt;
			@xsi'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$attribute_pattern</span> <span style="color: #339933;">=</span> 
		<span style="color: #0000ff;">'@
		(?P&lt;name&gt;\w+)							# attribute name
		\s*=\s*
		(
			(?P&lt;quote&gt;[\&quot;\'])(?P&lt;value_quoted&gt;.*?)(?P=quote)	# a quoted value
			|							# or
			(?P&lt;value_unquoted&gt;[^\s&quot;\']+?)(?:\s+|$)			# an unquoted value (terminated by whitespace or EOF) 
		)
		@xsi'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Find all tags </span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tag_pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #339933;">,</span> PREG_SET_ORDER <span style="color: #339933;">|</span> PREG_OFFSET_CAPTURE <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">//Return an empty array if we didn't find anything</span>
		<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$matches</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">//Parse tag attributes, if any</span>
		<span style="color: #000088;">$attributes</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
&nbsp;
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$attribute_pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$attribute_data</span><span style="color: #339933;">,</span> PREG_SET_ORDER <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				<span style="color: #666666; font-style: italic;">//Turn the attribute data into a name-&gt;value array</span>
				<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attribute_data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
					<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_quoted'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_quoted'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_unquoted'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_unquoted'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
&nbsp;
					<span style="color: #666666; font-style: italic;">//Passing the value through html_entity_decode is handy when you want</span>
					<span style="color: #666666; font-style: italic;">//to extract link URLs or something like that. You might want to remove</span>
					<span style="color: #666666; font-style: italic;">//or modify this call if it doesn't fit your situation.</span>
					<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #990000;">html_entity_decode</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #339933;">,</span> <span style="color: #000088;">$charset</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
					<span style="color: #000088;">$attributes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$tag</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'tag_name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tag'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'offset'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'contents'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">//empty for self-closing tags</span>
			<span style="color: #0000ff;">'attributes'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$attributes</span><span style="color: #339933;">,</span> 
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$return_the_entire_tag</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$tag</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'full_tag'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> 			
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$tags</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$tags</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Usage examples</strong></p>
<p>Extract all links and output their URLs :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'example.html'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'a'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Extract all heading tags and output their text :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'h\d+'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #990000;">strip_tags</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Extract meta tags :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'meta'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Extract bold and italicised text fragments :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'b'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'strong'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'em'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'i'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #990000;">strip_tags</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The function is pretty well documented, so check the source if anything is unclear. Of course, you can also leave a comment if you have any further questions or feedback.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>How To Make a &#8220;Falling Sand&#8221; Style Water Simulation</title>
		<link>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/</link>
		<comments>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 14:14:43 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[falling sand game]]></category>
		<category><![CDATA[fluid simulation]]></category>
		<category><![CDATA[game design]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[water simulation]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1295</guid>
		<description><![CDATA[Have you ever wondered how all those &#8220;falling sand&#8221; games work under the hood? If so, read on. Today I will discuss one of the possible ways how you could implement the &#8220;falling&#8221; part of the game &#8211; sand particles falling under the effects of gravity, water (or other liquids) flowing down a hillside, and [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered how all those <a href="http://chir.ag/stuff/sand/">&#8220;falling sand&#8221; games</a> work under the hood? If so, read on. Today I will discuss one of the possible ways how you could implement the &#8220;falling&#8221; part of the game &#8211; sand particles falling under the effects of gravity, water (or other liquids) flowing down a hillside, and so on. <a href="http://w-shadow.com/files/FallingWater.zip">Source code</a> and a <a href="http://w-shadow.com/files/FallingSandWater/">live demo</a> are also available. This tutorial is along the same vein as my previous <a href="http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/">fluid simulation post</a> that dealt with pseudo-compressible fluids and pressure, but the specific algorithm is much simpler (and probably quite a bit faster, too).<em> </em></p>
<p><em>Side-note : No, I haven&#8217;t been completely consumed by an inexorable desire to build fun graphical toys instead of practically useful software, why do you ask? <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  In fact, there&#8217;ll be some WordPress-related announcements later this week&#8230;</em></p>
<h3>Learning To <del datetime="2009-09-28T14:15:43+00:00">Fly</del> Fall</h3>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1299" title="Falling water movement" src="http://w-shadow.com/wp-content/uploads/2009/09/gravity-simulation-rules.png" alt="Falling water movement" width="120" height="236" />While I can&#8217;t claim intimate familiarity with the algorithms the aforementioned games use to simulate fire or explosions, it&#8217;s pretty easy to come up with a way to implement falling sand/flowing water. First, you need to figure out under what conditions something can fall/flow downwards. For a basic simulation this could be just a small set of very simple rules :</p>
<ul>
<li>For each entity that is affected by gravity
<ul>
<li>If there&#8217;s an empty space <strong>below</strong> it, move it <strong>down</strong>.</li>
<li>If there&#8217;s an empty space <strong>down and to the left</strong>, move it <strong>down and to the left</strong>.</li>
<li>If there&#8217;s an empty space <strong>down and to the right</strong>, move it <strong>down and to the right</strong>.</li>
</ul>
</li>
</ul>
<p>Next, you need to decide how to represent the simulation world and all the objects (like immovable walls, moving water particles <em>et cetera</em>) that it contains. One of the most common solutions is to use a two-dimensional array where each array element is an numeric ID of the material contained in that map tile. For example, 0 = air (or an empty square), 1 = wall, 2 = water, and so on.</p>
<p style="text-align: center;"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="size-full wp-image-1300 aligncenter" title="Map array" src="http://w-shadow.com/wp-content/uploads/2009/09/map-representation.png" alt="Map array" width="481" height="306" /></p>
<p>In most falling sand games each array element would correspond to a single pixel on the game&#8217;s screen. However, in my example application I used 20&#215;20 pixel tiles instead to make the underlying simulation behaviour easier to see.</p>
<p>If possible, use <em>byte</em> or <em>char</em> as the array element datatype. Using <em>int&#8217;s</em> might seem more straightforward, but it would also take up at least four times more memory and hurt performance. It&#8217;s also a good idea to make the array just a bit bigger than the actual map dimensions and create a single-tile &#8220;buffer zone&#8221; around the map so that you can avoid checking for boundary conditions during the simulation.</p>
<p>Finally, during the simulation step we just loop over the entire array and apply the simple rules I mentioned above to each tile that contains material that should be affected by gravity.</p>
<h3>Getting It Right</h3>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1301" title="Now that's just silly." src="http://w-shadow.com/wp-content/uploads/2009/09/whee.png" alt="Now that's just silly." width="78" height="211" />If you go ahead and implement the above algorithm as written, you will get a simulation that <em>kind-of</em> works, but quickly grinds to a halt on big maps and sometimes behaves in unexpected ways. For example, you might see sand tiles that seem to &#8220;teleport&#8221; to the bottom of the map instead of falling gradually and water that always flows <em>left</em> after hitting a free-standing ground tile (even though there&#8217;s a perfectly suitable channel available on the right side). Lets see what we can do about that.</p>
<p><strong>Keeping track of updated tiles</strong></p>
<p>The &#8220;teleportation&#8221; behaviour can happen if our simulation algorithm doesn&#8217;t keep track of which tiles it has already moved around during the current simulation step. For example, first it loops over the top row of the map, finds a water tile A and moves it downwards one row. Then it loops over the second row, finds the tile A, moves it again, goes to the third row, moves the same water tile <em>again</em>&#8230; and so on, until the water tile A hits a solid tile or falls off the map.</p>
<p>To prevent this bug we need to somehow remember which tiles have been updated already. Since I wanted to keep the memory use low, I used the most-significant bit of each map array element to indicate whether that tile was last updated on an even-numbered simulation step (0) or an odd-numbered step (1). Then, at the start of each step, the algorithm calculates what the flag should be for tiles updated in that step :</p>
<pre>update_mask = byte ( ( simulationFrameCount &amp; (long)1 ) &lt;&lt; 7 );
//this basically takes the modulo of frame-count / 2 and shifts the result 7 places to the left</pre>
<p>&#8230;then sets the msb of each tile it updates to that value and automatically skips tiles that have it already set to that value.</p>
<p><strong>Pseudo-random movement</strong></p>
<p>When a falling particle hits a free-standing fixed tile on a 2D map it has two choices &#8211; it can either move down and left, or down and right. In the naive algorithm I discussed above it will always try to move left first, leading to weirdness. Obviously we want it to choose at random, but on a big map generating a new random number for each tile would be slow. Instead, lets use the same approach as for the &#8220;teleportation&#8221; problem and move it either diagonally left if the current simulation step is even-numbered and or diagonally right if it&#8217;s odd-numbered. This can still introduce some artifacts in the simulation behaviour, but they&#8217;re rarer and and significantly less noticeable.</p>
<h3>Optimization</h3>
<p>Speaking of optimization, we don&#8217;t really need to update each gravity-enabled tile every time. Many of them will eventually end up in a situation where they can&#8217;t move anywhere (e.g. water at the bottom of a puddle or sand resting on a flat surface), so it would be nice if we could quickly skip them and not waste our time trying to apply the simulation rules to these static tiles. This would help performance quite a bit.</p>
<p>The way I implemented is with the help with another bit-flag. If the simulation algorithm discovers that it can&#8217;t move a tile in any direction, it will set the tile&#8217;s &#8220;static&#8221; bit-flag. It will also skip any tiles that have the &#8220;static&#8221; bit-flag set.</p>
<p>There&#8217;s some additional book-keeping we need to do to make this work as intended. When an empty space is created somewhere in the map (e.g. by a water tile moving down) we need to re-activate any gravity-enabled tiles that are directly above the newly created hole, so that they can fall/flow down into that space.</p>
<h3>Possible Improvements</h3>
<p>The result is a pretty basic and plain simulation that is useful to explain the basic principle, but it wouldn&#8217;t really qualify as a full game. Here are some ideas you could use to improve it :</p>
<ul>
<li>Make water flow horizontally if there&#8217;s another water tile on top of it. Consider adding a simple pressure model [link to my prev. article].</li>
<li>Implement fluid density. This one is easy &#8211; if the current tile is more dense than the tile below it, swap them.</li>
<li>Add tile generators, e.g. a faucet that creates a water tile below itself on each simulation step (included in my demo application).</li>
<li>To improve performance, use a <a href="http://en.wikipedia.org/wiki/Quadtree">quadtree</a> to keep track of which regions of the map have interacting tiles and quickly skip inactive regions.</li>
<li>Explore the source code of existing games and look for interesting ideas. Some open-source examples : <a href="http://www.piettes.com/fallingsandgame/download.html">wxSand</a>, <a href="http://sourceforge.net/projects/sdlsand/">SDL Sand</a>.</li>
</ul>
<h3>Live Demo &amp; Source</h3>
<p>Like my previous <a href="http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/">fluid simulation app</a>, this one was also written in <a href="http://processing.org/">Processing</a>. In addition to a working implementation of the algorithm discussed above it also lets you draw and erase water/ground/faucet tiles using your mouse, pan around the map with the WASD keys, zoom in/out with the mouse wheel and more. However, be warned that the map rendering code is not very optimized so the simulation <em>will</em> degenerate into a slideshow if you zoom all the way out, regardless of how fast your system is.</p>
<ul>
<li><a href="http://w-shadow.com/files/FallingSandWater/">Live demo  (requires Java)</a></li>
<li><a href="http://w-shadow.com/files/FallingWater.zip">Source code</a></li>
</ul>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Simple Fluid Simulation With Cellular Automata</title>
		<link>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/</link>
		<comments>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 19:48:33 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[fluid dynamics]]></category>
		<category><![CDATA[fluid simulation]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[water dynamics]]></category>
		<category><![CDATA[water simulation]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1285</guid>
		<description><![CDATA[Last week I couldn&#8217;t use my regular dev. machine (broken graphics card), so all my WordPress-related plans were on hold. To pass the time, I built a simple water simulation in Processing. Today I&#8217;m going to show you this little application and explain how it works. Online demo and source code are included. Big Words, [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I couldn&#8217;t use my regular dev. machine (broken graphics card), so all my WordPress-related plans were on hold. To pass the time, I built a simple water simulation in <a href="http://processing.org/">Processing</a>. Today I&#8217;m going to show you this little application and explain how it works. Online demo and source code are included.</p>
<h3>Big Words, or The Theoretical Part</h3>
<p>Fluid dynamics is a complex topic. If you so much as <a rel="nofollow" href="http://en.wikipedia.org/wiki/Computational_fluid_dynamics">look it up in Wikipedia</a>, you will be immediately assaulted by integrals, differentials  and other agents of mathematical insanity. To accurately model a fluid you would need a quite an in-depth understanding of physics and calculus. And while that&#8217;s certainly not something one couldn&#8217;t figure out given enough time, &#8220;proper&#8221; fluid simulation is still extremely rare in non-academic applications and games because it&#8217;s <strong>slow</strong>.</p>
<p>One way to create a faster (though less accurate) simulation is by using <a rel="nofollow" href="http://en.wikipedia.org/wiki/Cellular_automata">cellular automata</a> to represent the water. A cellular automaton is basically a grid where each cell can be in one of a finite number of states, plus a set of rules that determine how a cell can change from one state to another. The rules are typically local &#8211; that is, they consider only the current cell and it&#8217;s direct neighbours when determining the new state. During each step of the simulation, you simply loop through the entire grid and apply the rules to each cell.</p>
<p>When simulating water or other fluids it can more appropriate to store a continuous value (e.g. water mass) in each cell, instead of using discrete states.</p>
<h3>CA-Based Water Simulation</h3>
<p>Before we go into details, lets take a look at the promised online demo. It will give you a good idea about what you can achieve with this approach :</p>
<p><a href="http://w-shadow.com/files/water_sim/"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-1291" title="Click to run the simulation" src="http://w-shadow.com/wp-content/uploads/2009/09/Water-Simulation1-490x513.png" alt="Click to run the simulation" width="490" height="513" /></a> <em>(klicken Sie auf das Bild; Java required)</em></p>
<p>Alright, on to the code stuff. Lets try simulating the most common fluid &#8211; water.</p>
<p><strong>The basic data structure</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Map dimensions</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> map_width <span style="color: #339933;">=</span> <span style="color: #cc66cc;">16</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> map_height <span style="color: #339933;">=</span> <span style="color: #cc66cc;">16</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Block types</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> AIR <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> GROUND <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> WATER <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Data structures</span>
<span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> blocks <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> mass <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span>,
          new_mass <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I use two two-dimensional arrays to represent the simulation world. The <code>blocks</code> array defines a basic &#8220;map&#8221; where each cell can contain ground (solid, stops water flow), air (an empty cell, water can flow in) or water. Each water cell also has a corresponding entry in the <code>mass</code> array that defines how much water it contains. All water cells/blocks start out with one unit of water.</p>
<p>There&#8217;s also a third array &#8211; <code>new_mass</code> that is used to store intermediate mass values when running the simulation. Operating directly on the <code>mass</code> array is unadvisable because you would get various sideffects like water spreading at different speeds depending on the order in which you update the cells.</p>
<p><strong>Overall algorithm</strong></p>
<p>The main idea is to treat water as a slightly compressible liquid, as described in <a href="http://home.comcast.net/~tom_forsyth/papers/cellular_automata_for_physical_modelling.html">this article</a>. In terms of implementation, this means that if there are two or more water cells stacked vertically, the bottom cells will be able to hold slightly more water than normal. This way we don&#8217;t need to explicitly track pressure to make the water level equalize in communicating vessels &#8211; we can just look at how much excess water a cell has, and move it upwards if required.</p>
<p>Lets set up the exact fluid properties as constants :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Water properties</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MaxMass <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1.0</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//The normal, un-pressurized mass of a full water cell</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MaxCompress <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0.02</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//How much excess water a cell can store, compared to the cell above it</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MinMass <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0.0001</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">//Ignore cells that are almost dry</span></pre></div></div>

<p>For example, if one cell contains 1.0 units of water, the cell below it should contain up to 1.02 units, the cell below that one should contain 1.04, the next one 1.06, and so on. There is one however special case that we need to consider to get a plausible simulation &#8211; what if the if the top cell contains less than <code>MaxMass</code> units of water? In my implementation the bottom cell will contain a proportionally smaller excess amount, not the usual <code>mass_of_the_cell_above + MaxCompression</code> units.</p>
<p>Based on the above, we can simulate water movement by looping over the <code>mass</code> array and applying these cellular automaton rules to each cell :</p>
<ol>
<li>Take the mass of the current cell and the cell <strong>below</strong> it and figure out how much water the bottom cell should contain. If it has less than that, remove the corresponding amount from the current cell and add it to the bottom cell.</li>
<li>Check the cell to the <strong>left</strong> of this one. If it has less water, move over enough water to make both cells contain the same amount.</li>
<li>Do the same thing for the <strong>right</strong> neighbour.</li>
<li>Do the same thing as in step 1., but for the cell <strong>above</strong> the current one.</li>
</ol>
<p>While doing this you also need to keep track of how much water the current cell still has remaining, or you could end up with negative-mass water blocks.</p>
<p>After the new mass of each cell has been calculated, you can safely copy over the new values to the <code>mass</code> array. You also need to update the <code>blocks</code> array so that cells that are now dry get marked as empty and vice versa.</p>
<p>Here&#8217;s the simulation code :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">void</span> simulate_compression<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">float</span> Flow <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">float</span> remaining_mass<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Calculate and apply flow for each block</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;=</span> map_width<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;=</span> map_height<span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">//Skip inert ground blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Custom push-only flow</span>
       Flow <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
       remaining_mass <span style="color: #339933;">=</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//The block below this one</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span>blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         Flow <span style="color: #339933;">=</span> get_stable_state_b<span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">+</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
           Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//leads to smoother flow</span>
         <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span> Flow, <span style="color: #cc66cc;">0</span>, min<span style="color: #009900;">&#40;</span>MaxSpeed, remaining_mass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>   
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Left</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//Equalize the amount of water in this block and it's neighbour</span>
         Flow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span>Flow, <span style="color: #cc66cc;">0</span>, remaining_mass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Right</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//Equalize the amount of water in this block and it's neighbour</span>
         Flow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span>Flow, <span style="color: #cc66cc;">0</span>, remaining_mass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Up. Only compressed water flows upwards.</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         Flow <span style="color: #339933;">=</span> remaining_mass <span style="color: #339933;">-</span> get_stable_state_b<span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">+</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span> Flow, <span style="color: #cc66cc;">0</span>, min<span style="color: #009900;">&#40;</span>MaxSpeed, remaining_mass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>   
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
     <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Copy the new mass values to the mass array</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;</span> map_width <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;</span> map_height <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;=</span> map_width<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;=</span> map_height<span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">//Skip ground blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
       <span style="color: #666666; font-style: italic;">//Flag/unflag water blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> MinMass<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> WATER<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
         blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> AIR<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
     <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Remove any water that has left the map</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;</span> map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;</span> map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    mass<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    mass<span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And here&#8217;s the function that calculates how to distribute a given amount of water between two vertically adjacent cells :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Returns the amount of water that should be in the bottom cell.</span>
<span style="color: #000066; font-weight: bold;">float</span> get_stable_state_b <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">float</span> total_mass <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> total_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> total_mass <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">*</span>MaxMass <span style="color: #339933;">+</span> MaxCompress <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>MaxMass<span style="color: #339933;">*</span>MaxMass <span style="color: #339933;">+</span> total_mass<span style="color: #339933;">*</span>MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span>MaxMass <span style="color: #339933;">+</span> MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>total_mass <span style="color: #339933;">+</span> MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Full source code</strong></p>
<ul>
<li><a href="http://w-shadow.com/files/water_sim.zip"><strong>Download the source</strong></a> (23 KB)</li>
<li>You will need the Java-based <a href="http://processing.org/">Processing programming language</a> to run the code.</li>
</ul>
<p>I didn&#8217;t discuss how to render the water, or how to handle user interaction, but the source code also includes a simplistic implementation of those things.</p>
<h3>Conclusion</h3>
<p>CA-based algorithms have both advantages and disadvantages. On the one hand, they&#8217;re relatively fast and the simulation quality is often good enough for games and software toys. On the other, they can produce behaviour that is very unrealistic &#8211; for example, water falling into a basin will form a little &#8220;hill&#8221; and spread out slowly, instead of near-instantly as real water would. Whether this is an acceptable downside depends on your application.</p>
<p>For a different take on simulating fluid dynamics with cellular automata, check out this <a href="http://www.gamasutra.com/view/feature/3549/interview_the_making_of_dwarf_.php?page=9">interview with the author of Dwarf Fortress</a>.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
