<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>goodmami.org</title>
	<atom:link href="http://www.goodmami.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.goodmami.org</link>
	<description>Homepage of Michael Wayne Goodman, student of computational linguistics at the University of Washington</description>
	<lastBuildDate>Thu, 01 Mar 2012 20:28:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Background section complete-ish.</title>
		<link>http://www.goodmami.org/2012/03/background-section-complete-ish/</link>
		<comments>http://www.goodmami.org/2012/03/background-section-complete-ish/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 20:28:34 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=111</guid>
		<description><![CDATA[I think the draft of the background section of my morphology paper is complete. One thing that is absent is a review of position class morphology, but it may not be necessary. I also have a comment in the .tex file to review the Paradigm Function Morphology section for explanation received in Paris two summers [...]]]></description>
			<content:encoded><![CDATA[<p>I think the draft of the background section of my morphology paper is complete. One thing that is absent is a review of position class morphology, but it may not be necessary. I also have a comment in the .tex file to review the Paradigm Function Morphology section for explanation received in Paris two summers ago, but I don&#8217;t recall what that explanation was.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/03/background-section-complete-ish/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Accumulating dictionaries in Python</title>
		<link>http://www.goodmami.org/2012/02/accumulating-dictionaries-in-python/</link>
		<comments>http://www.goodmami.org/2012/02/accumulating-dictionaries-in-python/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 07:57:46 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[dictionaries]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=106</guid>
		<description><![CDATA[I often have a need to count tokens in a corpus. In Python, there are many ways to do this, but currently I most often use defaultdicts: 123d = defaultdict&#40;int&#41; for x in sequence: &#160; d&#91;x&#93; += 1 I would like to get rid of the for-loop and construct such a dictionary at once. I [...]]]></description>
			<content:encoded><![CDATA[<p>I often have a need to count tokens in a corpus. In Python, there are many ways to do this, but currently I most often use defaultdicts:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">d <span style="color: #66cc66;">=</span> defaultdict<span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> sequence:<br />
&nbsp; d<span style="color: black;">&#91;</span>x<span style="color: black;">&#93;</span> +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span></div></td></tr></tbody></table></div>
<p>I would like to get rid of the for-loop and construct such a dictionary at once. I wrote a dict-derived class to do that, but it can do even more. But first, here is how I would do the above:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">d <span style="color: #66cc66;">=</span> AccumulationDict<span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x<span style="color: #66cc66;">,</span> y: x + y<span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> sequence<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>That&#8217;s it!</p>
<p>Notice how it takes a function as its first parameter. This is similar to how defaultdict takes a callable, but instead of taking a 0-arity callable, AccumulationDict takes a binary function. Whenever it &#8220;accumulates&#8221; a key-value for a key that already exists, the existing value and new value are sent to this function, and the result is what is set as the new value in the dictionary. This function will most likely be addition (rather than the lambda expression one could use operator.add), but it could be anything. Say you&#8217;re calculating probabilities of multiple events, you could use operator.mul.</p>
<p>I did not want to break KeyErrors, so accumulating is separate from getting and setting. This means you can still use __setitem__() and update() to reset the values of keys. Accumulation happens in the constructor, in dictionary addition, and with a new accumulate() function. accumulate() is identical to update() in interface, but uses the provided accumulator function to &#8220;merge&#8221; values when there are key collisions.</p>
<p>The code is below, but it represents a proof-of-concept and could be improved:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">class</span> AccumulationDict<span style="color: black;">&#40;</span><span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> accumulator<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>accumulator<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'__call__'</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Accumulator must be a binary function.'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">accumulator</span> <span style="color: #66cc66;">=</span> accumulator<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">accumulate</span><span style="color: black;">&#40;</span>*args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> __additem__<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>.<span style="color: black;">accumulator</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> value<br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__add__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> other<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; result <span style="color: #66cc66;">=</span> AccumulationDict<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">accumulator</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; result.<span style="color: black;">accumulate</span><span style="color: black;">&#40;</span>other<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> result<br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> accumulate<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> arg <span style="color: #ff7700;font-weight:bold;">in</span> args:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>arg<span style="color: #66cc66;">,</span> <span style="color: #008000;">list</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> arg:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.__additem__<span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>arg<span style="color: #66cc66;">,</span> <span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> arg.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.__additem__<span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Argument must be of type list or dict.'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> kwargs:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.__additem__<span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> kwargs<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/02/accumulating-dictionaries-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hulden and Bischoff, similar implementation</title>
		<link>http://www.goodmami.org/2012/02/hulden-and-bischoff-similar-implementation/</link>
		<comments>http://www.goodmami.org/2012/02/hulden-and-bischoff-similar-implementation/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 23:25:57 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>
		<category><![CDATA[morphology]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=102</guid>
		<description><![CDATA[I just came across a paper for doing non-concatenative morphology with an implementation remarkably similar to my own. This paper by Mans Hulden and Shannon Bischoff uses unification of three different morphotactic constraints (unification, exclusion, coercion) in lexical rules to deal with co-occurrence restrictions and 4 different operators for modelling morpheme ordering (precedes, immediately precedes, [...]]]></description>
			<content:encoded><![CDATA[<p>I just came across a paper for doing non-concatenative morphology with an implementation remarkably similar to my own. <a href="http://dialnet.unirioja.es/servlet/articulo?codigo=2675984">This paper</a> by Mans Hulden and Shannon Bischoff uses unification of three different morphotactic constraints (unification, exclusion, coercion) in lexical rules to deal with co-occurrence restrictions and 4 different operators for modelling morpheme ordering (precedes, immediately precedes, follows, immediately follows).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/02/hulden-and-bischoff-similar-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Koskenniemi&#8217;s Two-Level Morphology</title>
		<link>http://www.goodmami.org/2012/01/koskenniemis-two-level-morphology/</link>
		<comments>http://www.goodmami.org/2012/01/koskenniemis-two-level-morphology/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 08:51:21 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>
		<category><![CDATA[morphology]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=95</guid>
		<description><![CDATA[I just read what appears to be Koskenniemi&#8217;s most cited article on Two-Level Morphology, and now I am reviewing my understanding before writing a summary in my paper. When Kimmo Koskenniemi worked out two-level morphology, generative phonology via context-sensitive rewrite rules were the common way of describing morphological systems. These kinds of rules were fairly [...]]]></description>
			<content:encoded><![CDATA[<p>I just read what appears to be Koskenniemi&#8217;s <a href="http://dl.acm.org/citation.cfm?id=980529">most cited article</a> on <a href="http://www.ling.helsinki.fi/~koskenni/esslli-2001-karttunen/">Two-Level Morphology</a>, and now I am reviewing my understanding before writing a summary in my paper.</p>
<p>When Kimmo Koskenniemi worked out two-level morphology, generative phonology via context-sensitive rewrite rules were the common way of describing morphological systems. These kinds of rules were fairly expressive in generating surface forms from lexical forms, but were nearly useless in lexical analysis, and furthermore were computationally expensive. <a href="http://en.scientificcommons.org/3718887">Johnson 1972</a>, and later Kay and Kaplan in &#8220;Phonological Rules and Finite-State Transducers&#8221;, 1981, showed that these rules were insufficient and proposed finite-state transducers as cascading rules applied to lexical forms, and further that the sequence of FSTs could be collapsed to a single, very-expressive (and large) FST. In this context, Koskenniemi&#8217;s proposed a two-level system where smaller FSTs were applied in parallel instead of in sequence.</p>
<p>Aside from the computationally tractable benefits of two-level morphology, from what I could tell it only addresses the morphophonological changes to a lexical item. For instance, it may define a rule that inserts an e after a consonate-y sequence and before a (morpheme-boundary)-s sequence (as in the English plural &#8220;spy&#8221; -> &#8220;spies&#8221;; a separate rule handles the y->i conversion):</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">C y 0 + s<br />
| | | | |<br />
_ _ e _ _</div></td></tr></tbody></table></div>
<p>I don&#8217;t see how the &#8220;spy0+s&#8221; lexical form gets created, but the generality of +s being plural for all inflectional patterns is convenient. Also, I don&#8217;t see how long distance restrictions are modeled, as the rules appear to be limited to immediately-adjacent contexts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/01/koskenniemis-two-level-morphology/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Morphology paper: AVM problem fixed, no new text yet</title>
		<link>http://www.goodmami.org/2012/01/morphology-paper-avm-problem-fixed-no-new-text-yet/</link>
		<comments>http://www.goodmami.org/2012/01/morphology-paper-avm-problem-fixed-no-new-text-yet/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 07:01:09 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=87</guid>
		<description><![CDATA[I fixed the problem I was having with avm.sty. It turned out I had some avm environments using an older style of notation which no longer worked with the 1.02 version of avm.sty. The whole document now compiles with xelatex. I also found some articles by Koskenniemi (here and here) and Karttunen, Kaplan, Zaenen (here), [...]]]></description>
			<content:encoded><![CDATA[<p>I fixed the problem I was having with avm.sty. It turned out I had some avm environments using an older style of notation which no longer worked with the 1.02 version of avm.sty. The whole document now compiles with xelatex.</p>
<p>I also found some articles by Koskenniemi (<a href="http://mnd.ly/zRv7Q4">here</a> and <a href="http://mnd.ly/Ax3umx">here</a>) and Karttunen, Kaplan, Zaenen (<a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.27.9455">here</a>), but I haven&#8217;t yet read or written about them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/01/morphology-paper-avm-problem-fixed-no-new-text-yet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Morphology paper update</title>
		<link>http://www.goodmami.org/2012/01/morphology-paper-update/</link>
		<comments>http://www.goodmami.org/2012/01/morphology-paper-update/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 02:45:52 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=81</guid>
		<description><![CDATA[Getting back into the general&#8217;s paper on morphology, I found that xelatex failed to compile it with the avm environment (using the 2006 version of avm.sty). So my current goals for the paper are: to compile the whole thing (after uncommenting the avms) do some reading, then write the background/previous-work section Koskenniemi&#8217;s 2-level automata Beesly [...]]]></description>
			<content:encoded><![CDATA[<p>Getting back into the general&#8217;s paper on morphology, I found that xelatex failed to compile it with the avm environment (using the 2006 version of avm.sty). So my current goals for the paper are:</p>
<ul>
<li>to compile the whole thing (after uncommenting the avms)</li>
<li>do some reading, then write the background/previous-work section</li>
<ul>
<li>Koskenniemi&#8217;s 2-level automata</li>
<li>Beesly and Karttunen&#8217;s flag diacritics</li>
</ul>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/01/morphology-paper-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple logging in Bash scripts</title>
		<link>http://www.goodmami.org/2011/07/simple-logging-in-bash-scripts/</link>
		<comments>http://www.goodmami.org/2011/07/simple-logging-in-bash-scripts/#comments</comments>
		<pubDate>Mon, 04 Jul 2011 21:53:04 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=62</guid>
		<description><![CDATA[I couldn&#8217;t find much mention of logging utilities for Linux shell scripting (namely Bash), so I wrote my own fairly quickly. I wanted several functions for various levels of logging (info, debug, warning, errors, etc), and a way to adjust what levels can be displayed. I followed the fairly standard convention of using numeric values [...]]]></description>
			<content:encoded><![CDATA[<p>I couldn&#8217;t find much mention of logging utilities for Linux shell scripting (namely Bash), so I wrote my own fairly quickly. I wanted several functions for various levels of logging (info, debug, warning, errors, etc), and a way to adjust what levels can be displayed. I followed the fairly standard convention of using numeric values for these levels and setting a &#8220;verbosity&#8221; level. If you know of an existing solution for Bash, let me know in the comments. Anyway, here&#8217;s the main idea:</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span> <span style="color: #666666; font-style: italic;"># logging stream (file descriptor 3) defaults to STDERR</span><br />
<span style="color: #007800;">verbosity</span>=<span style="color: #000000;">2</span> <span style="color: #666666; font-style: italic;"># default to show warnings</span><br />
<span style="color: #007800;">silent_lvl</span>=<span style="color: #000000;">0</span><br />
<span style="color: #007800;">err_lvl</span>=<span style="color: #000000;">1</span><br />
<span style="color: #007800;">wrn_lvl</span>=<span style="color: #000000;">2</span><br />
<span style="color: #007800;">inf_lvl</span>=<span style="color: #000000;">3</span><br />
<span style="color: #007800;">dbg_lvl</span>=<span style="color: #000000;">4</span><br />
<br />
notify<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$silent_lvl</span> <span style="color: #ff0000;">&quot;NOTE: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #666666; font-style: italic;"># Always prints</span><br />
error<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$err_lvl</span> <span style="color: #ff0000;">&quot;ERROR: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
warn<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$wrn_lvl</span> <span style="color: #ff0000;">&quot;WARNING: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
inf<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$inf_lvl</span> <span style="color: #ff0000;">&quot;INFO: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #666666; font-style: italic;"># &quot;info&quot; is already a command</span><br />
debug<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$dbg_lvl</span> <span style="color: #ff0000;">&quot;DEBUG: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
log<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbosity</span> <span style="color: #660033;">-ge</span> <span style="color: #007800;">$1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Expand escaped characters, wrap at 70 chars, indent wrapped lines</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;$2&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> fold <span style="color: #660033;">-w70</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'2~1s/^/ &nbsp;/'</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">3</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">fi</span><br />
<span style="color: #7a0874; font-weight: bold;">&#125;</span></div></td></tr></tbody></table></div>
<p>I added line wrapping and indenting so users don&#8217;t have to manually put in line-breaks to get nicer looking outputs, but there is the drawback that it makes the output harder to grep. Perhaps I should add an option to disable the line wrapping.</p>
<p><a href="http://goodmami.org/files/logging.bash">Here</a> is a longer example with some simple option parsing (apologies for using getopt; I&#8217;m currently looking for a better solution).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2011/07/simple-logging-in-bash-scripts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lightweight Music</title>
		<link>http://www.goodmami.org/2011/03/lightweight-music/</link>
		<comments>http://www.goodmami.org/2011/03/lightweight-music/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 11:09:15 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mpd]]></category>
		<category><![CDATA[music]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=38</guid>
		<description><![CDATA[I was getting tired of the bloat and memory usage of Rhythmbox, so I was searching for a new music player/manager. After trying Muine and Decibel and not being totally satisfied, I finally (re)found MPD, the Music Player Daemon. Once I figured out how to set it up (not too hard, but more work than [...]]]></description>
			<content:encoded><![CDATA[<p>I was getting tired of the bloat and memory usage of <a href="http://projects.gnome.org/rhythmbox/">Rhythmbox</a>, so I was searching for a new music player/manager. After trying <a href="http://muine.gooeylinux.org/">Muine</a> and <a href="decibel.silent-blade.org/">Decibel</a> and not being totally satisfied, I finally (re)found <a href="http://www.musicpd.org/">MPD</a>, the Music Player Daemon.</p>
<p>Once I figured out how to set it up (not too hard, but more work than usual), it&#8217;s been my favorite application for playing music. While GUI clients exist, I&#8217;ve been enjoying the command-line client MPC, as I can do things like this:</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mpc listall <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> Sigur <span style="color: #000000; font-weight: bold;">|</span> mpc add</div></td></tr></tbody></table></div>
<p>&#8230;which greps my whole music library for files with &#8220;Sigur&#8221; in the title, then adds them to the current playlist.</p>
<p>I also wanted to set up some key combos, so I didn&#8217;t have to execute commands in a terminal all the time. I used <a href="http://www.nongnu.org/xbindkeys/xbindkeys.html">XBindKeys</a> to bind some keys to mpc commands. For instance, the following commands toggles play/pause status (with Ctrl + the multimedia play button), skips to the next song (with Ctrl + multimedia next button), stops playback (with Ctrl + Alt + multimedia play button), and shows the currently playing song in a notification window (with Super + multimedia play button):</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff0000;">&quot;mpc toggle&quot;</span><br />
&nbsp; m:0x14 + c:<span style="color: #000000;">172</span><br />
&nbsp; Control+Mod2 + XF86AudioPlay</div></td></tr></tbody></table></div>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff0000;">&quot;mpc next&quot;</span><br />
&nbsp; m:0x14 + c:<span style="color: #000000;">171</span><br />
&nbsp; Control+Mod2 + XF86AudioNext</div></td></tr></tbody></table></div>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff0000;">&quot;mpc stop&quot;</span><br />
&nbsp; m:0x1c + c:<span style="color: #000000;">172</span><br />
&nbsp; Control+Alt+Mod2 + XF86AudioPlay</div></td></tr></tbody></table></div>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff0000;">&quot;notify-send -u normal &quot;</span>$<span style="color: #7a0874; font-weight: bold;">&#40;</span>mpc current<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #ff0000;">&quot;&quot;</span><br />
&nbsp; m:0x50 + c:<span style="color: #000000;">172</span><br />
&nbsp; Mod2+Mod4 + XF86AudioPlay</div></td></tr></tbody></table></div>
<p>And what about memory usage? It&#8217;s currently playing a song and only using 8Mb. For comparison, I just fired up Rhythmbox and while idle it uses 47Mb.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2011/03/lightweight-music/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tomboy and note-sharing</title>
		<link>http://www.goodmami.org/2010/04/tomboy-and-note-sharing/</link>
		<comments>http://www.goodmami.org/2010/04/tomboy-and-note-sharing/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 23:17:11 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[notes]]></category>
		<category><![CDATA[sharing]]></category>
		<category><![CDATA[synchronization]]></category>
		<category><![CDATA[Tomboy]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=33</guid>
		<description><![CDATA[Other than as a place to quickly jot down ideas, phone numbers, etc., Tomboy&#8216;s most common purpose for me is as a study aid for my coursework. The ability to link the different topics, concepts, and people that I learn about is very useful. Of course, I&#8217;m not the only student in my classes, and [...]]]></description>
			<content:encoded><![CDATA[<p>Other than as a place to quickly jot down ideas, phone numbers, etc., <a href="http://projects.gnome.org/tomboy/">Tomboy</a>&#8216;s most common purpose for me is as a study aid for my coursework. The ability to link the different topics, concepts, and people that I learn about is very useful. Of course, I&#8217;m not the only student in my classes, and I introduced my study group to Tomboy and they love it. But now we have a new problem: note sharing. Since we are learning the same material, it would make sense if we could sync our notes together. And now we have another problem: we don&#8217;t want to share all of our notes, just the relevant ones.</p>
<p>Note-sharing is not a <a href="http://live.gnome.org/Tomboy/NoteSharing">new</a> <a href="http://live.gnome.org/Tomboy/PlaceForNewIdeas#Sharing_.28Networked_Tomboy.29">idea</a>, but it seems to have not been implemented yet. The basic ideas are that users of Tomboy should be able to get notes from others, give others their own notes, possibly sync them, resolve conflicts (as with synchronization), and be able to limit what notes are shared. Nobody seems to have mentioned real-time collaborative editing, but I don&#8217;t think it&#8217;s a good idea at this point, either.</p>
<p>I think there is not all that much that needs to be changed to allow sharing. Essentially, one must be able to synchronize subsets of notes, rather than all notes, and synchronize them in different locations (perhaps multiple). <a href="http://live.gnome.org/Tomboy/Notebooks">notebooks</a> have been implemented, and they do a decent job of grouping notes, but they don&#8217;t add all that much functionally. I think users should be able to sync single notes, notebooks, or all notes with various locations. By doing so, I could keep all of my notes synchronized with my <a href="https://one.ubuntu.com/">Ubuntu One</a> account, and also sync my notebook for course notes to another server. My classmates can have an account with this other server, and by syncing with it we are sharing notes. If there&#8217;s a conflict, Tomboy should solve it in the simplest way possible (maybe prefix the conflicting lines with the username of the author?), or allow a user to launch an external diffing tool, such as <a href="http://meld.sourceforge.net/">Meld</a> or <a href="http://en.wikipedia.org/wiki/WinDiff">WinDiff</a>.</p>
<p>I&#8217;m sure there are issues I haven&#8217;t thought about too hard, such as how to deal with links to notes that don&#8217;t exist (e.g. outside of a shared notebook), what happens when users change, say, notebook names, Tomboy version or plugin mismatches, etc. But on the surface it seems that expanding synchronization to allow for syncing subsets of notes will allow for simple sharing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2010/04/tomboy-and-note-sharing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Traditional and Simplified Chinese in LaTeX</title>
		<link>http://www.goodmami.org/2009/04/traditional-and-simplified-chinese-in-latex/</link>
		<comments>http://www.goodmami.org/2009/04/traditional-and-simplified-chinese-in-latex/#comments</comments>
		<pubDate>Sun, 05 Apr 2009 07:42:46 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[chinese]]></category>
		<category><![CDATA[japanese]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/2009/04/traditional-and-simplified-chinese-in-latex/</guid>
		<description><![CDATA[I&#8217;ve been in the habit of using LaTeX&#8217;s CJK environment across a whole document to allow me to insert, for example, Japanese anywhere I like. However, if you want to have more than one language (not covered by the same font) in the same document (such as both traditional and simplified Chinese, Japanese and Korean, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been in the habit of using LaTeX&#8217;s CJK environment across a whole document to allow me to insert, for example, Japanese anywhere I like. However, if you want to have more than one language (not covered by the same font) in the same document (such as both traditional and simplified Chinese, Japanese and Korean, etc), prepare for trouble. You cannot have one CJK environment for the whole document unless you get a font that can handle all the code points (like this elusive, half-free Cyberbit font that seems to be a pain to install).</p>
<p>I <a href="http://www.tug.org/pipermail/texhax/2004-January/001476.html">found</a>, however, that there is another (and perhaps the intended) way to do it! You can create a command for each individual CJK environment you will need, and use them as needed. For example:</p>
<div class="codecolorer-container latex railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="latex codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/index.php?title=%5Cnewcommand"><span style="color: #800000;">newcommand</span></a><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;"><span style="color: #800000; font-weight: normal;">\zht</span><span style="color: #E02020; ">}[</span><span style="color: #C08020; font-weight: normal;">1</span><span style="color: #E02020; ">]{</span><span style="color: #C00000; font-weight: normal;">\begin</span><span style="color: #E02020; ">{</span><span style="color: #0000D0; font-weight: normal;">CJK</span><span style="color: #E02020; ">}{</span>UTF8<span style="color: #E02020; ">}{</span>bsmi<span style="color: #E02020; ">}</span>#1<span style="color: #C00000; font-weight: normal;">\end</span><span style="color: #E02020; ">{</span><span style="color: #0000D0; font-weight: normal;">CJK</span><span style="color: #E02020; ">}}</span><br />
<span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/index.php?title=%5Cnewcommand"><span style="color: #800000;">newcommand</span></a><span style="color: #E02020; ">{</span><span style="color: #800000; font-weight: normal;">\zhs</span><span style="color: #E02020; ">}[</span><span style="color: #C08020; font-weight: normal;">1</span><span style="color: #E02020; ">]{</span><span style="color: #C00000; font-weight: normal;">\begin</span><span style="color: #E02020; ">{</span><span style="color: #0000D0; font-weight: normal;">CJK</span><span style="color: #E02020; ">}{</span>UTF8<span style="color: #E02020; ">}{</span>gbsn<span style="color: #E02020; ">}</span>#1<span style="color: #C00000; font-weight: normal;">\end</span><span style="color: #E02020; ">{</span><span style="color: #0000D0; font-weight: normal;">CJK</span><span style="color: #E02020; ">}}</span><br />
<span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/index.php?title=%5Cnewcommand"><span style="color: #800000;">newcommand</span></a><span style="color: #E02020; ">{</span><span style="color: #800000; font-weight: normal;">\zh</span><span style="color: #E02020; ">}[</span><span style="color: #C08020; font-weight: normal;">4</span><span style="color: #E02020; ">]{</span><span style="color: #800000; font-weight: normal;">\zht</span><span style="color: #E02020; ">{</span>#1<span style="color: #E02020; ">}</span>/<span style="color: #800000; font-weight: normal;">\zhs</span><span style="color: #E02020; ">{</span>#2<span style="color: #E02020; ">}</span> (<span style="color: #E02020; ">\</span><a href="http://www.golatex.de/wiki/index.php?title=%5Cemph"><span style="color: #800000;">emph</span></a>{#3}) ``#4''</span><span style="color: #E02020; ">}</span></div></td></tr></tbody></table></div>
<p>The \zht command is for traditional chinese characters, the \zhs is for simplified, and the \zh uses both (eg to define a word using both variants in hanzi, a transliteration, and a gloss). For example,</p>
<div class="codecolorer-container latex railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="latex codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #800000; font-weight: normal;">\zh</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">藝術}{艺术}{<span style="color: #800000; font-weight: normal;">\yi</span>4 <span style="color: #800000; font-weight: normal;">\shu</span>4}{art</span><span style="color: #E02020; ">}</span></div></td></tr></tbody></table></div>
<p>will produce</p>
<pre>藝術/艺术 (yì shù) “art”</pre>
<p>This works great, except that you have to use one of these tags every time you want to switch to a different character set.</p>
<p>NB: When using this method the very first line is not displayed. I got around this by having a dummy line near the top of the document. For example:</p>
<div class="codecolorer-container latex railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="latex codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #800000; font-weight: normal;">\zht</span><span style="color: #E02020; ">{</span><span style="color: #E02020; ">}</span> &nbsp;<span style="color: #2C922C; font-style: italic;">% Dummy environment to get around display bug.</span><br />
<span style="color: #800000; font-weight: normal;">\zht</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">藝術</span><span style="color: #E02020; ">}</span> <span style="color: #2C922C; font-style: italic;">% Now this will be displayed.</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2009/04/traditional-and-simplified-chinese-in-latex/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

