<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">




<channel>
	<title>tagarga blok</title>
	<link>http://www.tagarga.com/blok</link>
	<description></description>
	<language>en</language>
	<pubDate>Thu, 05 Jun 2008 00:00:00 GMT</pubDate>
	<lastBuildDate>Thu, 05 Jun 2008 00:00:00 GMT</lastBuildDate>
	<generator>http://www.tagarga.com/blok/about_blok</generator>

		<item>
				<title>_array</title>
		<link>http://www.tagarga.com/blok/on/080605</link>
		<pubDate>Thu, 05 Jun 2008 00:00:00 GMT</pubDate>
						<description>_array is a (yet another) attempt to create object oriented API for php arrays.</description>
		<content:encoded><![CDATA[<p>_array is a class that provides a set of simple and &quot;fluent&quot; methods.</p>
<p>For example, this &quot;raw php&quot; code is verbose and inconsistent.</p>
<pre><code>$a = explode(&#039; &#039;, &#039;FOO BAR&#039;);
$a = array_map(&#039;strtolower&#039;, $a);
sort($a);
echo implode(&#039;, &#039;, $a); # &quot;bar, foo&quot;</code></pre>

<p>Using _array, the same is as simple as:</p>
<pre><code>echo _w(&#039;FOO BAR&#039;)-&gt;map(&#039;strtolower&#039;)-&gt;sort(); # &quot;bar, foo&quot;</code></pre>

<p>Another example:</p>
<pre><code>// read users from db
$qry = mysql_query(&quot;SELECT * FROM user&quot;);
$users = array();
while($rec = mysql_fetch_assoc($qry))
    $users[] = $rec;

// create list of names
$names = array();
foreach($users as $rec)
    $names[] = $users[&#039;name&#039;];

// remove admin
$n = array_search(&#039;admin&#039;, $names);
if($n !== false)
    array_splice($names, $n, 1);

// format and print
$names = array_map(&#039;ucfirst&#039;, $names);
sort($names);
echo implode(&quot;&lt;br&gt;&quot;, $names);</code></pre>

<p>with _array, this will be only two lines:</p>
<pre><code>$users = _array()-&gt;from_call(&#039;mysql_fetch_assoc&#039;, mysql_query(&quot;SELECT * FROM user&quot;));
echo $users-&gt;pluck(&#039;name&#039;)-&gt;remove(&#039;admin&#039;)-&gt;map(&#039;ucfirst&#039;)-&gt;sort()-&gt;join(&quot;&lt;br&gt;&quot;);</code></pre>

<p><a href="/blok/download/ary/_array.inc.php">download</a></p>
<p><a href="/blok/download/ary/_array.php">compact version</a> (with comments stripped)</p>
<p><a href="/files/ary/docs/html">documentation</a></p>
<p><a href="/blok/download/ary/_array_test.phps">test file</a> (requires <a href="/blok/on/080402">testik</a>)</p>
]]></content:encoded>
	</item>
		<item>
				<title>makrell 0.1</title>
		<link>http://www.tagarga.com/blok/on/080520</link>
		<pubDate>Tue, 20 May 2008 00:00:00 GMT</pubDate>
						<description>First &#34;release&#34; of makrell





 (requires )</description>
		<content:encoded><![CDATA[]]></content:encoded>
	</item>
		<item>
				<title>TableSort: custom sort rules</title>
		<link>http://www.tagarga.com/blok/on/080405</link>
		<pubDate>Sat, 05 Apr 2008 00:00:00 GMT</pubDate>
						<description>Meritxell asked me how to use  to sort a column based on a DOM attribute (checkbox &#34;checked&#34; value in that case). Well, in the original version it wasn&#39;t possible, but it was very easy to add.</description>
		<content:encoded><![CDATA[<link rel=stylesheet href="/files/tablesort/style.css">




<p>Check some checkboxes and click &#039;foo&#039; to sort this table.</p>
<table><thead><tr><td>foo</td><td>bar</td></tr></thead><tbody><tr><td><input type='checkbox' name='b'>Blythe</td><td>50</td></tr><tr><td><input type='checkbox' name='b'>Edmund</td><td>104</td></tr><tr><td><input type='checkbox' name='b'>Jonquil</td><td>12</td></tr><tr><td><input type='checkbox' name='b'>Lee</td><td>55</td></tr><tr><td><input type='checkbox' name='b'>Sky</td><td>33</td></tr><tr><td><input type='checkbox' name='b'>Archibald</td><td>75</td></tr><tr><td><input type='checkbox' name='b'>Emma</td><td>70</td></tr><tr><td><input type='checkbox' name='b'>Erin</td><td>92</td></tr><tr><td><input type='checkbox' name='b'>Edgar</td><td>25</td></tr></tbody></table>

<p>The first column uses the following custom comparison function</p>
<pre><code>// sort by checkboxes and then alphabetically

function compareCheckboxes(textA, textB, tdA, tdB) {
    var t = Number(tdA.firstChild.checked) -
        Number(tdB.firstChild.checked);
    if(t != 0) return t;
    return TableSort.compare.alpha(textB, textA);
}</code></pre>

<p>When TS compares two cells, it calls the function with four arguments. The first two are text content from the first and from the second table cell. The next two (that&#039;s what I added) are cells &quot;themselves&quot;, i.e. DOM <code>&lt;TD&gt;</code>  elements, so that you can access cells&#039; DOM contents in the function.</p>
<p>Of course, the above comparison needs to be enabled, you have to add something like this to the onload sequence:</p>
<pre><code>TableSort.enable(&#039;tableID&#039;, &#039;columnTitle&#039;, compareCheckboxes);</code></pre>

<p>See <a href="/blok/on/061023">TableSort</a> docs for more details.</p>
<p><a href="/blok/download/tablesort/tablesort.js">download updated version</a></p>
]]></content:encoded>
	</item>
		<item>
				<title>testik, the little unit tester</title>
		<link>http://www.tagarga.com/blok/on/080402</link>
		<pubDate>Wed, 02 Apr 2008 00:00:00 GMT</pubDate>
						<description>Unit testing and TDD are great and so is SimpleTest, however there&#39;s a problem: you have to write code for tests, and sometimes quite a lot. And this code is often not really readable and self-documented. _testik_ is an attempt to make testing as simple as it could be.</description>
		<content:encoded><![CDATA[<p>Suppose you&#039;re writing some new code, for example, an innovative factorial calculator, and need a test suite. With <em>testik</em>, it&#039;s going to look like this:</p>
<h4>factorial.test.php:</h4>

<pre><code>// include what we&#039;re testing
require &#039;factorial.php&#039;;

// include and run testik
require &#039;testik.php&#039;;
testik();

// tests

factorial(2); # 2
factorial(5); # 120</code></pre>

<p>You run this file (no matter, in browser or from the command line) and... see just nothing. If <em>testik</em> has nothing to complain, it doesn&#039;t bother you.</p>
<p>Now, let&#039;s add a new test to the suite:</p>
<h4>factorial.test.php:</h4>

<pre><code>require &#039;factorial.php&#039;;

require &#039;testik.php&#039;;
testik();

factorial(2); # 2
factorial(5); # 120
factorial(3); # 8</code></pre>

<p>If we run this, we&#039;ll see something like</p>
<pre><code>test failed in factorial_test.php on line 16
expect: int(8)
actual: int(6)</code></pre>

<p>You got the idea: <em>testik</em> looks for the lines in php source containing the &#039;#&#039; symbol and compares what&#039;s on the left of &#039;#&#039; (= actual value) to what&#039;s on the right (= expected value). Other lines are executed as is, so that your test cases can be arbitrary complex:</p>
<pre><code>$db = DBFactory::connection();
$mapper = new UserMapper($db);
$st = $mapper-&gt;select(&#039;*&#039;)-&gt;where(&#039;id&#039;)-&gt;moreThan(10);

$st-&gt;count(); # 123 &lt;-- testik &#039;sees&#039; only this line</code></pre>

<p>Of course, you can also group test cases in functions or class methods, <em>testik</em> doesn&#039;t enforce any particular structure, but it&#039;s your responsibility to call the test functions when appropriate.</p>
<p>Back to the factorial example, suppose you decided to document your package and provide a small text file with comments and examples.</p>
<h4>factorial.doc</h4>

<pre><code>Hello!

This is my very own implementation of the factorial function
(http://en.wikipedia.org/wiki/Factorial)

MIT license

factorial($n) computes a factorial of $n

    factorial(4); # 24
    factorial(5); # 120

By definition, 1! = 0! = 1

    factorial(1); # 1
    factorial(0); # 1

Invalid input yields &quot;error&quot;

    factorial(-1);    # &quot;error&quot;
    factorial(&#039;foo&#039;); # &quot;error&quot;

Number more than 10 yields &quot;overflow&quot;

    factorial(10);    # 3628800
    factorial(11);    # &quot;overflow&quot;
    factorial(111);   # &quot;overflow&quot;

Hope you like this function!</code></pre>

<p>Although this file is not php, you can still use <em>testik</em> to test the code examples:</p>
<h4>factorial.test.php</h4>

<pre><code>require &#039;factorial.php&#039;;

require &#039;testik.php&#039;;
testik(&#039;factorial.doc&#039;, &#039;text&#039;);</code></pre>

<p>The second parameter equal to <code>text</code>  tells <em>testik</em> to ignore all lines that start with a non-space and execute other (indented) lines, following the same &#039;#&#039; rule as above. This means essentially that you can directly use your &#039;readme&#039; files or specifications as test suites and vice versa. Quite neat!</p>
<p>Sometimes there&#039;s no need for the separate documentation file and everything is documented in the code, e.g. using phpdoc syntax.</p>
<h4>factorial.php</h4>

<pre><code>/**
    * Takes an integer and computes the factorial of it
    *
    * @param int
    * @return int | string
    *
    * &lt;code&gt;
    *    factorial(5); # 120
    *    factorial(1); # 1
    *    factorial(0); # 1
    * &lt;/code&gt;
    *
    * invalid input yields &quot;error&quot;
    * &lt;code&gt;
    *    factorial(-1);    # &quot;error&quot;
    *    factorial(&#039;foo&#039;); # &quot;error&quot;
    * &lt;/code&gt;
    *
    * number more than 10 yields &quot;overflow&quot;
    * &lt;code&gt;
    *    factorial(10);    # 3628800
    *    factorial(11);    # &quot;overflow&quot;
    *    factorial(111);   # &quot;overflow&quot;
    * &lt;/code&gt;
    *
**/
function factorial($n) {
...</code></pre>

<p>To test this with <em>testik</em>, we need to modify our test file slightly:</p>
<h4>factorial.test.php</h4>

<pre><code>require &#039;factorial.php&#039;;

require &#039;testik.php&#039;;
testik(&#039;factorial.php&#039;, &#039;doc&#039;);</code></pre>

<p><code>doc</code>  means that <em>testik</em> should only execute code within <code>&lt;code&gt;...&lt;/code&gt;</code>  tags.</p>
<p>Ok, that&#039;s pretty much all about that. Of course, <em>testik</em> is a very simple facility, it doesn&#039;t contain fancy assertion rules and cannot replace SimpleTest&#039;ing of a 100,000 lines codebase. The good news are that the whole &#039;framework&#039; is only 50 lines long.</p>
<pre><code>&lt;?php
function testik($file = null, $mode = &#039;php&#039;) {
    $args = func_get_args();
    if(count($args) &lt; 4) {
        $d = debug_backtrace(); $f = realpath($d[0][&#039;file&#039;]);
        $file = is_null($file) ?  $f : realpath($file);
        $line = ($file == $f) ? $d[0][&#039;line&#039;] : 0;
        $text = implode(&quot;\n&quot;,
            ($line &gt; 0 ? array_fill(0, $line, &#039;#&#039;) : array()) +
            preg_split(&quot;~\r?\n~&quot;, file_get_contents($file)));
        switch($mode) {
            case &#039;php&#039;:
                if($file == $f)
                    $text = preg_replace(&#039;~\b(function)[ \t]+([a-zA-Z])~&#039;,
                        &#039;$1 _DISABLE_$2&#039;, $text);
                break;
            case &#039;text&#039;:
                $text = preg_replace(&#039;~^\S.*~m&#039;, &#039;//&#039;, $text);
                break;
            case &#039;doc&#039;:
                $text = explode(&quot;\n&quot;,
                    str_replace(array(&#039;@code&#039;, &#039;@endcode&#039;),
                    array(&#039;&lt;code&gt;&#039;, &#039;&lt;/code&gt;&#039;), $text));
                $text = preg_replace(&#039;~^[ \t]*\*(?!/)~m&#039;, &#039;&#039;, $text);
                $t = array_fill(0, count($text), &#039;//&#039;);
                $c = 0;
                foreach($text as $n =&gt; $s)
                    if(!$c &amp;&amp; strpos($s, &quot;&lt;code&gt;&quot;) !== false) $c = 1;
                        else if($c &amp;&amp; strpos($s, &quot;&lt;/code&gt;&quot;) !== false) $c = 0;
                            else if($c) $t[$n] = $s;
                $text = implode(&quot;\n&quot;, $t);
                break;
        }
        $text = preg_replace(&#039;~^[ \t]*echo (.+);[ \t]*#~m&#039;, &#039;strval($1); #&#039;, $text);
        $text = preg_replace(&#039;~^(.+);[ \t]*#[ \t]*(.+)$~m&#039;,
            __FUNCTION__ . &quot;($1,$2,&#039;$file&#039;,__LINE__);&quot;, $text);
        if(preg_match(&quot;~^\s*&lt;\?~&quot;, $text)) $text = &quot;?&gt;$text&quot;;
        #foreach(explode(&quot;\n&quot;, $text) as $k=&gt;$v) printf(&quot;&lt;pre&gt;%04d: %s&lt;/pre&gt;\n&quot;, $k+1, $v);
        eval($text);
        if($file == $f) exit;
    } else if($args[0] != $args[1]) {
        ob_start();
        echo &quot;test failed in $args[2] on line $args[3]\n&quot;;
        echo &quot;expect: &quot;; var_dump($args[1]);
        echo &quot;actual: &quot;; var_dump($args[0]);
        $s = ob_get_clean();
        (php_sapi_name() == &#039;cli&#039;) ? fwrite(STDERR, $s) :
            print(&quot;&lt;pre&gt;&quot; . htmlspecialchars($s) . &quot;&lt;/pre&gt;&quot;);
    }
}
?&gt;</code></pre>

<p><a href="/blok/download/testik.php">download</a></p>
]]></content:encoded>
	</item>
		<item>
				<title>simple string interpolation in javascript</title>
		<link>http://www.tagarga.com/blok/on/080311</link>
		<pubDate>Tue, 11 Mar 2008 00:00:00 GMT</pubDate>
						<description>two-liner that adds perl/php style string interpolation to javascript</description>
		<content:encoded><![CDATA[<pre><code>function f(str, obj) {
    var a = arguments, obj = obj || window || this;
    return str.replace(/(\\\$)|(\$\$)|\$([0-9])|\$(\w+)|\$\{(\w+)\}/g,
        function() {
            var q = arguments;
            return (q[1] || q[2]) ? &#039;$&#039; : q[3] ? a[q[3]] :
                q[4] ? obj[q[4]] : obj[q[5]];
    });
}</code></pre>




<p><code>f(some_string)</code>  replaces (&quot;interpolates&quot;) placeholders like <code>$var</code>  or <code>${var}</code>  or <code>$5</code>  in the string. <code>f</code>  can be called with one, two or more arguments. If only one argument is given (= the format string), <code>$var</code>  placeholders are replaced with global variables or <code>window</code>  properties:</p>
<pre><code>s = f(&quot;position $screenX, $screenY&quot;);
alert(s);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_1();return false'>try it</a></p>

<p>With two arguments, the second should be an object and <code>$var</code> s are replaced with the corresponding properties of that object</p>
<pre><code>img = {
    src: &#039;woo.gif&#039;,
    title: &#039;hello&#039;,
    width: 150
};
s = f(&quot;&lt;img src=&#039;$src&#039; title=&#039;$title&#039; style=&#039;width:${width}px&#039;&gt;&quot;, img);
alert(s);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_2();return false'>try it</a></p>

<p>Numeric placeholders <code>$1</code> , <code>$2</code>  etc. are replaced with the value of the n-th argument:</p>
<pre><code>s = f(&quot;There are $1 monkeys on the $2&quot;, 100, &#039;tree&#039;);
alert(s);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_3();return false'>try it</a></p>

<p>You can mix numeric and symbolic placeholders:</p>
<pre><code>format = { bg: &quot;black&quot;, fg: &quot;white&quot; }
s = f(&quot;&lt;p style=&#039;background:$bg;color:$fg&#039;&gt;$2&lt;/p&gt; &quot;, format, &quot;hello&quot;);
alert(s);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_4();return false'>try it</a></p>

<p>\\$ or $$ escape the dollar sign:</p>
<pre><code>s = f(&quot;$1 costs \\$2 and $2 costs $$5&quot;, &quot;a beer&quot;, &quot;a meal&quot;);
alert(s);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_5();return false'>try it</a></p>
]]></content:encoded>
	</item>
		<item>
				<title>cut-and-paste technique for complex regexps</title>
		<link>http://www.tagarga.com/blok/on/080307</link>
		<pubDate>Fri, 07 Mar 2008 00:00:00 GMT</pubDate>
						<description>It&#39;s often desired to transform some text ignoring specific parts of it. The
&#34;classical&#34; example is to replace something in html, not touching the tags.</description>
		<content:encoded><![CDATA[<p>Consider the following:</p>
<pre><code>&lt;span class=&#039;foo&#039;&gt;the pic of my class mate&lt;/span&gt;</code></pre>

<p>We need to replace &quot;class&quot; with &quot;school&quot;. The naive</p>
<pre><code>$html = preg_replace(&#039;/class/&#039;, &#039;school&#039;, $html);</code></pre>

<p>will obviously break the formatting. We need a more sophisticated expression with lookaround groups. Although it would work for the simple
case like this, it can grow very complicated or, given the fact that lookbehids are fixed in length, just become impossible at some point. For example, how about &quot;remove newlines everywhere except tags and inside <code>&lt;script&gt;</code>  or <code>&lt;pre&gt;</code> &quot;?</p>
<p>The alternate method I often use is to replace things step-by-step: first, remove everything we want to ignore (leaving some &#039;invisble&#039; markers in text to be able to insert things back), apply transformation to the rest of the text and, finally, restore things we&#039;ve removed before.</p>
<p>Here&#039;s a small class that illustrates this technique</p>
<pre><code>class Clipboard
{
    var $_buf = array();

    function _tr($n) {
        static $dc = &quot;0123456789&quot;;
        static $sc = &quot;\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19&quot;;
        return intval($n) ? strtr($n, $dc, $sc) :
            intval(strtr($n, $sc, $dc));
    }
    //
    function cut($subject, $regexp = null) {
        if(is_array($subject)) {
            $this-&gt;_buf[] = $subject[0];
            return &quot;\x01&quot; . $this-&gt;_tr(count($this-&gt;_buf)) . &quot;\x01&quot;;
        }
        return preg_replace_callback($regexp,
            array(&amp;$this, &#039;cut&#039;), $subject);
    }
    function paste($subject) {
        if(is_array($subject))
            return $this-&gt;_buf[$this-&gt;_tr($subject[1]) - 1];
        return preg_replace_callback(&quot;~\x01([\x10-\x19]+)\x01~&quot;,
            array($this, &#039;paste&#039;), $subject);
    }
}</code></pre>

<p>For example, let&#039;s uppercase all text nodes in some html document. First, put together a regexp that
represents a html tag.</p>
<pre><code>$html_tag = &lt;&lt;&lt;REGEXP
    ~
        &lt;/?\w+
            (
                &quot;[^&quot;]*&quot; |
                &#039;[^&#039;]*&#039; |
                [^&quot;&#039;&gt;]+
            )*
        &gt;
    ~sx
REGEXP;</code></pre>

<p>Instantiate a new Clipboard and cut (remove) all tags:</p>
<pre><code>$c = &amp;new Clipboard;
$html = $c-&gt;cut($html, $html_tag);</code></pre>

<p>Make the rest uppercase and insert the tags back:</p>
<pre><code>$html = strtoupper($html);
echo $c-&gt;paste($html);</code></pre>

<p>For less verbosity, the calls can also be nested:</p>
<pre><code>echo $c-&gt;paste(strtoupper($c-&gt;cut($html, $html_tag)))</code></pre>

<p>This technique (along with other regexp tricks) is extensively used in <a href="http://tagarga.com/blok/on/070723">makrell</a>.</p>
]]></content:encoded>
	</item>
		<item>
				<title>gcui: gui for google chart api</title>
		<link>http://www.tagarga.com/blok/on/071212</link>
		<pubDate>Wed, 12 Dec 2007 00:00:00 GMT</pubDate>
						<description>Gcui is a browser-based tool for creating  urls. 

Current version is 0.1 &#38;beta;

The author is not affiliated with google. ;)</description>
		<content:encoded><![CDATA[]]></content:encoded>
	</item>
		<item>
				<title>generating combinations in php</title>
		<link>http://www.tagarga.com/blok/on/070910</link>
		<pubDate>Mon, 10 Sep 2007 00:00:00 GMT</pubDate>
						<description>This is just a follow-up to the previous post, describes how to enumerate combinations using php iterators.</description>
		<content:encoded><![CDATA[<p>The code is based on the same principle as the previous one. <code>Combinations($subject, $k)</code>  generates all k-combinations of subject (which can be array or string) in lexicographical order.</p>
<pre><code>foreach(new Combinations(&quot;ABCD&quot;, 2) as $substring)
    echo $substring, &#039; &#039;;</code></pre>

<p>prints</p>
<pre><code>AB AC AD BC BD CD</code></pre>

and
<pre><code>$fruits = array(&#039;apple&#039;, &#039;banana&#039;, &#039;orange&#039;, &#039;pear&#039;);
foreach(new Combinations($fruits, 3) as $k =&gt; $v)
    echo $k + 1, &#039; &#039;, implode(&#039;,&#039;, $v), &quot; \n&quot;;</code></pre>

<p>prints</p>
<pre><code>1 apple,banana,orange
2 apple,banana,pear
3 apple,orange,pear
4 banana,orange,pear</code></pre>

<p>The code is partially based on the java one found  <a href="http://www.merriampark.com/comb.htm">here</a>.</p>
<pre><code>class Combinations implements Iterator
{
    protected $c = null;
    protected $s = null;
    protected $n = 0;
    protected $k = 0;
    protected $pos = 0;

    function __construct($s, $k) {
        if(is_array($s)) {
            $this-&gt;s = array_values($s);
            $this-&gt;n = count($this-&gt;s);
        } else {
            $this-&gt;s = (string) $s;
            $this-&gt;n = strlen($this-&gt;s);
        }
        $this-&gt;k = $k;
        $this-&gt;rewind();
    }
    function key() {
        return $this-&gt;pos;
    }
    function current() {
        $r = array();
        for($i = 0; $i &lt; $this-&gt;k; $i++)
            $r[] = $this-&gt;s[$this-&gt;c[$i]];
        return is_array($this-&gt;s) ? $r : implode(&#039;&#039;, $r);
    }
    function next() {
        if($this-&gt;_next())
            $this-&gt;pos++;
        else
            $this-&gt;pos = -1;
    }
    function rewind() {
        $this-&gt;c = range(0, $this-&gt;k);
        $this-&gt;pos = 0;
    }
    function valid() {
        return $this-&gt;pos &gt;= 0;
    }
    //
    protected function _next() {
        $i = $this-&gt;k - 1;
        while ($i &gt;= 0 &amp;&amp; $this-&gt;c[$i] == $this-&gt;n - $this-&gt;k + $i)
            $i--;
        if($i &lt; 0)
            return false;
        $this-&gt;c[$i]++;
        while($i++ &lt; $this-&gt;k - 1)
            $this-&gt;c[$i] = $this-&gt;c[$i - 1] + 1;
        return true;
    }
}</code></pre>
]]></content:encoded>
	</item>
		<item>
				<title>generating permutations in php</title>
		<link>http://www.tagarga.com/blok/on/070816</link>
		<pubDate>Thu, 16 Aug 2007 00:00:00 GMT</pubDate>
						<description>Generating permutations (all possible combinations) of characters or array elements is asked often in php groups. Although simple, the answer is relatively verbose, so I thought I post it here for later reference.</description>
		<content:encoded><![CDATA[<pre><code>function next_permutation(&amp;$a) {
    $n = count($a);
    for($i = $n - 2; $a[$i] &gt; $a[$i + 1]; $i--)
        if(!$i) return false;
    for($j = $n - 1; $a[$i] &gt; $a[$j]; $j--);
    $q = $a[$j]; $a[$j] = $a[$i]; $a[$i] = $q;
    while(++$i &lt; --$n) {
        $q = $a[$n]; $a[$n] = $a[$i]; $a[$i] = $q;
    }
    return true;
}</code></pre>

<p>This code generates permutations in a &quot;lexicographical&quot; (alphabetical) order. We start with the sorted array of numbers and repeat until array is reverse sorted:</p>
<pre><code>$a = array(1, 2, 3);
$k = 0;
do {
    echo ++$k, &#039;. &#039;, implode(&#039;&#039;, $a), &quot; &lt;br&gt; \n&quot;;
} while(next_permutation($a));</code></pre>


<ol><li>123
</li><li>132
</li><li>213
</li><li>231
</li><li>312
</li><li>321</li></ol>

<p>This works ok, but not good enough: first, it&#039;s limited to integer arrays, we&#039;d like it to work with arbitrary arrays and strings, and second, do...while is certainly not the best way to loop, we want the &quot;natural&quot; php way, i.e. foreach. Fortunately, there is the Iterator interface in php5, we can utilize it to make our &quot;API&quot; as simple as</p>
<pre><code>foreach(new Permutations(&quot;ABC&quot;) as $k =&gt; $v)
    echo $v, &quot; &lt;br&gt; \n&quot;;</code></pre>

<p>or</p>
<pre><code>$fruits = array(&#039;apple&#039;, &#039;banana&#039;, &#039;orange&#039;);
foreach(new Permutations($fruits) as $k =&gt; $v)
    echo implode(&#039; &#039;, $v), &quot; &lt;br&gt; \n&quot;;</code></pre>

<p>The code is as follows:</p>
<pre><code>class Permutations implements Iterator
{
    protected $c = null;
    protected $s = null;
    protected $n = 0;
    protected $pos = 0;

    function __construct($s) {
        if(is_array($s)) {
            $this-&gt;s = array_values($s);
            $this-&gt;n = count($this-&gt;s);
        } else {
            $this-&gt;s = (string) $s;
            $this-&gt;n = strlen($this-&gt;s);
        }
        $this-&gt;rewind();
    }
    function key() {
        return $this-&gt;pos;
    }
    function current() {
        $r = array();
        foreach($this-&gt;c as $k)
            $r[] = $this-&gt;s[$k];
        return is_array($this-&gt;s) ? $r : implode(&#039;&#039;, $r);
    }
    function next() {
        if($this-&gt;_next())
            $this-&gt;pos++;
        else
            $this-&gt;pos = -1;
    }
    function rewind() {
        $this-&gt;c = range(0, $this-&gt;n - 1);
        $this-&gt;pos = 0;
    }
    function valid() {
        return $this-&gt;pos &gt;= 0;
    }
    //
    protected function _next() {
        $n = count($this-&gt;c);
        if($n == 1) return false;
        for($i = $n - 2; $this-&gt;c[$i] &gt; $this-&gt;c[$i + 1]; $i--)
            if(!$i) return false;
        for($j = $n - 1; $this-&gt;c[$i] &gt; $this-&gt;c[$j]; $j--);
        $q = $this-&gt;c[$j];
        $this-&gt;c[$j] = $this-&gt;c[$i];
        $this-&gt;c[$i] = $q;
        while(++$i &lt; --$n) {
            $q = $this-&gt;c[$n];
            $this-&gt;c[$n] = $this-&gt;c[$i];
            $this-&gt;c[$i] = $q;
        }
        return true;
    }
}</code></pre>
]]></content:encoded>
	</item>
		<item>
				<title>makrell, the macro processor</title>
		<link>http://www.tagarga.com/blok/on/070723</link>
		<pubDate>Mon, 23 Jul 2007 00:00:00 GMT</pubDate>
						<description>makrell is a simple but powerful macroprocessor for php language. It is aimed to simplify creating complex documents by using _macros_. A macro is a (typically short) chunk of text that replaces another (typically much longer) chunk. Macros act like functions in programming: once defined, they can be used over and over again.
 
The applications of makrell are templating, domain specific languages and php preprocessing.</description>
		<content:encoded><![CDATA[<p>There are perhaps thousands of php templates out there. Is there any reason to try yet another one? Yes, because makrell is different.</p>
<p>Every templating engine comes with its own language and even if it appears simple, you still have to learn it and to teach it to someone else, for example the designer you&#039;re working with. Sometimes the language is great, but not extensible, sometimes it&#039;s practical, but ugly, sometimes it just doesn&#039;t do what you want.</p>
<p>On the contrary, makrell doesn&#039;t have any hard-coded language, instead it provides the means for creating your own one on the fly. You are who decides what syntax is right for you.</p>
<p>Ok, enough happy talk for now. Let&#039;s just make a simple website with makrell. The first (and only) php file we need looks like this:</p>
<h5>file: index.php</h5>

<pre><code>include &#039;makrell.inc.php&#039;;

$page = key($_GET);
if(!ctype_alpha($page))
    $page = &#039;index&#039;;

$m = new Makrell;
echo $m-&gt;parse_file(&quot;$page.html&quot;);</code></pre>

<p>We get an url like <code>index.php?about</code>  and tell makrell to parse and output the file <code>about.html</code> .</p>
<p>The layout of our site is quite conventional: there is a header, navigation menu, content area and a footer.</p>
<h5>file: index.html</h5>
<pre><code>header
navigation
content
footer</code></pre>

<p>If we run it right away, what do we see?</p>
<blockquote>header navigation content footer</blockquote>

<p>Well... what did we expect? makrell is powerful, but it will not magically create our site for us. We have to tell it what we want.</p>
<h5>file: index.html</h5>
<pre><code>header
navigation
content
footer

header {{
    logo &lt;b&gt;title&lt;/b&gt;
}}

navigation {{
    &lt;div&gt;
    | &lt;a href=&quot;?about&quot;&gt;About us&lt;/a&gt;
    | &lt;a href=&quot;?news&quot;&gt;News&lt;/a&gt;
    | &lt;a href=&quot;?services&quot;&gt;Services&lt;/a&gt;
    &lt;/div&gt;
}}

footer {{
    &lt;p&gt;&lt;small&gt;copyright, terms of use&lt;/small&gt;&lt;/p&gt;
}}</code></pre>

<p>What do we see now?</p>
<blockquote>
logo <b>title</b>
<div>
    | <a href="?about">About us</a>
    | <a href="?news">News</a>
    | <a href="?services">Services</a>
</div>
content
<p><small>copyright, terms of use</small></p>
</blockquote>

<p>What happened? makrell has &quot;expanded&quot; the macros, i.e. replaced &quot;header&quot;, &quot;navigation&quot; and &quot;footer&quot; with corresponding {{ ... }} blocks. The word &quot;content&quot; is not replaced, because we didn&#039;t define any substitution for it.</p>
<p>Did I say makrell doesn&#039;t have syntax? I lied. Of course, macro definitions must follow the rules, otherwise makrell won&#039;t be able to recognize them. The syntax is simple, though</p>
<pre><code>macro {{ substitution }}</code></pre>

<p>The macro doesn&#039;t have be an identifier, we could also have used <code>{header}</code>  or <code>&lt;header/&gt;</code>  or even <code>&lt;ilovexml:tag xmlns:xmllovesme=&quot;blah&quot; foobar:tagname=&quot;header&quot; /&gt;</code> ... Just name it like you want, makrell doesn&#039;t limit your creativity.</p>
<p>Since we&#039;ve got three navigation items (about, news, services), we need three html files besides index. Apparently, the header, navigation and footer are common to all pages, it would be a good idea to store them in a separate file:</p>
<h5>file: layout</h5>
<pre><code>header
navigation
content
footer

header {{
    logo &lt;b&gt;title&lt;/b&gt;
}}

navigation {{
    &lt;div&gt;
    | &lt;a href=&quot;?about&quot;&gt;About us&lt;/a&gt;
    | &lt;a href=&quot;?news&quot;&gt;News&lt;/a&gt;
    | &lt;a href=&quot;?services&quot;&gt;Services&lt;/a&gt;
    &lt;/div&gt;
}}

footer {{
    &lt;p&gt;&lt;small&gt;copyright, terms of use&lt;/small&gt;&lt;/p&gt;
}}</code></pre>

<p>Now, in <code>index.html</code>  we define only homepage content and attach <code>layout</code> , that takes care of the rest:</p>
<h5>file: index.html</h5>
<pre><code>{{ include layout }}

content {{
    &lt;p&gt;Welcome to our site!&lt;/p&gt;
}}</code></pre>

<blockquote>
logo <b>title</b>
<div>
    | <a href="?about">About us</a>
    | <a href="?news">News</a>
    | <a href="?services">Services</a>
    </div>
<p>Welcome to our site!</p>
<p><small>copyright, terms of use</small></p>
</blockquote>

<p>Once we have this, the rest is easy:</p>
<h5>file: about.html</h5>
<pre><code>{{ include layout }}

content {{
    &lt;p&gt;Content for &quot;about us&quot; page&lt;/p&gt;
}}</code></pre>

<p>and the same for the &quot;services&quot; page:</p>
<h5>file: services.html</h5>
<pre><code>{{ include layout }}

content {{
    &lt;p&gt;Our services&lt;/p&gt;
}}</code></pre>

<p>Just to make things interesting, suppose that the &quot;news&quot; page has a different header. To achieve that, we don&#039;t need to touch our <code>layout</code> , we just define the header once again in <code>news.html</code> :</p>
<h5>file: news.html</h5>
<pre><code>{{ include layout }}

header {{
    &lt;b&gt;Hot News&lt;/b&gt;
}}

content {{
    &lt;p&gt;Some news&lt;/p&gt;
}}</code></pre>

<blockquote>
<b>Hot News</b>
<div>
    | <a href="?about">About us</a>
    | <a href="?news">News</a>
    | <a href="?services">Services</a>
    </div>
<p>Some news</p>
<p><small>copyright, terms of use</small></p>
</blockquote>

<p>Since the new definition is textually below that of <code>layout</code> , makrell &quot;prefers&quot; it over the old one. The whole thing is much like how inheritance in object-oriented languages works: we build an abstract prototype and override some parts of it to create specific functionality.</p>
<p>Of course, makrell can do much more than simply replacing one string with another, but more on that later... in the meantime, feel free to <a href="/blok/download/makrell.inc.php">download</a> makrell and to view <a href="/files/makrell_samples.php">examples</a></p>
]]></content:encoded>
	</item>
		<item>
				<title>printing a plain-text table</title>
		<link>http://www.tagarga.com/blok/on/070116</link>
		<pubDate>Tue, 16 Jan 2007 00:00:00 GMT</pubDate>
						<description>php function that creates a plain text table from array of arrays</description>
		<content:encoded><![CDATA[<p>Suppose we have something like this (probably a series of database records collected by mysql_fetch_assoc):</p>
<pre><code>$users = array(
    array(&#039;id&#039; =&gt; 1,
        &#039;name&#039; =&gt; &#039;Joe&#039;,
        &#039;age&#039; =&gt; &#039;15&#039;,
        &#039;city&#039; =&gt; &#039;London&#039;),
    array(&#039;id&#039; =&gt; 12,
        &#039;name&#039; =&gt; &#039;Sally&#039;,
        &#039;age&#039; =&gt; &#039;25&#039;,
        &#039;city&#039; =&gt; &#039;Yoknapatawha&#039;),
    array(&#039;id&#039; =&gt; 123,
        &#039;name&#039; =&gt; &#039;Yu&#039;,
        &#039;age&#039; =&gt; &#039;35&#039;,
        &#039;city&#039; =&gt; &#039;Seoul&#039;),
    array(&#039;id&#039; =&gt; 12345,
        &#039;name&#039; =&gt; &#039;Ermenegildo&#039;,
        &#039;age&#039; =&gt; &#039;45&#039;,
        &#039;city&#039; =&gt; &#039;Roma&#039;),
);</code></pre>

<p>and want (for whatever reason) a plain text table like in mysql command-line client:</p>

<pre>
+-------+-------------+-----+--------------+
| id    | name        | age | city         |
+-------+-------------+-----+--------------+
| 1     | Joe         | 15  | London       |
+-------+-------------+-----+--------------+
| 12    | Sally       | 25  | Yoknapatawha |
+-------+-------------+-----+--------------+
| 123   | Yu          | 35  | Seoul        |
+-------+-------------+-----+--------------+
| 12345 | Ermenegildo | 45  | Roma         |
+-------+-------------+-----+--------------+
</pre>
<p>The function is as follows:</p>
<pre><code>function text_table($data) {
    $keys = array_keys(end($data));
    $size = array_map(&#039;strlen&#039;, $keys);
    foreach(array_map(&#039;array_values&#039;, $data) as $e)
        $size = array_map(&#039;max&#039;, $size,
            array_map(&#039;strlen&#039;, $e));
    foreach($size as $n) {
        $form[] = &quot;%-{$n}s&quot;;
        $line[] = str_repeat(&#039;-&#039;, $n);
    }
    $form = &#039;| &#039; . implode(&#039; | &#039;, $form) . &quot; |\n&quot;;
    $line = &#039;+-&#039; . implode(&#039;-+-&#039;, $line) . &quot;-+\n&quot;;
    $rows = array(vsprintf($form, $keys));
    foreach($data as $e)
        $rows[] = vsprintf($form, $e);
    return $line . implode($line, $rows) . $line;
}

# example

echo &quot;&lt;pre&gt;\n&quot;;
echo text_table($users);
echo &quot;&lt;/pre&gt;\n&quot;;</code></pre>
]]></content:encoded>
	</item>
		<item>
				<title>closures in php</title>
		<link>http://www.tagarga.com/blok/on/061218</link>
		<pubDate>Mon, 18 Dec 2006 00:00:00 GMT</pubDate>
						<description>Php is definitely not a suitable language for functional programming. Php functions live in a parallel reality - when your program starts, the construction of functions is complete, nothing can be changed anymore. However, Php is an open language (as it has `eval`), so it should be possible to do some experiments.</description>
		<content:encoded><![CDATA[<p>Here the function that creates a <a href="http://en.wikipedia.org/wiki/Closure_(computer_science)">closure</a>.</p>
<p>It expects two arguments: <code>vars</code>  is a hash that maps variables&#039; names to values (as in <a href="http://php.net/compact">compact</a>), <code>body</code> is  the code of resulting function. Within the <code>body</code> , $0, $1 etc. can be used as arguments placeholders.</p>
<pre><code>function closure($vars, $body) {
    global $_cvars;

    if(!isset($_cvars))
        $_cvars = array();
    $len = count($_cvars);
    $_cvars[$len] = $vars;

    $argc = 0;
    preg_replace(&#039;/\$(\d)/e&#039;, &#039;$argc = max($argc, $1)&#039;, $body);
    $args = &#039;$_&#039; . implode(&quot;=&#039;&#039;,\$_&quot;, range(0, $argc)) . &quot;=&#039;&#039;&quot;;
    $expr = preg_replace(&#039;/(?&lt;!\\\\)\\$(\d)/&#039;, &#039;$_$1&#039;, $body);

    return create_function($args, &quot;
        extract(\$GLOBALS[&#039;_cvars&#039;][$len], EXTR_REFS);
        $expr;
    &quot;);
}</code></pre>

<p>Example of using <code>closure</code> :</p>
<pre><code># fibonacci n-step number generator
# http://mathworld.wolfram.com/Fibonaccin-StepNumber.html

function fibonacci($n) {
    $a = array(1);
    return closure(compact(&#039;a&#039;, &#039;n&#039;), &#039;
        $f = end($a);
        $a[] = array_sum($a);
        if(--$n &lt;= 0)
            array_shift($a);
        return $f;
    &#039;);
}

# ordinary fibonacci numbers
$f = fibonacci(2);
for($i = 0; $i &lt; 20; $i++)
    echo $f(),&#039; &#039;;

# tetranacci numbers
$f = fibonacci(4);
for($i = 0; $i &lt; 20; $i++)
    echo $f(),&#039; &#039;;</code></pre>

<p>Calling  <code>compact</code>  and typing-in lists of variables can become tedious, therefore there&#039;s another interface that is able to discover variables automatically. The price is that you must use <code>eval</code>  with it.</p>
<pre><code>function cc($body) {
    $body = addcslashes($body, &quot;&#039;\\&quot;);
    $v = array();
    preg_replace(&#039;/(?&lt;!\\\\)\\$([a-zA-Z]\w*)/e&#039;,
        &#039;$v[]=&quot;$1&quot;&#039;, $body);
    if(!count($v))
        return &quot;return closure(array(), &#039;$body&#039;);&quot;;
    $v = &quot;&#039;&quot; . implode(&quot;&#039;,&#039;&quot;, array_unique($v)) . &quot;&#039;&quot;;
    return &quot;return closure(compact($v), &#039;$body&#039;);&quot;;
}</code></pre>

<p>The usage is <code>eval(cc(&#039;function body&#039;))</code> . Note that <code>cc</code>  is not very accurate about parsing, fancy variable-variables syntax will probably confuse it. PrÃ¦monitus, prÃ¦munitus. ;)</p>
<p><code>cc</code>  example:</p>
<pre><code>function file_reader($filename) {
    $fp = fopen($filename, &quot;r&quot;);
    return eval(cc(&#039;
        $line = fgets($fp);
        if(FALSE === $line)
            fclose($fp);
        return $line;
    &#039;));
}

function sql_reader($query, $separator) {
    $qq = mysql_query($query);
    return eval(cc(&#039;
        $rec = mysql_fetch_row($qq);
        if(!$rec) {
            mysql_free_result($qq);
            return FALSE;
        }
        return implode($separator, $rec);
    &#039;));
}

function line_printer($reader) {
    $n = 0;
    while(FALSE !== ($line = $reader())) {
        $n++;
        print &quot;line $n: $line&lt;br&gt;\n&quot;;
    }
}

# lets print a file, line-by-line
line_printer(file_reader(__FILE__));

# lets print a mysql table
line_printer(sql_reader(&#039;SHOW VARIABLES&#039;, &#039;=&#039;));</code></pre>
]]></content:encoded>
	</item>
		<item>
				<title>quasi blocchi in php</title>
		<link>http://www.tagarga.com/blok/on/061208</link>
		<pubDate>Fri, 08 Dec 2006 00:00:00 GMT</pubDate>
						<description>Every programmer knows that iterators are generally better than loops. Although php has a variety of iterator functions, their use is seriously limited, because there is no way to pass user code to the iterator.</description>
		<content:encoded><![CDATA[<p>The overly verbose create_function() is a very unequal replacement for lambdas or blocks, but in php we have no other choice.  We can only try to reduce verbosity.</p>
<pre><code>function qe($body) {
    static $cache = array();
    if(!isset($cache[$body])) {
        $argc = 0;
        preg_replace(&#039;/\$(\d)/e&#039;, &#039;$argc = max($argc, $1)&#039;, $body);
        $args = &#039;$_&#039; . implode(&quot;=&#039;&#039;,\$_&quot;, range(0, $argc)) . &quot;=&#039;&#039;&quot;;
        $expr = preg_replace(&#039;/\$(\d)/&#039;, &#039;$_$1&#039;, $body);
        $cache[$body] = create_function($args, &quot;return $expr;&quot;);
    }
    return $cache[$body];
}</code></pre>

<p><code>qe()</code>  (= &quot;quoted expression&quot;) creates a dynamic function from an expression given in a string. $0...$9 act as function parameters (like in preg_replace). Examples</p>
<pre><code># find odd numbers &lt; 30

$a = array_filter(range(1, 30), qe(&#039;$0 % 2&#039;));
print_r($a);

# muliply two arrays

$a = array(3, 5, 7);
$b = array(4, 6, 8);

$product = array_map(qe(&#039;$0 * $1&#039;), $a, $b);
print_r($product);</code></pre>

<p>Unlike create_function,  <code>qe</code>  also caches its results, so that the identical functions are created only once. This is quite practical when calling <code>qe</code>  in a loop.</p>
<p><code>qe</code>  requires its argument to be an expression, i.e. no operators are allowed. The slight variation called <code>qf</code>  (&quot;quoted function&quot;) takes the complete function body as an argument.</p>
<pre><code>function qf($body) {
    static $cache = array();
    if(!isset($cache[$body])) {
        $argc = 0;
        preg_replace(&#039;/\$(\d)/e&#039;, &#039;$argc = max($argc, $1)&#039;, $body);
        $args = &#039;$_&#039; . implode(&quot;=&#039;&#039;,\$_&quot;, range(0, $argc)) . &quot;=&#039;&#039;&quot;;
        $expr = preg_replace(&#039;/\$(\d)/&#039;, &#039;$_$1&#039;, $body);
        $cache[$body] = create_function($args, &quot;$expr;&quot;);
    }
    return $cache[$body];
}</code></pre>

<p>Example</p>
<pre><code>$apples = array(0, 1, 2, 3);

$messages = array_map(qf(&#039;
    if($0 == 0) return &quot;no apples&quot;;
    if($0 == 1) return &quot;one apple&quot;;
    else return &quot;$0 apples&quot;
&#039;), $apples);

print_r($messages);</code></pre>

<p>Of course, this kind of code only makes sense with very short function definitions.</p>
]]></content:encoded>
	</item>
		<item>
				<title>php serialize trickery</title>
		<link>http://www.tagarga.com/blok/on/061130</link>
		<pubDate>Thu, 30 Nov 2006 00:00:00 GMT</pubDate>
						<description>A couple of code snippets that show how to do some intriguing  stuff in oop php using serialization</description>
		<content:encoded><![CDATA[<h2>changing the class of an instance</h2>

<p>Convert object to a new class is fairly simple, because serializer stores class name along with object&#039;s data.  The new mutated object inherits the properties from source object, but not methods.</p>
<pre><code>function to_class($obj, $klass) {
    return unserialize(preg_replace(
        &#039;/^O:\d+:\&quot;(\w+)/&#039;,
        &#039;O:&#039; . strlen($klass) . &#039;:&quot;&#039; . $klass,
        serialize($obj)));
}

# example

class A {
    public $a_var = &quot;var in A\n&quot;;
    function a_method() {
        echo &quot;method in A\n&quot;;
    }
}

class B {
    public $b_var = &quot;var in B\n&quot;;
}

$old = new B;
$new = to_class($old, &#039;A&#039;);
$new-&gt;a_method();
echo $new-&gt;a_var;
echo $new-&gt;b_var;</code></pre>


<h2>accessing private members</h2>

<p>More convoluted (and far dirtier) serialize trick for accessing private members from outside of the class.</p>
<pre><code>function get_private($obj, $member) {
    $c = get_class($obj);
    $s = array(&quot;O:&quot;.strlen($c).&quot;:\&quot;$c\&quot;&quot;, &quot;\000$c\000$member&quot;);
    $r = array(&quot;O:8:\&quot;stdClass\&quot;&quot;, &quot;\001$c\001$member&quot;);
    $q = unserialize(str_replace($s, $r, serialize($obj)));
    return $q-&gt;{$r[1]};
}

function set_private(&amp;$obj, $member, $value) {
    $c = get_class($obj);
    $s = array(&quot;O:&quot;.strlen($c).&quot;:\&quot;$c\&quot;&quot;, &quot;\000$c\000$member&quot;);
    $r = array(&quot;O:8:\&quot;stdClass\&quot;&quot;, &quot;\001$c\001$member&quot;);
    $q = unserialize(str_replace($s, $r, serialize($obj)));
    $q-&gt;{$r[1]} = $value;
    $obj = unserialize(str_replace($r, $s, serialize($q)));
}

# example:

class A {
    private $x = &#039;foo&#039;;
    function echo_priv() {
        echo &quot;private x= &quot;,  $this-&gt;x, &quot;\n&quot;;
    }
}

$a = new A();

echo get_private($a, &#039;x&#039;), &quot;\n&quot;;

$a-&gt;echo_priv();
set_private($a, &#039;x&#039;, &#039;NEW&#039;);
$a-&gt;echo_priv();</code></pre>

<p>Important notice: these functions are not for use in production environments. ;)</p>
]]></content:encoded>
	</item>
		<item>
				<title>zend opcode dumper</title>
		<link>http://www.tagarga.com/blok/on/061124</link>
		<pubDate>Fri, 24 Nov 2006 00:00:00 GMT</pubDate>
						<description>This windows program I wrote recently prints Zend engine &#34;assembler&#34; generated from php code. Quite useful for understanding on what&#39;s going on there... and sometimes quite funny.</description>
		<content:encoded><![CDATA[]]></content:encoded>
	</item>
		<item>
				<title>ajaxik, the tiny ajax</title>
		<link>http://www.tagarga.com/blok/on/061103</link>
		<pubDate>Fri, 03 Nov 2006 00:00:00 GMT</pubDate>
						<description>Ajaxik is a tiny javascript library for basic ajax interaction, can also be used for &#34;lazy&#34; ajax (without javascript programming).</description>
		<content:encoded><![CDATA[<p><a href="/blok/download/ajaxik/ajaxik.js">download js file</a></p>


<p><style>
#BOX, #BOX_2 { border:1px dotted black;height:10em;width:48em;overflow:scroll; padding:1em;}
</style></p>
<h2>lazy ajax</h2>

<p>At page load time, Ajaxik finds forms and links in document, that have <code>jtarget</code> attribute and makes them ajax&#039;able. When user clicks such a link (or submits such a form), server response will be inserted in a html element instead of reloading the whole page. The value of <code>jtarget</code>  should be an ID of that element.</p>
<pre><code>&lt;a href=&quot;/files/ajaxik/test.php&quot; jtarget=&quot;BOX&quot;&gt;click me&lt;/a&gt;

&lt;div id=&quot;BOX&quot;&gt;&lt;/div&gt;</code></pre>

<div class='xmp'>
<a href="/files/ajaxik/test.php" jtarget="BOX">click me</a>

<div id="BOX"></div>
</div>
<p>If for some reason ajax cannot be started or any kind of error occurs during transfer, Ajaxik &quot;downgrades gracefully&quot; and just follows the link (or submits).</p>
<h2>on-demand initialization</h2>

<p>If you feel uncomfortable with a non-standard attribute and autoload, you can also <em>ajaxize</em> html elements in an unobtrusive way.</p>
<pre><code>Ajaxik.enable(element, target)</code></pre>

<p>This makes given <code>element</code>  (link or form) ajax&#039;able. <code>element</code>  and <code>target</code>  are DOM objects or their ids. No changes in html are needed.</p>
<pre><code>&lt;div id=&quot;LINKS&quot;&gt;&lt;a href=&quot;/files/ajaxik/test.php&quot;&gt;click me&lt;/a&gt;&lt;/div&gt;
&lt;div id=&quot;BOX&quot;&gt;&lt;/div&gt;

....

&lt;script&gt;
window.onload = function() {
    Ajaxik.enable(
          document.getElementById(&quot;LINKS&quot;).firstChild, 
          &quot;BOX&quot;)
}
&lt;/script&gt;</code></pre>


<h2>loading feedback</h2>

<p>When Ajaxik starts receiving data from the server, it searches for a special event handler on the target element: <code>onajax</code> .  If defined, the handler is invoked with three arguments: <code>readyState</code>  (which is <a href="http://www.xulplanet.com/references/objref/XMLHttpRequest.html">XMLHttpRequest</a> readyState property), <code>text</code>  (= server response, responseText) and <code>xmlhttp</code>  (XMLHttpRequest itself).</p>
<pre><code>&lt;a href=&quot;/files/ajaxik/test.php&quot; jtarget=&quot;BOX_2&quot;&gt;click me too&lt;/a&gt;

&lt;div id=&quot;BOX_2&quot; 
   onajax=&quot;this.innerHTML = (readyState==4) ? text : &#039;Loading...&#039; &quot;
&gt;&lt;/div&gt;</code></pre>

<div class='xmp'>
<a href="/files/ajaxik/test.php" jtarget="BOX_2">click me too</a>

<div id="BOX_2" 
   onajax="this.innerHTML = (readyState==4) ? text : 'Loading...' "
></div>
</div>
<p>Note that if you define the handler directly in HTML (like above), you should name the arguments exactly as documented. Out-of-line definition allows arbitrary argument names:</p>
<pre><code>someElement.onajax = function(ready, text_from_server, xml_http) { ... }</code></pre>


<h2>on the server side</h2>

<p>Ajaxik adds  <code>__ajax__</code>  variable (equal to some random integer) to the request. This makes it possible for server-side script to tell the difference between &quot;normal&quot; and ajax calls, e.g.</p>
<pre><code>if(isset($_REQUEST[&#039;__ajax__&#039;]))
    // output only updated block
else
    // output whole page</code></pre>


<h2>api</h2>

<p>For direct http communication there are two methods in Ajaxik, <code>get</code>  and <code>post</code> :</p>
<pre><code>Ajaxik.get(url, proc);
Ajaxik.post(url, data, proc);</code></pre>

<p><code>proc</code>  is an (optional) <code>onpropertychange</code>  callback, that takes three arguments: readyState, text and XMLHttpRequest object.</p>
<pre><code>Ajaxik.get(&#039;page.php&#039;, function(readyState, text, xmlhttp) {
    if(readyState == 4) {
        if(xmlhttp.status == 200)
            alert(text);
        else
            alert(&quot;Error!&quot;);
    }
})</code></pre>
]]></content:encoded>
	</item>
		<item>
				<title>there are %d monkeys in the tree</title>
		<link>http://www.tagarga.com/blok/on/061029</link>
		<pubDate>Sun, 29 Oct 2006 00:00:00 GMT</pubDate>
						<description>Simple functions to create php tree structures (nested arrays) from &#34;flat&#34; storage formats.</description>
		<content:encoded><![CDATA[<h2> Adjacency list to tree</h2>

<p><a href="http://google.com/search?q=adjacency+list">Adjacency lists</a> are widely used to store trees in SQL tables.  With ALs, inserts and updates are cheap, but retrieving the whole tree is tricky. Some people use recursion and nested queries for this (which doesn&#039;t scale well) or build JOIN statements dynamically (which is messy). The &quot;pure php&quot; solution is, on the contrary,  quite trivial: we simply select all rows and &quot;sieve&quot;  them through tree builder function.</p>
<pre><code>function adj_tree(&amp;$tree, $item) {
    $i = $item[&#039;id&#039;];
    $p = $item[&#039;parent_id&#039;];
    $tree[$i] = isset($tree[$i]) ? $item + $tree[$i] : $item;
    $tree[$p][&#039;_children&#039;][] = &amp;$tree[$i];
}

$tree = array();
$rs = my_query(&quot;SELECT * FROM categories&quot;);
while($row = my_fetch($rs))
    adj_tree($tree, $row);</code></pre>

<p>At the end, <code>$tree[0]</code>  contains the root of the hierarchy. Moreover, <code>$tree[N]</code>  will be a subtree for the node with id = N, so you can easily select subtrees.</p>
<h2>Indented lists</h2>

<p>The second function reconstructs the tree from the data &quot;printed&quot; as an indented list like this one (spaces replaced with dots for clarity):</p>
<pre><code>Hardware
...Scanners
....Monitors
......CRT monitors
.......LCD monitors
...Input devices
......Keyboards
......Mice</code></pre>

<p>The function is as follows:</p>
<pre><code>function indent_tree($text, $indent = &#039; &#039;) {
    $root  = array();
    $stack = array(&amp;$root);
    $depth = -1;
    $temp  = array();
    $re = &#039;/^(&#039; . preg_quote($indent) . &#039;)+/&#039;;
    $len = strlen($indent);

    foreach(explode(&quot;\n&quot;, trim($text)) as $line) {
        $v = preg_replace($re, &#039;&#039;, $line);
        $k = (strlen($line) - strlen($v)) / $len;
        while($depth-- &gt;= $k)
            array_pop($stack);
        while(++$depth &lt; $k) {
            array_unshift($temp, array());
            $stack[count($stack) - 1][&#039;_children&#039;][] = &amp;$temp[0];
            $stack[] = &amp;$temp[0];
        }
        $stack[count($stack) - 1][&#039;value&#039;] = trim($v);
    }
    return $root;
}</code></pre>

<p>The code doesn&#039;t require the list to be precisely indented: indents are rounded down,  you only need to pass  the &quot;average&quot; indent string (in above case, it would be three spaces).</p>
]]></content:encoded>
	</item>
		<item>
				<title>table sort</title>
		<link>http://www.tagarga.com/blok/on/061023</link>
		<pubDate>Mon, 23 Oct 2006 00:00:00 GMT</pubDate>
						<description>No, your eyes don&#39;t deceive you, this is Yet Another Javascript Table Sort script,  designed to be unobtrusive, simple and flexible... (skipped 1000 lines of happy talk ;)</description>
		<content:encoded><![CDATA[<link rel=stylesheet href="/files/tablesort/style.css">


<table><thead><tr><td>Login</td><td>Points</td><td>Created at</td><td>US&nbsp;Date</td><td>German Date</td><td>Money</td><td>Image</td></tr></thead><tbody><tr><td>Blythe</td><td>50</td><td>Wed, November 24, 2004</td><td>04/12/03</td><td>3.9.05</td><td align="right">$6,89</td><td>img20.png</td></tr><tr><td>Edmund</td><td>104</td><td>Fri, January 23, 2004</td><td>03/20/03</td><td>10.1.05</td><td align="right">$87,75</td><td>img27.png</td></tr><tr><td>Jonquil</td><td>12</td><td>Sat, January 22, 2005</td><td>04/15/03</td><td>30.8.04</td><td align="right">$1.239,14</td><td>img1b.png</td></tr><tr><td>Lee</td><td>55</td><td>Fri, March 11, 2005</td><td>06/03/05</td><td>4.5.05</td><td align="right">$41,74</td><td>img129.png</td></tr><tr><td>Sky</td><td>33</td><td>Fri, May 27, 2005</td><td>02/02/05</td><td>22.9.04</td><td align="right">-$8,92</td><td>img15.png</td></tr><tr><td>Archibald</td><td>75</td><td>Tue, January 18, 2005</td><td>01/14/04</td><td>23.2.04</td><td align="right">--</td><td>img10a.png</td></tr><tr><td>Emma</td><td>70</td><td>Tue, August 23, 2005</td><td>01/14/05</td><td>01.05.03</td><td align="right">$6,64</td><td>img.png</td></tr><tr><td>Erin</td><td>92</td><td>Tue, August 9, 2005</td><td>08/27/03</td><td>01.03.04</td><td align="right">$12,77</td><td>image</td></tr><tr><td>Edgar</td><td>25</td><td>Fri, January 2, 2004</td><td>12/22/03</td><td>12.06.05</td><td align="right">$56,20</td><td>img1.png</td></tr><tr><td>Prudence</td><td>85</td><td>Thu, April 29, 2004</td><td>05/13/04</td><td>15.8.03</td><td align="right">-$37,62</td><td>img10.png</td></tr><tr><td>Walter</td><td>50</td><td>Sun, March 16, 2003</td><td>03/27/04</td><td>16.7.05</td><td align="right">$1.234,56</td><td>&nbsp;</td></tr><tr><td>Reginald</td><td>81</td><td>Sat, March 8, 2003</td><td>10/07/04</td><td>21.3.05</td><td align="right">$74,74</td><td>img3.png</td></tr><tr><td>Mercy</td><td>50</td><td>Thu, June 17, 2004</td><td>09/04/03</td><td>30.07.05</td><td align="right">$75,96</td><td>img1.png</td></tr><tr><td>Holly</td><td>60</td><td>Tue, August 23, 2005</td><td>12/14/04</td><td>10.03.04</td><td align="right">$53,77</td><td>not found</td></tr><tr><td>Cedric</td><td>76</td><td>Mon, June 28, 2004</td><td>08/18/04</td><td>13.1.03</td><td align="right">$1,48</td><td>img1a.png</td></tr></tbody></table>

<p><a href="/blok/download/tablesort/tablesort.js">download js file</a></p>
<h2>usage</h2>

<pre><code>&lt;script src=&quot;tablesort.js&quot;&gt;&lt;/script&gt;</code></pre>

<p>that&#039;s all about it. ;)</p>
<p>By default, the script starts automatically at page load and makes all tables in document sortable. To disable autostart, set <code>TableSortNoAutoStart</code>  to <code>true</code> before including the script.</p>
<p>As usual, your tables should be divided into THEAD and TBODY, you also need to declare three css classes for table header cells, for example:</p>
<pre><code>/* indicates that the column can be sorted */
td.sortable
    { background:#606060; font-weight: bold; cursor: pointer; }

/* indicates that the column is sorted from low to high */
td.sorted_asc
    { background:#606060 url(up.gif) center right no-repeat; }

/* indicates that the column is sorted from high to low */
td.sorted_desc
    { background:#606060 url(down.gif) center right no-repeat; }</code></pre>

<h2>data types</h2>

<p>TS can handle different kinds of data in table columns.  The built-in sorting rules are</p>
<ul><li>nocase -- case-insensitive sort (default)
</li><li>alpha -- case-sensitive sort
</li><li>numeric -- 123 or 123.5 or 1e+3
</li><li>natural --  <a href="http://sourcefrog.net/projects/natsort/">natural</a> sort (like Image column in the table above)
</li><li>currency -- currency values like $0,55 or 1,234.56â¬
</li><li>date -- dates (in any format javascript <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date:parse">parse</a> can handle)
</li><li>usdate -- US dates (mm/dd/yyyy)
</li><li>eudate -- German dates (dd.mm.yyyy)</li></ul>

<p>TS is able to detect most data types based on the contents of the first cell in the column.</p>
<h2>api</h2>

<p>For javascript programmers among us ;) TS provides two public functions: <code>enable()</code>  and <code>sort()</code> . The prototype of <code>enable()</code>   is as follows</p>
<pre><code>TableSort.enable(table, column, compare)</code></pre>

<p>This turns on sorting of table <code>table</code>  on column <code>column</code>  using <code>compare</code>  as comparison function (well, was it really necessary to say that? Good programs don&#039;t need any documentation, do they? ;) Anyways,</p>
<ul><li><code>table</code>  is either an id or DOM table object
</li><li><code>column</code>  is a column number  (starting from 1) or title (without any html)
</li><li><code>compare</code>  is one of the rules listed above (in quotes) or a pointer to your own comparison function (as in <a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:sort">sort</a>)</li></ul>

<p>If an argument is omitted (use <code>&#039;&#039;</code>  or <code>null</code>  as placeholder when appropriate), TS uses the following defaults:</p>
<ul><li>if <code>table</code>  is omitted, it takes all tables (with THEADs)
</li><li>if <code>column</code>  is omitted, all columns will be sortable
</li><li>if <code>compare</code>  is omitted, TS does its best to guess the correct datatype for the column</li></ul>

<p>Examples:</p>
<pre><code>// sort all columns in all tables using default comparison rules
TableSort.enable()

// sort &#039;Points&#039; (the second) column in the &#039;people&#039; table
// using default comparison rule
TableSort.enable(&#039;people&#039;, &#039;Points&#039;)

// same as above
TableSort.enable(&#039;people&#039;, 2)

// same as above
TableSort.enable(document.getElementsByTagName(&#039;TABLE&#039;)[0],  2)

// sort &#039;Created at&#039; using &#039;human date&#039; comparison
TableSort.enable(&#039;people&#039;, &#039;Created at&#039;, &#039;date&#039;)

// sort &#039;Product Number&#039; in all tables using custom comparator
TableSort.enable(&#039;&#039;, &#039;Product Number&#039;,  MyDomain.compareProductNumbers)</code></pre>

<p>TS handles events (clicks) on its own, it is also possible to call the sorting function from your code. That&#039;s what the <code>sort</code>  method is for.</p>
<pre><code>TableSort.sort(table, column, compare)</code></pre>

<p>The parameters are as above, but <code>table</code>  and <code>column</code>  are required.</p>
<h2>previous work</h2>

<p>This script is based on the works of <a href="http://delete.me.uk/dom/07/">Paul Sowden</a> and <a href="http://www.kryogenix.org/code/browser/sorttable/">Stuart Langridge</a>. There is also a <a href="http://www.google.com/search?q=javascript+table+sort">plenty</a> of similar scripts already written...</p>
]]></content:encoded>
	</item>
		<item>
				<title>js debug console</title>
		<link>http://www.tagarga.com/blok/on/061003</link>
		<pubDate>Tue, 03 Oct 2006 00:00:00 GMT</pubDate>
						<description>Debug Console is a small utility for printing debug messages on the &#34;console&#34;. Console is simply a `textarea` hanging in the corner of the page. No popups, no fancy formatting, but simple, clean and cross-browser.

Console also provides utility functions for printing stack trace and for measuring execution speed.</description>
		<content:encoded><![CDATA[

<p><a href="/blok/download/dbgc.js">download js file</a></p>
<p>Here&#039;s what the Console can do (feel free to click &quot;try it&quot; links, to hide the console reload the page).</p>
<h3>p() -- print multiple arguments</h3>

<pre><code>p(&#039;hello&#039;, 99, [&#039;a&#039;, &#039;b&#039;, &#039;c&#039;], window.noSuchObject);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_6();return false'>try it</a></p>

<pre><code>// whitespaces are &quot;visible&quot;

p(&#039;a line \n with tabs\t\t and spaces\t and tabs&#039;);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_7();return false'>try it</a></p>

<pre><code>// trace nested array

ary = [1, 2, [33, [444, 555], 66], 7]
p(ary);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_8();return false'>try it</a></p>

<h3>pp() -- print a single structured object</h3>

<pre><code>// second argument is a maximal depth (negative = infinite)
// by default, functions are not traced

var person = {
    name : &#039;John&#039;, age : 33,
    occupation : {
        type : &#039;programmer&#039;,
        skills : {
            php : &#039;good&#039;,
            js : &#039;expert&#039;,
            ruby : &#039;poor&#039;
        },
        points: [1, 2, [33, 44], 5]
    },
    someMethod: function() { alert(&#039;Hi&#039;) }
}
pp(person, -1);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_9();return false'>try it</a></p>

<pre><code>// pp() is able to break infinite recursion

var ring = {
    a: 1, b: 2, c: 3
}
ring.self = ring
pp(ring, -1);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_10();return false'>try it</a></p>

<pre><code>// trace DOM node (default recursion depth 1 recommended)

pp(document.body);</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_11();return false'>try it</a></p>

<h3>dbgc &quot;API&quot;</h3>

<pre><code>Dbgc.print(&#039;Hello&#039;)</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_12();return false'>try it</a></p>

<pre><code>Dbgc.trace(&#039;Hello&#039;)</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_13();return false'>try it</a></p>

<pre><code>Dbgc.clear()</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_14();return false'>try it</a></p>

<pre><code>Dbgc.close()</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_15();return false'>try it</a></p>

<pre><code>alert(Dbgc.inspect(&#039;Hello&#039;))</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_16();return false'>try it</a></p>

<h3>miscellaneous</h3>

<pre><code>// time()
// measure execution time

function foo() {
    for(var i = 0; i != 500; i++)
        Math.sin(i)
}
Dbgc.print(Dbgc.time(foo))</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_17();return false'>try it</a></p>

<pre><code>// stack()
// print stack trace

function a(x, y, z) {
    Dbgc.stack();
}
function b(one, two) {
    a(11, 22, 33);
}
function c() {
    b(&#039;aa&#039;, &#039;bb&#039;);
}
c()</code></pre>


<p class='xmp_link'><a href='#' onclick='jsxmp_18();return false'>try it</a></p>
]]></content:encoded>
	</item>
	</channel>

</rss>