<?xml version="1.0"?>
<rss version="2.0"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/" >
<channel>
<title>Kanru's Adventure Journal</title>
<link>http://kanru.info/blog/</link>
<description>Kanru&#39;s Adventure Journal</description>
<item>

	<title>GCIN in Debian is seeking co-maintainer</title>


	<guid isPermaLink="false">urn:uuid:c5eeedde-bc7a-5df6-a2c1-fb483fef1aba</guid>

	<link>http://kanru.info/blog/archives/2011/12/18/gcin-in-debian-is-seeking-co-maintainer/</link>

	<pubDate>Sun, 18 Dec 2011 14:07:53 +0800</pubDate>
	<dcterms:modified>2011-12-18T06:12:15Z</dcterms:modified>

	<description>&lt;h2&gt;尋找 GCIN co-maintainer&lt;/h2&gt;

&lt;p&gt;HIME 的事件鬧的沸沸揚揚，一切的起因之一就是有人認為 HIME 會取代 Debian
裡面的 GCIN，這是什麼狀況呢？因為在 Debian 裡面把 GCIN 棄養 (orphan)
的就是我，似乎也有必要說明一下。以下提到 GCIN 都是指 Debian 裡面的 GCIN。&lt;/p&gt;

&lt;p&gt;最早的 GCIN 維護者是 caleb，後來他因為不再使用 Debian 所以開始找其他人幫忙維護，而我成為 Debian Developer 的初衷就是要幫助本地的使用者有習慣好用的套件可以用，所以就接下了這個位子。當時我也有使用 GCIN 所以就算劉老大 (eliu) 每兩三天就有新版本我也還可以跟上，只是沒有辦法把套件整理的乾淨點，後來不用 GCIN 了，套件的更新就漸漸脫節，因為有 Luna Archiver
的存在也讓我有偷懶的藉口，最後發現花在這個套件的時間與 Debian 的
&lt;a href=&quot;http://qa.debian.org/popcon.php?package=gcin&quot;&gt;Popcon&lt;/a&gt; 統計不成比例，就決定把套件給棄養了。&lt;/p&gt;

&lt;p&gt;Debian 對於被棄養的套件的處理方式是，如果沒有出什麼大問題就會由 QA
team 來管理，但是如果有人提出 RM: RoQA 的要求，因為使用者 (Popcon) 少且無人管理，就有可能被移出 Debian，但無正當理由甚少有直接使用新專案取代舊專案的狀況，因此 Debian 要使用 HIME 取代 GCIN 純粹是誤解而已。&lt;/p&gt;

&lt;p&gt;後來想想也不能把 GCIN 就這樣晾著，所以我決定要再出點力，把 GCIN 納入
Debian IME Packaging Team 的管理，並誠徵對維護 GCIN 套件有興趣的人一起來 co-maintain，讓 GCIN 的使用者可以直接用到最新、高品質的 GCIN 套件。&lt;/p&gt;

&lt;p&gt;有興趣的人請與我聯絡，寄信到 koster&amp;#x40;debian.org 或是
630484&amp;#x40;bugs.debian.org 都可以。&lt;/p&gt;
</description>


</item>
<item>

	<title>Not Again, MingLiu!</title>


	<guid isPermaLink="false">urn:uuid:4ccabe37-a9fb-5a2b-8fe1-41fa223f812d</guid>

	<link>http://kanru.info/blog/archives/2011/08/29/not-again-mingliu/</link>


	<category>PDF</category>

	<category>freetype</category>


	<pubDate>Tue, 30 Aug 2011 20:09:07 +0800</pubDate>
	<dcterms:modified>2011-08-30T13:21:56Z</dcterms:modified>

	<description>&lt;p&gt;長話短說，從 FreeType 2.4.4 (2010-11-28 release) 開始，只要編譯的時候有啟用 BCI (Byte Code Interpreter) ，新細明體就不應該會破掉了，只是因為一些原因 (下面詳述)，一直到 2.4.5 (2011-06-24 release) 才算是完全解決。&lt;/p&gt;

&lt;p&gt;這個問題牽扯到許多有趣知識，所以我決定作個筆記以免以後忘掉。&lt;/p&gt;

&lt;h2&gt;TrueType&lt;/h2&gt;

&lt;p&gt;首先是一些名詞解釋，TrueType 是常見的字型 (font) 格式，由 Apple 發展，後來被 Microsoft 採用並發揚光大；雖然沒有經過任何國際組織的標準化，在當時儼然已經成為業界標準 (de facto standard)。&lt;/p&gt;

&lt;p&gt;TrueType 使用的檔案格式又稱為 &lt;code&gt;sfnt&lt;/code&gt; 格式，由許多不同的表格 (table) 組成，每個表格由四個字的標籤 (tag) 表示，其中我們最關心的是 &lt;code&gt;glyf&lt;/code&gt; 這個表格，因為所有的字符 (glyph) 都儲存在這個表格內。每個字符僅僅紀錄了形狀，要知道某個編碼的某個字元 (character) 是對應到哪個形狀，還要透過 &lt;code&gt;cmap&lt;/code&gt;
這個表格來查詢；也有一個字沒有相對應的字符，或是沒有任何字對應到某個字符的情況。&lt;/p&gt;

&lt;p&gt;參考資料：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.apple.com/fonts/TTRefMan/index.html&quot;&gt;Apple: TrueType Reference Manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/Truetype&quot;&gt;Wikipedia: Truetype&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/OpenType&quot;&gt;Wikipedia: OpenType&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Hinting (Instructing)&lt;/h2&gt;

&lt;p&gt;TrueType 是一種外框字型 (Outline Font)，也就是說每一個字符都是以向量圖形的方式呈現，理論上可以在各種不同解析度下呈現相同的形狀。&lt;/p&gt;

&lt;p&gt;&lt;!-- e e e e e e 圖 --&gt;
&lt;a href=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/o_dejavu_rasterize.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/650x-o_dejavu_rasterize.png&quot; width=&quot;650&quot; height=&quot;114&quot; alt=&quot;DejaVu.ttf O Rasterize&quot; class=&quot;center&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/mm_rasterize.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/x300-mm_rasterize.png&quot; width=&quot;131&quot; height=&quot;300&quot; alt=&quot;M M Rasterize&quot; class=&quot;right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;但是越是在低解析度的時候，由於可用的像素較少，越容易遇到邊界的表達能力問題，如右圖的 &lt;code&gt;M&lt;/code&gt; 字，若沒有對齊像素點的話，呈現出來的圖案就會比較瘦長且左右不對稱，如果稍微向右移動並加寬一點，呈現出來的圖案就會比較接近原本向量圖形所預期的形狀；這個動作正是 Hinting 中的對齊格線 (grid
fitting) 功能。&lt;/p&gt;

&lt;p&gt;在 TrueType 檔案中，描述 Hinting 的方式其實是儲存在字型的 &lt;code&gt;fpgm&lt;/code&gt; 與
&lt;code&gt;prep&lt;/code&gt; 表格中的小程式，或是內嵌在字符中。看起來像是這樣：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;PUSHB[000]   # Push one byte onto the stack.
3            # Value for loop variable.
SLOOP[]      # Set the loop count to 3.
PUSHB[002]   # Push three bytes onto the stack.
5            # Point number.
46           # Point number.
43           # Point number.
ALIGNRP[]    # Align the points 5, 46 and 43 with rp0 (point 8). This will
             # align the height of the two lower serifs. 
&lt;/pre&gt;

&lt;p&gt;使用這個小程式的方法是 Apple 的專利，但是因為 TrueType 一開始只是業界標準，Apple 並沒有在規格書裡面提及專利的相關資訊，造成後來使用 FreeType
啟用 BCI (Byte Code Interpreter) 可能會侵犯專利的問題。(相關專利已經在 2010 年 4 月全數過期)&lt;/p&gt;

&lt;p&gt;對每個字符做 Hinting 是個耗時耗力的工作，就算是只有數百個字符的西文字型也要花上數倍於繪圖的時間來做 Hinting，因此除了少數高品質的字型外，多數的字型是沒有 Hinting 的。而隨著顯示裝置的解析度越來越高，對於
Hinting 的需求也越來越少，在較新的作業系統上可能會忽略部份 Hinting 的資訊或是完全關閉 Hinting。而在自由軟體的世界中，大多使用 FreeType
的 Auto-Hinting 技術來支援解析度較低的顯示裝置。&lt;/p&gt;

&lt;p&gt;參考資料：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.microsoft.com/typography/TrueTypeHintingIntro.mspx&quot;&gt;Microsoft: TrueType Hinting Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fontforge.sourceforge.net/ttfinstrs.html&quot;&gt;FontForge: Edit Instructions...&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.apple.com/fonts/TTRefMan/RM03/Chap3.html&quot;&gt;Apple: Instructing Fonts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;MingLiu&lt;/h2&gt;

&lt;p&gt;細明體 (MingLiu) 與新細明體 (PMingLiu) 是華康 (DynaLab) 設計的字型，內建於 Microsoft 的作業系統中，使用非常廣泛。華康的字型使用了特殊的組字方式，似乎是為了從自有的字型資料轉換到 TrueType 才會使用這樣的方法。&lt;/p&gt;

&lt;p&gt;首先，定義一組筆劃的字符，只用來組字，不對應到任何的編碼：&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/pmingliu_strokes.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/650x-pmingliu_strokes.png&quot; width=&quot;650&quot; height=&quot;359&quot; alt=&quot;PMingLiu Strokes&quot; class=&quot;center&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;然後在每一個個別的字符中用參照的方式把筆劃匯入，這時筆劃間的相對位置是亂的，最後再用 Hinting 的功能把筆劃移動到對的位置去：&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/pmingliu_uni65b0.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/pmingliu_uni65b0.png&quot; width=&quot;442&quot; height=&quot;335&quot; alt=&quot;PMingLiu uni65B0&quot; class=&quot;center&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/pmingliu_hinting.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/pmingliu_hinting.png&quot; width=&quot;505&quot; height=&quot;442&quot; alt=&quot;PMingLiu Hinting&quot; class=&quot;center&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;這樣濫用 Hinting 的方式，也導致如果不開啟 Hinting 就會看到破碎的字符：&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/pmingliu_broken_glyph.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/650x-pmingliu_broken_glyph.png&quot; width=&quot;650&quot; height=&quot;359&quot; alt=&quot;PMingLiu Broken Glyph&quot; class=&quot;center&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;為什麼說是濫用？因為只要沒有打開 Hinting 就會顯示錯誤，表示用錯地方了；有些時候是不需要，或是沒辦法使用 Hinting 的。&lt;/p&gt;

&lt;p&gt;參考資料：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://ubb.frostyplace.com/viewtopic.php?p=92722&quot;&gt;老地方冰果室交流區：PDF 裡面新細明體的字會碎掉是因為專利問題？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Tricky Fonts&lt;/h2&gt;

&lt;p&gt;除了新細明體，華康還有一些字型也是使用類似的方式組字，同樣很多人使用的標楷體就是其中之一，還有一些日本字型也是濫用 Hinting 的功能來繪製字符，所以 FreeType 其實有內建黑名單來對付這樣的字型，遇到了就強制開啟
Hinting。一開始這個名單是用字型名稱來列表的：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl kwb&quot;&gt;static const char&lt;/span&gt; trick_names&lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;TRICK_NAMES_COUNT&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
                             &lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;TRICK_NAMES_MAX_CHARACTERS &lt;span class=&quot;hl opt&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;] =&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;DFKaiSho-SB&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;hl com&quot;&gt;/* dfkaisb.ttf */&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;DFKaiShu&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;DFKai-SB&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;hl com&quot;&gt;/* kaiu.ttf */&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;HuaTianKaiTi?&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;hl com&quot;&gt;/* htkt2.ttf */&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;HuaTianSongTi?&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;hl com&quot;&gt;/* htst3.ttf */&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;MingLiU&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;         &lt;span class=&quot;hl com&quot;&gt;/* mingliu.ttf &amp;amp; mingliu.ttc */&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;PMingLiU&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;hl com&quot;&gt;/* mingliu.ttc */&lt;/span&gt;
  &lt;span class=&quot;hl str&quot;&gt;&amp;quot;MingLi43&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;hl com&quot;&gt;/* mingli.ttf */&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;};&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;但是這樣還不夠，因為很多 PDF 輸出軟體會把字型的名稱亂改：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;%&lt;/span&gt; pdffonts ~&lt;span class=&quot;hl opt&quot;&gt;/&lt;/span&gt;pdf31yNwCi71d.pdf
name                                 &lt;span class=&quot;hl kwb&quot;&gt;type&lt;/span&gt;              emb sub uni object ID
&lt;span class=&quot;hl opt&quot;&gt;------------------------------------ ----------------- --- --- --- ---------&lt;/span&gt;
AAAAAA&lt;span class=&quot;hl opt&quot;&gt;+&lt;/span&gt;TimesNewRoman                 TrueType          &lt;span class=&quot;hl kwc&quot;&gt;yes yes yes&lt;/span&gt;      &lt;span class=&quot;hl num&quot;&gt;9  0&lt;/span&gt;
AAAAAB&lt;span class=&quot;hl opt&quot;&gt;+&lt;/span&gt;___                           TrueType          &lt;span class=&quot;hl kwc&quot;&gt;yes yes yes&lt;/span&gt;     &lt;span class=&quot;hl num&quot;&gt;16  0&lt;/span&gt;
AAAAAC&lt;span class=&quot;hl opt&quot;&gt;+&lt;/span&gt;___                           TrueType          &lt;span class=&quot;hl kwc&quot;&gt;yes yes yes&lt;/span&gt;     &lt;span class=&quot;hl num&quot;&gt;17  0&lt;/span&gt;
AAAAAE&lt;span class=&quot;hl opt&quot;&gt;+&lt;/span&gt;____                          TrueType          &lt;span class=&quot;hl kwc&quot;&gt;yes yes yes&lt;/span&gt;     &lt;span class=&quot;hl num&quot;&gt;18  0&lt;/span&gt;
AAAAAD&lt;span class=&quot;hl opt&quot;&gt;+&lt;/span&gt;____                          TrueType          &lt;span class=&quot;hl kwc&quot;&gt;yes yes yes&lt;/span&gt;     &lt;span class=&quot;hl num&quot;&gt;19  0&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;遇到這樣的情況就破功了，所以很多人在看 PDF 的時候會遇到字破掉的問題，我先在&lt;a href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=591094#186&quot;&gt;信&lt;/a&gt;中提出可能的解法，後來發現 Suzuki Toshiya 在 2010-11-22 的時候加入用 &lt;code&gt;cvt/fpgm/prep&lt;/code&gt; 表格的加總檢查來比對黑名單，因為這三個表格是只要是有使用 Hinting 的字型都會有，也不太會改變的。&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl kwb&quot;&gt;static const&lt;/span&gt; tt_sfnt_id_rec sfnt_id&lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;TRICK_SFNT_IDS_NUM_FACES&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
                                   &lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;TRICK_SFNT_IDS_PER_FACE&lt;span class=&quot;hl opt&quot;&gt;] = {&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl com&quot;&gt;/* MingLiU 1995 */&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x05bcf058&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x000002e4&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;hl com&quot;&gt;/* cvt  */&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x28233bf1&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x000087c4&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;hl com&quot;&gt;/* fpgm */&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0xa344a1ea&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x000001e1&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;hl com&quot;&gt;/* prep */&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl com&quot;&gt;/* MingLiU 1996- */&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x05bcf058&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x000002e4&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;hl com&quot;&gt;/* cvt  */&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x28233bf1&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x000087c4&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;hl com&quot;&gt;/* fpgm */&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0xa344a1eb&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0x000001e1&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;hl com&quot;&gt;/* prep */&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;...&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;只是原先這個方法只有在字型沒有名稱的時候才會啟用，我加了 patch 改成無條件檢查黑名單，從此就應該不會有漏網之魚了。&lt;/p&gt;

&lt;p&gt;參考資料：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=591094#186&quot;&gt;Re: How to read Chinese PDFs anymore with xpdf?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=9f5dd61bf3deee315da14d3aca7f436bbf9cc76a&quot;&gt;[truetype] Identify the tricky fonts by cvt/fpgm/prep checksums.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=abc47aa1362713192cf8f6747b8de25a3f54e513&quot;&gt;[truetype] Always check the checksum to identify tricky fonts.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=86b7b2f614873386a3bd56be77c8ba37a69a2a02&quot;&gt;[truetype] Revert the reordering of trickyness checking.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=1e89d15a2708f98cacb95ec8a0f1386adf062a64&quot;&gt;[truetype] Register a set of tricky fonts, NEC FA family.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Sign Extension&lt;/h2&gt;

&lt;p&gt;只是後來我在我的機器上面仍然發現某些 PDF 仍然顯示破碎字型，難道是加總檢查也會出錯？因為牽扯到&lt;strong&gt;加總&lt;/strong&gt;的問題，第一個想到的就是可能跟機器的整數長度有關，立刻改用 32-bit 的環境測試同一個 PDF，果然就好了。但是計算檢查碼的演算法很簡單，也沒有溢位的疑慮，那是哪裡出了問題？好在 IRC
上有大大給了提示：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;kanru&amp;gt; hum.. checksum *: 0xa344a1eb
kanru&amp;gt; checksum #: 0xffffffffa344a1eb
j5g&amp;gt; kanru: 哈，因為 init checksum = 0xffffffff, sign extension 變成 0xffffffffffffffff?
j5g&amp;gt; 然後之後都只處理後面 32bit
kanru&amp;gt; j5g: 不過有可能是 font 裡面是錯的
kanru&amp;gt; 0xffffffffa344a1eb 是直接從 font table 讀出來的
j5g&amp;gt; 喔，那就是 0xa344a1eb sign extended to 0xffffffffa344a1eb
&lt;/pre&gt;

&lt;p&gt;原來是 FreeType 在讀入字型資訊的時候，強制把 int 轉型為 uint 結果發生
sign extension 錯誤，之後比對的時候就跟著錯了。送了 patch 之後，應該天下太平了吧？&lt;/p&gt;

&lt;p&gt;參考資料：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=21b1a0de7c052dcd25348c4e3597c8a631108f61&quot;&gt;Fix reading of signed integers from files on 64bit platforms.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;PDF correctness&lt;/h2&gt;

&lt;p&gt;有人問說：那為什麼不乾脆隨時打開 Hinting 就好？據我所知目前的自由 PDF
Viewer 都是預設關閉 Hinting 的，除了上述的理由外，我猜大概是因為
Hinting 有可能大幅度的改變一個字符的寬度，如下圖：&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/dejavu_ftdiff.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2011/08/29/not-again-mingliu/dejavu_ftdiff.png&quot; width=&quot;638&quot; height=&quot;478&quot; alt=&quot;FtDiff DejaVu&quot; class=&quot;center&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;可以發現三種顯示方式的寬度都不一樣，而 PDF 是一種接近印刷品質的檔案格式，有可能在輸出 PDF 的時候已經丟失動態改變寬度的能力，&lt;code&gt;kern&lt;/code&gt; 的修正也已經沒辦法修改，這時候如過還讓 Hinting 去改變字符的寬度的話，很有可能得到不理想的結果。不過以上只是我的猜想，還沒有找各 PDF Viewer 的作者證實。至於封閉的商業 PDF Viewer 又是怎麼做的就更不得而知了。&lt;/p&gt;

&lt;p&gt;結論：快升級到最新的 FreeType 吧！如果還有遇到顯示錯誤的 PDF 可以寄給我，如果以上筆記有疏漏錯誤的地方歡迎指正 :P&lt;/p&gt;
</description>


</item>
<item>

	<title>Speed comparison C vs Common Lisp</title>


	<guid isPermaLink="false">urn:uuid:417b81ab-966f-59e3-a35b-467ee318f0b2</guid>

	<link>http://kanru.info/blog/archives/2011/08/08/euler12-common-lisp/</link>


	<category>lisp</category>


	<pubDate>Mon, 08 Aug 2011 22:28:17 +0800</pubDate>
	<dcterms:modified>2011-08-08T14:51:14Z</dcterms:modified>

	<description>&lt;p&gt;昨天看到有人轉噗一則 &lt;a href=&quot;http://stackoverflow.com/questions/6964392/speed-comparison-c-vs-python-vs-erlang-vs-haskell&quot;&gt;StackOverflow&lt;/a&gt; 上面的問題，內容是問他分別用 C,
python, erlang 與 haskell 寫了 Project Euler 的第&lt;a href=&quot;http://projecteuler.net/index.php?section=problems&amp;amp;id=12&quot;&gt;十二題&lt;/a&gt;，但是
haskell 版本慢得不像話，該如何改進？&lt;/p&gt;

&lt;p&gt;以下是苦主的原始 C 語言版：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl ppc&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hl ppc&quot;&gt;#include &amp;lt;math.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hl kwd&quot;&gt;factorCount&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwb&quot;&gt;long&lt;/span&gt; n&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hl kwb&quot;&gt;double&lt;/span&gt; square &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl kwd&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;hl opt&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt; isquare &lt;span class=&quot;hl opt&quot;&gt;= (&lt;/span&gt;&lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt; square&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt; count &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; isquare &lt;span class=&quot;hl opt&quot;&gt;==&lt;/span&gt; square ? &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;hl kwb&quot;&gt;long&lt;/span&gt; candidate&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;candidate &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt; candidate &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;=&lt;/span&gt; isquare&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt; candidate &lt;span class=&quot;hl opt&quot;&gt;++)&lt;/span&gt;
        &lt;span class=&quot;hl kwa&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;==&lt;/span&gt; n &lt;span class=&quot;hl opt&quot;&gt;%&lt;/span&gt; candidate&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt; count &lt;span class=&quot;hl opt&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;return&lt;/span&gt; count&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hl kwd&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hl kwb&quot;&gt;long&lt;/span&gt; triangle &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt; index &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;factorCount&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;triangle&lt;span class=&quot;hl opt&quot;&gt;) &amp;lt;&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;1001&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;{&lt;/span&gt;
        index &lt;span class=&quot;hl opt&quot;&gt;++;&lt;/span&gt;
        triangle &lt;span class=&quot;hl opt&quot;&gt;+=&lt;/span&gt; index&lt;span class=&quot;hl opt&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;hl kwd&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;%ld&lt;/span&gt;&lt;span class=&quot;hl esc&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; triangle&lt;span class=&quot;hl opt&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;我的執行時間約為 5.48s&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;%&lt;/span&gt; gcc &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;lm &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;o euler12.bin euler12.c
&lt;span class=&quot;hl opt&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;time&lt;/span&gt; .&lt;span class=&quot;hl opt&quot;&gt;/&lt;/span&gt;euler12.bin 
&lt;span class=&quot;hl num&quot;&gt;842161320&lt;/span&gt;
.&lt;span class=&quot;hl opt&quot;&gt;/&lt;/span&gt;euler12.bin  &lt;span class=&quot;hl num&quot;&gt;5.48&lt;/span&gt;s user &lt;span class=&quot;hl num&quot;&gt;0.00&lt;/span&gt;s system &lt;span class=&quot;hl num&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;%&lt;/span&gt; cpu &lt;span class=&quot;hl num&quot;&gt;5.484&lt;/span&gt; total
&lt;/pre&gt;

&lt;p&gt;手癢想看看據說可以編譯出不錯的機器碼的 Common Lisp 速度怎麼樣，於是第一個版本如下 (用 sbcl 執行)：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;defun&lt;/span&gt; factor-count &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;* ((&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;sqrt&lt;/span&gt; n&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt;
         &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;squaref&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;floor&lt;/span&gt; square&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt;
         &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;eql&lt;/span&gt; squaref square&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt; -&lt;span class=&quot;hl num&quot;&gt;1 0&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)))&lt;/span&gt;
      &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;loop&lt;/span&gt;
         for cand from &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt; to squaref
         count &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;eql&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;rem&lt;/span&gt; n cand&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt; into c
         finally &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(+&lt;/span&gt; count c c&lt;span class=&quot;hl opt&quot;&gt;)))))&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;defun&lt;/span&gt; first-triangle-over &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;loop&lt;/span&gt;
       for idx from &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt;
       sum idx into triangle
       until &lt;span class=&quot;hl opt&quot;&gt;(&amp;gt;= (&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;factor-count&lt;/span&gt; triangle&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt; n&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
       finally &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;return&lt;/span&gt; triangle&lt;span class=&quot;hl opt&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; (time (first-triangle-over 1000))&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; Evaluation took:&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   11.192 seconds of real time&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   11.184699 seconds of total run time (11.184699 user, 0.000000 system)&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   99.94% CPU&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   30,135,882,489 processor cycles&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   32,912 bytes consed&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   &lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; 842161320&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;還不錯，11.192s，這個版本採用原文中給 haskell 的建議，使用 rem 而不是 mod，可以加快一點速度。再給一點關於型別的提示，然後把第一個 function inline，第二版可以跑出和 C 版本差不多的成績 5.563s :-)&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;declaim&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;inline&lt;/span&gt; factor-count&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;hl slc&quot;&gt;;; &amp;lt;----&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;defun&lt;/span&gt; factor-count &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;* ((&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;square&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;sqrt&lt;/span&gt; n&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt;
         &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;squaref&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;floor&lt;/span&gt; square&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt;
         &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;eql&lt;/span&gt; squaref square&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt; -&lt;span class=&quot;hl num&quot;&gt;1 0&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)))&lt;/span&gt;
      &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;loop&lt;/span&gt;
         for cand from &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt; to squaref
         count &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;eql&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;rem&lt;/span&gt; n cand&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt; into c
         finally &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;(+&lt;/span&gt; count c c&lt;span class=&quot;hl opt&quot;&gt;)))))&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;defun&lt;/span&gt; first-triangle-over &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;loop&lt;/span&gt;
       for idx of-type fixnum from &lt;span class=&quot;hl num&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;hl slc&quot;&gt;;; &amp;lt;----&lt;/span&gt;
       sum idx into triangle of-type fixnum  &lt;span class=&quot;hl slc&quot;&gt;;; &amp;lt;----&lt;/span&gt;
       until &lt;span class=&quot;hl opt&quot;&gt;(&amp;gt;= (&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;factor-count&lt;/span&gt; triangle&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt; n&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
       finally &lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;return&lt;/span&gt; triangle&lt;span class=&quot;hl opt&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; (time (first-triangle-over 1000))&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; Evaluation took:&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   5.563 seconds of real time&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   5.556347 seconds of total run time (5.556347 user, 0.000000 system)&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   99.87% CPU&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   14,970,270,903 processor cycles&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;   32,768 bytes consed&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; 842161320&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;純粹湊個熱鬧而已，有興趣的人可以試試看把 loop 改成和原文其他語言一樣使用遞迴來實做，大部分 Lisp 都有做 TCO，速度應該差不多...&lt;/p&gt;

&lt;p&gt;結論：Common Lisp is awesome ;-)&lt;/p&gt;
</description>


</item>
<item>

	<title>Literate Programming</title>


	<guid isPermaLink="false">urn:uuid:c0159c1e-20b6-5b10-bb09-b16926eed31c</guid>

	<link>http://kanru.info/blog/archives/2011/07/07/literate-programming/</link>


	<category>programming</category>


	<pubDate>Thu, 07 Jul 2011 01:02:09 +0800</pubDate>
	<dcterms:modified>2011-07-06T18:02:37Z</dcterms:modified>

	<description>&lt;blockquote&gt;
  &lt;p&gt;Let us change our traditional attitude to the construction of
  programs: Instead of imagining that our main task is to instruct a
  computer what to do, let us concentrate rather on explaining to human
  beings what we want a computer to do.
                 &lt;br&gt;-- Donald Knuth. &quot;Literate Programming (1984)&quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;http://www.codemud.net/~thinker/GinGin_CGI.py/&quot;&gt;Thinker&lt;/a&gt; 的一篇&lt;a href=&quot;http://www.codemud.net/~thinker/GinGin_CGI.py/show_id_doc/445&quot;&gt;心靈與程式碼的協奏曲&lt;/a&gt;提到程式由後往前寫似乎比較符合思考的方向，不禁讓我想到 &lt;a href=&quot;http://www-cs-faculty.stanford.edu/~knuth/&quot;&gt;Knuth&lt;/a&gt; 提出的 &lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/Literate_programming&quot;&gt;Literate Programming&lt;/a&gt; 方法；其實我們思考的順序有時是跳躍式的，用 LP 的方法可以完全跳脫先後關係，用自己喜歡的順序來寫，我覺得也可以稱為碎碎唸寫法。&lt;/p&gt;

&lt;p&gt;用 Thinker 的同一個例子，改作 &lt;a href=&quot;http://www.cs.tufts.edu/~nr/noweb/&quot;&gt;noweb&lt;/a&gt; 的格式，用 LP 的方法來寫，會變成怎樣？首先定義問題：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;假設問題是，function 接受一字串，裡面的每一行有兩個欄位，皆是整數。欄
  位以一個空白相隔。function 必把每一行的兩個欄位的數字相乘，然後再將每
  一行的結果加總。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;我們需要一個接受一個字串的 function ：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;接受字串的 function&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;
&lt;span class=&quot;hl kwa&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hl kwd&quot;&gt;mul_n_sum&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;hl opt&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;function 內容&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;&amp;#64;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;這個 function 必須把每一行的兩欄數字相乘，然後相加；假設我們取得每一行的兩個數字之後照順序存放在 &lt;code&gt;field_lines&lt;/code&gt; 這個變數裡面，則用 &lt;code&gt;sum&lt;/code&gt; 就可以把兩兩相乘之後的數字加總：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;function 內容&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;取得每一行的兩個數字&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hl kwa&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hl kwb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;([&lt;/span&gt;field1 &lt;span class=&quot;hl opt&quot;&gt;*&lt;/span&gt; field2 &lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; field1&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; field2 &lt;span class=&quot;hl kwa&quot;&gt;in&lt;/span&gt; field_lines&lt;span class=&quot;hl opt&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;&amp;#64;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;要怎麼取得每一行的兩個數字呢？首先要把每一行的字串切開：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;取得每一行的兩個數字&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;
lines &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;hl esc&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;&amp;#64;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;然後被切開的每一行字串經過分割後，會變成依照&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;field1&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; field2&lt;span class=&quot;hl opt&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;field1&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; field2&lt;span class=&quot;hl opt&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;field1&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; field2&lt;span class=&quot;hl opt&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;...&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;順序排列的&lt;em&gt;字串&lt;/em&gt;，所以我們還要轉換成數字才能運算：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;取得每一行的兩個數字&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;分割欄位&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;
field_lines &lt;span class=&quot;hl opt&quot;&gt;= [[&lt;/span&gt;&lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;field1&lt;span class=&quot;hl opt&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;field2&lt;span class=&quot;hl opt&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; field1&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; field2 &lt;span class=&quot;hl kwa&quot;&gt;in&lt;/span&gt; txt_field_lines&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;&amp;#64;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;最後，分割欄位有很多方法，因為我們已經知道輸入的格式不會錯誤，所以用簡單的 &lt;code&gt;str.split()&lt;/code&gt; 來切割就可以了：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;分割欄位&lt;span class=&quot;hl opt&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt;
txt_field_lines &lt;span class=&quot;hl opt&quot;&gt;= [&lt;/span&gt;line&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; line &lt;span class=&quot;hl kwa&quot;&gt;in&lt;/span&gt; lines&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;&amp;#64;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;這篇 blog 經過 notangle 的處理，會變成以下的 python 程式：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl slc&quot;&gt;# notangle -R&#39;接受字串的 function&#39; literate-programming.mdwn&lt;/span&gt;
&lt;span class=&quot;hl kwa&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;hl kwd&quot;&gt;mul_n_sum&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;hl opt&quot;&gt;):&lt;/span&gt;
    lines &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;hl esc&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&#39;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
    txt_field_lines &lt;span class=&quot;hl opt&quot;&gt;= [&lt;/span&gt;line&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; line &lt;span class=&quot;hl kwa&quot;&gt;in&lt;/span&gt; lines&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
    field_lines &lt;span class=&quot;hl opt&quot;&gt;= [[&lt;/span&gt;&lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;field1&lt;span class=&quot;hl opt&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;field2&lt;span class=&quot;hl opt&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; field1&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; field2 &lt;span class=&quot;hl kwa&quot;&gt;in&lt;/span&gt; txt_field_lines&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hl kwb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;([&lt;/span&gt;field1 &lt;span class=&quot;hl opt&quot;&gt;*&lt;/span&gt; field2 &lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; field1&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; field2 &lt;span class=&quot;hl kwa&quot;&gt;in&lt;/span&gt; field_lines&lt;span class=&quot;hl opt&quot;&gt;])&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;可以跟 Thinker 的結果比比看 :)&lt;/p&gt;

&lt;p&gt;這篇是故意使用類似的思考邏輯來寫，所以會產生相似的程式，且為了展示 LP
我最後還刻意調整了一下順序。只要換一下思考的方向，要寫出 loop 的版本也是有可能的。重點在於隨想隨寫，邊寫程式邊紀錄思考過程。&lt;/p&gt;

&lt;p&gt;碎碎唸的好處是不怕跳躍式的思考，想寫什麼就寫什麼，邊想邊寫，壞處是最後組合出來的程式一般人可能沒辦法直接看懂，但是這樣寫還真的滿有趣的，有機會一定要試試！&lt;/p&gt;

&lt;p&gt;其他參考資料：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://literateprogramming.com/&quot;&gt;Literrate Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jonaquino.blogspot.com/2010/04/nowebpy-or-worlds-first-executable-blog.html&quot;&gt;Python 版的 noweb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bergie/noweb.php&quot;&gt;PHP 版的 noweb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>


</item>
<item>

	<title>Android: Wakelocks and TuxOnIce</title>


	<guid isPermaLink="false">urn:uuid:e95626a2-2d2e-5067-9a84-1af70508ef83</guid>

	<link>http://kanru.info/blog/archives/2011/06/29/android-wakelocks-n-tuxonice/</link>


	<category>0xlab</category>

	<category>android</category>

	<category>linux</category>


	<pubDate>Wed, 29 Jun 2011 10:26:28 +0800</pubDate>
	<dcterms:modified>2011-06-29T13:02:58Z</dcterms:modified>

	<description>&lt;p&gt;最近為了把 &lt;a href=&quot;http://tuxonice.net/&quot;&gt;TuxOnIce&lt;/a&gt; 整到 &lt;a href=&quot;https://gitorious.org/0xlab-kernel/kernel/commits/toi/linaro-android.38&quot;&gt;Android 上面&lt;/a&gt;，著實把 Linux 的電源管理系統中關於 suspend 與 hibernation 的部份研究了一下。而 Android 為了增加待機時間加入了 wakelock 的機制，讓情況變得更加複雜。&lt;/p&gt;

&lt;h2&gt;TuxOnIce&lt;/h2&gt;

&lt;h3&gt;TOI Patch&lt;/h3&gt;

&lt;p&gt;TuxOnIce 簡稱 TOI，前身是 Software Suspend 2，是一個長期在 linux
upstream 以外耕耘的一個休眠補釘，相較於早期整合到 linux kernel 內的
swsusp，TOI 的功能非常豐富，可以指定把記憶體內容儲存到多種不同的位置，如檔案或置換空間，還可以選擇不同的壓縮方法。&lt;/p&gt;

&lt;p&gt;首先幫 ARM 平台加上基本的休眠功能，使用 Hiroshi DOYU 的 patch:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://article.gmane.org/gmane.linux.power-management.general/20543&quot;&gt;http://article.gmane.org/gmane.linux.power-management.general/20543&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;然後到 TOI 網站下載最新的 3.2 補釘，打上去的時候會有一些衝突但是都還滿容易解決，要注意的是某些衝突是看不出來的，例如因為函式移動位置而造成重複定義，要小心檢查。&lt;/p&gt;

&lt;p&gt;然後因為 TOI 對於非 x86 平台有一些假設現在已經不適用，所以需要修改&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gitorious.org/0xlab-kernel/kernel/commit/e551caf&quot;&gt;https://gitorious.org/0xlab-kernel/kernel/commit/e551caf&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;OMAPFB&lt;/h3&gt;

&lt;p&gt;使用 Pandaboard 加上 Android 測試才發現從休眠醒來後 LCD 不會自動點亮，通常在 x86 平台上有 pm-utils 或是 hibernate script 來幫忙處理這種關閉打開 LCD 的問題，這次我是先在 kernel 內幫 OMAPFB 加上一個電源管理的呼叫，讓 kernel 醒來的時候自己重新設定 LCD。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gitorious.org/0xlab-kernel/kernel/commit/21e0f14&quot;&gt;https://gitorious.org/0xlab-kernel/kernel/commit/21e0f14&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Pandaboard &amp;amp; Beagleboard xM&lt;/h3&gt;

&lt;p&gt;在 Pandaboard 或 Beagleboard xM 上面沒有 NAND 可以當作儲存空間，所以一般都是把檔案放在MMC 上面，第一個 patch 讓 kernel 在開機的時候不要初始化不存在的 NAND 空間&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gitorious.org/0xlab-kernel/kernel/commit/3ae6b4c&quot;&gt;https://gitorious.org/0xlab-kernel/kernel/commit/3ae6b4c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;然後因為 MMC 的 probe 需要時間，第二個 patch 讓 TOI 等待指定的 resume
device 已經偵測到之後才開始進行 resume&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gitorious.org/0xlab-kernel/kernel/commit/1078bd7&quot;&gt;https://gitorious.org/0xlab-kernel/kernel/commit/1078bd7&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Wakelock&lt;/h2&gt;

&lt;p&gt;wakelock 是 Android 為了讓裝置可以更積極的休眠又不妨礙正常工作的進行而加入的機制，究竟是好是壞已經在 LKML 與 LWN 上面討論過非常多次，可以參考：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://lwn.net/Articles/318611/&quot;&gt;Wakelocks and the embedded problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lwn.net/Articles/388131/&quot;&gt;Blocking suspend blockers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://thread.gmane.org/gmane.linux.kernel/985471&quot;&gt;Suspend block api (version 7)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;失眠症&lt;/h3&gt;

&lt;p&gt;開始測試 TOI 的效果時遇到的第一個問題就是失眠症，因為 wakelock 從中作梗，導致每次休眠到一半就被取消掉。原來是因為 TOI 的休眠途徑會先強制檔案系統把內容寫回，而 MMC 子系統會在寫入/讀取一段時間後嘗試進入低耗電模式，偏偏 Android 在這裡安插了一個 wakelock，導致之後要凍結所有執行緒的時候失敗。&lt;/p&gt;

&lt;p&gt;解法，首先因為休眠的後半段路徑其實就是要準備進行關機，而一般來說休眠都是人為啟動，因此可以假設此時使用者了解工作可能還未完成，可以忽略
wakelock，所以第一個 patch 就是讓休眠的路徑不去檢查 wakelock，避免像
MMC 這樣的問題。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gitorious.org/0xlab-kernel/kernel/commit/3bb5d6f&quot;&gt;https://gitorious.org/0xlab-kernel/kernel/commit/3bb5d6f&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;接下來是一般的待機路徑，似乎是因為新的 kernel 會積極的嘗試把 MMC 變成低耗電模式，但 OMAP 預設的 MMC timeout 是 100 毫秒，把工作放在 Queue
裡面反而不斷鎖住 wakelock 讓 Android 無法休眠，第二個 patch 就是讓 MMC
子系統在準備休眠的時候就不要作無謂的掙扎，直接進入低耗電模式。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gitorious.org/0xlab-kernel/kernel/commit/88823b9&quot;&gt;https://gitorious.org/0xlab-kernel/kernel/commit/88823b9&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;嗜睡症&lt;/h3&gt;

&lt;p&gt;解決了失眠症沒想到接下來遇到嗜睡症，因為手機插著 USB 的時候是不會真正睡著的，所以一直沒機會觀察 Android 睡著是怎麼樣，原來只把 kernel 叫醒是沒用的，Android 還會檢查目前的 input event 是否屬於 user activity 的範圍，是的話才會把整個系統帶醒，不然因為 wakelock 的機制，馬上就會又睡著。&lt;/p&gt;

&lt;p&gt;參考：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.elinux.org/Android_Power_Management&quot;&gt;Android Power Management&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>


</item>
<item>

	<title>Android 2.3 Introduction &#x26; Statistics</title>


	<guid isPermaLink="false">urn:uuid:e84c0855-25f2-5058-bf1a-ba693dc97127</guid>

	<link>http://kanru.info/blog/archives/2010/12/29/android23-introduction/</link>


	<category>0xlab</category>

	<category>android</category>

	<category>gingerbread</category>


	<pubDate>Wed, 29 Dec 2010 15:41:29 +0800</pubDate>
	<dcterms:modified>2011-06-29T13:33:30Z</dcterms:modified>

	<description>&lt;p&gt;如果你有收看 LWN.net 的話，大概知道每次 linux kernel 有新的 release 前都會有一次針對這次 release 的統計資料，看看主要的貢獻是由哪些人，哪些公司完成。藉由這次跟 0xlab 分享 Android 2.3 新特性的時候，我學 LWN.net
做了一些小統計，還滿有趣的。&lt;/p&gt;

&lt;h2&gt;Most active Android 2.3 organizations (by changesets)&lt;/h2&gt;

&lt;table&gt;
&lt;tr&gt;&lt;td&gt;
&lt;pre&gt;4204 google.com
1354 android.com
98 sonyericsson.com
71 gmail.com
39 codeaurora.org
39 samsung.com
38 intel.com
32 nokia.com
32 holtmann.org
&lt;strong&gt;29 0xlab.org&lt;/strong&gt;
25 trusted-logic.com
17 openbossa.org
11 nxp.com
&lt;strong&gt;11 linux.org.tw&lt;/strong&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;
&lt;pre&gt;10 ti.com
10 acer.com.tw
8 themaw.net
8 garmin.com
7 snpe.rs
7 motorola.com
7 mc.pp.se
7 googlemail.com
5 invensense.com
4 mirbsd.org
3 windriver.com
3 realvnc.com
2 teleca.com
2 sharp.co.jp&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;
&lt;pre&gt;2 nvidia.com
2 motoya.co.jp
2 lge.com
2 broadcom.com
1 yahoo-inc.com
1 xs4all.nl
1 wdsglobal.com
1 uwevoelker.de
1 strongswan.org
1 stericsson.com
1 signove.com
1 saftware.de
1 richlowe.net
1 pv.com&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;
&lt;pre&gt;1 promwad.com
1 pcc.me.uk
1 padovan.org
1 osbeck.com
1 nii.net
1 martin.st
1 ilovelinux.de
1 happydroid.com
1 droidmod.org
1 cpeterso.com
1 big.or.jp
1 arm.com&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;h2&gt;Most active Android 2.3 developers (by lines changed)&lt;/h2&gt;

&lt;table&gt;
&lt;tr&gt;&lt;td&gt;
&lt;pre&gt;Jesse Wilson
Eric Laurent
Dianne Hackborn
David &#39;Digit&#39; Turner
Nick Pelly
Mathias Agopian
Nick Kralevich
Brian Carlstrom
Eric Fischer
Andreas Huber&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre&gt;386588
364359
260033
205494
160707
124119
103004
83492
61646
61233&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre&gt;12.8708%
12.13%
8.65%
6.84% 
5.35%
4.13%
3.42%
2.77%
2.05%
2.03%&lt;/pre&gt;
&lt;/td&gt;
&lt;/table&gt;

&lt;hr&gt;

&lt;div class=&quot;center&quot; style=&quot;width:425px&quot; id=&quot;__ss_6395491&quot;&gt;&lt;object
id=&quot;__sse6395491&quot; width=425&quot; height=355&quot;&gt;&lt;param name=&quot;movie&quot;
value=&quot;//static.slidesharecdn.com/swf/ssplayer2.swf?doc=android23intro-101229014534-phpapp02&amp;rel=0&amp;stripped_title=android23intro&amp;userName=kanru&quot;
/&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;/&gt;&lt;param
name=&quot;allowScriptAccess&quot; value=&quot;always&quot;/&gt;&lt;embed name=&quot;__sse6395491&quot;
src=&quot;http://kanru.info//static.slidesharecdn.com/swf/ssplayer2.swf?doc=android23intro-101229014534-phpapp02&amp;rel=0&amp;stripped_title=android23intro&amp;userName=kanru&quot;
type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot;
allowfullscreen=&quot;true&quot; width=412&quot; height=355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;

&lt;p&gt;投影片中還研究了一下各主要開發者主要研究的方向，看 log 的時候依照這個順序去看，有一定的脈絡可尋 :)&lt;/p&gt;
</description>


</item>
<item>

	<title>Convert Texinfo to MOBI</title>


	<guid isPermaLink="false">urn:uuid:e79dc08c-43bf-52e6-a551-f43345623091</guid>

	<link>http://kanru.info/blog/archives/2010/11/18/convert-texinfo-to-mobi/</link>


	<category>hack</category>

	<category>kindle</category>


	<pubDate>Thu, 18 Nov 2010 10:36:26 +0800</pubDate>
	<dcterms:modified>2010-11-22T07:38:57Z</dcterms:modified>

	<description>&lt;p&gt;GNU software often comes with a large set of documents in
&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/texinfo&quot;&gt;texinfo&lt;/a&gt; format, which can be typesetted to a real book.
For example the &lt;a href=&quot;http://www.gnus.org/manual.html&quot;&gt;Gnus Manual&lt;/a&gt; has over 500 pages, full of fun and
humor. Having a mobi version on my Kindle would be quite handy.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2010/11/18/convert-texinfo-to-mobi/gnus-manual.gif&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2010/11/18/convert-texinfo-to-mobi/x200-gnus-manual.gif&quot; width=&quot;137&quot; height=&quot;200&quot; alt=&quot;Gnus Manual on Kindle&quot; class=&quot;right&quot; /&gt;&lt;/a&gt;
This work involves two parts, first is to convert texinfo to docbook,
second is to convert docbook to mobi.  In fact the second part could
be applied on all docbooks.&lt;/p&gt;

&lt;h2&gt;Convert Texinfo to DocBook&lt;/h2&gt;

&lt;p&gt;Texinfo has native support of converting texi file to docbook format:&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;makeinfo &lt;span class=&quot;hl opt&quot;&gt;--&lt;/span&gt;docbook gnus.texi
&lt;/pre&gt;

&lt;p&gt;will output gnus.xml.&lt;/p&gt;

&lt;p&gt;If the texi includes some other texis the the makeinfo command somehow
doesn&#39;t strip the &lt;code&gt;@setfilename&lt;/code&gt; macro from the included file, so
cluttered output.  Use the following sed script to fix it:&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl kwc&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;i &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;e &lt;span class=&quot;hl str&quot;&gt;&#39;s#&amp;lt;para&amp;gt;&amp;amp;lt;setfilename&amp;amp;gt;.*&amp;amp;lt;/setfilename&amp;amp;gt;&amp;lt;/para&amp;gt;##&#39;&lt;/span&gt; gnus.xml
&lt;/pre&gt;

&lt;h2&gt;Convert DocBook to MOBI&lt;/h2&gt;

&lt;p&gt;Since DocBook 1.74, they included a ruby script &lt;code&gt;dbtoepub&lt;/code&gt; to convert
xml file to epub format.  Then we can use &lt;code&gt;kindlegen&lt;/code&gt; or &lt;code&gt;calibre&lt;/code&gt; to
convert epub to mobi.&lt;/p&gt;

&lt;p&gt;However the docbook xsl produces nested navPoints and &lt;code&gt;&amp;lt;dl&amp;gt;&lt;/code&gt; formated
TOC. Both aren&#39;t handled very well by Kindle.&lt;/p&gt;

&lt;p&gt;So I created a customized layer above the docbook.xsl for mobi
creation.  This mobi.xsl will flatten the navPoints and use &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;
formated TOC.  The output mobi looked very nice on my Kindle.&lt;/p&gt;

&lt;h2&gt;All in one script&lt;/h2&gt;

&lt;p&gt;Download the &lt;a href=&quot;http://kanru.info/blog/./archives/2010/11/18/convert-texinfo-to-mobi/texi2mobi.tar.gz&quot;&gt;texi2mobi.tar.gz&lt;/a&gt;, which contains the script and the
style sheet used to create mobi friendly epub.&lt;/p&gt;

&lt;p&gt;To use this script you have to install &lt;code&gt;makeinfo&lt;/code&gt;, &lt;code&gt;dbtoepub&lt;/code&gt; and
&lt;code&gt;kindlegen&lt;/code&gt;. I use &lt;code&gt;kindlegen&lt;/code&gt; here because it creates better mobi at
present.&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;apt&lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;get &lt;span class=&quot;hl kwc&quot;&gt;install&lt;/span&gt; texinfo
apt&lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;get &lt;span class=&quot;hl kwc&quot;&gt;install&lt;/span&gt; dbtoepub
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;kindlegen&lt;/code&gt; could be downloaded form &lt;a href=&quot;http://www.amazon.com/gp/feature.html?ie=UTF8&amp;amp;docId=1000234621&quot;&gt;Amazon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Untar the tarball then use&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;texi2mobi.sh TEXINFO&lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;FILE
&lt;/pre&gt;

&lt;p&gt;Create your mobi version! Have fun ☺&lt;/p&gt;
</description>


</item>
<item>

	<title>Understanding UUID</title>


	<guid isPermaLink="false">urn:uuid:8f49b28b-927f-54ab-8eae-dab349328339</guid>

	<link>http://kanru.info/blog/archives/2010/11/16/uuid-el/</link>


	<category>emacs</category>


	<pubDate>Tue, 16 Nov 2010 22:16:58 +0800</pubDate>
	<dcterms:modified>2011-06-29T14:16:39Z</dcterms:modified>

	<description>&lt;p&gt;通用唯一識別碼 (Universally Unique IDentifier, &lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/UUID&quot;&gt;UUID&lt;/a&gt;) 或是全域唯一識別碼 (Globally Unique IDentifier, GUID) 是一個 128 bits 的整數，並保證其在時間與空間的分佈都是獨一無二的。UUID 由開放軟體基金會
(&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/OSF&quot;&gt;OSF&lt;/a&gt;) 標準化後用在他們的
&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/Distributed%5FComputing%5FEnvironment&quot;&gt;DCE&lt;/a&gt; 系統上，後來在微軟的 COM 系統上發揚光大。除此之外在許多地方也都可以看到 UUID 的身影，如 Linux 上的分割表/區塊裝置就是以 UUID 來標示，或是
&lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/RSS&quot;&gt;RSS&lt;/a&gt; 的 &lt;code&gt;&amp;lt;guid&amp;gt;&lt;/code&gt; 標籤也可以使用 UUID，實際上 UUID 是標準的 &lt;a href=&quot;https://secure.wikimedia.org/wikipedia/en/wiki/Uniform%5FResource%5FName&quot;&gt;URN&lt;/a&gt; 表示法之一，你可以在任何需要標示單一物件的地方使用 UUID。&lt;/p&gt;

&lt;p&gt;UUID 的文字形式為一個 &lt;code&gt;8-4-4-4-12&lt;/code&gt; 的十六進位表示，共有 16 個 bytes，有人說使用 UUID 不方便人類辨識，但了解 UUID 的組成後你還是可以從這個表示法看出一些端倪來。本文參考的是 IETF 版本的 &lt;a href=&quot;http://www.ietf.org/rfc/rfc4122.txt&quot;&gt;RFC 4122&lt;/a&gt;。&lt;/p&gt;

&lt;div style=&quot;text-align:center&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2010/11/16/uuid-el/uuid.png&quot; width=&quot;300&quot; height=&quot;200&quot; class=&quot;img&quot; /&gt;&lt;/div&gt;

&lt;p&gt;UUID 共有四個版本，第 13 個字元的位置就是表示版本號。第一種是以時間和網路卡號組成，時間是以一百奈秒為單位，網路卡號理論上是不會重複的，再加上
&lt;code&gt;clock_seq&lt;/code&gt; 這個每次開機重設一次的亂數欄位，就算時間回朔了也不會重複，代號是 &lt;em&gt;1&lt;/em&gt;。第二種和第四種是以命名空間加上一個 hash 組成的，分別可以使用MD5 或是 SHA1 演算法，算出來後就填到空位中，代號是 &lt;em&gt;3&lt;/em&gt; 跟 &lt;em&gt;5&lt;/em&gt;。第三種是全亂數組成，代號是 &lt;em&gt;4&lt;/em&gt;。&lt;/p&gt;

&lt;p&gt;因此我們可以在不同的情境選用不同的 UUID，也可以從 UUID 看出版本跟時間等資訊，如 &lt;code&gt;4ef17586-f187-11df-8xxx-xxxxxxxxxxxx&lt;/code&gt; 看到第三個區塊是
&lt;code&gt;11df&lt;/code&gt; 就可以知道是最近產生的以時間卡號為基礎的 UUID，時間
&lt;code&gt;1dff1874ef17586&lt;/code&gt; 解出來就是 2010-11-16 13:42:09.173031.0 UTC。而
&lt;code&gt;7c0fdbe4-1b09-4278-9fc9-5f0c6a1f2ae2&lt;/code&gt; 就是純亂數的 UUID，沒有任何意義。&lt;/p&gt;

&lt;h2&gt;uuid-el&lt;/h2&gt;

&lt;p&gt;在轉換 Blog 到 ikiwiki 的時候，為了要整合 Disqus 系統，每篇都需要一個唯一的識別碼，這樣 Disqus 就只認 UUID 而不是網址，將來網址變了也可以對得上，而此 ID 也可以用在 RSS, ATOM 上面。研究了 RFC 4122 後，用 elisp 寫了產生 UUID 的工具，&lt;a href=&quot;http://github.com/kanru/uuid-el&quot;&gt;uuid-el&lt;/a&gt;，使用只需要：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;&#39;&lt;/span&gt;uuid&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; Generate UUIDv1&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;uuid-1&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; Generate UUIDv4&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;uuid-4&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;;; Generate UUIDv3, v5&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;uuid-3&lt;/span&gt; uuid-ns-url &lt;span class=&quot;hl str&quot;&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;uuid-4&lt;/span&gt; uuid-ns-url &lt;span class=&quot;hl str&quot;&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;搭配以下 snippet 就可以快速展開需要的 metadata：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl opt&quot;&gt;#&lt;/span&gt; -&lt;span class=&quot;hl opt&quot;&gt;*&lt;/span&gt;- mode&lt;span class=&quot;hl opt&quot;&gt;:&lt;/span&gt; snippet -&lt;span class=&quot;hl opt&quot;&gt;*&lt;/span&gt;-
&lt;span class=&quot;hl opt&quot;&gt;#&lt;/span&gt; name&lt;span class=&quot;hl opt&quot;&gt;:&lt;/span&gt; meta
&lt;span class=&quot;hl opt&quot;&gt;#&lt;/span&gt; key&lt;span class=&quot;hl opt&quot;&gt;:&lt;/span&gt; meta
&lt;span class=&quot;hl opt&quot;&gt;#&lt;/span&gt; --
&lt;span class=&quot;hl opt&quot;&gt;[[!&lt;/span&gt;meta  title&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;$1&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;[[!&lt;/span&gt;meta  guid&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;${1:$(uuid-urn (uuid-5 uuid-ns-kanru text))}&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;hl opt&quot;&gt;[[!&lt;/span&gt;meta  date&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;${2:`(current-time-string)`}&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;]]&lt;/span&gt;
$&lt;span class=&quot;hl num&quot;&gt;0&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;最後補上影片：&lt;/p&gt;

&lt;div style=&quot;text-align:center&quot;&gt;
&lt;video src=&quot;./archives/2010/11/16/uuid-el/uuid-el_in_action.webm&quot; width=&quot;478&quot; height=&quot;280&quot; class=&quot;video&quot; loop controls/&gt;
&lt;/div&gt;

&lt;p&gt;下一集：用 ffmpeg 製作桌面錄影&lt;/p&gt;
</description>


</item>
<item>

	<title>Blog Redesigned</title>


	<guid isPermaLink="false">urn:uuid:950c406d-7b37-5de9-8c59-616540a582e6</guid>

	<link>http://kanru.info/blog/archives/2010/11/15/blog-redesigned/</link>


	<category>emacs</category>

	<category>web</category>


	<pubDate>Sun, 14 Nov 2010 22:04:38 +0800</pubDate>
	<dcterms:modified>2010-11-15T02:59:45Z</dcterms:modified>

	<description>&lt;p&gt;最近又把 Blog 整頓了一番，目標是改用靜態網頁。使用靜態網頁搭配一些網頁樣板程式不禁讓人想起最初使用 MT 來寫 Blog 的時候，不同的是現在有像
&lt;a href=&quot;http://disqus.com/&quot;&gt;Disqus&lt;/a&gt; 或是 &lt;a href=&quot;http://www.intensedebate.com/&quot;&gt;IntenseDebate&lt;/a&gt; 這樣的動態留言服務，讓網頁可以完全的只提供靜態內容，不用多一個 cgi 程式來提供留言功能，這隱然成為最近流行的網頁設計方法之一。&lt;/p&gt;

&lt;p&gt;轉換的過程中學到一些新東西，紀錄於此。&lt;/p&gt;

&lt;h2&gt;網頁編譯器&lt;/h2&gt;

&lt;p&gt;現在網頁是用
&lt;a href=&quot;http://ikiwiki.info/&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2010/11/15/blog-redesigned/x16-ikiwiki.png&quot; width=&quot;60&quot; height=&quot;16&quot; alt=&quot;IkiWiki&quot; class=&quot;img&quot; /&gt;&lt;/a&gt;
產生的，它是大師 &lt;a href=&quot;http://ikiwiki.info/users/joey/&quot;&gt;Joey Hess&lt;/a&gt; 的作品，大師稱它是一個 &lt;em&gt;wiki compiler&lt;/em&gt;，可以透過各種規則把網頁的原始碼 (可能是 markdown 的格式) 轉成 HTML 網頁。因為強大的 inline 規則以及各式各樣的外掛程式，也有許多人把 ikiwiki 當作
Blog 的平台。&lt;/p&gt;

&lt;p&gt;轉換的過程其實滿順利的，因為舊的 Blog 都是以 Markdown 寫成，換到
ikiwiki 的 Markdown 引擎只需要一點點修改。要感謝 Wordpress 可以把資料庫匯出成 XML 格式，轉換只需要簡單的 XSLT 就完成了，我用的
&lt;a href=&quot;http://kanru.info/blog/./archives/2010/11/15/blog-redesigned/wp2txt.xsl&quot;&gt;XSL&lt;/a&gt; 是參考&lt;a href=&quot;http://ikiwiki.info/tips/Importing_posts_from_Wordpress/&quot;&gt;這裡&lt;/a&gt;修改，去掉 Comment 以及更新 meta
的格式而成。&lt;/p&gt;

&lt;p&gt;改用文字編輯器來寫 Blog 後，會習慣在 72 行的地方換行，但是在瀏覽器中只要換行就會多一個空白，以前寫網頁的時候遇到中文都要小心的換行才不會讓不該空白的地方出現空白，也不能打開 Emacs 的 auto-fill 模式。拜 ikiwiki 強大的外掛程式架構以及 Perl 的 Unicode 正規表示式支援，寫個&lt;a href=&quot;http://kanru.info/blog/./archives/2010/11/15/blog-redesigned/cjkfix.pm&quot;&gt;外掛&lt;/a&gt;把不該空白的地方黏起來只要幾分鐘時間！而 Blog 原始碼則維持容易閱讀的格式。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2010/11/15/blog-redesigned/2010-11-14-234802_488x420_scrot.png&quot; width=&quot;518&quot; height=&quot;450&quot; class=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;HTML5&lt;/h2&gt;

&lt;p&gt;既然都換了 Blog 系統，也打算換新的版面，乾脆就升級到網頁標準的新世代
HTML5。在收集 HTML5 相關資訊時發現了 &lt;a href=&quot;http://html5boilerplate.com/&quot;&gt;HTML5 Boilerplate&lt;/a&gt; 這個網頁樣板計畫，包含了許多目前 HTML5 的 Best Practice，基於這個樣板設計網頁讓你馬上就 HTML5 Ready ☺&lt;/p&gt;

&lt;p&gt;我認為 HTML5 最有趣的一點是帶有語意的新標籤，如 &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;,
&lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; 等等，搭配新的&lt;a href=&quot;http://www.whatwg.org/specs/web-apps/current-work/multipage/sections.html&quot;&gt;大綱演算法&lt;/a&gt;可以自動產生大綱，運用得當的話，對於機器或是身體不便的人都能更方便的取得資訊。&lt;/p&gt;

&lt;p&gt;ikiwiki 原本就有支援實驗性的 HTML5 模式，但是預設的樣板不是很完美，例如多層嵌套的 &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; 與 &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; 和 &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;，都會產生多餘的大綱節點，若只是需要群組與排版功能的話，最好還是使用 &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 就好。如我現在用的 template 長得就像這樣：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;TITLE&lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;time&amp;gt;&lt;/span&gt;TIME&lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;/time&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;hl kwb&quot;&gt;class&lt;/span&gt;=&lt;span class=&quot;hl str&quot;&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;&amp;gt;&lt;/span&gt;
        CONTENT
    &lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;footer&amp;gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hl kwa&quot;&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;這裡推薦使用 &lt;a href=&quot;http://gsnedders.html5.org/outliner/&quot;&gt;HTML 5 Outliner&lt;/a&gt; 來檢查網頁的大綱，或是用專門的
&lt;a href=&quot;https://chrome.google.com/extensions/detail/afoibpobokebhgfnknfndkgemglggomo&quot;&gt;Chrome 擴展&lt;/a&gt;，如果網頁設計無誤，應該會看到如下乾淨的大綱：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2010/11/15/blog-redesigned/2010-11-15-001750_1366x768_scrot.png&quot; width=&quot;623&quot; height=&quot;352&quot; class=&quot;img&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Web Fonts&lt;/h2&gt;

&lt;p&gt;使用網路字體可以讓網頁在不同的作業系統、不同的瀏覽器上看起來都是一樣的，現在有很多提供網路字體的服務，像是 Google 也推出
&lt;a href=&quot;http://code.google.com/webfonts&quot;&gt;Google Font Directory&lt;/a&gt;，甚至 &lt;a href=&quot;http://webfonts.fonts.com/&quot;&gt;Fonts.com&lt;/a&gt; 還有免費的中文網路字體，參考 &lt;a href=&quot;http://www.typeisbeautiful.com/&quot;&gt;Type Is Beautiful&lt;/a&gt; 的&lt;a href=&quot;http://www.typeisbeautiful.com/files/webfonts.html&quot;&gt;測試頁&lt;/a&gt;，速度還不錯呢。&lt;/p&gt;

&lt;p&gt;我現在用的是從 &lt;a href=&quot;http://www.fontsquirrel.com/&quot;&gt;Font Squirrel&lt;/a&gt; 下載的自由字體，這個網站上不但有大量的自由字體可以挑選，還有預先整理好的 @font-face Kits 可以直接使用，或是用 @font-face Generator 產生最佳化的網路字體。&lt;/p&gt;

&lt;h2&gt;結語&lt;/h2&gt;

&lt;p&gt;這篇是心得筆記的性質，因為如果不紀錄一下可能很快就忘了...有許多細節都省略過去，若是要深入探討則每個主題都可以發展成長篇大論，需要更詳細資料的網友可以參考引用的連結。&lt;/p&gt;

&lt;p&gt;一些眉眉角角的東西希望之後有機會可以再單獨拿出來分享囉 ☻&lt;/p&gt;
</description>


</item>
<item>

	<title>TOP 20 Space-Hungry Packages</title>


	<guid isPermaLink="false">urn:uuid:565a4da6-b538-5aa5-8ab5-c06798c206ac</guid>

	<link>http://kanru.info/blog/archives/2010/11/14/gen-top20pkg/</link>


	<category>arch</category>

	<category>debian</category>

	<category>hack</category>


	<pubDate>Sun, 14 Nov 2010 16:40:13 +0800</pubDate>
	<dcterms:modified>2010-11-14T08:40:13Z</dcterms:modified>

	<description>&lt;p&gt;Arch Linux 與 Debian 皆可以在安裝的時候選擇最小安裝，究竟哪一個
Distribution 在使用一段時間之後最佔空間呢？  剛安裝完的時候似乎是 Arch
比較小一點，但是因為 Debian 套件切的比較細，所以最後可能是 Debian 會比較小。&lt;/p&gt;

&lt;p&gt;當初在試用 Arch 的時候寫了小程式來畫出前 20 個最佔空間的套件，並依此來瘦身，結果如下：&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2010/11/14/gen-top20pkg/arch-top20pkg.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2010/11/14/gen-top20pkg/650x-arch-top20pkg.png&quot; width=&quot;650&quot; height=&quot;224&quot; alt=&quot;Arch Linux Package Size TOP 20&quot; class=&quot;img&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://kanru.info/blog/./archives/2010/11/14/gen-top20pkg/debian-top20pkg.png&quot;&gt;&lt;img src=&quot;http://kanru.info/blog/./archives/2010/11/14/gen-top20pkg/650x-debian-top20pkg.png&quot; width=&quot;650&quot; height=&quot;224&quot; alt=&quot;Debian Package Size TOP 20&quot; class=&quot;img&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;兩邊因為安裝的套件種類不同因此無從比較，Arch 的 TeXLive 因為沒有切所以會比 Debian 上較大一點，Debian 上的 ghc6 則是為了測試 xmonad 裝的，
Haskell 本身做出來的執行檔就頗大，ghc6 需要 369MB 實在不意外...&lt;/p&gt;

&lt;p&gt;底下是製作圖片的程式，實際上是用 Google Chart API 畫的：&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl slc&quot;&gt;#!/usr/bin/python&lt;/span&gt;
&lt;span class=&quot;hl slc&quot;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;span class=&quot;hl kwa&quot;&gt;from&lt;/span&gt; pygooglechart &lt;span class=&quot;hl kwa&quot;&gt;import&lt;/span&gt; StackedHorizontalBarChart&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; Axis
&lt;span class=&quot;hl kwa&quot;&gt;from&lt;/span&gt; subprocess &lt;span class=&quot;hl kwa&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;*&lt;/span&gt;

TITLE&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;Debian Package Size TOP 20&amp;quot;&lt;/span&gt;
PKGSIZE_PROG&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;./dpkgsize&amp;quot;&lt;/span&gt;
OUTPUT&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;debian-top20pkg.png&amp;quot;&lt;/span&gt;

chart &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl kwd&quot;&gt;StackedHorizontalBarChart&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;930&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;320&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
chart&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;set_bar_width&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
chart&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;set_title&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;TITLE&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;

size_data &lt;span class=&quot;hl opt&quot;&gt;= []&lt;/span&gt;
name_data &lt;span class=&quot;hl opt&quot;&gt;= []&lt;/span&gt;

&lt;span class=&quot;hl kwa&quot;&gt;for&lt;/span&gt; ln &lt;span class=&quot;hl kwa&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;hl kwd&quot;&gt;Popen&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;([&lt;/span&gt;PKGSIZE_PROG&lt;span class=&quot;hl opt&quot;&gt;],&lt;/span&gt; stdout&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;PIPE&lt;span class=&quot;hl opt&quot;&gt;).&lt;/span&gt;stdout&lt;span class=&quot;hl opt&quot;&gt;:&lt;/span&gt;
    size&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; name &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; ln&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;()&lt;/span&gt;
    size_data&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt;
    name_data&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;

chart&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;add_data&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;size_data&lt;span class=&quot;hl opt&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;])&lt;/span&gt;

max_size &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; size_data&lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
min_size &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; size_data&lt;span class=&quot;hl opt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
label &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl kwb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl kwa&quot;&gt;lambda&lt;/span&gt; x&lt;span class=&quot;hl opt&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl kwb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;hl opt&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;hl num&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;)+&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&amp;quot;MB&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;hl kwb&quot;&gt;xrange&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;min_size&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; max_size&lt;span class=&quot;hl opt&quot;&gt;, (&lt;/span&gt;max_size&lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;min_size&lt;span class=&quot;hl opt&quot;&gt;)/&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;))&lt;/span&gt;
label&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;()&lt;/span&gt;

rev_name_data &lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt; name_data&lt;span class=&quot;hl opt&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;hl num&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;]&lt;/span&gt;
rev_name_data&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;()&lt;/span&gt;
chart&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;set_axis_labels&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;Axis&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;LEFT&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; rev_name_data&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
chart&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;set_axis_labels&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;Axis&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;BOTTOM&lt;span class=&quot;hl opt&quot;&gt;,&lt;/span&gt; label&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;hl kwa&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;chart&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;get_url&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;())&lt;/span&gt;
chart&lt;span class=&quot;hl opt&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl kwd&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;hl opt&quot;&gt;(&lt;/span&gt;OUTPUT&lt;span class=&quot;hl opt&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;把 &lt;code&gt;PKGSIZE_PROG&lt;/code&gt; 代換成自己 Distro 的就可以了：&lt;/p&gt;

&lt;p&gt;Debian:&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl slc&quot;&gt;#!/bin/sh&lt;/span&gt;
dpkg&lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;query &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;W &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;f&lt;span class=&quot;hl opt&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&#39;${Installed-Size} ${Package}&lt;/span&gt;&lt;span class=&quot;hl esc&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;hl str&quot;&gt;&#39;&lt;/span&gt;|&lt;span class=&quot;hl kwc&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;nr
&lt;/pre&gt;

&lt;p&gt;Arch:&lt;/p&gt;

&lt;pre class=&quot;hl&quot;&gt;&lt;span class=&quot;hl slc&quot;&gt;#!/bin/sh&lt;/span&gt;
pacman &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;Qi|&lt;span class=&quot;hl kwc&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;hl str&quot;&gt;&#39;/^Installed Size/{print int($4), name} /^Name/{name=$3}&#39;&lt;/span&gt;|&lt;span class=&quot;hl kwc&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;hl opt&quot;&gt;-&lt;/span&gt;nr
&lt;/pre&gt;
</description>


</item>

</channel>
</rss>

