OS X: Editable address bar in Finder windows with FinderPath

Windows and Linux veterans migrating to Mac OS X can find it painful for one very simple reason. The Finder windows do not have an editable address bar showing you exactly where you are on the computer. You can’t see the path. You can’t copy/paste the path. You can’t quickly edit the path. There is no option to turn it on.

Fortunately, I found a (third party) solution!

If you haven’t already, start showing the full path in title bar by running these commands in Terminal:

defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES
killall Finder

Then install FinderPath:
http://bahoom.com/finderpath/
After adding it to your Applications, run it once.
It should (transparently) start on system boot.

You just have to click on the path in the title bar, and it turns into an editable field with tab completion. Alternatively, you can press Command+G to activate it.

I have tested this successfully on Snow Leopard and Lion.

FinderPath
FinderPath enables this

Algae will replace petroleum with biodiesel, biogasoline, and even plastic

I am amazed by algae to the point that I am convinced it can almost completely replace petroleum (the raw fossil fuel commonly referred to as “oil”).

Here are some important products that can be derived from processing petroleum OR algae:

And yes, the algae-based fuels (and plastics) work just as well as the petroleum-based fuels, and can be used in existing engines without any modification. Engines will run the same and burn cleaner (although they still emit CO2).

Of course algae and petroleum aren’t exactly the same. Petroleum can be processed to get: tar, asphalt, and pesticides. Algae can be processed to get: nutrients, animal feed, and vegetable oil.

Biofuels (like biodiesel) can be produced from any biomass (like corn, soy, or even wood chips). However, the efficiency (in terms of oil yield per acre) of algae is astronomical compared any other feedstock.

Algae:

  • naturally takes CO2 out of the atmosphere and releases oxygen (while alive)
  • grows very fast (harvest cycle of 1–10 days)
  • does not require fresh water (seawater and wastewater will do)
  • does not require quality farm land (dry or saline soil will do)
  • actually thrives off wastewater (found at a wastewater treatment facility, post-bacteria)
  • also thrives by consuming CO2 emissions directly from factories and power plants

Algae farms can easily have symbiotic (mutually beneficial) relationship with cement factories, coal power plants, wastewater treatment facilities, or any other facility that produces CO2 emissions. For example, CO2 emissions are normally an unwanted bi-product. However, pumping the CO2 through algae will reduce the emissions and feed the algae growth leading to faster oil production.

Properly produced biofuels can be used in existing engines without modification. You’d have to modify a diesel engine to run on vegetable oil, yes, but it can be done. However, biodiesel is essentially the same as “petrodiesel” and can be used as a drop in replacement. To quote an article:

These biofuels, which some refer to as “renewable petroleum,” will be designed with the same properties of hydrocarbons that now fuel our vehicles, but be made from biomass, rather than petroleum.

Custom-designed synthetic fuels are very appealing to established fossil fuel providers because, unlike ethanol, they should not require significant changes to the existing fuel infrastructure, said Nathanael Greene, a biofuels policy analyst at the National Resource Defense Council (NRDC).

http://news.cnet.com/8301-11128_3-9849832-54.html

Plastic can also be derived from algae (as opposed to petroleum). See:
http://www.celsias.com/article/cereplast-algae-plastic/
http://en.wikipedia.org/wiki/Bioplastic

Videos

A couple of algae based companies have decent YouTube videos promoting their work.

PetroAlgae
http://www.youtube.com/watch?v=e-RyKyvWr3I (video removed)

Valcent / Vertigro

Investing

I wish I could just invest in an index of all companies doing work with algae. However, no such index exists. Additionally, many companies doing good work are still privately owned. They are competing and guarding their secrets; thus slowing down progress. However, in the end, we will all benefit from the good ol’ American competition.

During my research, these companies stuck out:

Many sites discussing the up-coming algae market and companies refer to this list of 15 promising startups

For more on investing in green companies (including algae biofuels), check out:
http://www.greenchipstocks.com/
http://greenworldinvestor.com/

For general news and information on the algae industry, check out:
http://www.oilgae.com/
http://www.algalbiomass.org/
http://www.algaeindustrymagazine.com/

More Wikipedia pages:
List of algal fuel producers
List of biofuel companies and researchers

Cost and Timeline

Currently it’s cheaper to drill for petroleum. However, petroleum is a limited resource and prices are always going up. Meanwhile, technology surrounding harvesting and processing algae for biofuels and other products keeps getting better and cheaper. It’s only a matter of time before those 2 lines cross on the graph.

Obama supports domestic biofuels. If the government started officially endorsing (probably via tax credits) biofuels, and stopped supporting “petrofuels”, I am confident that we would be able to make the switch from fossil fuels to renewable fuels (for the vast majority of its applications).

This market is just waiting to explode. In the future, vehicles may have engines that work in completely different ways. For example, the hydrogen fuel cell, which powers electric cars and only releases water as the bi-product. However, for the time being, we have to deal with the millions of vehicles and engines that already exist. The intermediate step will be to replace the FUEL.

PHP: Clean encoding issues with smart (curly) quotes, em dashes and more

When dealing with content from various sources, such as XML feeds, you will inevitably encounter problems with smart quotes, em dashes, and other random encoding issues. Smart quotes are known by other names such as curly quotes and left/right angled quotes.

The main problem is Windows. Many Windows programs use Windows-1252 character encoding, which is very similar to ISO-8859-1, but with some differences. Attempts to detect the encoding of a Windows-1252 string will tend to result in a guess of ISO-8859-1. So conversion tools will overlook the differences. Unfortunately, there are some relatively common characters among the differences. These characters include left/right angled single/double quotes, em/en dashes, ellipsis, and bullets.

To deal with these encoding issues, I wrote a function to do the cleanup and convert the string to UTF-8.

Note: I have only tested this with the English language / character set.

Full disclosure: PHP must have the mbstring extension enabled to use the mb_* functions.

/**
 * cleanEncoding deals with pesky characters like curly smart quotes and em dashes (and some other encoding related problems)
 *
 * @param string $text Text string to cleanup / convert
 * @param string $type 'standard' for standard characters, 'reference' for decimal numerical character reference
 *
 * @return $text Cleaned up UTF-8 string
 */
function cleanEncoding( $text, $type='standard' ){
    // determine the encoding before we touch it
    $encoding = mb_detect_encoding($text, 'UTF-8, ISO-8859-1');
    // The characters to output
    if ( $type=='standard' ){
        $outp_chr = array('...',          "'",            "'",            '"',            '"',            '•',            '-',            '-'); // run of the mill standard characters
    } elseif ( $type=='reference' ) {
        $outp_chr = array('…',      '‘',      '’',      '“',      '”',      '•',      '–',      '—'); // decimal numerical character references
    }
    // The characters to replace (purposely indented for comparison)
        $utf8_chr = array("\xe2\x80\xa6", "\xe2\x80\x98", "\xe2\x80\x99", "\xe2\x80\x9c", "\xe2\x80\x9d", '\xe2\x80\xa2', "\xe2\x80\x93", "\xe2\x80\x94"); // UTF-8 hex characters
        $winc_chr = array(chr(133),       chr(145),       chr(146),       chr(147),       chr(148),       chr(149),       chr(150),       chr(151)); // ASCII characters (found in Windows-1252)
    // First, replace UTF-8 characters.
    $text = str_replace( $utf8_chr, $outp_chr, $text);
    // Next, replace Windows-1252 characters.
    $text = str_replace( $winc_chr, $outp_chr, $text);
    // even if the string seems to be UTF-8, we can't trust it, so convert it to UTF-8 anyway
    $text = mb_convert_encoding($text, 'UTF-8', $encoding);
    return $text;
}

If you are interested in more information on this topic, here are some links you may find helpful:
http://www.joelonsoftware.com/articles/Unicode.html
http://shiflett.org/blog/2005/oct/convert-smart-quotes-with-php#comment-3
http://web.forret.com/tools/charmap.asp?show=ascii
http://en.wikipedia.org/wiki/Extended_ASCII
http://www.ascii-code.com/
http://stackoverflow.com/questions/631406/what-is-the-difference-between-em-dash-151-and-8212
http://en.wikipedia.org/wiki/Numeric_character_reference
http://www.dwheeler.com/essays/quotes-in-html.html
http://www.i18nguy.com/markup/ncrs.html
http://www.kadifeli.com/fedon/utf.htm

PHP: Truncate string while preserving HTML tags and whole words

Truncating strings is a very common task while programming. Sometimes those strings have HTML code within them. If you simply truncated at X characters, you risk outputting very broken HTML. If you can live without the HTML, the easy solution is to strip_tags. However, if you want to preserve the HTML tags, you’ll need a smarter truncate function.

I yanked this function from a blog who looks like they yanked it from another blog, who yanked in from the CakePHP framework. This function is too good not to share.

/**
 * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
 *
 * @param string $text String to truncate.
 * @param integer $length Length of returned string, including ellipsis.
 * @param string $ending Ending to be appended to the trimmed string.
 * @param boolean $exact If false, $text will not be cut mid-word
 * @param boolean $considerHtml If true, HTML tags would be handled correctly
 *
 * @return string Trimmed string.
 */
function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true) {
	if ($considerHtml) {
		// if the plain text is shorter than the maximum length, return the whole text
		if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
			return $text;
		}
		// splits all html-tags to scanable lines
		preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
		$total_length = strlen($ending);
		$open_tags = array();
		$truncate = '';
		foreach ($lines as $line_matchings) {
			// if there is any html-tag in this line, handle it and add it (uncounted) to the output
			if (!empty($line_matchings[1])) {
				// if it's an "empty element" with or without xhtml-conform closing slash
				if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
					// do nothing
				// if tag is a closing tag
				} else if (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
					// delete tag from $open_tags list
					$pos = array_search($tag_matchings[1], $open_tags);
					if ($pos !== false) {
					unset($open_tags[$pos]);
					}
				// if tag is an opening tag
				} else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
					// add tag to the beginning of $open_tags list
					array_unshift($open_tags, strtolower($tag_matchings[1]));
				}
				// add html-tag to $truncate'd text
				$truncate .= $line_matchings[1];
			}
			// calculate the length of the plain text part of the line; handle entities as one character
			$content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
			if ($total_length+$content_length> $length) {
				// the number of characters which are left
				$left = $length - $total_length;
				$entities_length = 0;
				// search for html entities
				if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
					// calculate the real length of all entities in the legal range
					foreach ($entities[0] as $entity) {
						if ($entity[1]+1-$entities_length <= $left) {
							$left--;
							$entities_length += strlen($entity[0]);
						} else {
							// no more characters left
							break;
						}
					}
				}
				$truncate .= substr($line_matchings[2], 0, $left+$entities_length);
				// maximum lenght is reached, so get off the loop
				break;
			} else {
				$truncate .= $line_matchings[2];
				$total_length += $content_length;
			}
			// if the maximum length is reached, get off the loop
			if($total_length>= $length) {
				break;
			}
		}
	} else {
		if (strlen($text) <= $length) {
			return $text;
		} else {
			$truncate = substr($text, 0, $length - strlen($ending));
		}
	}
	// if the words shouldn't be cut in the middle...
	if (!$exact) {
		// ...search the last occurance of a space...
		$spacepos = strrpos($truncate, ' ');
		if (isset($spacepos)) {
			// ...and cut the text in this position
			$truncate = substr($truncate, 0, $spacepos);
		}
	}
	// add the defined ending to the text
	$truncate .= $ending;
	if($considerHtml) {
		// close all unclosed html-tags
		foreach ($open_tags as $tag) {
			$truncate .= '</' . $tag . '>';
		}
	}
	return $truncate;
}

Ice cubes forming ice spikes as water freezes

ice-spike-icecube

I’ve seen these many times over the years. Each time I was slightly curious, but never felt motivated to look it up – until today.

These formations are commonly referred to as “ice spikes”. They seem to grow most readily with distilled water and an air current. They can also form with regular tap water, although much less frequently. Every time I have personally witnessed these formations has been using regular tap water in regular ice cube trays.

The idea is that the edges, including the surface, freeze faster than the interior of the ice cube. Water expands as it freezes, so if the surface is (nearly) frozen over, pressure will build up from the interior of the cube, and water will force its way up. This can form a tunnel or tube that the water travels up until freezing along the rim of the tube (forming the ice spike).

ice-spike-formation

CalTech with some good info:
http://www.its.caltech.edu/~atomic/snowcrystals/icespikes/icespikes.htm

More links pertaining to ice spikes:
http://www.physics.utoronto.ca/~smorris/edl/icespikes/icespikes.html
http://en.wikipedia.org/wiki/Ice_spike
http://www.halbertcicles.com/how.htm
http://www.sciforums.com/Unexplainable-Water-Phenomenon-t-46063.html