<?xml version='1.0' encoding='utf-8' ?>
<!--  If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/  -->
<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:media='http://search.yahoo.com/mrss/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>refusal computing</title>
  <link>http://aaronhawley.livejournal.com/</link>
  <description>refusal computing - LiveJournal.com</description>
  <lastBuildDate>Tue, 17 Apr 2012 12:22:09 GMT</lastBuildDate>
  <generator>LiveJournal / LiveJournal.com</generator>
  <lj:journal>aaronhawley</lj:journal>
  <lj:journalid>14167250</lj:journalid>
  <lj:journaltype>personal</lj:journaltype>
  <atom10:link rel='hub' href='http://pubsubhubbub.appspot.com/' />
  <image>
    <url>http://l-userpic.livejournal.com/68128516/14167250</url>
    <title>refusal computing</title>
    <link>http://aaronhawley.livejournal.com/</link>
    <width>48</width>
    <height>48</height>
  </image>

<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/29976.html</guid>
  <pubDate>Tue, 17 Apr 2012 12:22:09 GMT</pubDate>
  <title>Prius saves gas money? (follow-up)</title>
  <link>http://aaronhawley.livejournal.com/29976.html</link>
  <description>&lt;p&gt;Toyota makes the Prius -- a popular hybrid car that gets around 50 miles to the gallon (21 km/L, 4.7L/100km).  Presumably, these vehicles save you money at the fuel pump.  However, their sticker price is seemingly high.  One way to check the economic argument is to compare its total cost with a similar but non-hybrid conventional car and see when driving a hybrid starts saving you money.  A convenient and fair comparison is the Corolla also made by Toyota.&lt;/p&gt;

&lt;p&gt;Almost 5 years ago, &lt;a href=&quot;http://www.bfccomputing.com/2007/10/29/prius-or-corolla/&quot; rel=&quot;nofollow&quot;&gt;Bill McGonigle compared a Prius with a Corolla&lt;/a&gt; and found that only after driving 280613 miles (451603 km) will you start saving money.  &lt;a href=&quot;http://aaronhawley.livejournal.com/2790.html&quot;&gt;I confirmed his math with some simple Lisp programming&lt;/a&gt;.  Has this result changed?&lt;/p&gt;

&lt;p&gt;Five years later, the price of gas is up to 4 dollars (US) from 3 dollars but the price point for a Prius is higher.  You still need to drive 229354 (369109 km) miles before you start saving gas money.  That&apos;s 60000 miles (96560 km) less than 5 years ago.  Here&apos;s the arithmetic in the Emacs Lisp programming language.&lt;/p&gt;

&lt;pre&gt;
(let ((gas-price 4.0)         ;; dollars/gallon
      (prius-price 24000.0)   ;; US dollars
      (corolla-price 16130.0) ;; US dollars
      (prius-mileage 48.0)    ;; miles/gallon
      (corolla-mileage 34.0)) ;; miles/gallon
  (/
   (* prius-mileage corolla-mileage
      (/ (- prius-price corolla-price) gas-price))
   (- prius-mileage corolla-mileage)))
&lt;/pre&gt;

&lt;p&gt;Toyota has introduced a new &lt;em&gt;c model&lt;/em&gt; of the Prius this year.  A smaller-sized version, it is tuned to get better mileage in the city -- better than it does for highway driving.  It&apos;s also 15% cheaper than the regular Prius.  If you compared a city-driving Corolla with the Prius c you&apos;d only have to drive 38802 miles (62446 km).  That&apos;s pretty good, but is it a fair comparison?  Here&apos;s that arithmetic before I answer that question.&lt;/p&gt;

&lt;pre&gt;
(let ((gas-price 4.0)         ;; dollars/gallon
      (priusc-price 18950.0)  ;; US dollars
      (corolla-price 16130.0) ;; US dollars
      (priusc-mileage 53.0)   ;; miles/gallon
      (corolla-mileage 27.0)) ;; miles/gallon
  (/
   (* priusc-mileage corolla-mileage
      (/ (- priusc-price corolla-price) gas-price))
   (- priusc-mileage corolla-mileage)))
&lt;/pre&gt;

&lt;p&gt;Average drivers don&apos;t earn 15000 miles (24140 km) a year in the city.  Most of those miles are at a highway&apos;s pace.  Further, the smaller Prius c is more comparable to the Toyota Yaris than a Corolla.  Comparing the lower sticker price and highway mileage of a Yaris with the Prius c driven on the highway requires driving 264112 miles (425047 km).  Here&apos;s the arithmetic.&lt;/p&gt;

&lt;pre&gt;
(let ((gas-price 4.0)         ;; dollars/gallon
      (priusc-price 18950.0)  ;; US dollars
      (yaris-price 14115.0)   ;; US dollars
      (priusc-mileage 46.0)   ;; miles/gallon
      (yaris-mileage 38.0))   ;; miles/gallon
  (/
   (* priusc-mileage yaris-mileage
      (/ (- priusc-price yaris-price) gas-price))
   (- priusc-mileage yaris-mileage)))
&lt;/pre&gt;

&lt;p&gt;After 5 years, the hybrid car still isn&apos;t economical unless a typical owner drives one for 15 years.  According to Consumer Reports, &lt;a href=&quot;http://news.consumerreports.org/cars/2011/02/200000-mile-toyota-prius-still-performs.html&quot; rel=&quot;nofollow&quot;&gt;Toyota&apos;s reputation for reliability is extending to the Prius&lt;/a&gt;, where a Prius is able to maintain its efficiency and the batteries have held up after 10 years.  However, the average Prius owner probably doesn&apos;t hold on to the car this long.&lt;/p&gt;

&lt;p&gt;More likely, consumers purchase hybrid vehicles because of their reduced environmental impact.  It&apos;s &lt;a href=&quot;http://science.howstuffworks.com/science-vs-myth/everyday-myths/does-hybrid-car-production-waste-offset-hybrid-benefits1.htm&quot; rel=&quot;nofollow&quot;&gt;estimated that just producing a car can be 10 to 20% of a vehicle&apos;s lifetime emissions&lt;/a&gt;.  Presumably, the energy to make a Prius is greater than a conventional car since it has two engines (combustion and electrical) and additional battery.  However, Toyota doesn&apos;t release the estimated emissions from manufacturing a Prius.&lt;/p&gt;

&lt;p&gt;The city-optimized Prius c is a triple threat in metropolitan areas for its lower price, better efficiency and reduce impact on smog.  However, these places typically have mass transit.  The best way to save money is commute by walking, biking, car pooling or taking the bus or train.  These options are better for the environment as well.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/29976.html</comments>
  <category>programming</category>
  <category>emacs</category>
  <category>ecology</category>
  <lj:security>public</lj:security>
  <lj:reply-count>14</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/29617.html</guid>
  <pubDate>Thu, 05 Jan 2012 17:09:38 GMT</pubDate>
  <title>Spring cleaning</title>
  <link>http://aaronhawley.livejournal.com/29617.html</link>
  <description>&lt;p&gt;After 50 years as an academic economist, spending it deconstructing the neo-classical economics of Alfred Marshall and his &quot;Cambridge School&quot; -- of which she was a member early in her career -- and producing work deserving of a Nobel Prize, Joan Robinson would instead see the system resurrected in the US -- notably by the &quot;Chicago School&quot; of Milton Friedman and Fred Hayek.  In 1980, she commented on the poverty of orthodox economics and sketched a solution.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;q&gt;After the Second World War, the baton of leadership in teaching economics, along with leadership in the capitalist world, passed to the USA.  Instead of meeting the challenge of the Keynesian revolution head on, the profession in the USA split the subject into two parts, macro and micro.  In the macro section it was permissible to contemplate fluctuations in employment and even to hint at remedies for a deficiency in effective demand, while micro theory returned to the analysis of equilibrium established by the free play of market forces.  Keynesian ideas were allowed a certain sphere of operation while the central doctrine was safely walled off from them.[...]&lt;/q&gt;&lt;/p&gt;

&lt;p&gt;&lt;q&gt;The whole subject [of inequality] is so embarrassing that in fact it is scarcely mentioned.  There is no treatment at all of the determination of the distribution of income in orthodox teaching, and precious little about its consequences.  What to the general public appears one of the most interesting of all questions in economics is simply left out of the syllabus.&lt;/q&gt;&lt;/p&gt;

&lt;p&gt;&lt;q&gt;In its general influence on educated public opinion, orthodox teaching has been not merely feeble and confused but positively pernicious.  It gives support to the view that expenditure by a government that is beneficial to the inhabitants of its territory is &apos;socialism&apos; and must be prevented at all costs.  This reconciles an otherwise more or less sane and benevolent public opinion to the arms race which seems to be dragging us all to destruction.  But that is another story.&lt;/q&gt;&lt;/p&gt;

&lt;p&gt;&lt;q&gt;It seems to me that the whole complex of theories and models in the textbooks is in need of a thorough spring cleaning.  We should throw out all self-contradictory propositions, unmeasurable quantities and indefinable concepts and reconstruct a logical basis for analysis with what, if anything, remains.&lt;/q&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;From the essay &quot;The theory of normal prices and reconstruction of economic theory&quot; published in &lt;cite&gt;Issues in contemporary macroeconomics and distribution&lt;/cite&gt; edited by George R. Feiwel.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/29617.html</comments>
  <category>economy</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/29311.html</guid>
  <pubDate>Tue, 13 Dec 2011 18:25:58 GMT</pubDate>
  <title>Emacs custom global key bindings</title>
  <link>http://aaronhawley.livejournal.com/29311.html</link>
  <description>&lt;p&gt;The only place reserved for users to put custom global key bindings in Emacs is &lt;kbd&gt;`C-c LETTER&apos;&lt;/kbd&gt;.  (Obviously, all Emacs key bindings can be changed at ones own peril and people often do.)  Here&apos;s some examples.&lt;/p&gt;

&lt;pre&gt;
(global-set-key (kbd &quot;C-c r&quot;) &apos;query-replace-regexp)
(global-set-key (kbd &quot;C-c i&quot;) &apos;insert-buffer)
(global-set-key (kbd &quot;C-c w&quot;) &apos;write-region)
&lt;/pre&gt;

&lt;p&gt;I also used to like having short aliases for &lt;kbd&gt;`M-x&apos;&lt;/kbd&gt;.  Here&apos;s some popular ones used for working with Emacs Lisp.&lt;/p&gt;

&lt;pre&gt;
(defalias &apos;tdoe &apos;toggle-debug-on-error)
(defalias &apos;eval- &apos;eval-region) ;; M-x eval
(defalias &apos;load- &apos;load-file) ;; M-x load
(defalias &apos;ff &apos;find-function)
(defalias &apos;fv &apos;find-variable)
(defalias &apos;fl &apos;find-library)
(defalias &apos;ll &apos;load-library)
&lt;/pre&gt;

&lt;p&gt;I&apos;ve come across the strategy of using &lt;kbd&gt;`C-c&apos;&lt;/kbd&gt; and short words or phrases for key bindings rather than single keys.&lt;/p&gt;

&lt;pre&gt;
(global-set-key (kbd &quot;C-c now&quot;)
                (lambda ()
                  &quot;Insert current universal time.&quot;
                  (interactive &quot;*&quot;)
                  (insert
                   (format-time-string &quot;%Y-%m-%d %H:%M UTC&quot;
                                       (current-time) &apos;universal))))

(global-set-key (kbd &quot;C-c file&quot;) 
                (lambda (file &amp;optional args)
                  &quot;Insert name of FILE into buffer after point.&quot;
                  (interactive &quot;*fInsert file name: \nP&quot;)
                  (cond ((eq &apos;- args)
                         (insert (file-relative-name file)))
                        ((not (null args))
                         (insert (expand-file-name file)))
                        (t
                         (insert file)))))

(global-set-key (kbd &quot;C-c fill&quot;) &apos;fill-region)
(global-set-key (kbd &quot;C-c delete&quot;) &apos;delete-region)
(global-set-key (kbd &quot;C-c svn&quot;) &apos;svn-status)
(global-set-key (kbd &quot;C-c git&quot;) &apos;magit-status)
(global-set-key (kbd &quot;C-c compile&quot;) &apos;compile)
;; Same as M-x recompile
(global-set-key (kbd &quot;C-c recompile&quot;) &apos;recompile) 

(global-set-key (kbd &quot;C-c copy SPC line&quot;) ;; Repeat with `C-x z&apos;
                (lambda ()
                  (interactive)
                  (forward-line 1)
                  (open-line 1)
                  (copy-from-above-command))) ;; From misc.el
;; Same as M-x copy above RET
(global-set-key &quot;\C-ccopy above&quot; &apos;copy-from-above-command)
&lt;/pre&gt;

&lt;p&gt;For the seeing Emacs user, display the keys you&apos;ve pressed earlier by modifying this variable to something closer to the speed of the human eye.  By default, Emacs only shows the keys you&apos;ve entered in the echo area after every one second.&lt;/p&gt;

&lt;pre&gt;
(setq echo-keystrokes 0.02)
&lt;/pre&gt;


&lt;p&gt;It&apos;s nice how Emacs automatically creates prefix key maps for these long key sequences.  For instance, &lt;kbd&gt;`C-c compile&apos;&lt;/kbd&gt; and &lt;kbd&gt;`C-c copy line&apos;&lt;/kbd&gt; share the &lt;kbd&gt;`C-c c&apos;&lt;/kbd&gt; and &lt;kbd&gt;`C-c co&apos;&lt;/kbd&gt; prefixes. However, there is no way to use both single key bindings and the new longer ones simultaneously should they share letters.  When they conflict, the shorter will get stomped by the longer version. For example, the previous single key binding for &lt;kbd&gt;`C-c r&apos;&lt;/kbd&gt; will not work since it gets shadowed by &lt;kbd&gt;`C-c recompile&apos;&lt;/kbd&gt;.&lt;/p&gt;

&lt;p&gt;I&apos;m using a mix of both short and long key bindings since there are some editing commands that I need to keep on a short key binding but some less frequently used commands on single key bindings that I couldn&apos;t remember easily.  Although, it is a delicate dance of picking useful short phrases that don&apos;t conflict with single key bindings and vice versa.  I&apos;m not planning to get carried away with it all.  I&apos;m a &lt;a href=&quot;http://aaronhawley.livejournal.com/28413.html&quot;&gt;satisfied user of M-x&lt;/a&gt;.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/29311.html</comments>
  <category>emacs</category>
  <category>howto</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/29138.html</guid>
  <pubDate>Fri, 11 Nov 2011 16:50:13 GMT</pubDate>
  <title>World War Two Veteran Quote</title>
  <link>http://aaronhawley.livejournal.com/29138.html</link>
  <description>&lt;blockquote&gt;&lt;q&gt;I don’t think there’s ever been a good war, never been one.  It’s the height of ignorance.  I mean, it’s legalized murder.  You’re killing somebody and then your mother teaches you to believe in God and then, at 17, they say now we’re gonna show you how to kill.  It’s too schizophrenic.  It doesn’t make sense.  We should believe in God, believe in being a human being, and giving to the earth instead of taking from it.&lt;/q&gt; -- Anthony Dominick Benedetto
&lt;/blockquote&gt;

&lt;p&gt;Tony Bennett recently received criticism for making the obvious point about a so-called war on terrorism, &quot;But who are the terrorists? Are we the terrorists or are they the terrorists? Two wrongs don’t make a right.&quot;&lt;/p&gt;

&lt;p&gt;Tony Bennett served in the the US Army and a tour in the final year of the second World War that began in France and ended in Germany.  He saw the Battle of the Bulge, spent winter months in a foxhole, engaged in town-to-town fighting and liberated one of the German concentration camps at Dachau.&lt;/p&gt;

&lt;p&gt;It&apos;s said that freedoms in the US were and are fought for in wars here and abroad.  If you fight in a war don&apos;t you get the right to speak freely?  It was a corollary that never existed. It was invented.&lt;/p&gt;

&lt;p&gt;Studies have shown that recent veterans are facing unemployment at twice the US average.  Returning veterans represent nearly 1/5 of all suicides.  More recently, Dover Air Force Base has been found to be mishandling the remains of soldiers returning from US occupations and interventions.&lt;/p&gt;

&lt;p&gt;I do not participate in the genuflection and formal observance of Veteran&apos;s Day, but will support the rights and respect of veterans every day of the year.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/29138.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/28618.html</guid>
  <pubDate>Wed, 10 Aug 2011 13:58:48 GMT</pubDate>
  <title>Update to big Emacs reference card</title>
  <link>http://aaronhawley.livejournal.com/28618.html</link>
  <description>For the first time in over 2 years, I finally got around to updating my &lt;a href=&quot;http://www.emacswiki.org/emacs/Reference_Sheet_by_Aaron_Hawley&quot; rel=&quot;nofollow&quot;&gt;giant Emacs reference card&lt;/a&gt;.  There are now more than 1500 commands up from 1000.  It should also be consistent with the latest version of &lt;a href=&quot;http://www.gnu.org/software/emacs/&quot; rel=&quot;nofollow&quot;&gt;Emacs&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I transform the Wiki markup from a simple text markup using some &quot;quick and dirty&quot; Emacs Lisp.  Besides being easier to work on than Wiki markup, the source format is also printable.  The HTML version is almost 60 pages.  Using &lt;a href=&quot;http://www.gnu.org/software/a2ps/&quot; rel=&quot;nofollow&quot;&gt;a2ps&lt;/a&gt; on the text format it prints on 15 pieces of paper.&lt;br /&gt;&lt;br /&gt;It&apos;s a lot of work, but it&apos;s a good way for me to learn more about Emacs.  Hopefully, others will find it useful, too.  I suggest printing only a few sections that you would like to improve on.&lt;br /&gt;&lt;br /&gt;Since it is released under a bunch of free licenses, including version 2 or later of the &lt;a href=&quot;http://www.gnu.org/copyleft/gpl.html&quot; rel=&quot;nofollow&quot;&gt;GNU GPL&lt;/a&gt; and version 1.2 or later of the &lt;a href=&quot;http://www.gnu.org/licenses/fdl.html&quot; rel=&quot;nofollow&quot;&gt;GNU FDL&lt;/a&gt;, people are free to share and modify it.</description>
  <comments>http://aaronhawley.livejournal.com/28618.html</comments>
  <category>emacs</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/28413.html</guid>
  <pubDate>Wed, 13 Jul 2011 19:15:58 GMT</pubDate>
  <title>Learning Emacs key bindings</title>
  <link>http://aaronhawley.livejournal.com/28413.html</link>
  <description>&lt;p&gt;Emacs key bindings are intimidating at first since they are quite distinct from those used in other applications and platforms.  The following is based on discussion on the Emacs IRC channel and is posted to the &lt;a href=&quot;http://www.emacswiki.org/emacs/LearningEmacs&quot; rel=&quot;nofollow&quot;&gt;Emacs Wiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After studying the tutorial that comes with Emacs, most people learn best by doing and not just by reading over a list of commands and trying to memorize them. Get yourself a text file to play around with. Make a backup copy if you&apos;re nervous about losing it. But don&apos;t worry -- Emacs makes it hard to lose your work, and it has a great undo command: `&lt;kbd&gt;C-/&lt;/kbd&gt;&apos; or `&lt;kbd&gt;C-_&lt;/kbd&gt;&apos;.&lt;/p&gt;

&lt;p&gt;Keep the following advice in mind.&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;Try to memorize the most commonly used commands in the tutorial.
 &lt;li&gt;Use Apropos or help to find commands to accomplish a task.
 &lt;li&gt;Run the command for a task with `&lt;kbd&gt;M-x&lt;/kbd&gt;&apos; and typing it in.
 &lt;li&gt;Run the command again by using `&lt;kbd&gt;M-x M-p&lt;/kbd&gt;&apos; or by typing it in again.
 &lt;li&gt;On the third time, see if the command is bound to a key binding with `&lt;kbd&gt;C-h w&lt;/kbd&gt;&apos;.
 &lt;li&gt;If you forget a key binding (sometimes you forget even the basic commands introduced in the tutorial), try `&lt;kbd&gt;C-h w M-p&lt;/kbd&gt;&apos; to peek at it again or use `&lt;kbd&gt;C-h b&lt;/kbd&gt;&apos; to browse the available bindings.
 &lt;li&gt;If you can&apos;t burn a key binding in to your brain with this approach, then you&apos;re not using it enough and it doesn&apos;t deserve a key binding.
 &lt;li&gt;If a key binding is atrocious, only then bind the command to an unused key.
&lt;/ol&gt;

&lt;p&gt;Some beginners rush too quickly and add or change key bindings. This avoids learning Emacs and risks spending more time configuring. Competency with `&lt;kbd&gt;M-x&lt;/kbd&gt;&apos; and help are actually core Emacs skills for life. `&lt;kbd&gt;M-x&lt;/kbd&gt;&apos; should become your command line in Emacs.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/28413.html</comments>
  <category>emacs</category>
  <category>howto</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/27978.html</guid>
  <pubDate>Tue, 21 Jun 2011 18:05:29 GMT</pubDate>
  <title>Executive Director, GNOME Foundation </title>
  <link>http://aaronhawley.livejournal.com/27978.html</link>
  <description>It was announced today that &lt;a href=&quot;http://www.gnome.org/press/2011/06/karen-sandler-named-new-executive-director-of-the-gnome-foundation/&quot; rel=&quot;nofollow&quot;&gt;Karen Sandler was named new Executive Director of the GNOME Foundation&lt;/a&gt;.  I don&apos;t know Karen, nor am I currently a stock holder of Karen Sandler or the GNOME foundation, but she is a co-host of the &lt;a href=&quot;http://www.faif.us/&quot; rel=&quot;nofollow&quot;&gt;Free as in Freedom oggcast&lt;/a&gt; of which I&apos;m a dedicated listener.&lt;br /&gt;&lt;br /&gt;Given her years as general counsel at the &lt;a href=&quot;http://www.softwarefreedom.org/&quot; rel=&quot;nofollow&quot;&gt;Software Freedom Law Center&lt;/a&gt; (SFLC) and the usual legal experience appointing a lawyer to a board gives, Karen is also a good appointment for her non-law insights on free software development by building organizations that sustain and protect the free software ecosystem.</description>
  <comments>http://aaronhawley.livejournal.com/27978.html</comments>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/27271.html</guid>
  <pubDate>Thu, 24 Sep 2009 06:39:48 GMT</pubDate>
  <title>Refusing to learn</title>
  <link>http://aaronhawley.livejournal.com/27271.html</link>
  <description>An essay called &lt;a href=&quot;http://dept-info.labri.u-bordeaux.fr/~strandh/Essays/psychology.html&quot; rel=&quot;nofollow&quot;&gt;The psychology of learning&lt;/a&gt; from 2003 by &lt;a href=&quot;http://dept-info.labri.u-bordeaux.fr/~strandh/index.en.html&quot; rel=&quot;nofollow&quot;&gt;Robert Strandh&lt;/a&gt;, director of the D&amp;eacute;partement d&apos;Informatique at Universit&amp;eacute; Bordeaux, France, describes a trend in computing where close-mindedness (my phrase) risks opportunities for learning &lt;em&gt;and&lt;/em&gt; effectiveness.&lt;br /&gt;&lt;br /&gt;The bad-mouthing of competing technologies by adherents of another technology is well known.&amp;nbsp; The practice goes back to early days of hacker culture when arguments would abound in choice of programming languages (or assembly), mainframe manufacturer or model (consider also &amp;quot;PC&amp;nbsp;versus Mac&amp;quot; over the last two recent decades).&amp;nbsp; These divisions can partition customers, industries and educators into islands with different customs and ideas.&amp;nbsp; Strandh doesn&apos;t visit this in the essay.&amp;nbsp; No, according to Strandh, opinions like these arise in young students in more subtle but still worrisome ways.&lt;br /&gt;&lt;blockquote&gt;[...] I have often observed that students are very inefficient in their work.  They frequently use methods of working that are unproductive and slow.  Some examples:&lt;ul&gt;&lt;li&gt;&lt;div&gt;Students do not know how to touch-type.  Instead of taking the        relatively limited time to learn to do it, they waste many hours per week on slow typing and typing errors.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;Students frequently do not know how to use advanced features in        the text editor such as the interface to the version-control        system, the interface to the Lisp system, etc.  Again instead        of taking a short time to learn, they waste much more time.&lt;/li&gt;&lt;li&gt;Students do not know how to use a debugger.  Instead, they        waste time debugging programs with trace output. [...]&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;Strandh suggests this could simply be &amp;quot;reluctance to learning new tools and methods&amp;quot;, but can also become &amp;quot;a kind of reaction orders of magnitude stronger&amp;quot;.  He attributes the reaction to &amp;quot;a need to achieve performance &lt;em&gt;immediately&lt;/em&gt;&amp;quot; (original emphasis).  Continuing:&lt;br /&gt;&lt;blockquote&gt;Such performance leaves no time for intellectual curiosity.  Instead, techniques already known to them must be applied to solve problems.  To these people, failure is a disaster whose sole feature is to harm instant performance.  Similarly, learning represents the possibility of failure and must thus be avoided if possible.  To the people in this category, knowledge in other people also represents a threat. As long as everybody around them use tools, techniques, and methods that they themselves know, they can count on outperforming these other people.  But when the people around them start learning different, perhaps better, ways, they must defend themselves. [...]&lt;/blockquote&gt;Strandh attributes these behaviors to a description given to him personally by Boston College psychology professor, &lt;a href=&quot;http://www2.bc.edu/~barretli/&quot; rel=&quot;nofollow&quot;&gt;Lisa Feldman Barrett&lt;/a&gt;, who in turn cites the work of well-known psychologist &lt;a href=&quot;http://en.wikipedia.org/wiki/Carol_Dweck&quot; rel=&quot;nofollow&quot;&gt;Carol Dweck&lt;/a&gt;. The research which posits a duality of &lt;dfn&gt;perfection-oriented&lt;/dfn&gt; and &lt;dfn&gt;performance-oriented&lt;/dfn&gt; is worth looking into as an explanation.&lt;br /&gt;&lt;br /&gt;The best part of the essay are not about the psychology theory, but his personal anecdotes on computing inspired by the psychology researcher&apos;s works.&lt;br /&gt;&lt;blockquote&gt;[...] I talked to a student of computer science who told me why a particular programming language was bad.  In fact he told me it was so bad that he had moved to a different university in order to avoid courses that used that particular language.  When asked, he admitted he had never written a single program in that language.  He simply did not know what he was talking about.  And he was willing to fight for it. [...]&lt;br /&gt;&lt;br /&gt;[...] I have seen professors in mathematics who were obviously perfection-oriented with respect to mathematics, be firmly in the performance-oriented category with respect to the efficient use of (say) word processors.  It is almost a surrealistic experience to see a person in one situation full of intellectual curiosity and wanting to know everything about everything, and in another situation argue why you should not use a particular method that he himself does not know anything about, for reasons that are obviously totally artificial. [...]&lt;br /&gt;&lt;br /&gt;[...] I have observed that people ignorant in a particular domain, or not knowing a particular tool or technique, would go to great trouble to explain why knowing this domain, tool, or technique, would be a complete waste of time. Usually these explanations were based on erroneous ideas of what it represented.  To make things worse, they were perfectly willing to present their erroneous arguments to the very experts in the field in question. [...]&lt;br /&gt;&lt;/blockquote&gt;In this anecode, Strandh likely admits his membership in the Church of Emacs.&lt;br /&gt;&lt;blockquote&gt;[...]  I have heard people argue against a tool that they ignore based on the fact that it can do &lt;em&gt;too much&lt;/em&gt;.  Too much functionality in a tools is a problem only if unneeded or unwanted functionality somehow makes it harder to use the needed and wanted parts.  I have heard people argue about the amount of memory a particular tool requires, whereas the additional memory required might represent a cost equivalent to a few hours of work at most.  A favorite idea is to label a particular tool with a name suggesting what it ought to be doing, and then arguing that it is doing &lt;em&gt;more&lt;/em&gt; than that.  For instance, a text editor that is capable of automatic indentation would be accused of being a &amp;quot;kitchen-sink&amp;quot; tool because after all it does much more than allowing the user to just edit text. (original emphasis) [...]&lt;br /&gt;&lt;/blockquote&gt;Strandh ends by revealing his own transgressions of this same type.&lt;br /&gt;&lt;blockquote&gt;[...] I myself recently discovered a marvelous feature in a programming language that I had purposely avoided for the past 10 years, simply because 10 years ago, a colleague (who did not know the feature) explained to me that it was no good.  We were both victims of our own minds.  My colleague because he obviously needed to defend that he had made a different choice, and myself because I subconsciously found it very appealing to be able to brush off the feature as useless and thus not having to learn it.  It is hard to overestimate the wasted time I have put in during the past 10 years due to considerably lower productivity than I could have had, had I realized at the time what I now know about human psychology. [...]&lt;/blockquote&gt;I would add another possible explanation for these reactions is another one rooted in &amp;quot;human psychology&amp;quot;:&amp;nbsp; It is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Defence_mechanism&quot; rel=&quot;nofollow&quot;&gt;defense mechanism&lt;/a&gt;.&amp;nbsp; Computing possesses a great diversity and many ways to do things.&amp;nbsp; Barring a few mighty monopolies in hardware and software, there still exists much complexity and specialization in the field of computing.&amp;nbsp; As regressive overt opinions are, the instinct may be a method for people to manage and focus on their work.&amp;nbsp; This would especially be the case for budding students.&amp;nbsp; Avoiding potentially labor-saving tools and knowledge in the rush to finish a task is unfortunate, but investigating alternatives has to be limited or else a task is never started.&amp;nbsp; It&apos;s like the lumberjack (or jill) in the metaphor who sharpens their saw or axe but never cut the tree down since they never got around to swinging the axe.&lt;br /&gt;&lt;br /&gt;Despite my sympathy, people who let this close-minded instinct take over and influence themselves and others is indefensible.&amp;nbsp; People should simply answer &amp;quot;I don&apos;t know&amp;quot; rather than than making &amp;quot;complete fools of themselves&amp;quot; by expressing what are only hunches.&amp;nbsp; A couple famous quotes about &amp;quot;ignorance&amp;quot; and &amp;quot;fear&amp;quot; are probably worth inserting here.&amp;nbsp; I&apos;ll leave it as an exercise.&amp;nbsp; The point is stop being cavalier and just admit you don&apos;t know rather than trying to prove knowing everything.</description>
  <comments>http://aaronhawley.livejournal.com/27271.html</comments>
  <category>programming</category>
  <category>emacs</category>
  <category>software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/25343.html</guid>
  <pubDate>Mon, 29 Jun 2009 21:26:19 GMT</pubDate>
  <title>Iran is not a twitter revolution</title>
  <link>http://aaronhawley.livejournal.com/25343.html</link>
  <description>&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Reese_Erlich&quot; rel=&quot;nofollow&quot;&gt;Reese Erlich&lt;/a&gt; is a freelance journalist and author who&apos;s been covering recent events in Iran -- *from Iran* and not just his computer chair like many in the mainstream media have.&lt;/p&gt;

&lt;p&gt;He recently countered &quot;left-wing Doubting Thomas arguments&quot; in an &lt;a href=&quot;http://www.commondreams.org/view/2009/06/28-10&quot; rel=&quot;nofollow&quot;&gt;article on Common Dreams .org&lt;/a&gt;.  In his arguments, I found these observations about Iranians &quot;fighting for political, social and economic justice&quot; inspiring.&lt;/p&gt;

&lt;blockquote&gt;

&lt;p&gt;[...]&lt;/p&gt;

&lt;p&gt;Assertion: The U.S. has a long history of meddling in Iran, so it must be behind the current unrest. &lt;/p&gt;

&lt;p&gt;[...]&lt;/p&gt;

&lt;p&gt;Frankly, based on my observations, no one was leading the demonstrations. During the course of the week after the elections, the mass movement evolved from one protesting vote fraud into one calling for much broader freedoms. You could see it in the changing composition of the marches. There were not only upper middle class kids in tight jeans and designer sun glasses. There were growing numbers of workers and women in very conservative chadors.&lt;/p&gt;

&lt;p&gt;Iranian youth particularly resented President Ahmadinejad&apos;s support for religious militia attacks on unmarried young men and women walking together and against women not covering enough hair with their hijab. Workers resented the 24 percent annual inflation that robbed them of real wage increases. Independent trade unionists were fighting for decent wages and for the right to organize.&lt;/p&gt;

&lt;p&gt;Some demonstrators wanted a more moderate Islamic government. Others advocated a separation of mosque and state, and a return to parliamentary democracy they had before the 1953 coup. But virtually everyone believes that Iran has the right to develop nuclear power, including enriching uranium. Iranians support the Palestinians in their fight against Israeli occupation, and they want to see the U.S. get out of Iraq.&lt;/p&gt;

&lt;p&gt;So if the [sic] CIA was manipulating the demonstrators, it was doing a piss poor job.&lt;/p&gt;

&lt;p&gt;[...]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;See also Erlich&apos;s &lt;a href=&quot;http://blogs.reuters.com/great-debate/author/reeseerlich/&quot; rel=&quot;nofollow&quot;&gt;Iran is not a twitter revolution&lt;/a&gt;.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/25343.html</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/24759.html</guid>
  <pubDate>Wed, 24 Jun 2009 20:25:06 GMT</pubDate>
  <title>Drivable Motor Vehicle Act</title>
  <link>http://aaronhawley.livejournal.com/24759.html</link>
  <description>I noticed an &lt;a href=&quot;http://drupal.geek.nz/blog/richard-stallman-free-software-christchurch#comment-375&quot; rel=&quot;nofollow&quot;&gt;old comment posted to someone&apos;s site&lt;/a&gt; by &lt;span class=&apos;ljuser ljuser-name_mjd_blog&apos; lj:user=&apos;mjd_blog&apos; style=&apos;white-space:nowrap&apos;&gt;&lt;a href=&apos;http://mjd-blog.livejournal.com/profile&apos;&gt;&lt;img src=&apos;http://l-stat.livejournal.com/img/syndicated.gif?v=92.1&apos; alt=&apos;[info]&apos; width=&apos;16&apos; height=&apos;16&apos; style=&apos;vertical-align: bottom; border: 0; padding-right: 1px;&apos;/&gt;&lt;/a&gt;&lt;a href=&apos;http://mjd-blog.livejournal.com/&apos;&gt;&lt;b&gt;Matthew Davidson&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; who wrote a car metaphor for free software.  This is a commonly used metaphor device, but I think it&apos;s especially good.  (I *swear* I didn&apos;t find this in a search for my own surname).&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;I drive a little Toyota hatchback. I do so because I got it relatively cheap from my sister-in-law. This was possible because she owned the car, [instead of having] a non-transferable license to use the car under certain conditions.&lt;br /&gt;&lt;br /&gt;I know how to pump up the tyres and refill the thing that squirts water on the windscreen. That&apos;s all I know about maintaining the vehicle, and probably all I ever will know. I take it to the local mechanic of my choice every couple of years and he fustigates the Smoot-Hawley flanges or whatever for me, at what I can only assume is a reasonable price.&lt;br /&gt;&lt;br /&gt;I am very glad that the bonnet was not locked shut at the factory by Toyota, and that there is not a Drivable Motor Vehicle Act (DMVA) to make it a criminal offense for anybody to attempt to service their own car, or pay somebody other than the manufacturer to service it. I may not personally know the first thing about its [sic] inner workings, but if I suspect I&apos;m being charged to much for some work on my car, I can go a few hundred metres up the road to the next mechanic who can provide me with a quote.&lt;br /&gt;&lt;br /&gt;Most of these mechanics probably chose this trade after opening up the bonnet of their own car and having a playful poke around, the same way I learned how to program computers. Now as Richard Stallman would say, the ethical issues around car manufacturing and software manufacturing are not the same; I don&apos;t have the legal right to make a perfect copy of my car, but that&apos;s okay because I don&apos;t have the practical means to do so -- no matter how much technical skill I am able to acquire, and neither does anybody but very large corporations, so losing that freedom (through patents) doesn&apos;t cost me anything, while potentially delivering the benefits to society that the patent system [for car manufacturing] is supposed to provide.&lt;br /&gt;&lt;br /&gt;But if somebody paid me to write some software for them and I said &quot;okay, I&apos;ll write it for you, but only under the condition that you don&apos;t copy it or attempt to fix or improve it yourself, or pay somebody else to fix or improve it,&quot; that would be a very bad deal for the customer, because the means to do these things are so cheap that you are practically only paying for the time of the person who does the work (or not, if you do it yourself). It would be such a bad deal in fact, that if I managed to convince a sucker to fall for it, I would have to regard my own behaviour as unethical.&lt;br /&gt;&lt;br /&gt;Granted there aren&apos;t as many programmers as motor vehicle mechanics in my town, but that can and should change. Already I can point to half a dozen people I know who could (and hopefully will) become as familiar with the inner workings of [the free software package] Drupal as myself with only a little effort. As this begins to happen across a wide range of software the real cost of proprietary software (as opposed to the mere price tag), and the benefits of freedom, will become apparent to even the most non-technical users.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Speaking of &quot;tryes&quot;, &quot;metres&quot; and &quot;bonnets&quot;; the &lt;a href=&quot;http://www.endsoftpatents.org/&quot; rel=&quot;nofollow&quot;&gt;end software patents campaign&lt;/a&gt; needs help documenting the patent issue in &lt;a href=&quot;http://en.swpat.org/wiki/Australia&quot; rel=&quot;nofollow&quot;&gt;Australia&lt;/a&gt; and &lt;a href=&quot;http://en.swpat.org/wiki/New_Zealand&quot; rel=&quot;nofollow&quot;&gt;New Zealand&lt;/a&gt;, among other locales.</description>
  <comments>http://aaronhawley.livejournal.com/24759.html</comments>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/24499.html</guid>
  <pubDate>Thu, 18 Jun 2009 18:05:14 GMT</pubDate>
  <title>Release of dump package</title>
  <link>http://aaronhawley.livejournal.com/24499.html</link>
  <description>The &lt;a href=&quot;http://dump.sourceforge.net/&quot; rel=&quot;nofollow&quot;&gt;dump/restore package&lt;/a&gt; version 0.4b42 is being released today.  It is the first release in over 3 years.  &lt;a href=&quot;http://sourceforge.net/project/shownotes.php?group_id=1306&amp;amp;release_id=690716&quot; rel=&quot;nofollow&quot;&gt;Read the release notes&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It supports versions two through four of the Linux kernel&apos;s extended file system (ext2, ext3, ext4).  Technically, it is considered beta software, but I have reason to believe there are a lot of people who use it in production systems.  You can also use it for disk-based backups.  You don&apos;t need to have a &lt;a href=&quot;http://en.wikipedia.org/wiki/Tape_jukebox&quot; rel=&quot;nofollow&quot;&gt;tape jukebox&lt;/a&gt; to use it, although it is designed for use with tape backups.</description>
  <comments>http://aaronhawley.livejournal.com/24499.html</comments>
  <category>unix</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/24262.html</guid>
  <pubDate>Thu, 28 May 2009 19:39:53 GMT</pubDate>
  <title>Sorting UTF-8 strings in PHP</title>
  <link>http://aaronhawley.livejournal.com/24262.html</link>
  <description>&lt;p&gt;With Unicode characters, in this case the popular UTF-8, sometimes you need to convert characters to ASCII to get things done in PHP.  In the case of sorting Unicode, there are the existing solutions of &lt;a href=&quot;php.net/collator.sort&quot;&gt;collator_sort()&lt;/a&gt; for PHP5 and &lt;a href=&quot;http://php.net/strcoll&quot; rel=&quot;nofollow&quot;&gt;strcoll()&lt;/a&gt; since PHP4.  However, they both assume a locale.  A hack that is locale-agnostic would just &quot;normalize&quot; Unicode characters to ASCII.&lt;/p&gt;

&lt;p&gt;This is far from complete, but seems to do the right thing.&lt;/p&gt;

&lt;pre&gt;
    &lt;span style=&quot;color: #da70d6;&quot;&gt;&amp;lt;?php&lt;/span&gt;

    &lt;span style=&quot;color: #b22222;&quot;&gt;/**&lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
     * Normalize international characters for purposes like sorting and
     * searching by using a heuristic that just uses ASCII--the english
     * alphabet ordering--for a multilingual solution--no locale setting.
     &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;*/&lt;/span&gt;
    &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;header(&lt;/span&gt;&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;Content-type: text/plain; charset=utf-8&quot;&lt;/span&gt;);

    &lt;span style=&quot;color: #b22222;&quot;&gt;/**&lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
     * I&amp;#241;t&amp;#235;rn&amp;#226;ti&amp;#244;n&amp;#224;liz&amp;#230;ti&amp;#248;n
     *
     * Example from Sam Ruby
     * http://intertwingly.net/stories/2004/04/14/i18n.html
     * 
     * By way of WACT team
     * http://www.phpwact.org/php/i18n/charsets
     &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;*/&lt;/span&gt;
    $&lt;span style=&quot;color: #b8860b;&quot;&gt;internationalization&lt;/span&gt; = &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;array(&lt;/span&gt;
				  &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;I&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;I
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB1&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#241;
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;t&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;t
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xAB&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#235;
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;r&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;r
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;n&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;n
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA2&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#226;
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;t&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;t
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;i
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB4&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#244;
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;n&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;n
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA0&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#224;
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;l&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;l
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;i
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;z&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;z
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA6&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#230;
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;t&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;t
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;i
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB8&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#248;
    &lt;/span&gt;                              &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;n&quot;&lt;/span&gt;); &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;n
    &lt;/span&gt;
    &lt;span style=&quot;color: #b22222;&quot;&gt;/** &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
     * Use strtr() with this dictionary to convert to ASCII.
     * This data structure is not comprehensive.
     &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;*/&lt;/span&gt;
    $&lt;span style=&quot;color: #b8860b;&quot;&gt;utf8_dict&lt;/span&gt; = &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;array(&lt;/span&gt;&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x80&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#192;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x81&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#193;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x82&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#194;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x83&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#195;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x84&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#196;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x85&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#197;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x86&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;A&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#198;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x9E&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;B&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#222;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x87&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;C&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#199;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\x86&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;C&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#262;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\x8C&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;C&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#268;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\x90&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;Dj&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#272;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x88&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;E&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#200;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x89&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;E&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#201;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x8A&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;E&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#202;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x8B&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;E&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#203;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\x9E&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;G&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#286;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x8C&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;I&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#204;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x8D&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;I&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#205;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x8E&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;I&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#206;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x8F&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;I&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#207;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\xB0&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;I&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#304;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x91&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;N&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#209;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x92&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;O&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#210;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x93&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;O&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#211;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x94&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;O&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#212;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x95&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;O&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#213;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x96&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;O&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#214;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x98&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;O&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#216;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x9F&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;Ss&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#223;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x99&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;U&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#217;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x9A&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;U&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#218;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x9B&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;U&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#219;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x9C&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;U&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#220;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\x9D&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;Y&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#221;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA0&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#224;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA1&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#225;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA2&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#226;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA3&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#227;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA4&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#228;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA5&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#229;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA6&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;a&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#230;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xBE&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;b&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#254;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA7&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;c&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#231;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\x87&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;c&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#263;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\x8D&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;c&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#269;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC4\x91&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;dj&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#273;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA8&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;e&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#232;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xA9&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;e&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#233;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xAA&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;e&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#234;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xAB&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;e&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#235;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xAC&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#236;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xAD&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#237;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xAE&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#238;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xAF&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;i&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#239;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB0&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;o&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#240;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB1&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;n&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#241;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB2&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;o&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#242;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB3&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;o&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#243;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB4&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;o&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#244;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB5&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;o&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#245;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB6&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;o&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#246;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB8&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;o&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#248;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC5\x94&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;R&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#340;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC5\x95&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;r&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#341;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC5\xA0&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;S&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#352;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC5\x9E&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;S&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#350;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC5\xA1&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;s&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#353;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xB9&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;u&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#249;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xBA&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;u&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#250;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xBB&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;u&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#251;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xBC&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;u&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#252;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xBD&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;y&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#253;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xBD&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;y&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#253;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC3\xBF&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;y&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#255;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC5\xBD&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;Z&quot;&lt;/span&gt;, &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#381;
    &lt;/span&gt;                   &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\xC5\xBE&quot;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;z&quot;&lt;/span&gt;); &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;#382;
    &lt;/span&gt;
    $&lt;span style=&quot;color: #b8860b;&quot;&gt;i18n&lt;/span&gt; = &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;join(&lt;/span&gt;&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;&quot;&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;internationalization&lt;/span&gt;);
    &lt;span style=&quot;color: #a020f0;&quot;&gt;print&lt;/span&gt; $&lt;span style=&quot;color: #b8860b;&quot;&gt;i18n&lt;/span&gt; . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\n&quot;&lt;/span&gt;;

    &lt;span style=&quot;color: #b22222;&quot;&gt;/**&lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
     * UTF-8 regular expression from
     * http://php.net/manual/en/function.utf8-decode.php (comment 57069)
     &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;*/&lt;/span&gt;
    $&lt;span style=&quot;color: #b8860b;&quot;&gt;utf8_re&lt;/span&gt; = &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;/^([\\x00-\\x7f]|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;[\\xc2-\\xdf][\\x80-\\xbf]|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\\xe0[\\xa0-\\xbf][\\x80-\\xbf]|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;[\\xe1-\\xec][\\x80-\\xbf]{2}|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\\xed[\\x80-\\x9f][\\x80-\\xbf]|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\\xef[\\x80-\\xbf][\\x80-\\xbc]|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\\xee[\\x80-\\xbf]{2}|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\\xf0[\\x90-\\xbf][\\x80-\\xbf]{2}|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;[\\xf1-\\xf3][\\x80-\\xbf]{3}|&quot;&lt;/span&gt;
      . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\\xf4[\\x80-\\x8f][\\x80-\\xbf]{2})*$/&quot;&lt;/span&gt;;

    &lt;span style=&quot;color: #a020f0;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;Valid UTF-8?: &quot;&lt;/span&gt; . (&lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;preg_match(&lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;utf8_re&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;i18n&lt;/span&gt;) &amp;gt; &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;0&lt;/span&gt;
			      ? &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;true&quot;&lt;/span&gt; : &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;false&quot;&lt;/span&gt;) . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\n&quot;&lt;/span&gt;;

    &lt;span style=&quot;color: #a020f0;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;strtr(&lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;i18n&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;utf8_dict&lt;/span&gt;) . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\n&quot;&lt;/span&gt;;

    &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;Doesn&apos;t work in PHP4?
    &lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;sorted&lt;/span&gt; = &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;preg_split(&lt;/span&gt;&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;//u&quot;&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;i18n&lt;/span&gt;, -&lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;1&lt;/span&gt;, &lt;span style=&quot;color: #ff0000; font-weight: bold;&quot;&gt;PREG_SPLIT_NO_EMPTY&lt;/span&gt;);
    &lt;span style=&quot;color: #b22222;&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;So, just use the original array, instead.
    &lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;sorted&lt;/span&gt; = $&lt;span style=&quot;color: #b8860b;&quot;&gt;internationalization&lt;/span&gt;;

    &lt;span style=&quot;color: #a020f0;&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;compare&lt;/span&gt;($&lt;span style=&quot;color: #b8860b;&quot;&gt;s1&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;s2&lt;/span&gt;)
    {
      &lt;span style=&quot;color: #a020f0;&quot;&gt;global&lt;/span&gt; $&lt;span style=&quot;color: #b8860b;&quot;&gt;utf8_dict&lt;/span&gt;;
      &lt;span style=&quot;color: #a020f0;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;strcasecmp(strtr(&lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;s1&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;utf8_dict&lt;/span&gt;),
			&lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;strtr(&lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;s2&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;utf8_dict&lt;/span&gt;));
    }

    &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;usort(&lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;sorted&lt;/span&gt;, &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;compare&quot;&lt;/span&gt;);
    &lt;span style=&quot;color: #a020f0;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;join(&lt;/span&gt;&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;&quot;&lt;/span&gt;, $&lt;span style=&quot;color: #b8860b;&quot;&gt;sorted&lt;/span&gt;) . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\n&quot;&lt;/span&gt;;

    &lt;span style=&quot;color: #b22222;&quot;&gt;/**&lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
     * Results:
     * 
     * I&amp;#241;t&amp;#235;rn&amp;#226;ti&amp;#244;n&amp;#224;liz&amp;#230;ti&amp;#248;n
     * Valid UTF-8?: true
     * Internationalization
     * &amp;#224;&amp;#230;&amp;#226;&amp;#235;Iiiil&amp;#241;nnn&amp;#248;&amp;#244;rtttz
     &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;*/&lt;/span&gt;
    &lt;span style=&quot;color: #da70d6;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;I tried the &lt;a href=&quot;http://pear.php.net/package/I18N_UnicodeNormalizer&quot; rel=&quot;nofollow&quot;&gt;I18N_UnicodeNormalizer&lt;/a&gt; from the PHP PEAR project, and it didn&apos;t do what I wanted.&lt;/p&gt;

&lt;pre&gt;
    &lt;span style=&quot;color: #da70d6;&quot;&gt;&amp;lt;?php&lt;/span&gt;

    &lt;span style=&quot;color: #a020f0;&quot;&gt;require_once&lt;/span&gt;(&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&apos;I18N/UnicodeNormalizer.php&apos;&lt;/span&gt;);

    &lt;span style=&quot;color: #a020f0;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #228b22;&quot;&gt;I18N_UnicodeNormalizer&lt;/span&gt;::&lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;toNFD(&lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;i18n&lt;/span&gt;) . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\n&quot;&lt;/span&gt;;
    &lt;span style=&quot;color: #a020f0;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #228b22;&quot;&gt;I18N_UnicodeNormalizer&lt;/span&gt;::&lt;span style=&quot;color: #000000; background-color: #ffffff;&quot;&gt;toNFC(&lt;/span&gt;$&lt;span style=&quot;color: #b8860b;&quot;&gt;i18n&lt;/span&gt;) . &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;\n&quot;&lt;/span&gt;;
    &lt;span style=&quot;color: #da70d6;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;There&apos;s a good chance I don&apos;t know what I&apos;m doing there with the PEAR library, however.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/24262.html</comments>
  <category>programming</category>
  <category>php</category>
  <category>howto</category>
  <lj:security>public</lj:security>
  <lj:reply-count>6</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/23852.html</guid>
  <pubDate>Wed, 27 May 2009 18:33:38 GMT</pubDate>
  <title>Unicode hex in PHP string</title>
  <link>http://aaronhawley.livejournal.com/23852.html</link>
  <description>&lt;p&gt;In Emacs, insert UTF-8 hex value for a PHP string of the character at point.&lt;/p&gt;

&lt;pre&gt;
(defun php-hex-for-char ()
  (interactive)
  (insert
   (mapconcat (lambda (x) (format &quot;\\x%02X&quot; x))
              (encode-coding-char (char-after (point)) &apos;utf-8)
              &quot;&quot;)))

&lt;/pre&gt;

&lt;p&gt;Lisp lifted from `describe-char&apos; and `encoded-string-description&apos;.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/23852.html</comments>
  <category>programming</category>
  <category>php</category>
  <category>emacs</category>
  <category>howto</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/23429.html</guid>
  <pubDate>Mon, 18 May 2009 22:26:06 GMT</pubDate>
  <title>Shell hack: Files with some DOS lines</title>
  <link>http://aaronhawley.livejournal.com/23429.html</link>
  <description>&lt;p&gt;I came across a project whose source code contains both DOS text files and Unix text files.  Some of the Unix files contain carriage return line endings.  Though, perhaps they were DOS files with Unix end lines!  I wanted to suggest converting those files with mixed line endings to Unix.&lt;/p&gt;

&lt;p&gt;Sometimes, the &lt;tt&gt;file&lt;/tt&gt; command is helpful for showing what files have a mixed end of line style, but not always.  For example, the &lt;tt&gt;file&lt;/tt&gt; command will say &quot;ASCII C program text, with CRLF, LF line terminators&quot;.  That&apos;s perfect.  However, sometimes the command just says, &quot;PHP script text&quot;.&lt;/p&gt;

&lt;p&gt;I wrote this &lt;tt&gt;find&lt;/tt&gt; expression that would get files that contain DOS carriage returns, but not entirely DOS files.&lt;/p&gt;

&lt;pre&gt;
$ find -type f -execdir grep -qe &apos;^V^M$&apos; {} \; \
       ! -execdir awk &apos;BEGIN{is_dos=1;}!/\r$/{is_dos=0}END{exit(!is_dos);}&apos; {} \; \
       -print
&lt;/pre&gt;

&lt;p&gt;The above doesn&apos;t work, since many DOS files don&apos;t end in a newline (and without a carriage return) as they do for Unix text files.&lt;/p&gt;

&lt;p&gt;Awk obviously considers the last line as a line, but since there&apos;s no carriage return the file is not considered a DOS file based on the logic I&apos;ve written.  This results in a false negative.&lt;/p&gt;

&lt;p&gt;This change to the Awk script makes this hack work as it should.&lt;/p&gt;

&lt;pre&gt;
$ find -type f -execdir grep -qe &apos;^V^M$&apos; {} \; \
       ! -execdir awk &apos;BEGIN{is_dos=1;}
                       !/\r$/ &amp;&amp; is_dos{is_dos=0;n=NR}
                       END{exit(!is_dos &amp;&amp; n != NR);}&apos; {} \; \
       -print
&lt;/pre&gt;</description>
  <comments>http://aaronhawley.livejournal.com/23429.html</comments>
  <category>programming</category>
  <category>unix</category>
  <category>howto</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/23288.html</guid>
  <pubDate>Wed, 13 May 2009 20:43:10 GMT</pubDate>
  <title>Send Amazon&apos;s Bezos some peaches</title>
  <link>http://aaronhawley.livejournal.com/23288.html</link>
  <description>I just noticed there was a great action by the FSF&apos;s anti-DRM campaign last month against Amazon&apos;s Kindle electronic book.  See &lt;a href=&quot;http://www.defectivebydesign.org/impeach-jeff-bezos-for-kindle-swindle&quot; rel=&quot;nofollow&quot;&gt;Defective by Design: Impeach Bezos for Amazon&apos;s Kindle Swindle&lt;/a&gt;.  The idea is to send baby food peaches to Jeff Bezos for having terms that allow Amazon to deny customer&apos;s access to read their electronic books.&lt;br /&gt;&lt;br /&gt;Sending baby food is pretty easy in the age of the Internet, see the link and instructions at the end of the post.</description>
  <comments>http://aaronhawley.livejournal.com/23288.html</comments>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/22856.html</guid>
  <pubDate>Tue, 05 May 2009 18:08:18 GMT</pubDate>
  <title>Change log entries for HTML files</title>
  <link>http://aaronhawley.livejournal.com/22856.html</link>
  <description>&lt;p&gt;Someone asked me if there was a good way to annotate the changes of an HTML file.  It sounded like the person had to maintain some legacy, HTML-hell, home-brewed, template files for some business Web site.&lt;/p&gt;

&lt;p&gt;I suggested using the &lt;a href=&quot;http://www.gnu.org/software/emacs/manual/html_node/emacs/Change-Log.html&quot; rel=&quot;nofollow&quot;&gt;ChangeLog support of Emacs&lt;/a&gt;, and using HTML comments to organize sections of an HTML source file.  Here&apos;s a simple, made-up example of such an HTML file.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;html&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;head&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;&gt;Sample only&lt;/span&gt;&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;title&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;head&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;body&lt;/span&gt;&amp;gt;
&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;lt;!-- begin header --&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;p&lt;/span&gt;&amp;gt;[ &amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;color: #b8860b;&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;top&quot;&lt;/span&gt; &lt;span style=&quot;color: #b8860b;&quot;&gt;href&lt;/span&gt;=&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;#bottom&quot;&lt;/span&gt;&amp;gt;bottom&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;a&lt;/span&gt;&amp;gt; ]&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;p&lt;/span&gt;&amp;gt;
&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;lt;!-- end header --&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;span style=&quot;font-weight: bold; text-decoration: underline;&quot;&gt;Sample title&lt;/span&gt;&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;h1&lt;/span&gt;&amp;gt;
&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;lt;!-- BEGIN: PAGE_CONTENT --&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;div&lt;/span&gt;&amp;gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;p&lt;/span&gt;&amp;gt;Testing.&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;p&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;div&lt;/span&gt;&amp;gt;
&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;lt;!-- END: PAGE_CONTENT --
  -- footer-bottom start --&amp;gt;&lt;/span&gt;
&amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;p&lt;/span&gt;&amp;gt;[ &amp;lt;&lt;span style=&quot;color: #0000ff;&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;color: #b8860b;&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;bottom&quot;&lt;/span&gt; &lt;span style=&quot;color: #b8860b;&quot;&gt;href&lt;/span&gt;=&lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;#top&quot;&lt;/span&gt;&amp;gt;top&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;a&lt;/span&gt;&amp;gt; ]&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;p&lt;/span&gt;&amp;gt;
&lt;span style=&quot;color: #b22222;&quot;&gt;&amp;lt;!-- footer-bottom end --&amp;gt;&lt;/span&gt;
&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;body&lt;/span&gt;&amp;gt;
&amp;lt;/&lt;span style=&quot;color: #0000ff;&quot;&gt;html&lt;/span&gt;&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Unfortunately, support for either the above sectioning style, or even another alternative, is not provided by the &lt;a href=&quot;http://www.gnu.org/software/emacs/manual/html_node/emacs/HTML-Mode.html&quot; rel=&quot;nofollow&quot;&gt;HTML mode&lt;/a&gt; that ships with Emacs.  This is understandable because there is no consistent standard of doing this, and people use other variations than even those covered in the example.  Not to mention, HTML comments are used for other reasons than naming regions of the file.&lt;/p&gt;

&lt;p&gt;Regardless, I&apos;ve put together the following regular expression for &lt;code&gt;add-log-current-defun-header-regexp&lt;/code&gt;.  It handles the cases in the example above.  It is set for all buffers using HTML mode.  Just put the following in your &lt;a href=&quot;http://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html&quot; rel=&quot;nofollow&quot;&gt;&lt;tt&gt;.emacs&lt;/tt&gt; file&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;
    (add-hook &apos;html-mode-hook
        (lambda ()
          (make-local-variable
           &apos;add-log-current-defun-header-regexp)
           (setq add-log-current-defun-header-regexp
               (concat &quot;^[ \t]*&amp;lt;?!?--[ \t]*\\(?:begin\\|BEGIN\\|start\\)?&quot;
                       &quot;[ \t:]*\\([-_[:alnum:]]+\\)&quot;
                       &quot;[ \t]*\\(?:begin\\|BEGIN\\|start\\)?[ \t]*--&quot;))))
&lt;/pre&gt;

&lt;p&gt;Use it by typing `&lt;kbd&gt;C-x 4 a&lt;/kbd&gt;&apos; (&lt;tt&gt;add-change-log-entry-other-window&lt;/tt&gt;).  An entry like the following will be added in a nearby &lt;tt&gt;ChangeLog&lt;/tt&gt; file:&lt;/p&gt;
    &lt;pre&gt;
&lt;span style=&quot;color: #bc8f8f;&quot;&gt;2009-05-05  &lt;/span&gt;&lt;span style=&quot;color: #5f9ea0;&quot;&gt;Aaron S. Hawley&lt;/span&gt;  &amp;lt;&lt;span style=&quot;color: #b8860b;&quot;&gt;aaronhawley@livejournal.com&lt;/span&gt;&amp;gt;

        * &lt;span style=&quot;color: #0000ff;&quot;&gt;file.html&lt;/span&gt; (&lt;span style=&quot;color: #a020f0;&quot;&gt;PAGE_CONTENT&lt;/span&gt;): Add a test paragraph.
        (&lt;span style=&quot;color: #a020f0;&quot;&gt;footer-bottom&lt;/span&gt;): Added link to &quot;#top&quot;.
&lt;/pre&gt;

&lt;p&gt;This setup will work for most cases except for scenarios where there is nested sectioning or where you&apos;ve run `&lt;kbd&gt;C-x 4 a&lt;/kbd&gt;&apos; from a point outside of a &quot;section&quot; and get a false-positive.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/22856.html</comments>
  <category>programming</category>
  <category>emacs</category>
  <category>howto</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/22779.html</guid>
  <pubDate>Fri, 01 May 2009 09:26:43 GMT</pubDate>
  <title>Shell hack: Avoiding built-ins</title>
  <link>http://aaronhawley.livejournal.com/22779.html</link>
  <description>&lt;p&gt;To avoid using a &lt;em&gt;builtin&lt;/em&gt; command of a Bourne or Bash shell in a shell script, one can use the full path of the executable command.  For example, rather than&lt;/p&gt;

&lt;pre&gt;
$ echo Hello, World\!
Hello, World!
&lt;/pre&gt;

&lt;p&gt;you could&lt;/p&gt;

&lt;pre&gt;
$ /bin/echo Hello, World\!
Hello, World!
&lt;/pre&gt;

&lt;p&gt;Here&apos;s a way to show the difference--and make fun of the &lt;a href=&quot;http://www.gnu.org/prep/standards/&quot; rel=&quot;nofollow&quot;&gt;GNU coding standards&lt;/a&gt; at the same time.&lt;/p&gt;

&lt;pre&gt;
$ echo --version
--version
&lt;/pre&gt;

&lt;pre&gt;
$ /bin/echo --version
echo (GNU coreutils) 6.12
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3 : GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Brian Fox and Chet Ramey.
&lt;/pre&gt;

&lt;p&gt;I prefer to use &lt;code&gt;exec&lt;/code&gt; than using the full path for a command so that the &lt;tt&gt;PATH&lt;/tt&gt; environment variable is used, and avoid the day should the full path to a binary change some day.&lt;/p&gt;

&lt;p&gt;Unfortunately, a consequence of &lt;code&gt;exec&lt;/code&gt; is that it runs the command in the current process and therefore will exit on completion, thus cutting short the life of your shell script.  To avoid that, just wrap an exec statement in a sub-shell by using parens:&lt;/p&gt;

&lt;pre&gt;
$ ( exec echo --version )
echo (GNU coreutils) 6.12
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3 : GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Brian Fox and Chet Ramey.
&lt;/pre&gt;

&lt;p&gt;I have never seen this written in a script before.  Perhaps, there&apos;s another way--that&apos;s a bit more canonical--to do this.  This construct is entirely redundant and contradictory--&quot;exec something in the current shell, but also in a sub-shell&quot;.  Further, it&apos;s probably pretty much always the case to opt for the shell built-in.  There are zero to no cases where you want to avoid the built-in.  My only scenarios are &lt;a href=&quot;http://aaronhawley.livejournal.com/9225.html&quot;&gt;timing processes in the shell&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;According to the &lt;a href=&quot;http://www.gnu.org/software/autoconf/manual/html_node/Limitations-of-Builtins.html&quot; rel=&quot;nofollow&quot;&gt;Limitations of Shell Builtins&lt;/a&gt; section of the GNU Autoconf manual,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When it is desired to avoid a regular shell built-in, the workaround is
to use some other forwarding command, such as &lt;samp&gt;&lt;span&gt;env&lt;/span&gt;&lt;/samp&gt; or
&lt;samp&gt;&lt;span&gt;nice&lt;/span&gt;&lt;/samp&gt;, that will ensure a path search:&lt;/p&gt;

     &lt;pre&gt;          $ &lt;kbd&gt;pdksh -c &apos;exec true --version&apos; | head -n1&lt;/kbd&gt;

          $ &lt;kbd&gt;pdksh -c &apos;nice true --version&apos; | head -n1&lt;/kbd&gt;
          true (GNU coreutils) 6.10
          $ &lt;kbd&gt;pdksh -c &apos;env true --version&apos; | head -n1&lt;/kbd&gt;
          true (GNU coreutils) 6.10
     &lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;That manual has everything it it.  I guess I&apos;ll go with &lt;code&gt;env&lt;/code&gt;, doesn&apos;t sound as nice as &quot;&lt;code&gt;exec&lt;/code&gt;&quot;, but it&apos;s a good mnemonic since it use the &lt;em&gt;environment&lt;/em&gt;&apos;s path variable to run the command.&lt;/p&gt;

&lt;pre&gt;
$ env echo --version
echo (GNU coreutils) 6.12
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Brian Fox and Chet Ramey.
&lt;/pre&gt;</description>
  <comments>http://aaronhawley.livejournal.com/22779.html</comments>
  <category>unix</category>
  <category>programming languages</category>
  <category>howto</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>6</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/21792.html</guid>
  <pubDate>Sun, 26 Apr 2009 05:42:40 GMT</pubDate>
  <title>Shell hack: Date work</title>
  <link>http://aaronhawley.livejournal.com/21792.html</link>
  <description>&lt;p&gt;Needed to make some &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_alias.html#redirect&quot; rel=&quot;nofollow&quot;&gt;Apache redirects&lt;/a&gt; for some links on a unix user&apos;s group Web site I maintain.  The new site is based in a Wiki, and a member of the group moved all the pages with meeting announcements by hand using more readable page names.  The old pages had the data as a four-digit year, two-digit month followed by the two-digit day (for example, &lt;samp&gt;20061219&lt;/samp&gt;).  The new pages have the spelled out version of the week day and month (for example, &lt;samp&gt;Tuesday, December 19, 2006&lt;/samp&gt;).&lt;/p&gt;

&lt;p&gt;Here&apos;s a sample of what I needed for the &lt;tt&gt;.htaccess&lt;/tt&gt; file.&lt;/p&gt;

&lt;pre&gt;
Redirect /group/meeting-20061219.html   http://host.org/group/wiki/index.php/Tuesday,_December_19,_2006
Redirect /group/meeting-20070417.html   http://host.org/group/wiki/index.php/Tuesday,_April_17,_2007
Redirect /group/meeting-20070515.html   http://host.org/group/wiki/index.php/Tuesday,_May_15,_2007
Redirect /group/meeting-20070717.html   http://host.org/group/wiki/index.php/Tuesday,_July_17,_2007
Redirect /group/meeting-20071128.html   http://host.org/group/wiki/index.php/Wednesday,_November_28,_2007
Redirect /group/meeting-20080618.html   http://host.org/group/wiki/index.php/Wednesday,_June_18,_2008
&lt;/pre&gt;

&lt;p&gt;I could do this by-hand, but I&apos;d rather get a shell script to do it right, the first time.  I found it easy to do with an &lt;a href=&quot;http://www.gnu.org/software/grep/doc/grep_12.html&quot; rel=&quot;nofollow&quot;&gt;extended Grep expression&lt;/a&gt;, &lt;a href=&quot;http://www.gnu.org/software/gawk/&quot; rel=&quot;nofollow&quot;&gt;awk&lt;/a&gt; and the &lt;tt&gt;date&lt;/tt&gt; command that comes with &lt;a href=&quot;http://www.gnu.org/software/coreutils/&quot; rel=&quot;nofollow&quot;&gt;GNU coreutils&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;
$ ls -1 \
  | grep -Ee &apos;[0-9]{8}.html$&apos; \
  | perl -pe &apos;s/([0-9]{4})([0-9]{2})([0-9]{2}).html$/$&amp;\t\1-\2-\3/&apos; \
  | awk &apos;{printf $1 &quot;\t&quot;;
          system(&quot;date +\&quot;%A,_%B_%e,_%Y\&quot; -d &quot;  $2);}&apos; \
  | awk &apos;{print &quot;Redirect&quot;, &quot;/group/&quot; $1,
                &quot;http://host.org/group/wiki/index.php/&quot; $2;}&apos;
&lt;/pre&gt;

&lt;p&gt;I&apos;m thankful I consistently used a file naming convention with the old site.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/21792.html</comments>
  <category>programming</category>
  <category>unix</category>
  <category>howto</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>8</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/21687.html</guid>
  <pubDate>Fri, 24 Apr 2009 01:26:36 GMT</pubDate>
  <title>Database programming</title>
  <link>http://aaronhawley.livejournal.com/21687.html</link>
  <description>&lt;p&gt;This simple bit of PHP made some changes to a MediaWiki installation for me recently.  Don&apos;t use it.  My point here is in showing the satisfaction from changing a database with code that generates the SQL statements for you.   The golden rule for database applications is to make sure there&apos;s an interface or programming layer to the actual database to preserve data integrity and keep changes limited in scope.  One should use some of the scripts that come with MediaWiki--&lt;code&gt;batchMove.php&lt;/code&gt; or &lt;code&gt;namespaceDupes.php&lt;/code&gt; for example--to do this.  Such scripts are better trusted, but also handle the schema should it change in a later release of the software.&lt;/p&gt;

&lt;p&gt;Now that the disclaimer is out of the way, I was pleasantly surprised how consistent the schema for MediaWiki was for allowing me to rely on simple data structures and some for-loops to update 9 tables.  Clearly, the schema isn&apos;t entirely normalized, but I predict there is a rationale for having some of the data &lt;a href=&quot;http://en.wikipedia.org/wiki/Denormalization&quot; rel=&quot;nofollow&quot;&gt;denormalized&lt;/a&gt;.  Given this scenario, it is a real compliment to a software package and its schema if one can write very concise code to generate a series of SQL statements for a task.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;?php
// Move 3 pages, and start 2 namespaces.  Don&apos;t use this code!

$table = array(&apos;page&apos; =&amp;gt; &apos;mw_page&apos;,
	       &apos;rc&apos; =&amp;gt; &apos;mw_recentchanges&apos;,
	       &apos;pl&apos; =&amp;gt; &apos;mw_pagelinks&apos;,
	       &apos;pt&apos; =&amp;gt; &apos;mw_protected_titles&apos;,
	       &apos;qc&apos; =&amp;gt; &apos;mw_querycache&apos;,
	       &apos;qcc&apos; =&amp;gt; &apos;mw_querycachetwo&apos;,
	       &apos;rd&apos; =&amp;gt; &apos;mw_redirect&apos;,
	       &apos;tl&apos; =&amp;gt; &apos;mw_templatelinks&apos;,
	       &apos;wl&apos; =&amp;gt; &apos;mw_watchlist&apos;);

$namespaces = array(100 =&amp;gt; &apos;ThisWiki&apos;,
		    /* 101 =&amp;gt; &apos;ThisWiki talk&apos;, */
		    110 =&amp;gt; &apos;RPM&apos;,
		    /* 111 =&amp;gt; &apos;RPM talk&apos; */);

$rename = array(&apos;Changes_to_Wiki_database&apos; =&amp;gt; &apos;ThisWiki:Changes_to_database&apos;,
		&apos;LocalSettings.php&apos; =&amp;gt; &apos;ThisWiki:LocalSettings.php&apos;,
		&apos;Changes_to_Monobook_skin&apos;
		  =&amp;gt; &apos;ThisWiki:Changes_to_Monobook_skin&apos;);

foreach ($table as $short =&amp;gt; $t) {
  // Move:
  foreach ($rename as $orig =&amp;gt; $new) {
    foreach (array(0 =&amp;gt; &apos;&apos;, 1 =&amp;gt; &apos;Talk&apos;) as $old_ns =&amp;gt; $old_name) {
      printf(&quot;UPDATE %s\n&quot;
	     . &quot;SET %s_title = &apos;%s&apos;\n&quot;
	     . &quot;WHERE %s_title = &apos;%s&apos; AND %s_namespace = %d;\n&quot;,
	     $t, $short, $new, $short, $orig, $short, $old_ns);
    }
  }
  // Fix namespace:
  foreach ($namespaces as $num =&amp;gt; $name) {
    foreach (array(0 =&amp;gt; &apos;&apos;, 1 =&amp;gt; &apos;Talk&apos;) as $old_ns =&amp;gt; $old_name) {
      printf(&quot;UPDATE %s\n&quot;
	     . &quot;SET %s_title = REPLACE(%s_title, &apos;%s:&apos;, &apos;&apos;), &quot;
	     . &quot;%s_namespace = %d\n&quot;
	     . &quot;WHERE %s_title LIKE &apos;%s:%%&apos; AND %s_namespace = %d;\n&quot;,
	     $t, $short, $short, $name, $short, $num + $old_ns,
	     $short, $name, $short, $old_ns);
    }
  }
}
?&amp;gt;
&lt;/pre&gt;

&lt;p&gt;It&apos;s dangerous to show this code, because someone may come to this page after a Web search and erroneously think this is the way to introduce namespaces in MediaWiki or something.  I&apos;ll say it again: Don&apos;t use this!&lt;/p&gt;

&lt;p&gt;Unfortunately, generating SQL statements by-hand is a dirty little secret of database maintenance.  I&apos;ve seen database maintenance done by evaluating SQL commands one-at-time more often than I&apos;d like.  Instead of being programmatic and more efficient, &quot;easter egging&quot; methods often introduce typos by either rousing &quot;copy and paste&quot; hell or a &quot;search and replace&quot; hell, and therefore risks typo errors and who knows what else.  Writing database maintenance scripts programmaticaly enables you to work as a single transaction and study the results in each iteration.  This quality forces one to use a test version of the data and avoid another database &lt;em&gt;faux pas&lt;/em&gt; -- working on live databases.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/21687.html</comments>
  <category>database</category>
  <category>programming</category>
  <category>free software</category>
  <category>software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/21031.html</guid>
  <pubDate>Sun, 19 Apr 2009 06:08:32 GMT</pubDate>
  <title>Study Emacs with Lisp or natural language?</title>
  <link>http://aaronhawley.livejournal.com/21031.html</link>
  <description>There was a back and forth between Emacs bloggers Jared Dilettante and Ian Eure about whether Emacs users should &lt;a href=&quot;http://curiousprogrammer.wordpress.com/2009/04/16/dangerous-elisp/&quot; rel=&quot;nofollow&quot;&gt;write Emacs Lisp code for their own purposes&lt;/a&gt; or whether &lt;a href=&quot;http://atomized.org/2009/04/central-documentation-and-wasted-effort/&quot; rel=&quot;nofollow&quot;&gt;working in Emacs Lisp should primarily be in support of existing modes&lt;/a&gt;--and with the mode&apos;s documentation thoroughly read.  At this point, the argument has fizzled out, but its worth pointing out that a manual for &lt;a href=&quot;http://www.geocities.com/kensanata/emacs-sql.html&quot; rel=&quot;nofollow&quot;&gt;SQL mode&lt;/a&gt; doesn&apos;t seem to exist.  SQL mode, like most Emacs modes, is &lt;a href=&quot;http://www.emacswiki.org/emacs/SelfDocumentation&quot; rel=&quot;nofollow&quot;&gt;self-documented&lt;/a&gt; well.  However, this argument is evidence that it could probably use a manual.&lt;br /&gt;&lt;br /&gt;As someone who&apos;s neither a trained writer nor a good one, I know that writing in one&apos;s own spoken language is difficult.  However, writing concise documentation about Emacs can be just as important as writing Emacs Lisp code, if not maybe more so.  Writing documentation will give you a deeper understanding of how something works and help you learn things you didn&apos;t already know.   It&apos;s also important because the documentation you write will help someone else to learn how to use Emacs, too.&lt;br /&gt;&lt;br /&gt;Documenting Emacs also improves your Emacs Lisp skills because you&apos;ll likely be reading other hacker&apos;s Emacs Lisp code.  Most important of all you&apos;ll be working on existing code for Emacs rather than making more when it is not entirely necessary to reinvent the wheel.&lt;br /&gt;&lt;br /&gt;Don&apos;t get me wrong.  It&apos;s fine to twiddle code.  Reinventing the wheel is the basis for higher education and university study and critical to life-long learning.  However, writing code and championing your work as a solution only acts to avoid studying and maintaining existing code and risks distracting the Emacs community from progress.  In a way, it&apos;s almost anti-social.&lt;br /&gt;&lt;br /&gt;I know some Emacs hackers think multiple implementations are important, and &quot;I wouldn&apos;t have learned as much if I didn&apos;t manage my own Emacs package&quot;.  These arguments are spurious, though.  One should be able to earn these same benefits--and more--by joining in on an existing project, rather than forking a new one.  It may take more effort but its the right thing to do and is under my column of &quot;best practices&quot;.&lt;br /&gt;&lt;br /&gt;The &lt;a href=&quot;http://www.gnu.org/copyleft/gpl.html&quot; rel=&quot;nofollow&quot;&gt;GNU General Public License&lt;/a&gt; gives the Emacs hacker a lot of freedom, but we all could still use the occasional self-discipline.</description>
  <comments>http://aaronhawley.livejournal.com/21031.html</comments>
  <category>programming</category>
  <category>emacs</category>
  <category>free software</category>
  <category>software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>4</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/20794.html</guid>
  <pubDate>Mon, 13 Apr 2009 04:22:13 GMT</pubDate>
  <title>Cheap tricks in Emacs: Elisp manual</title>
  <link>http://aaronhawley.livejournal.com/20794.html</link>
  <description>Another subtle feature of Emacs that I hope doesn&apos;t go away any time soon is an easy way get to the Elisp manual.  The key sequence is  `&lt;kbd&gt;C-h r TAB RET&lt;/kbd&gt;&apos;.&lt;br /&gt;&lt;br /&gt; Here&apos;s how it works.  In Emacs 22, a new key binding appeared to access the Emacs manual, `&lt;kbd&gt;C-h r&lt;/kbd&gt;&apos;.  Conveniently the first cross reference in the Emacs manual is &quot;See Emacs Lisp(elisp)&quot;.  Hitting `&lt;kbd&gt;TAB&lt;/kbd&gt;&apos; skips you to the first cross reference, then `&lt;kbd&gt;RET&lt;/kbd&gt;&apos; follows the cross reference.</description>
  <comments>http://aaronhawley.livejournal.com/20794.html</comments>
  <category>emacs</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/20592.html</guid>
  <pubDate>Tue, 07 Apr 2009 04:16:21 GMT</pubDate>
  <title>DrScheme v. Emacs: Inferior REPL buffer</title>
  <link>http://aaronhawley.livejournal.com/20592.html</link>
  <description>&lt;a href=&quot;http://blog.plt-scheme.org/2009/03/drscheme-repl-isnt-lisp.html&quot; rel=&quot;nofollow&quot;&gt;Interesting discussion on how the REPL buffer of DrScheme is not like Emacs&apos;s&lt;/a&gt;.  &lt;a href=&quot;http://plt-scheme.org/&quot; rel=&quot;nofollow&quot;&gt;DrScheme&lt;/a&gt; is the GUI editor for PLT Scheme.  PLT was how I learned Scheme in school a decade ago.&lt;br /&gt;&lt;br /&gt;The argument pronounced by one of the academics who oversees the software&apos;s maintenance is essentially that having an inferior buffer to send and evaluate Scheme expressions is confusing for pedagogical reasons, and even to non-students.  Years later, many of PLT followers and supporters want this feature.  I recall seeing a PLT researcher who would argue that PLT was real-world, production-ready software.  &lt;br /&gt;&lt;br /&gt;My favorite is that the author starts it as a letter with the caustic greeting &quot;Dear old Lisper&quot;.  I&apos;ve never seen the author speak but have heard of his self-sown reputation as an &lt;a href=&quot;http://www.ccs.neu.edu/home/matthias/&quot; rel=&quot;nofollow&quot;&gt;iconoclast&lt;/a&gt;.</description>
  <comments>http://aaronhawley.livejournal.com/20592.html</comments>
  <category>scheme</category>
  <category>emacs</category>
  <category>programming languages</category>
  <category>free software</category>
  <category>software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/20141.html</guid>
  <pubDate>Fri, 27 Mar 2009 19:55:20 GMT</pubDate>
  <title>Shell hack: Min function</title>
  <link>http://aaronhawley.livejournal.com/20141.html</link>
  <description>&lt;p&gt;I couldn&apos;t find a minimum function for my shell scripting, nor a utility on GNU/Linux, so I am using this function.&lt;/p&gt;

    &lt;pre&gt;
&lt;span style=&quot;color: #b22222;&quot;&gt;###&lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
&lt;/span&gt; &lt;span style=&quot;color: #b22222;&quot;&gt;# &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;min NUM ...
&lt;/span&gt; &lt;span style=&quot;color: #b22222;&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
&lt;/span&gt; &lt;span style=&quot;color: #b22222;&quot;&gt;# &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;Find smallest value of NUMs.
&lt;/span&gt; &lt;span style=&quot;color: #b22222;&quot;&gt;##&lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #a020f0;&quot;&gt;function&lt;/span&gt; min() {
    &lt;span style=&quot;color: #da70d6;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&quot;$@&quot;&lt;/span&gt; | tr &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&apos;[[:space:]]&apos;&lt;/span&gt; &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&apos;\n&apos;&lt;/span&gt; \
     | grep -Ee &lt;span style=&quot;color: #bc8f8f;&quot;&gt;&apos;^-?[[:digit:],]+(.[[:digit:]]*)?$&apos;&lt;/span&gt; \
     | sort -n | sed 1q
} &lt;span style=&quot;color: #b22222;&quot;&gt;## &lt;/span&gt;&lt;span style=&quot;color: #b22222;&quot;&gt;end min
&lt;/span&gt;&lt;/pre&gt;

It supports floating point numbers with decimal notation, but does not support exponential notation or other.

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;min 1 0.2 1,023.56 -0 -1.3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Gives: -1.3&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;max&lt;/code&gt; function is the same thing but needing to change either&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;kbd&gt;sort -nr&lt;/kbd&gt;&lt;/li&gt;&lt;li&gt;&lt;kbd&gt;sed &apos;$p;d&apos;&lt;/kbd&gt;&lt;/li&gt;&lt;li&gt;&lt;kbd&gt;sed -n &apos;$p&apos;&lt;/kbd&gt;&lt;/li&gt;&lt;/ul&gt;</description>
  <comments>http://aaronhawley.livejournal.com/20141.html</comments>
  <category>programming</category>
  <category>unix</category>
  <category>howto</category>
  <lj:security>public</lj:security>
  <lj:reply-count>8</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/19769.html</guid>
  <pubDate>Thu, 12 Mar 2009 20:51:34 GMT</pubDate>
  <title>PHP gets Lambda</title>
  <link>http://aaronhawley.livejournal.com/19769.html</link>
  <description>PHP has always had a hackish way to support first-class functions by making it possible to assign anonymous functions with &lt;a href=&quot;http://php.net/create_function&quot; rel=&quot;nofollow&quot;&gt;&lt;code&gt;create_function&lt;/code&gt;&lt;/a&gt; and run them with any functions that support callbacks (See &lt;a href=&quot;http://php.net/array_map&quot; rel=&quot;nofollow&quot;&gt;&lt;code&gt;array_map&lt;/code&gt;&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;PHP 5.3 (unreleased as of 2009-03-12) will introduce &lt;a href=&quot;http://wiki.php.net/rfc/closures&quot; rel=&quot;nofollow&quot;&gt;Lambda functions and closures&lt;/a&gt;.  I&apos;m not really sure if the implementation is sound or complete, but I&apos;m sure there are enough functional programming language implementations and progammers to make sure its *doing the right thing*.  I&apos;m very glad because I was afraid PHP was going to be steered backwards by &lt;a href=&quot;http://blog.libssh2.org/index.php?/archives/60-create_function-is-not-your-friend.html&quot; rel=&quot;nofollow&quot;&gt;opinions like this&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;See also IBM Developer Works, which had an article on these forthcoming features in &lt;a href=&quot;http://www.ibm.com/developerworks/opensource/library/os-php-5.3new2/index.html&quot; rel=&quot;nofollow&quot;&gt;What&apos;s new in PHP V5.3, Part 2: Closures and lambda functions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Someone asked recently what the design philosophy of PHP was.  I had to say, &quot;PHP was meant to be a server-side include system for HTML documents with a Perl syntax. It&apos;s been trying to outrun its heritage ever since.&quot;</description>
  <comments>http://aaronhawley.livejournal.com/19769.html</comments>
  <category>php</category>
  <category>programming languages</category>
  <category>lambda</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://aaronhawley.livejournal.com/19234.html</guid>
  <pubDate>Tue, 23 Dec 2008 21:09:44 GMT</pubDate>
  <title>Load all meta data of files into PostgreSQL</title>
  <link>http://aaronhawley.livejournal.com/19234.html</link>
  <description>&lt;p&gt;In the previous installment, I quickly showed how to use &lt;a href=&quot;http://www.gnu.org/software/findutils/&quot; rel=&quot;nofollow&quot;&gt;GNU Findutils&lt;/a&gt; to load file system meta information into a PostgreSQL database.  I did so using a comma separated value (CSV) file generated from a tab delimited file.  The us of tabs limited the data set to files without newlines or tabs in their names.  Here I will show how to load any file name.&lt;/p&gt;

&lt;p&gt;The &lt;kbd&gt;find&lt;/kbd&gt; command can output all possible files by separating the fields in the output with nulls, and each line by double nulls.&lt;/p&gt;

&lt;p&gt;Here&apos;s the new &lt;code&gt;-printf&lt;/code&gt; statement that outputs nulls between records, and two nulls between each line.&lt;/p&gt;

&lt;p&gt;
&lt;tt&gt;$ &lt;/tt&gt;&lt;kbd&gt;find / -printf &apos;%i\0%f\0%p\0%h\0%y\0%u\0%U\0%g\0%G\0%M\0%m\0%s\0%b\0%k\0%l\0%n\0%AY-%Am-%Ad %AH:%AM:%AS\0%TY-%Tm-%Td %TH:%TM:%TS\0%CY-%Cm-%Cd %CH:%CM:%CS\0%F\0%D\0\0&apos; &amp;gt; finddb.txt&lt;/kbd&gt;
&lt;/p&gt;

&lt;p&gt;This Perl scriptlet will convert the output to CSV.&lt;/p&gt;

&lt;p&gt;
&lt;tt&gt;$ &lt;/tt&gt;&lt;kbd&gt;perl -mText::CSV_XS -e &apos;my $csv = Text::CSV_XS-&amp;gt;new ({ binary =&amp;gt; 1, eol =&amp;gt; $/ }); my $n = 21; my @c = (); local $/ = &quot;\0\0&quot;;&apos; -ne &apos;$_ .= &quot;\n&quot;; push(@c, split(/\0/)); pop(@c); if ($#c + 1 &amp;lt; $n) {next;} elsif ($#c + 1 &amp;gt; $n) {pop; if ($csv-&amp;gt;combine(@c[0 .. $n - 1])) {print $csv-&amp;gt;string;} else {printf STDERR $csv-&amp;gt;error_input;} @c = @c[$n .. $#_];}&apos; -e &apos;if (@c &amp;gt; 0) {printf STDERR (&quot;Extra fields at the end\n&quot;);}&apos; finddb.txt &amp;gt; finddb.csv&lt;/kbd&gt;
&lt;/p&gt;

&lt;p&gt;Coincidentally, double-nulls don&apos;t help delimit records in the output, since they could be confused as an empty field.  So the script above keeps an internal tally of fields in a record, and is hard-coded as 21.  Thus, when enough null-delimited fields are read, then the next record is read.&lt;/p&gt;

&lt;p&gt;With the resulting CSV file, loading into PostgreSQL is as easy as the following command.&lt;/p&gt;

&lt;p&gt;
&lt;tt&gt;$ &lt;/tt&gt;&lt;kbd&gt;psql -c &apos;\copy finddb from STDIN CSV FORCE NOT NULL path, symlink&apos; &amp;lt; finddb.csv&lt;/kbd&gt;
&lt;/p&gt;

&lt;p&gt;I put the CSV file generation bits together in a Perl script, &lt;a href=&quot;http://agave.garden.org/~aaronh/perl/find-csv.pl&quot; rel=&quot;nofollow&quot;&gt;find-csv.pl&lt;/a&gt;.  It tries to maintain the consistency between GNU findutils &lt;code&gt;-printf&lt;/code&gt; formatting fields, the names of database columns, and the Perl code for generating CSV files.&lt;/p&gt;

&lt;p&gt;In a follow-up, I will give more tastings on possible database queries that can be made of this file system information.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href=&quot;http://excession.spiral-arm.org/jay/&quot; rel=&quot;nofollow&quot;&gt;James Youngman&lt;/a&gt; for reading a previous version of this article.  This post is the result of just one of his generous comments.&lt;/p&gt;</description>
  <comments>http://aaronhawley.livejournal.com/19234.html</comments>
  <category>database</category>
  <category>programming</category>
  <category>unix</category>
  <category>howto</category>
  <category>free software</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>

