<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.iany.me/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
<title>~iany/blog</title>
<link href="http://blog.iany.me/" />

<updated>2012-03-30T16:00:00Z</updated>
<id>http://blog.iany.me/</id>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<rights>Copyright (c) 2012, Ian Yang</rights>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.iany.me/ianyblog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="ianyblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">ianyblog</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><entry>
<id>http://blog.iany.me/2012/03/fix-tab-binding-for-yasnippet-and-auto-complete/</id>
<link href="http://blog.iany.me/2012/03/fix-tab-binding-for-yasnippet-and-auto-complete/" rel="alternate" type="text/html" />
<title>Fix TAB Binding For yasnippet And auto-complete</title>
<published>2012-03-30T16:00:00Z</published>
<updated>2012-03-30T13:30:04Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="Emacs" term="emacs" /><content type="html"><![CDATA[<p>There are two TAB&rsquo;s in Emacs, <code>(kbd "TAB")</code> (<code>\t</code>, <code>[9]</code>) and <code>(kbd "&lt;tab&gt;")</code>&#x000A;(<code>[tab]</code>). If modes like <a href="http://capitaomorte.github.com/yasnippet/index.html" class=" external">yasnippet</a> and <a href="https://github.com/m2ym/auto-complete" class=" external">auto-complete</a> want to bind on&#x000A;<code>TAB</code>, their trigger key must be the same with the original Tab command. Since&#x000A;Emacs binds <code>indent-for-tab-command</code> on <code>(kbd "TAB")</code>, so it&rsquo;s better to use&#x000A;it as the trigger key. Yasnippet binds to it by default, It is also easy to&#x000A;setup <code>auto-complete</code> to trigger using Tab.</p>&#x000A;&#x000A;<pre class="code cl"><code class="cl"><span class="line-margin"><span class="line"><span class="c1">;; trigger using TAB and disable auto start</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">custom-set-variables</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="o">'</span><span class="p">(</span><span class="nv">ac-trigger-key</span> <span class="s">"TAB"</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="o">'</span><span class="p">(</span><span class="nv">ac-auto-start</span> <span class="no">nil</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="o">'</span><span class="p">(</span><span class="nv">ac-use-menu-map</span> <span class="no">t</span><span class="p">))</span></span></span></code></pre>&#x000A;&#x000A;<p>But in some modes (<code>ruby-mode</code>, <code>markdown-mode</code>, <code>org-mode</code>), the command is&#x000A;bind to <code>(kbd "&lt;tab&gt;")</code>, when the real Tab key is typed, the function bind on&#x000A;<code>(kbd "&lt;tab&gt;)</code> has higher priority, so yasnippet and auto-complete are not&#x000A;invoked. It is easy to fix by moving the keybinding:</p>&#x000A;&#x000A;<pre class="code cl"><code class="cl"><span class="line-margin"><span class="line"><span class="p">(</span><span class="nb">defun</span> <span class="nv">iy-tab-noconflict</span> <span class="p">()</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">command</span> <span class="p">(</span><span class="nv">key-binding</span> <span class="nv">[tab]</span><span class="p">)))</span> <span class="c1">; remember command</span>&#x000A;</span></span><span class="line-margin"><span class="line">    <span class="p">(</span><span class="nv">local-unset-key</span> <span class="nv">[tab]</span><span class="p">)</span> <span class="c1">; unset from (kbd "&lt;tab&gt;")</span>&#x000A;</span></span><span class="line-margin"><span class="line">    <span class="p">(</span><span class="nv">local-set-key</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"TAB"</span><span class="p">)</span> <span class="nv">command</span><span class="p">)))</span> <span class="c1">; bind to (kbd "TAB")</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">add-hook</span> <span class="ss">'ruby-mode-hook</span> <span class="ss">'iy-ac-tab-noconflict</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">add-hook</span> <span class="ss">'markdown-mode-hook</span> <span class="ss">'iy-ac-tab-noconflict</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">add-hook</span> <span class="ss">'org-mode-hook</span> <span class="ss">'iy-ac-tab-noconflict</span><span class="p">)</span></span></span></code></pre>]]></content></entry>
<entry>
<id>http://blog.iany.me/2012/03/use-popup-isearch-for-yasnippet-prompt/</id>
<link href="http://blog.iany.me/2012/03/use-popup-isearch-for-yasnippet-prompt/" rel="alternate" type="text/html" />
<title>Use Popup isearch For Yasnippet Prompt</title>
<published>2012-03-29T16:00:00Z</published>
<updated>2012-03-30T13:30:12Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="Emacs" term="emacs" /><content type="html"><![CDATA[<p><a href="http://capitaomorte.github.com/yasnippet/index.html" class=" external">Yasnippet</a> tries functions in <code>yas/prompt-functions</code> when it needs user to&#x000A;select one choice, such as selecting snippets with the same trigger key, such&#x000A;as helper method <code>yas/choose-value</code>.</p>&#x000A;&#x000A;<p><a href="https://github.com/m2ym/popup-el" class=" external">popup</a> is a visual popup interface library extracted from <a href="https://github.com/m2ym/auto-complete" class=" external">auto-complete</a>&#x000A;by its author. It has better look and feel than all the built-in&#x000A;<code>yas/prompt-functions</code>. Also it is easy to customize, and its isearch mode is&#x000A;very efficient, the items are filtered on-the-fly when typing.</p>&#x000A;&#x000A;<figure class="two-columns"><img src="http://assets.iany.me/gallery/2012/03/use-popup-isearch-for-yasnippet-prompt/choises.png"><img src="http://assets.iany.me/gallery/2012/03/use-popup-isearch-for-yasnippet-prompt/filter_by_keyword.png"><figcaption>Popup isearch by typing &ldquo;f&rdquo;</figcaption></figure><p>The integration is easy. Load <code>popup.el</code>, implement one prompt function and&#x000A;add it to <code>yas/prompt-functions</code>.</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">yasnippet-popup-isearch-prompt.el <a class="gist external" href="https://gist.github.com/2245733" rel="gist">gist:2245733</a>&#x000A;</div>&#x000A;<pre class="code cl"><code class="cl"><span class="line-margin"><span class="line"><span class="p">(</span><span class="nb">require</span> <span class="ss">'popup</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nb">require</span> <span class="ss">'yasnippet</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line">&#x000A;</span></span><span class="line-margin"><span class="line"><span class="c1">;; add some shotcuts in popup menu mode</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">define-key</span> <span class="nv">popup-menu-keymap</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"M-n"</span><span class="p">)</span> <span class="ss">'popup-next</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">define-key</span> <span class="nv">popup-menu-keymap</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"TAB"</span><span class="p">)</span> <span class="ss">'popup-next</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">define-key</span> <span class="nv">popup-menu-keymap</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"&lt;tab&gt;"</span><span class="p">)</span> <span class="ss">'popup-next</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">define-key</span> <span class="nv">popup-menu-keymap</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"&lt;backtab&gt;"</span><span class="p">)</span> <span class="ss">'popup-previous</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">define-key</span> <span class="nv">popup-menu-keymap</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"M-p"</span><span class="p">)</span> <span class="ss">'popup-previous</span><span class="p">))</span>&#x000A;</span></span><span class="line-margin"><span class="line">&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="nb">defun</span> <span class="nv">yas/popup-isearch-prompt</span> <span class="p">(</span><span class="nv">prompt</span> <span class="nv">choices</span> <span class="k">&amp;optional</span> <span class="nv">display-fn</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nv">featurep</span> <span class="ss">'popup</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line">    <span class="p">(</span><span class="nv">popup-menu*</span>&#x000A;</span></span><span class="line-margin"><span class="line">     <span class="p">(</span><span class="nb">mapcar</span>&#x000A;</span></span><span class="line-margin"><span class="line">      <span class="p">(</span><span class="k">lambda</span> <span class="p">(</span><span class="nv">choice</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line">        <span class="p">(</span><span class="nv">popup-make-item</span>&#x000A;</span></span><span class="line-margin"><span class="line">         <span class="p">(</span><span class="nb">or</span> <span class="p">(</span><span class="nb">and</span> <span class="nv">display-fn</span> <span class="p">(</span><span class="nb">funcall</span> <span class="nv">display-fn</span> <span class="nv">choice</span><span class="p">))</span>&#x000A;</span></span><span class="line-margin"><span class="line">             <span class="nv">choice</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line">         <span class="ss">:value</span> <span class="nv">choice</span><span class="p">))</span>&#x000A;</span></span><span class="line-margin"><span class="line">      <span class="nv">choices</span><span class="p">)</span>&#x000A;</span></span><span class="line-margin"><span class="line">     <span class="ss">:prompt</span> <span class="nv">prompt</span>&#x000A;</span></span><span class="line-margin"><span class="line">     <span class="c1">;; start isearch mode immediately</span>&#x000A;</span></span><span class="line-margin"><span class="line">     <span class="ss">:isearch</span> <span class="no">t</span>&#x000A;</span></span><span class="line-margin"><span class="line">     <span class="p">)))</span>&#x000A;</span></span><span class="line-margin"><span class="line">&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">(</span><span class="k">setq</span> <span class="nv">yas/prompt-functions</span> <span class="o">'</span><span class="p">(</span><span class="nv">yas/popup-isearch-prompt</span> <span class="nv">yas/no-prompt</span><span class="p">))</span></span></span></code></pre>&#x000A;</div>&#x000A;]]></content></entry>
<entry>
<id>http://blog.iany.me/2012/02/css-line-wrap-indicator/</id>
<link href="http://blog.iany.me/2012/02/css-line-wrap-indicator/" rel="alternate" type="text/html" />
<title>CSS Line Wrap Indicator</title>
<published>2012-02-03T16:00:00Z</published>
<updated>2012-02-04T05:57:13Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="css" term="css" />
<category label="html" term="html" /><content type="html"><![CDATA[<p>Many editor can wrap a line that reaches the window width and show an&#x000A;indicator in the margin, for example, Emacs.</p>&#x000A;&#x000A;<figure class="right"><img src="http://assets.iany.me/gallery/2012/02/css-line-wrap-indicator/emacs.png"><figcaption>Emacs line wrap with bent arrow in fringe</figcaption></figure><p>I want to add such line wrap indicators to the code block in HTML. It is easy&#x000A;to add indicators as background image in CSS. But the indicators should&#x000A;only be shown when the line is wrapped. And from the figure, the wrap&#x000A;indicator is not displayed on the last line in the right margin, and not on&#x000A;the first line in the left margin. There&rsquo;s a <code>:first-line</code> pseudo element&#x000A;selector, there&rsquo;s no <code>:last-line</code>. However, it can be achieved by using&#x000A;<code>:before</code> and <code>:after</code> with position trick.</p>&#x000A;&#x000A;<p>You can check the result in this jsfiddle: <a href="http://jsfiddle.net/fbDKQ/6/" class=" external">http://jsfiddle.net/fbDKQ/6/</a>&#x000A;. Resize the result panel to see the line wrap indicators. Following is a&#x000A;detailed explanation.</p>&#x000A;&#x000A;<!-- more -->&#x000A;&#x000A;<h2 id="csliwrin-1-add-line-markup">Add Line Markup</h2>&#x000A;&#x000A;<p>First, the code block in pre must be split by lines and add markup so that CSS&#x000A;can be applied.</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">Before</div>&#x000A;<pre class="code html"><code class="html"><span class="line-margin"><span class="line"><span class="nt">&lt;pre&gt;&lt;code&gt;</span>(font-lock-add-keywords&#x000A;</span></span><span class="line-margin"><span class="line"> 'ruby-mode&#x000A;</span></span><span class="line-margin"><span class="line"> '(("\\(\\b\\sw[_a-zA-Z0-9]*:\\)\\(?:\\s-\\|$\\)" (1 font-lock-constant-face))))&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">&lt;/code&gt;&lt;/pre&gt;</span></span></span></code></pre>&#x000A;</div>&#x000A;&#x000A;&#x000A;&#x000A;<p>is converted to</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">After</div>&#x000A;<pre class="code html"><code class="html"><span class="line-margin"><span class="line"><span class="nt">&lt;pre&gt;&lt;code&gt;&lt;span</span> <span class="na">class=</span><span class="s">"line"</span><span class="nt">&gt;</span>(font-lock-add-keywords&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">&lt;/span&gt;&lt;span</span> <span class="na">class=</span><span class="s">"line"</span><span class="nt">&gt;</span> 'ruby-mode&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">&lt;/span&gt;&lt;span</span> <span class="na">class=</span><span class="s">"line"</span><span class="nt">&gt;</span> '(("\\(\\b\\sw[_a-zA-Z0-9]*:\\)\\(?:\\s-\\|$\\)" (1 font-lock-constant-face))))&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</span></span></span></code></pre>&#x000A;</div>&#x000A;&#x000A;&#x000A;&#x000A;<p>It is easy to do such conversion by replace new line character <code>\n</code> to&#x000A;<code>\n&lt;/span&gt;&lt;span class="line"&gt;</code> and then wrap with first open tag and the last&#x000A;close tag.</p>&#x000A;&#x000A;<p>Because I want to show indicators in left, right padding of <code>span.line</code>, it&#x000A;should be displayed as block to expand horizontally. Also enable line wrap on&#x000A;<code>pre</code>.</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">Line Markup</div>&#x000A;<pre class="code css"><code class="css"><span class="line-margin"><span class="line"><span class="nt">pre</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">white-space</span><span class="o">:</span> <span class="n">pre</span><span class="o">-</span><span class="n">wrap</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">pre</span> <span class="nt">code</span><span class="o">,</span> <span class="nt">span</span><span class="nc">.line</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">display</span><span class="o">:</span> <span class="k">block</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span></span></span></code></pre>&#x000A;</div>&#x000A;&#x000A;&#x000A;&#x000A;<p>Pay attention to the new line position. It is included in the added&#x000A;<code>span.line</code> elements. Otherwise extra empty line is added between lines.</p>&#x000A;&#x000A;<h2 id="csliwrin-2-add-indicators">Add Indicators</h2>&#x000A;&#x000A;<p>The indicators are added through <code>:before</code> and <code>:after</code>. They have the same&#x000A;height with the line by setting <code>height</code> to <code>100%</code>.</p>&#x000A;&#x000A;<p>To ensure the indicators are aligned to each wrapped line, the picture must be&#x000A;the same height with <code>line-height</code>.</p>&#x000A;&#x000A;<p>I use following two icons. The height is 28px. So also set <code>span.line</code>&#x000A;<code>line-height</code> to 28px.</p>&#x000A;&#x000A;<ul>&#x000A;<li>Left: <img alt="left line wrap indicator" src="http://assets.iany.me/line-left.png">&#x000A;</li>&#x000A;<li>Right: <img alt="right line wrap indicator" src="http://assets.iany.me/line-right.png">&#x000A;</li>&#x000A;</ul><div class="file">&#x000A;<div class="caption">Line height = picuture height</div>&#x000A;<pre class="code css"><code class="css"><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">line-height</span><span class="o">:</span> <span class="m">28px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span></span></span></code></pre>&#x000A;</div>&#x000A;&#x000A;&#x000A;&#x000A;<p>Then just add <code>:before</code> and <code>:after</code> and apply vertically repeat background on&#x000A;them. <code>position</code> of <code>span.line</code> is set to <code>relative</code> so <code>:before</code> and <code>:after</code>&#x000A;can be positioned relative to it. It is easy to add them in <code>span.line</code>&#x000A;padding. I use padding instead of margin because later I&rsquo;ll set overflow to&#x000A;hidden to hide indicators outside of <code>span.line</code>, where margin is considered&#x000A;outside.</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">Indicators in :before and :after</div>&#x000A;<pre class="code css"><code class="css"><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">padding</span><span class="o">:</span> <span class="m">0</span> <span class="m">13px</span><span class="p">;</span> <span class="c">/* 8px for indicator, 5px for space around text */</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">position</span><span class="o">:</span> <span class="k">relative</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span><span class="nd">:before</span><span class="o">,</span> <span class="nt">span</span><span class="nc">.line</span><span class="nd">:after</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">background-repeat</span><span class="o">:</span> <span class="k">repeat-y</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">content</span><span class="o">:</span> <span class="s2">""</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">display</span><span class="o">:</span> <span class="k">block</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">width</span><span class="o">:</span> <span class="m">10px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">height</span><span class="o">:</span> <span class="m">100</span><span class="o">%</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">position</span><span class="o">:</span> <span class="k">absolute</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span><span class="nd">:before</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">background-image</span><span class="o">:</span> <span class="sx">url("line-left.png")</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">top</span><span class="o">:</span> <span class="m">0</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">left</span><span class="o">:</span> <span class="m">1px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span><span class="nd">:after</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">background-image</span><span class="o">:</span> <span class="sx">url("line-right.png")</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">top</span><span class="o">:</span> <span class="m">0</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">right</span><span class="o">:</span> <span class="m">-1px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span></span></span></code></pre>&#x000A;</div>&#x000A;&#x000A;&#x000A;&#x000A;<p>Now the indicators are shown in left and right padding on all lines. Use <code>top</code>&#x000A;to shift down left indicators and <code>bottom</code> to shift up right indicators, so&#x000A;left indicator is not shown on the first line and right indicator is not shown&#x000A;on the last line. But some indicators are moved out, use <code>overflow:hidden</code> to&#x000A;hide them.</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">No left indicator on first line and no right indicator on last line</div>&#x000A;<pre class="code css"><code class="css"><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">overflow</span><span class="o">:</span> <span class="k">hidden</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span><span class="nd">:before</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">top</span><span class="o">:</span> <span class="m">28px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span><span class="nd">:after</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">top</span><span class="o">:</span> <span class="k">auto</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">bottom</span><span class="o">:</span> <span class="m">28px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span></span></span></code></pre>&#x000A;</div>&#x000A;&#x000A;&#x000A;&#x000A;<h2 id="csliwrin-3-add-color-to-padding">Add Color to Padding</h2>&#x000A;&#x000A;<p>Use border and background on <code>pre</code> to add different color to indicators&#x000A;padding and code block. Use negative margin to align indicators to the&#x000A;borders.</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">Add Color</div>&#x000A;<pre class="code css"><code class="css"><span class="line-margin"><span class="line"><span class="nt">pre</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">border-style</span><span class="o">:</span> <span class="k">solid</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">border-color</span><span class="o">:</span> <span class="m">#EEE</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">border-width</span><span class="o">:</span> <span class="m">0</span> <span class="m">8px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">background-color</span><span class="o">:</span> <span class="m">#AAA</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nt">span</span><span class="nc">.line</span> <span class="p">{</span>&#x000A;</span></span><span class="line-margin"><span class="line">  <span class="k">margin</span><span class="o">:</span> <span class="m">0</span> <span class="m">-8px</span><span class="p">;</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="p">}</span></span></span></code></pre>&#x000A;</div>&#x000A;]]></content></entry>
<entry>
<id>http://blog.iany.me/2012/01/hilight-ruby-new-hash-in-emacs/</id>
<link href="http://blog.iany.me/2012/01/hilight-ruby-new-hash-in-emacs/" rel="alternate" type="text/html" />
<title>Hilight Ruby New Hash In Emacs</title>
<published>2012-01-11T16:00:00Z</published>
<updated>2012-01-12T12:13:05Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="Emacs" term="emacs" />
<category label="Ruby" term="ruby" /><content type="html"><![CDATA[<p>Not fully tested, let me know if it mess up your buffer.</p>&#x000A;&#x000A;<div class="file">&#x000A;<div class="caption">my-ruby-mode.el <a class="gist external" href="https://gist.github.com/1600148" rel="gist">gist:1600148</a>&#x000A;</div>&#x000A;<pre class="code cl"><code class="cl"><span class="line-margin"><span class="line"><span class="p">(</span><span class="nv">font-lock-add-keywords</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="ss">'ruby-mode</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="o">'</span><span class="p">((</span><span class="s">"\\(\\b\\sw[_a-zA-Z0-9]*:\\)\\(?:\\s-\\|$\\)"</span> <span class="p">(</span><span class="mi">1</span> <span class="nv">font-lock-constant-face</span><span class="p">))))</span></span></span></code></pre>&#x000A;</div>&#x000A;]]></content></entry>
<entry>
<id>http://blog.iany.me/2011/12/zero-configuration-nginx-with-passenger/</id>
<link href="http://blog.iany.me/2011/12/zero-configuration-nginx-with-passenger/" rel="alternate" type="text/html" />
<title>Zero Configuration Nginx With Passenger</title>
<published>2011-12-08T16:00:00Z</published>
<updated>2011-12-31T07:24:40Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="rails" term="rails" />
<category label="ruby" term="ruby" />
<category label="rack" term="rack" />
<category label="nginx" term="nginx" />
<category label="passenger" term="passenger" />
<category label="pow" term="pow" /><content type="html"><![CDATA[<p><a href="http://pow.cx" class=" external">Pow</a> is a zero-config Rack server for Mac OS X. Here I steal its idea to&#x000A;build a zero-config system based on Nginx with Passenger.</p>&#x000A;&#x000A;<!-- more -->&#x000A;&#x000A;<h2 id="zecongpa-1-auto-virtual-hosts">Auto Virtual Hosts</h2>&#x000A;&#x000A;<p>Since 0.8.25, Nginx supports named captures in&#x000A;<a href="http://wiki.nginx.org/HttpCoreModule#server_name" class=" external">server_name</a> directive.</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">server {&#x000A;</span></span><span class="line-margin"><span class="line">  server_name   ~^(www\.)?(?<domain>.+)$;&#x000A;</domain></span></span><span class="line-margin"><span class="line">  root  /sites/$domain;&#x000A;</span></span><span class="line-margin"><span class="line">}</span></span></code></pre>&#x000A;&#x000A;<p>It can be used to setup passenger virtual hosts and locate the rails/rack root&#x000A;directory based on the server name.</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">server {&#x000A;</span></span><span class="line-margin"><span class="line">  server_name ~^(.*\.)?(?<app>[^.]+)\.dev$;&#x000A;</app></span></span><span class="line-margin"><span class="line">  root /opt/apps/$app/public;&#x000A;</span></span><span class="line-margin"><span class="line">  rails_env development;&#x000A;</span></span><span class="line-margin"><span class="line">  passenger_enabled on;&#x000A;</span></span><span class="line-margin"><span class="line">}</span></span></code></pre>&#x000A;&#x000A;<p>The configuration above matches all sever names that ends with &ldquo;.dev&rdquo;, and use&#x000A;the 2nd level domain name to locate application root directory. For example,&#x000A;<code>myapp.dev</code> and <code>www.myapp.dev</code> both use the root <code>/opt/apps/myapp/public</code>,&#x000A;thus will serve the rails/rack app <code>/opt/apps/myapp/</code>.</p>&#x000A;&#x000A;<p>Sure, <code>/opt/apps</code> can be changed to any directory accessible by Nginx. And&#x000A;remember to reload Nginx (<code>nginx -s reload</code>) after change the config file.</p>&#x000A;&#x000A;<p>Now new app can be added just like Pow, creating a symbol link in&#x000A;<code>/opt/apps</code>.</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">cd /opt/apps&#x000A;</span></span><span class="line-margin"><span class="line">ln -s /path/to/myapp</span></span></code></pre>&#x000A;&#x000A;<p>We can setup more server blocks for different environments, for example:</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">server {&#x000A;</span></span><span class="line-margin"><span class="line">  server_name ~^(.*\.)?(?<app>[^.]+)\.staging;&#x000A;</app></span></span><span class="line-margin"><span class="line">  root /opt/apps/$app/public;&#x000A;</span></span><span class="line-margin"><span class="line">  rails_env staging;&#x000A;</span></span><span class="line-margin"><span class="line">  passenger_enabled on;&#x000A;</span></span><span class="line-margin"><span class="line">}</span></span></code></pre>&#x000A;&#x000A;<p>Add a record in <code>/etc/hosts</code> and open browser to see whether <code>http://myapp.dev</code>&#x000A;works.</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">127.0.0.1 myapp.dev</span></span></code></pre>&#x000A;&#x000A;<h2 id="zecongpa-2-local-dns-resolver">Local DNS Resolver</h2>&#x000A;&#x000A;<p>Pow starts its own DNS and utilizes&#x000A;<a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man5/resolver.5.html" class=" external">Mac /etc/resolver system</a>&#x000A;to resolve all subdomains of specified top-level domain to <code>127.0.0.1</code>.</p>&#x000A;&#x000A;<p>It is written for nodejs, and I wrote a simple wrapper&#x000A;<a href="https://github.com/doitian/simpledns" class=" external">simpledns</a> to only start the DNS server&#x000A;in Pow.</p>&#x000A;&#x000A;<ul>&#x000A;<li><p>Install <a href="http://nodejs.org" class=" external">nodejs</a> first</p></li>&#x000A;<li>&#x000A;<p>Clone simpledns</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">git clone git://github.com/doitian/simpledns.git</span></span></code></pre>&#x000A;</li>&#x000A;<li><p>Read README.md in it and start the DNS server.</p></li>&#x000A;</ul><p>The server echoes something like</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">Save following content as files: /etc/resolver/dev&#x000A;</span></span><span class="line-margin"><span class="line">&#x000A;</span></span><span class="line-margin"><span class="line"># File generated by simpledns/server.js&#x000A;</span></span><span class="line-margin"><span class="line">namespace: 127.0.0.1&#x000A;</span></span><span class="line-margin"><span class="line">port: 20560&#x000A;</span></span><span class="line-margin"><span class="line"># File content ends here</span></span></code></pre>&#x000A;&#x000A;<p>Follow the instruction and create the file in <code>/etc/resolver</code>.</p>&#x000A;&#x000A;<p>Now remove the line <code>127.0.0.1 myapp.dev</code>, restart your browser to see whether&#x000A;<code>http://myapp.dev</code> still works.</p>]]></content></entry>
<entry>
<id>http://blog.iany.me/2011/06/tmux-and-rvmrc/</id>
<link href="http://blog.iany.me/2011/06/tmux-and-rvmrc/" rel="alternate" type="text/html" />
<title>Tmux And Rvmrc</title>
<published>2011-06-16T16:00:00Z</published>
<updated>2011-12-02T19:41:51Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="tmux" term="tmux" />
<category label="rvm" term="rvm" />
<category label="ruby" term="ruby" />
<category label="console" term="console" /><content type="html"><![CDATA[<p><a href="http://tmux.sourceforge.net/" class=" external">Tmux</a> is a terminal multiplexer. I switched to Tmux from <a href="http://www.gnu.org/software/screen/" class=" external">GNU Screen</a>&#x000A;recently.</p>&#x000A;&#x000A;<p>I work on several Ruby projects. I use <a href="http://beginrescueend.com/" class=" external">RVM</a> to manage gem set for different&#x000A;projects, and use <a href="http://beginrescueend.com/workflow/rvmrc/" class=" external">rvmrc</a> file to switch gem set automatically. I usually start&#x000A;a Tmux session for a project in its root directory, so all the windows and panes&#x000A;in the session use the project root as default directory. The problem is, the&#x000A;new created shell in the session does not load <code>.rvmrc</code> in the root directory. I&#x000A;have to force loading the file using &ldquo;<code>cd .</code>&rdquo;</p>&#x000A;&#x000A;<!--more-->&#x000A;&#x000A;<p>I also use <a href="https://github.com/aziz/tmuxinator" class=" external">Tmuxinator</a>. It can specify a rvm gem set though project yml&#x000A;file. But this setting only has effect on the windows and panes pre-configured&#x000A;in the yml file, the new created shells do not load <code>.rvmrc</code>. Moreover, if the&#x000A;project needs different gem sets for different branches, each gem set must has&#x000A;its own tmuxinator project file.</p>&#x000A;&#x000A;<p>Finally, I figured out a simple solution. Just append <code>cd .</code> to the end of the&#x000A;shell init file (<code>.bashrc</code> for bash and <code>.zshrc</code> for zsh). Then all the new&#x000A;shells will try to load the <code>.rvmrc</code> file in the default directory where it&#x000A;starts, including shells in Tmux.</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line"># try loading .rvmrc, add it below the line loading RVM&#x000A;</span></span><span class="line-margin"><span class="line">cd .</span></span></code></pre>]]></content></entry>
<entry>
<id>http://blog.iany.me/2011/05/mendeley-cross-platform-research-management-tool/</id>
<link href="http://blog.iany.me/2011/05/mendeley-cross-platform-research-management-tool/" rel="alternate" type="text/html" />
<title>Mendeley: Cross Platform Research Management Tool</title>
<published>2011-05-17T16:00:00Z</published>
<updated>2011-12-02T19:42:02Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="utility" term="utility" />
<category label="productivity" term="productivity" />
<category label="app" term="app" /><content type="html"><![CDATA[<p><a href="http://www.mendeley.com/" class=" external">Mendeley</a> is a research management tool for desktop &amp; web. It has clients for&#x000A;Linux, Mac, Windows and iPhone and a Web interface. Mendeley can manage any&#x000A;documents, but is better to work with PDF. The file meta data are synchronized&#x000A;though Mendeley server. The attached files (PDF or any other formats) can also&#x000A;be synchronized, but the free account has a quota of 500MB. However, the&#x000A;attached files directory and underlying sqlite database can be synchronized&#x000A;manually.</p>&#x000A;&#x000A;<!--more-->&#x000A;&#x000A;<p>Mendeley is also a collaboration platform that all the added documents can be&#x000A;shared with others. Co-workers can create group to maintain a shared documents&#x000A;list. Mendeley also maintains a public database, from which you can search and&#x000A;add result to your Mendeley library directly. Mendeley also supports importing&#x000A;data from other services such as <a href="http://www.citeulike.org/" title="CiteULike: Everyone's library" class=" external">CiteULike</a>.</p>&#x000A;&#x000A;<p>Mendeley client supports tags and PDF file indexing. It makes easy to search&#x000A;documents. If you use BibTex to manage references in your writings, the client&#x000A;can export all documents into a BibTex file and synchronize your further changes&#x000A;in Mendeley to that file.</p>&#x000A;&#x000A;<h2 id="mecrplto-1-get-started">Get Started</h2>&#x000A;&#x000A;<p>You need to register an account in <a href="http://www.mendeley.com/" class=" external">Mendeley</a>. Then&#x000A;<a href="http://www.mendeley.com/download-mendeley-desktop/" class=" external">download</a> a client for your&#x000A;platform. Following is the snapshot of Mendeley under Linux.</p>&#x000A;&#x000A;<h2 id="mecrplto-2-add-documents">Add Documents</h2>&#x000A;&#x000A;<p>The documents can be added by adding attached files directly. Mendeley will try&#x000A;to extract meta information from files. It is also able to create an entry and&#x000A;edit meta information manually, and attach file later.</p>&#x000A;&#x000A;<p>But the most convenient solution is search the documents in&#x000A;<a href="http://www.mendeley.com/research-papers/" class=" external">Mendeley database</a>, add the search result and synchronize to the client, then&#x000A;attach files in client. However, I have not found a way to use a search result&#x000A;as the meta information of an existing document.</p>&#x000A;&#x000A;<p>The meta information and attached files can be managed in details panel, which&#x000A;is opened by clicking the handler in the right side.</p>&#x000A;&#x000A;<h2 id="mecrplto-3-synchronize">Synchronize</h2>&#x000A;&#x000A;<p>Documents meta information are all synchronized. The attached files are&#x000A;synchronized according to the per folder settings. All folders are listed under&#x000A;My Library. Just select the folder you want to synchronize and edit its settings&#x000A;to enable.</p>&#x000A;&#x000A;<p>If attached files are not synchronize attached files, their local paths are also&#x000A;not synchronized. It is very inconvenient. You cannot synchronize your attached&#x000A;files manually across machines with the same position and let Mendeley just&#x000A;synchronize the meta information.</p>&#x000A;&#x000A;<p>However, you can manually synchronize the attached files directory and&#x000A;underlying sqlite database.</p>&#x000A;&#x000A;<h3 id="mecrplto-3_1-organize-files">Organize files</h3>&#x000A;&#x000A;<p>Open options dialog through menu Tools -&gt; Options and switch to &ldquo;File Organizer&rdquo; tab.</p>&#x000A;&#x000A;<ul>&#x000A;<li>Enable &ldquo;Organize my files&rdquo; and select a directory such as &ldquo;/Mendeley&rdquo;. It must&#x000A;be the same in different machines. So the manual solution cannot synchronize&#x000A;between Windows and Mac, Linux.</li>&#x000A;<li>Enable &ldquo;Sort files into sub-folders&rdquo; to avoid file name conflicts. I prefer the&#x000A;Folder path <code>Year</code>/<code>Author</code>.</li>&#x000A;</ul><h3 id="mecrplto-3_2-manual-synchronization">Manual Synchronization</h3>&#x000A;&#x000A;<p>The attached files directory and the meta info sqlite database can be&#x000A;synchronized using <a href="http://db.tt/I4zEuqN" title="cloud service for file synchronization" class=" external">Dropbox</a>, <a href="http://en.wikipedia.org/wiki/Rsync" title="file synchronization command" class=" external">Rsync</a> or <a href="http://code.google.com/p/lsyncd/" title="Live Syncing (Mirror) Daemon" class=" external">Lsyncd</a>. For Dropbox, just make&#x000A;symbol links in the Dropbox directory.</p>&#x000A;&#x000A;<p>The database file is created when you have logged-in in the client. It is stored&#x000A;in different location in different platform. I have figured out its location in&#x000A;Linux and Mac (replace <a href="mailto:email@example.com">email@example.com</a> with your own registered email).</p>&#x000A;&#x000A;<ul>&#x000A;<li>Linux: <code>$HOME/.local/share/data/Mendeley Ltd./Mendeley Desktop/email@example.com@www.mendeley.com.sqlite</code>&#x000A;</li>&#x000A;<li>Mac: <code>$HOME/Library/Application Support/Mendeley Desktop/email@example.com@www.mendeley.com.sqlite</code>&#x000A;</li>&#x000A;</ul><p>Because the sqlite database file is binary, you cannot simply merge two database&#x000A;files. I recommend to add and edit documents only in one machine, and use other&#x000A;machines as read only copies. Otherwise you may loose data during&#x000A;synchronization.</p>]]></content></entry>
<entry>
<id>http://blog.iany.me/2010/08/switch-window-using-fuzz-matching/</id>
<link href="http://blog.iany.me/2010/08/switch-window-using-fuzz-matching/" rel="alternate" type="text/html" />
<title>Switch Window Using Fuzz Matching</title>
<published>2010-08-25T16:00:00Z</published>
<updated>2011-12-07T20:40:44Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="desktop" term="desktop" />
<category label="Linux" term="linux" />
<category label="productivity" term="productivity" />
<category label="script" term="script" /><content type="html"><![CDATA[<p>This article demonstrates how to quickly switch to a window using <strong>gpicker</strong>&#x000A;and <strong>wmctrl</strong>. You type significant letters of workspace name, application name&#x000A;or title and gpicker provides a list of windows you most likely mean to pick.</p>&#x000A;&#x000A;<!--more-->&#x000A;&#x000A;<h2 id="swwiusma-1-gpicker">Gpicker</h2>&#x000A;&#x000A;<blockquote>&#x000A;<p><a href="http://savannah.nongnu.org/projects/gpicker" title="Gpicker" class=" external">Gpicker</a> is a program that allows you to quickly and conveniently pick file&#x000A;in a (possibly very large) project. You type significant letters of file name&#x000A;(typically from the start of words) and gpicker provides you with a list of&#x000A;files you most likely mean to pick. The program filters and orders project&rsquo;s&#x000A;list of files in real-time as you type.</p>&#x000A;</blockquote>&#x000A;&#x000A;<p>You need to <a href="http://ftp.twaren.net/Unix/NonGNU/gpicker/" class=" external">download</a> and install&#x000A;it manually (for Ubuntu, you can download the Debian package).</p>&#x000A;&#x000A;<p>Gpicker is designed as a filter, so it can be used to select item from an&#x000A;arbitrary list. The selected item is printed on standard output.</p>&#x000A;&#x000A;<p>For example, use gpicker to select a number between 1 and 10:</p>&#x000A;&#x000A;<pre class="code console"><code class="console"><span class="line-margin"><span class="line"><span class="gp">$</span> seq -w 1 10 | gpicker -n <span class="s2">"\n"</span> -</span></span></code></pre>&#x000A;&#x000A;<figure><img alt="Gpicker picks 1 to 10" src="http://assets.iany.me/gallery/2010/08/switch-window-using-fuzz-matching/picker_1_to_10.png"><figcaption>Gpicker picks 1 to 10</figcaption></figure><p>The last dash tells gpicker to read list from standard input, and option &ldquo;-n&rdquo;&#x000A;sets the list separator. Gpicker uses &ldquo;\0&rdquo; as item separator by default.</p>&#x000A;&#x000A;<h2 id="swwiusma-2-wmctrl">Wmctrl</h2>&#x000A;&#x000A;<p><strong>Wmctrl</strong> is a command line utility to interact with a EWMH/NetWM compatible X&#x000A;Window Manager. It can list all windows, switch to a window or bring a window to&#x000A;current workspace. Wmctrl can be installed by package manager in most Linux&#x000A;distribution.</p>&#x000A;&#x000A;<p>Wmctrl lists all windows using option &ldquo;-l&rdquo;. We can add &ldquo;-x&rdquo; to list windows&#x000A;resource and class as well. The output of <code>wmctrl -l -x</code> looks like:</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">0x03200009  0 urxvt.URxvt       ian-desktop urxvt&#x000A;</span></span><span class="line-margin"><span class="line">0x0340008e  1 Navigator.Firefox ian-desktop Vimperator / test&#x000A;</span></span><span class="line-margin"><span class="line">0x03e000a4  2 emacs.Emacs       ian-desktop Emacs: _theme.sass</span></span></code></pre>&#x000A;&#x000A;<p>The first column is the window ID. We can switch to or bring a window using the&#x000A;ID.</p>&#x000A;&#x000A;<pre class="code bash"><code class="bash"><span class="line-margin"><span class="line"><span class="c"># switch to Emacs, raise and focus it</span>&#x000A;</span></span><span class="line-margin"><span class="line">wmctrl -i -a 0x03e000a4&#x000A;</span></span><span class="line-margin"><span class="line">&#x000A;</span></span><span class="line-margin"><span class="line"><span class="c"># bring Emacs to current workspace, raise and focus it</span>&#x000A;</span></span><span class="line-margin"><span class="line">wmctrl -i -R 0x03e000a4</span></span></code></pre>&#x000A;&#x000A;<h2 id="swwiusma-3-windows-picker">Windows Picker</h2>&#x000A;&#x000A;<p>Now we can use wmctrl to list windows, gpicker to select one window, and&#x000A;wmctrl again to switch to the selected window.</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">wmctrl -i -a `wmctrl -l -x | gpicker -n "\n" -d "\n" -`</span></span></code></pre>&#x000A;&#x000A;<p>The directory separator is set to &ldquo;\n&rdquo; in the first windows picker above,&#x000A;because gpicker is designed to pick files primarily and it has special rules&#x000A;in the matching algorithm.</p>&#x000A;&#x000A;<p>First the item is split by directory separator. Before we enter a directory&#x000A;separator (&ldquo;/&rdquo; by default), only the last component (it is the file name if the&#x000A;item is a file path) is used in matching. For example, &ldquo;bin&rdquo; does not match item&#x000A;&ldquo;bin/ruby&rdquo;, but &ldquo;bin/&rdquo;, even &ldquo;b/&rdquo; does match. If the window title contains the&#x000A;directory separator, for example the Firefox in the <code>wmctrl -l -x</code> output above:</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">0x0340008e  1 Navigator.Firefox    ian-desktop Vimperator / test</span></span></code></pre>&#x000A;&#x000A;<p>To match it, we must enter &ldquo;firefox/&rdquo;. So I set directory separator to &ldquo;\n&rdquo; to&#x000A;disable this feature, and the whole item is used to match.</p>&#x000A;&#x000A;<p>However, we can take advantage of this feature. If we construct the window item&#x000A;likes:</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">id/workspace/window_class/window_title</span></span></code></pre>&#x000A;&#x000A;<p>I can match window title by type significant letters directory. I also can&#x000A;use directory separator &ldquo;/&rdquo; to filter all windows in a specific workspace, or&#x000A;windows with the same window class.</p>&#x000A;&#x000A;<p>It is very useful for me. Because I uses tiling windows manager&#x000A;<a href="http://xmonad.org/" class=" external">Xmonad</a> and places windows in different windows. Following&#x000A;are some examples:</p>&#x000A;&#x000A;<table>&#x000A;<thead><tr>&#x000A;<th>I have entered</th>&#x000A;<th>Windows I want to match</th>&#x000A;</tr></thead>&#x000A;<tbody>&#x000A;<tr>&#x000A;<td>www/ff/</td>&#x000A;<td>Firefox in workspace &ldquo;2.www&rdquo;</td>&#x000A;</tr>&#x000A;<tr>&#x000A;<td>ruby</td>&#x000A;<td>Windows which title contains ruby</td>&#x000A;</tr>&#x000A;<tr>&#x000A;<td>xpdf/ruby</td>&#x000A;<td>A document opened using xpdf and the title contains ruby</td>&#x000A;</tr>&#x000A;<tr>&#x000A;<td>sys/usrshare</td>&#x000A;<td>The terminal I opened visit /usr/share in workspace &ldquo;1.sys&rdquo;</td>&#x000A;</tr>&#x000A;</tbody>&#x000A;</table><figure><img src="http://assets.iany.me/gallery/2010/08/switch-window-using-fuzz-matching/picker-windows-list.png"><figcaption>Windows List</figcaption></figure><figure><img src="http://assets.iany.me/gallery/2010/08/switch-window-using-fuzz-matching/picker-xpdf-ruby.png"><figcaption>Select Ruby document opened in Xpdf</figcaption></figure><p>Sure, we have to remove &ldquo;/&rdquo; from workspace name and window title.</p>&#x000A;&#x000A;<p>I use a Ruby <a href="http://gist.github.com/551432" class=" external">script</a> to format the&#x000A;list. Workspace name can be listed using <code>wmctrl -d</code>.</p>&#x000A;&#x000A;<p>Now we can use the ruby script in the revised version:</p>&#x000A;&#x000A;<pre class="code"><code><span class="line-margin"><span class="line">wmctrl -i -a `wlist.rb | gpicker - | sed 's;/.*$;;'`</span></span></code></pre>&#x000A;&#x000A;<p>Replace &ldquo;-a&rdquo; with &ldquo;-R&rdquo; to bring window to current workspace.</p>]]></content></entry>
<entry>
<id>http://blog.iany.me/2010/05/study-on-alias-method/</id>
<link href="http://blog.iany.me/2010/05/study-on-alias-method/" rel="alternate" type="text/html" />
<title>Study on Alias Method</title>
<published>2010-05-28T16:00:00Z</published>
<updated>2011-12-07T04:59:17Z</updated>
<author>
<name>Ian Yang</name>
<email>me@iany.me</email>
<uri>http://iany.me/</uri>
</author>
<category label="algorithm" term="algorithm" />
<category label="probability" term="probability" /><content type="html"><![CDATA[<p><a href="http://twitter.com/miloyip" class=" external">@miloyip</a> has published a&#x000A;<a href="http://www.cnblogs.com/miloyip/archive/2010/05/27/reply_discrete.html" class=" external">post</a>&#x000A;recently which motioned the Alias Method to generate a discrete random variable&#x000A;in <em>O(1)</em>. After some research, I find out that it is a neat and clever&#x000A;algorithm. Following are some notes of my study on it.</p>&#x000A;&#x000A;<!--more-->&#x000A;&#x000A;<h2 id="stonalme-1-what-alias-method">What is Alias Method</h2>&#x000A;&#x000A;<p>Alias method is an efficient algorithm to generate a discrete random variable&#x000A;with specified probability mass function using a uniformly distributed&#x000A;random variable.</p>&#x000A;&#x000A;<p>Let <code class="mathjax" lang="latex">Z</code> be the discrete random variable which has n possible outcomes&#x000A;<code class="mathjax" lang="latex">z_0,z_1,\ldots,z_{n-1}</code>.  To make the discussion below simple, we study&#x000A;another variable <code class="mathjax" lang="latex">Y</code>, where <code class="mathjax" lang="latex">P\{Y=i\}=P\{Z=z_i\}</code>. And when <code class="mathjax" lang="latex">Y</code> takes on&#x000A;value <code class="mathjax" lang="latex">i</code>, let <code class="mathjax" lang="latex">Z</code> be <code class="mathjax" lang="latex">z_i</code>. So <code class="mathjax" lang="latex">Z</code> can be generated from <code class="mathjax" lang="latex">Y</code>.</p>&#x000A;&#x000A;<p>Random variable <code class="mathjax" lang="latex">X</code> is uniformly distributed in <code class="mathjax" lang="latex">(0, n)</code>, which probability&#x000A;density function is</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="sb">\[</span><span class="nb"> f</span><span class="o">(</span><span class="nb">x</span><span class="o">)</span><span class="nb"> </span><span class="o">=</span><span class="nb"> </span><span class="nv">\left\{</span><span class="nb"></span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb"> </span><span class="nv">\begin</span><span class="nb">{array}{rl}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb">  </span><span class="m">1</span><span class="o">/</span><span class="nb">n &amp; </span><span class="nv">\text</span><span class="nb">{if } </span><span class="m">0</span><span class="nb"> &lt; x &lt; n</span><span class="nv">\\</span><span class="nb"></span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb">  </span><span class="m">0</span><span class="nb"> &amp; </span><span class="nv">\text</span><span class="nb">{otherwise}</span><span class="nv">\\</span><span class="nb"></span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb"> </span><span class="nv">\end</span><span class="nb">{array} </span><span class="nv">\right</span><span class="nb">. </span><span class="s">\]</span></span></span></code></pre>&#x000A;&#x000A;<p>Now generate a variable <code class="mathjax" lang="latex">Y'</code> that</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="sb">\[</span><span class="nb"> Y' </span><span class="o">=</span><span class="nb">  </span><span class="nv">\left\{</span><span class="nb"></span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb"> </span><span class="nv">\begin</span><span class="nb">{array}{rl}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb">  </span><span class="nv">\lfloor</span><span class="nb"> x  </span><span class="nv">\rfloor</span><span class="nb"> &amp; </span><span class="nv">\text</span><span class="nb">{if } </span><span class="o">(</span><span class="nb">x </span><span class="o">-</span><span class="nb"> </span><span class="nv">\lfloor</span><span class="nb"> x </span><span class="nv">\rfloor</span><span class="o">)</span><span class="nb"> &lt; F</span><span class="o">(</span><span class="nv">\lfloor</span><span class="nb"> x </span><span class="nv">\rfloor</span><span class="o">)</span><span class="nv">\\</span><span class="nb"></span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb">  A</span><span class="o">(</span><span class="nv">\lfloor</span><span class="nb"> x </span><span class="nv">\rfloor</span><span class="o">)</span><span class="nb">  &amp; </span><span class="nv">\text</span><span class="nb">{otherwise}</span><span class="nv">\\</span><span class="nb"></span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="nb"> </span><span class="nv">\end</span><span class="nb">{array} </span><span class="nv">\right</span><span class="nb">.</span><span class="s">\]</span></span></span></code></pre>&#x000A;&#x000A;<p><code class="mathjax" lang="latex">A(i)</code> is the alias function. When <code class="mathjax" lang="latex">x</code> falls in range&#x000A;<code class="mathjax" lang="latex">[i, i + 1)</code> (<code class="mathjax" lang="latex">i</code> is an integer), <code class="mathjax" lang="latex">y</code> has the probability <code class="mathjax" lang="latex">F(i)</code> to be <code class="mathjax" lang="latex">i</code>,&#x000A;and probability <code class="mathjax" lang="latex">1 - F(i)</code> to be <code class="mathjax" lang="latex">A(i)</code>. Because <code class="mathjax" lang="latex">x</code> is uniformly distributed,</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="k">\begin</span><span class="nb">{</span>align*<span class="nb">}</span>&#x000A;</span></span><span class="line-margin"><span class="line">P<span class="k">\{</span>x <span class="k">\in</span> [i, i + F(i))<span class="k">\}</span>     <span class="nb">&amp;</span>= <span class="k">\int</span><span class="nb">_</span>i<span class="nb">^{</span>i+F(i)<span class="nb">}</span><span class="k">\frac</span><span class="nb">{</span>1<span class="nb">}{</span>n<span class="nb">}</span>dx<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">                             <span class="nb">&amp;</span>= (i + F(i) - i) <span class="k">\times</span> 1/n<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">                             <span class="nb">&amp;</span>= F(i)/n,<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">P<span class="k">\{</span>x <span class="k">\in</span> [i + F(i), i + 1)<span class="k">\}</span> <span class="nb">&amp;</span>= <span class="k">\int</span><span class="nb">_{</span>i+F(i)<span class="nb">}^{</span>i+1<span class="nb">}</span><span class="k">\frac</span><span class="nb">{</span>1<span class="nb">}{</span>n<span class="nb">}</span>dx<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">                             <span class="nb">&amp;</span>= (i + 1 - (i + F(i))) <span class="k">\times</span> 1/n<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">                             <span class="nb">&amp;</span>= (1-F(i))/n&#x000A;</span></span><span class="line-margin"><span class="line"><span class="k">\end</span><span class="nb">{</span>align*<span class="nb">}</span></span></span></code></pre>&#x000A;&#x000A;<p>Let&rsquo;s denote the set of values <code class="mathjax" lang="latex">j</code> that satisfies <code class="mathjax" lang="latex">A(j) = i</code> as <code class="mathjax" lang="latex">A^{-1}(i)</code>. The&#x000A;generated variable <code class="mathjax" lang="latex">Y'</code> has following probability mass function:</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="sb">\[</span><span class="nb"> P</span><span class="nv">\{</span><span class="nb">Y' </span><span class="o">=</span><span class="nb"> i</span><span class="nv">\}</span><span class="nb"> </span><span class="o">=</span><span class="nb"> F</span><span class="o">(</span><span class="nb">i</span><span class="o">)/</span><span class="nb">n </span><span class="o">+</span><span class="nb"> </span><span class="nv">\sum</span><span class="nb">_{j </span><span class="nv">\in</span><span class="nb"> A^{</span><span class="o">-</span><span class="m">1</span><span class="nb">}</span><span class="o">(</span><span class="nb">i</span><span class="o">)</span><span class="nb">}</span><span class="nv">\frac</span><span class="nb">{</span><span class="m">1</span><span class="o">-</span><span class="nb">F</span><span class="o">(</span><span class="nb">j</span><span class="o">)</span><span class="nb">}{n} </span><span class="s">\]</span></span></span></code></pre>&#x000A;&#x000A;<p>Alias method is the algorithm to construct <code class="mathjax" lang="latex">A</code> and <code class="mathjax" lang="latex">F</code> so that <code class="mathjax" lang="latex">P\{Y' = i\}</code>&#x000A;equals to <code class="mathjax" lang="latex">P\{Y = i\}</code> for all <code class="mathjax" lang="latex">i</code>. Because the domain of both <code class="mathjax" lang="latex">A</code> and <code class="mathjax" lang="latex">F</code> are&#x000A;integers <code class="mathjax" lang="latex">0,1,\ldots,n-1</code>, they can be stored in array and values can be&#x000A;looked up in <em>O(1)</em>, where the space efficiency is in <em>O(n)</em>.</p>&#x000A;&#x000A;<p>In miloyip&rsquo;s implementation, <code class="mathjax" lang="latex">A</code> and <code class="mathjax" lang="latex">F</code> are stored in&#x000A;<code>std::vector&lt;AliasItem&gt; mAliasTable</code>, where <code class="mathjax" lang="latex">A</code>&rsquo;s values are stored in&#x000A;<code>AliasItem::index</code> and <code class="mathjax" lang="latex">F</code>&rsquo;s values are <code>AliasItem::prob</code>.</p>&#x000A;&#x000A;<h2 id="stonalme-2-algorithm">Algorithm</h2>&#x000A;&#x000A;<h3 id="stonalme-2_1-construct-steps">Construct Steps</h3>&#x000A;&#x000A;<p>Initialize the set <code class="mathjax" lang="latex">S</code> to be <code class="mathjax" lang="latex">{0,1,\ldots,n-1}</code> and n variables <code class="mathjax" lang="latex">p_i</code> that with values:</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="sb">\[</span><span class="nb"> p_i </span><span class="o">=</span><span class="nb"> P</span><span class="nv">\{</span><span class="nb">Y</span><span class="o">=</span><span class="nb">i</span><span class="nv">\}</span><span class="nb">, i </span><span class="nv">\in</span><span class="nb"> S </span><span class="s">\]</span></span></span></code></pre>&#x000A;&#x000A;<p>Denote the number of elements in <code class="mathjax" lang="latex">S</code> as <code class="mathjax" lang="latex">\|S\|</code>. We have a important invariant that</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="sb">\[</span><span class="nb"> </span><span class="nv">\sum</span><span class="nb">_{i </span><span class="nv">\in</span><span class="nb"> S}{p_i} </span><span class="o">=</span><span class="nb"> </span><span class="nv">\|</span><span class="nb">S</span><span class="nv">\|</span><span class="nb"> </span><span class="o">/</span><span class="nb"> n </span><span class="s">\]</span></span></span></code></pre>&#x000A;&#x000A;<p>At the begin of the algorithm, the invariant holds because the sum of all&#x000A;probabilities must equal to 1.</p>&#x000A;&#x000A;<p>The algorithm is performed using following steps.</p>&#x000A;&#x000A;<ol>&#x000A;<li>If there is an element <code class="mathjax" lang="latex">i</code> in set <code class="mathjax" lang="latex">S</code> such that <code class="mathjax" lang="latex">p_i &lt; 1/n</code>, there must be a <code class="mathjax" lang="latex">j</code> in&#x000A;set <code class="mathjax" lang="latex">S</code> such that <code class="mathjax" lang="latex">p_j &gt; 1/n</code>.<sup class="fnref" id="stonalme-fnref-1"><a href="#stonalme-fn-1" rel="footnote">[1]</a></sup>&#x000A;Let <code class="mathjax" lang="latex">A(i) = j</code> and&#x000A;<code class="mathjax" lang="latex">F(i) = p_i / (1/n) = p_i \times n</code>. Remove <code class="mathjax" lang="latex">i</code> from <code class="mathjax" lang="latex">S</code> and subtract <code class="mathjax" lang="latex">n/1 - p_i</code> from&#x000A;<code class="mathjax" lang="latex">p_j</code>. It is easy to verify that the invariant still holds after these&#x000A;changes.<sup class="fnref" id="stonalme-fnref-2"><a href="#stonalme-fn-2" rel="footnote">[2]</a></sup>&#x000A;/li&gt;&#x000A;</li>&#x000A;<li>Repeat step 1 until <code class="mathjax" lang="latex">S</code> is empty or there is no more elements <code class="mathjax" lang="latex">i</code> in&#x000A;<code class="mathjax" lang="latex">S</code> that <code class="mathjax" lang="latex">p_i &lt; 1/n</code>. If <code class="mathjax" lang="latex">S</code> is empty, the algorithm finishes. Otherwise for&#x000A;all remaining <code class="mathjax" lang="latex">i</code> in <code class="mathjax" lang="latex">S</code>, we must have <code class="mathjax" lang="latex">p_i = 1/n</code>.<sup class="fnref" id="stonalme-fnref-3"><a href="#stonalme-fn-3" rel="footnote">[3]</a></sup>&#x000A;Let <code class="mathjax" lang="latex">A(i)=i</code>&#x000A;and <code class="mathjax" lang="latex">F(i)=p_i\times n=1</code> for all remaining <code class="mathjax" lang="latex">i</code>, and remove them from the&#x000A;set <code class="mathjax" lang="latex">S</code>.</li>&#x000A;</ol><p>The algorithm finishes when <code class="mathjax" lang="latex">S</code> becomes empty, and an element is removed only&#x000A;when its corresponding <code class="mathjax" lang="latex">A</code> and <code class="mathjax" lang="latex">F</code> has been determined, so all values of&#x000A;<code class="mathjax" lang="latex">A</code> and <code class="mathjax" lang="latex">F</code> has been generated.</p>&#x000A;&#x000A;<p>In miloyip&rsquo;s implementation, <code class="mathjax" lang="latex">p_i</code> is stored in <code>AliasItem::prob</code> before <code class="mathjax" lang="latex">i</code>&#x000A;is removed from the set. When <code class="mathjax" lang="latex">i</code> is removed from the set, <code>AliasItem::prob</code>&#x000A;is set to <code class="mathjax" lang="latex">F(i)</code>.</p>&#x000A;&#x000A;<h3 id="stonalme-2_2-correctness">Correctness</h3>&#x000A;&#x000A;<p>The invariant holds at the beginning and at the end of each step, it guarantees&#x000A;that the algorithm can finish. It is easy to prove it using mathematical&#x000A;induction. So we only need to prove <code class="mathjax" lang="latex">P\{Y'=i\}=P\{Y=i\}</code> for any <code class="mathjax" lang="latex">i</code>, i.e.,</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="sb">\[</span><span class="nb"> P</span><span class="nv">\{</span><span class="nb">Y </span><span class="o">=</span><span class="nb"> i</span><span class="nv">\}</span><span class="nb"> </span><span class="o">=</span><span class="nb"> F</span><span class="o">(</span><span class="nb">i</span><span class="o">)/</span><span class="nb">n </span><span class="o">+</span><span class="nb"> </span><span class="nv">\sum</span><span class="nb">_{j </span><span class="nv">\in</span><span class="nb"> A^{</span><span class="o">-</span><span class="m">1</span><span class="nb">}</span><span class="o">(</span><span class="nb">i</span><span class="o">)</span><span class="nb">}</span><span class="nv">\frac</span><span class="nb">{</span><span class="m">1</span><span class="o">-</span><span class="nb">F</span><span class="o">(</span><span class="nb">j</span><span class="o">)</span><span class="nb">}{n} </span><span class="s">\]</span></span></span></code></pre>&#x000A;&#x000A;<p>Denote <code class="mathjax" lang="latex">p'_i</code> as the value of <code class="mathjax" lang="latex">p_i</code> when <code class="mathjax" lang="latex">i</code> is removed from set&#x000A;<code class="mathjax" lang="latex">S</code>. Check the construction steps again, we get following properties:</p>&#x000A;&#x000A;<ol>&#x000A;<li>No <code class="mathjax" lang="latex">p_i</code> can increase. Thus <code class="mathjax" lang="latex">p_i &lt;= P\{Y=i\}</code> in all steps and <code class="mathjax" lang="latex">p'_i &lt;= P\{X=i\}</code>.</li>&#x000A;<li>&#x000A;<code class="mathjax" lang="latex">p_i</code> decreases only when its initial value <code class="mathjax" lang="latex">P\{Y=i\}&gt;1/n</code>. So if&#x000A;<code class="mathjax" lang="latex">P\{Y=i\}&lt;=1/n</code>, <code class="mathjax" lang="latex">p_i = P\{Y=i\}</code> throughout the algorithm and&#x000A;<code class="mathjax" lang="latex">p'_i=P\{Y=i\}</code>.</li>&#x000A;<li>$F(i) = p'_i \times n$</li>&#x000A;<li>&#x000A;<code class="mathjax" lang="latex">i</code> is removed only when <code class="mathjax" lang="latex">p_i \leq 1/n</code>, i.e., <code class="mathjax" lang="latex">p'_i \leq 1/n</code>, thus&#x000A;<code class="mathjax" lang="latex">F(i)=p'_i \times n \leq 1</code>.</li>&#x000A;<li>&#x000A;<code class="mathjax" lang="latex">A(j)</code> is set to a value <code class="mathjax" lang="latex">i \neq j</code> only if <code class="mathjax" lang="latex">p_i &gt; 1/n</code> (see step 1),&#x000A;i.e., <code class="mathjax" lang="latex">P\{Y=i\}&gt;1/n</code>.</li>&#x000A;</ol><p>Now consider value <code class="mathjax" lang="latex">i</code> when <code class="mathjax" lang="latex">P\{Y=i\}&lt;1/n</code>, <code class="mathjax" lang="latex">P\{Y=i\}=1/n</code> and&#x000A;<code class="mathjax" lang="latex">P\{Y=i\}&gt;1/n</code>.</p>&#x000A;&#x000A;<h4 id="stonalme-2_2_1-pyi1n">P{Y=i} &lt; 1/n</h4>&#x000A;&#x000A;<p>If <code class="mathjax" lang="latex">P\{Y=i\} &lt; 1/n</code>, from property 2 and property 3,&#x000A;<code class="mathjax" lang="latex">F(i) = p'_i \times n = P\{Y=i\} \times n</code>.</p>&#x000A;&#x000A;<p>Apparently <code class="mathjax" lang="latex">A^{-1}(i) = {}</code>, because <code class="mathjax" lang="latex">A</code> is either set to value <code class="mathjax" lang="latex">j</code> where&#x000A;<code class="mathjax" lang="latex">p_j&gt;1/n</code> in step 1 or <code class="mathjax" lang="latex">k</code> where <code class="mathjax" lang="latex">p_k = 1/n</code> in step 2.</p>&#x000A;&#x000A;<p>Thus</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="k">\begin</span><span class="nb">{</span>align*<span class="nb">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="nb">&amp;</span>F(i)/n + <span class="k">\sum</span><span class="nb">_{</span>j <span class="k">\in</span> A<span class="nb">^{</span>-1<span class="nb">}</span>(i)<span class="nb">}</span><span class="k">\frac</span><span class="nb">{</span>1-F(j)<span class="nb">}{</span>n<span class="nb">}</span><span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>F(i)/n<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>P<span class="k">\{</span>Y=i<span class="k">\}</span> <span class="k">\times</span> n / n<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>P<span class="k">\{</span>Y=i<span class="k">\}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="k">\end</span><span class="nb">{</span>align*<span class="nb">}</span></span></span></code></pre>&#x000A;&#x000A;<p>which completes the proof.</p>&#x000A;&#x000A;<h4 id="stonalme-2_2_2-pyi1n">P{Y=i} = 1/n</h4>&#x000A;&#x000A;<p>If <code class="mathjax" lang="latex">P\{Y=i\} = 1/n</code>, apparently <code class="mathjax" lang="latex">A(i) = i</code>. If there&rsquo;s another value&#x000A;<code class="mathjax" lang="latex">j\neq~i</code> also satisfies <code class="mathjax" lang="latex">A(j) = i</code>, from property 4, <code class="mathjax" lang="latex">P\{Y=i\} &gt; 1/n</code>,&#x000A;conflict with the condition. So <code class="mathjax" lang="latex">A^{-1}(i) = {i}</code></p>&#x000A;&#x000A;<p>Thus</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="k">\begin</span><span class="nb">{</span>align*<span class="nb">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="nb">&amp;</span>F(i)/n + <span class="k">\sum</span><span class="nb">_{</span>j <span class="k">\in</span> A<span class="nb">^{</span>-1<span class="nb">}</span>(i)<span class="nb">}</span><span class="k">\frac</span><span class="nb">{</span>1-F(j)<span class="nb">}{</span>n<span class="nb">}</span><span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>F(i)/n + (1-F(i))/n<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>1/n&#x000A;</span></span><span class="line-margin"><span class="line"><span class="k">\end</span><span class="nb">{</span>align*<span class="nb">}</span></span></span></code></pre>&#x000A;&#x000A;<p>which completes the proof.</p>&#x000A;&#x000A;<h4 id="stonalme-2_2_3-pyi1n">P{Y=i} &gt; 1/n</h4>&#x000A;&#x000A;<p>When <code class="mathjax" lang="latex">P\{Y=i\} &gt; 1/n</code>, apparently i is not in <code class="mathjax" lang="latex">A^{-1}(i)</code>.</p>&#x000A;&#x000A;<p>Consider each value <code class="mathjax" lang="latex">j</code> in set <code class="mathjax" lang="latex">A^{-1}(i)</code>. Once <code class="mathjax" lang="latex">j</code> is removed from <code class="mathjax" lang="latex">S</code>, <code class="mathjax" lang="latex">A(j)</code> is set to&#x000A;<code class="mathjax" lang="latex">i</code> and <code class="mathjax" lang="latex">1/n - p'_j</code> is subtracted from <code class="mathjax" lang="latex">p_i</code>. Thus</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="sb">\[</span><span class="nb"> p'_i </span><span class="o">=</span><span class="nb"> P</span><span class="nv">\{</span><span class="nb">Y</span><span class="o">=</span><span class="nb">i</span><span class="nv">\}</span><span class="nb"> </span><span class="o">-</span><span class="nb"> </span><span class="nv">\sum</span><span class="nb">_{j </span><span class="nv">\in</span><span class="nb"> A^{</span><span class="o">-</span><span class="m">1</span><span class="nb">}</span><span class="o">(</span><span class="nb">i</span><span class="o">)</span><span class="nb">}</span><span class="o">(</span><span class="m">1</span><span class="o">/</span><span class="nb">n </span><span class="o">-</span><span class="nb"> p'_j</span><span class="o">)</span><span class="nb"> </span><span class="s">\]</span></span></span></code></pre>&#x000A;&#x000A;<p>Then</p>&#x000A;&#x000A;<pre class="code mathjax latex"><code class="mathjax"><span class="line-margin"><span class="line"><span class="k">\begin</span><span class="nb">{</span>align*<span class="nb">}</span>&#x000A;</span></span><span class="line-margin"><span class="line"> <span class="nb">&amp;</span>F(i)/n + <span class="k">\sum</span><span class="nb">_{</span>j <span class="k">\in</span> A<span class="nb">^{</span>-1<span class="nb">}</span>(i)<span class="nb">}</span><span class="k">\frac</span><span class="nb">{</span>1-F(j)<span class="nb">}{</span>n<span class="nb">}</span><span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>p'<span class="nb">_</span>i <span class="k">\times</span> n / n + <span class="k">\sum</span><span class="nb">_{</span>j <span class="k">\in</span> A<span class="nb">^{</span>-1<span class="nb">}</span>(i)<span class="nb">}</span><span class="k">\frac</span><span class="nb">{</span>1-(p'<span class="nb">_</span>j <span class="k">\times</span>~n)<span class="nb">}{</span>n<span class="nb">}</span><span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>P<span class="k">\{</span>Y=i<span class="k">\}</span> - <span class="k">\sum</span><span class="nb">_{</span>j <span class="k">\in</span> A<span class="nb">^{</span>-1<span class="nb">}</span>(i)<span class="nb">}</span>(1/n - p'<span class="nb">_</span>j)<span class="k">\ </span>+ <span class="k">\sum</span><span class="nb">_{</span>j <span class="k">\in</span> A<span class="nb">^{</span>-1<span class="nb">}</span>(i)<span class="nb">}</span>(1/n - p'<span class="nb">_</span>j)<span class="k">\\</span>&#x000A;</span></span><span class="line-margin"><span class="line">=<span class="nb">&amp;</span>P<span class="k">\{</span>Y=i<span class="k">\}</span>&#x000A;</span></span><span class="line-margin"><span class="line"><span class="k">\end</span><span class="nb">{</span>align*<span class="nb">}</span></span></span></code></pre>&#x000A;&#x000A;<p>For all <code class="mathjax" lang="latex">i</code>, <code class="mathjax" lang="latex">P\{Y'=i\} = P\{Y=i\}</code>, the proof completes.</p>&#x000A;&#x000A;<h2 id="stonalme-3-intuitive-presentation">Intuitive Presentation</h2>&#x000A;&#x000A;<p>The algorithm can be presented in intuitive meaning. The range <code class="mathjax" lang="latex">(0, n]</code> is&#x000A;split into n consecutive sub ranges <code class="mathjax" lang="latex">(i, i + 1]</code> for <code class="mathjax" lang="latex">i = 0, 1, \ldots, n - 1</code>. The&#x000A;probability of <code class="mathjax" lang="latex">X</code> falls into any range is <code class="mathjax" lang="latex">(i + 1 - i) \times 1/n = 1/n</code>.</p>&#x000A;&#x000A;<p>For <code class="mathjax" lang="latex">P\{Y=i\} = 1/n</code>, we can allocate the whole slot <code class="mathjax" lang="latex">i</code> to it. Let <code class="mathjax" lang="latex">Y=i</code>&#x000A;when <code class="mathjax" lang="latex">x</code> falls in <code class="mathjax" lang="latex">(i, i + 1]</code> which has the probability <code class="mathjax" lang="latex">1/n</code>.</p>&#x000A;&#x000A;<p>If <code class="mathjax" lang="latex">P\{Y=i\} &lt; 1/n</code>, we can allocate the starting part&#x000A;<code class="mathjax" lang="latex">(i,i+n\times~P\{Y=i\}]</code> in <code class="mathjax" lang="latex">(i,i+1]</code>. Let <code class="mathjax" lang="latex">Y = i</code> when <code class="mathjax" lang="latex">x</code> falls in&#x000A;<code class="mathjax" lang="latex">(i, i + n\times P\{Y=i\}]</code>, where the probability is&#x000A;<code class="mathjax" lang="latex">n\times~P\{Y=i\}\times(1/n)=P\{Y=i\}</code>.</p>&#x000A;&#x000A;<p>If <code class="mathjax" lang="latex">P\{Y=i\} &gt; 1/n</code>, we can allocate unused ranges in <code class="mathjax" lang="latex">(j + n\times P\{Y=j\}, j + 1]</code> for&#x000A;any <code class="mathjax" lang="latex">j</code> that <code class="mathjax" lang="latex">P\{Y=j\} &lt; 1/n</code>. However, unused range is not allowed to be split again.</p>&#x000A;&#x000A;<p>See the figure below, which demonstrates how to generate <code class="mathjax" lang="latex">Y</code> with probability mass&#x000A;function <code class="mathjax" lang="latex">n = 5</code></p>&#x000A;&#x000A;<figure><img alt="Alias Method" src="http://assets.iany.me/gallery/2010/05/study-on-alias-method/alias_method.png"></figure><ul>&#x000A;<li><code class="mathjax" lang="latex">P\{Y=0\} = 0.16</code></li>&#x000A;<li><code class="mathjax" lang="latex">P\{Y=1\} = 0.1</code></li>&#x000A;<li><code class="mathjax" lang="latex">P\{Y=2\} = 0.32</code></li>&#x000A;<li><code class="mathjax" lang="latex">P\{Y=3\} = 0.22</code></li>&#x000A;<li><code class="mathjax" lang="latex">P\{Y=4\} = 0.2</code></li>&#x000A;</ul><p><code class="mathjax" lang="latex">P\{Y=4\}=1/n</code>, so let <code class="mathjax" lang="latex">Y = 4</code> only when <code class="mathjax" lang="latex">x</code> falls in <code class="mathjax" lang="latex">(4, 5]</code>, which probability is&#x000A;<code class="mathjax" lang="latex">(5-4)\times 0.2 = 0.2</code>.</p>&#x000A;&#x000A;<p><code class="mathjax" lang="latex">P\{Y=0\}=0.16&lt;0.2</code>, so let <code class="mathjax" lang="latex">Y = 0</code> only when <code class="mathjax" lang="latex">x</code> falls in&#x000A;<code class="mathjax" lang="latex">(0,0.16\times~5]</code>, i.e., <code class="mathjax" lang="latex">(0,0.8]</code>, which probability is&#x000A;<code class="mathjax" lang="latex">(0.8-0)\times~0.2=0.16</code>. <code class="mathjax" lang="latex">(0.8,1]</code> is unused.</p>&#x000A;&#x000A;<p><code class="mathjax" lang="latex">P\{Y=1\}</code> is the same. <code class="mathjax" lang="latex">(1,1.5]</code> is allocated and <code class="mathjax" lang="latex">(1.5,2]</code> is unused.</p>&#x000A;&#x000A;<p><code class="mathjax" lang="latex">P\{Y=2\} = 0.32 &gt; 0.2</code>, it needs ranges with total length&#x000A;<code class="mathjax" lang="latex">0.32\times~5=1.6</code>. We allocates the range <code class="mathjax" lang="latex">(0.8, 1]</code> and <code class="mathjax" lang="latex">(1.5, 2]</code>. The&#x000A;remaining length <code class="mathjax" lang="latex">1.6-0.2-0.5=0.9&lt;1</code>, then we can allocate a part of its own&#x000A;slot. Finally, three ranges have been allocated, <code class="mathjax" lang="latex">(0.8,1]</code>, <code class="mathjax" lang="latex">(1.5,2]</code> and&#x000A;<code class="mathjax" lang="latex">(2,2.9]</code>. <code class="mathjax" lang="latex">(2.9,3]</code> is unused.</p>&#x000A;&#x000A;<p>Follow the same step to handle <code class="mathjax" lang="latex">Y=3</code>. The final allocation is depicted in&#x000A;<code class="mathjax" lang="latex">D</code>. The allocation is not unique, <code class="mathjax" lang="latex">F</code> depicts another solution.</p>&#x000A;&#x000A;<h2 id="stonalme-4-references">References</h2>&#x000A;&#x000A;<ul>&#x000A;<li>&#x000A;<a href="http://portal.acm.org/citation.cfm?id=355749" class=" external">An Efficient Method for Generating Discrete Random Variables with General Distributions</a>,&#x000A;Alastair J. Walker</li>&#x000A;<li>&#x000A;<a href="http://www.cnblogs.com/miloyip/archive/2010/05/27/reply_discrete.html" class=" external">回应CSDN肖舸《做程序，要“专注”和“客观”》，实验比较各离散采样算法 - Milo的游戏开发 - 博客园</a>,&#x000A;Milo Yip</li>&#x000A;</ul>&#x000A;&#x000A;&#x000A;&#x000A;<footer><div class="footnotes">&#x000A;<h2 class="no-chapsec" id="stonalme-footnotes">Footnotes</h2>&#x000A;<ol>&#x000A;<li id="stonalme-fn-1">  If all <code class="mathjax" lang="latex">j</code> except <code class="mathjax" lang="latex">i</code> that <code class="mathjax" lang="latex">p_j \leq 1/n</code>, Sum up both end of the&#x000A;      inequalities for all <code class="mathjax" lang="latex">j</code> and <code class="mathjax" lang="latex">p_i &lt; 1/n</code>, we can get&#x000A;      <code class="mathjax" lang="latex">\sum_{i \in S}{p_i} &lt; \|S\| / n</code> which is conflict with the invariant.&#x000A;<a href="#stonalme-fnref-1" rev="footnote">↩</a>&#x000A;</li>&#x000A;<li id="stonalme-fn-2">  The right side has decreased <code class="mathjax" lang="latex">1/n</code> because <code class="mathjax" lang="latex">\|S\|</code> has decreased 1. The&#x000A;      left side has decreased <code class="mathjax" lang="latex">p_i + (n/1 - p_i) = 1/n</code>, because <code class="mathjax" lang="latex">i</code> is removed from the&#x000A;      set and <code class="mathjax" lang="latex">(n/1 - p_i)</code> is subtracted from <code class="mathjax" lang="latex">p_j</code>. Thus both side decrease the same&#x000A;      amount, the equality still holds.&#x000A;<a href="#stonalme-fnref-2" rev="footnote">↩</a>&#x000A;</li>&#x000A;<li id="stonalme-fn-3">  Because no <code class="mathjax" lang="latex">p_i &lt; 1/n</code>, then <code class="mathjax" lang="latex">p_i \geq 1/n</code>. To satisfy the invariant, no <code class="mathjax" lang="latex">p_i</code>&#x000A;      can be larger then <code class="mathjax" lang="latex">1/n</code>. Thus for all <code class="mathjax" lang="latex">i</code> in <code class="mathjax" lang="latex">S</code>, <code class="mathjax" lang="latex">p_i = 1/n</code>.&#x000A;<a href="#stonalme-fnref-3" rev="footnote">↩</a>&#x000A;</li>&#x000A;</ol>&#x000A;</div></footer>]]></content></entry>
</feed>

