Golang import path `all`

go help packages 可以看到三個 reserved names 如下:

1
2
3
4
5
6
7
8
- "main" denotes the top-level package in a stand-alone executable.

- "all" expands to all package directories found in all the GOPATH
trees. For example, 'go list all' lists all the packages on the local
system.

- "std" is like all but expands to just the packages in the standard
Go library.

實際使用起來有如下的一些可能,不過最好用 root 裝 go,免得影響到 std libraries.

  1. 更新全部 go get -u all
  2. 清掉全部 build 出的 libraries go clean -i all
  3. install 全部 go install all

善用 exec redirection

寫 shell script 時常碰到 list 不好處理的問題,裡面如果包含空白之類的 IFS 區隔,一不小心就會發生意外。例如目錄中包含 My Music 這個目錄, 用以下的 shell script 處理 ls -1 時,就會分別印 MyMusic

1
2
3
for f in `ls -1`; do
echo $f
done

解法可以用 read 讀入變數:

1
2
3
ls -1 | while read f; do
echo $f
done

如果需要複雜一些的篩選,甚至處理有 \n 在裡頭的檔案,那可以用 find -print0

1
2
3
4
find -mindepth 1 -maxdepth 1 -print0 | \
while read -d $'\0' f; do
echo $f
done

但這又有個討厭的地方,就是在迴圈中如果需要用到 stdin 就出錯了,因為 stdin 是接到 findstdout。解法會動用到 process substitution 跟 exec redirection 用來改變環境的 file descriptor 設定。

1
2
3
4
exec 3< <(find -mindepth 1 -maxdepth 1 -type d -print0)
while read -d $'\0' f <&3-; do
echo $f
done

主要差異是第一行,<(COMMAND) 的用意是把 find 的輸出接到一個 named pipe 或者是 /dev/fd 之下當成一個檔案(詳情請參閱 info bash),而 exec 3< 的意思則是用 fd 3 打開這個檔案。下一行 read 後面接的 <&3- 是把 fd 3 move 到 read 的 stdin,這樣就不會影響到 loop 中的 stdin 了。

中文字型大不易

個人習慣的閱讀用字型為 sans-serif,為求搭配,中文字也想採用無襯線的黑體 或圓體。然而這件事情卻是超乎想像的困難,原因在於以下需求:

  1. 繁體部份不得為 GB 18030 寫法。(參考 GB 18030 就在你身邊 )若非為此,文泉驿系列字型,就是很好的選擇。

  2. 簡繁字體需同源。這是由於 UTF-8 中簡繁字有許多共用,若 fontconfig 先 指定繁體字集,再 failover 到簡體,而兩者風格不一致,那麼在顯示簡體文章 時,若在繁體字集中先找到字,就會直接使用,找不到的話就會用簡體字集。這 會導致整個版面交錯排列來自兩個字集的字型,此時若不一致,就會非常難看。 譬如這種慘況:

在 Ubuntu 13.10 中直接可找到的繁體黑體或圓體,比如 fonts-cwtex-heib 或 fonts-cwtex-yen 都有跟簡體字型不一致的問題。反倒是如果不要求要無襯線字 體,fonts-arphic-uming 就已經解決了,因為簡、繁、香港字型皆有提供。

Apple 的 黑體-繁黑体-简 , 以及微軟的正黑體,其實都符合這些需求,但 Ubuntu 套件中的中文字型則不然。

Update 2018/08/21:

Google 的 Noto CJK 符合以上所有需求, 且有襯線與無襯線皆提供。

Big Integer in JavaScript

應該很多人都知道 JavaScript 的數值型別沒有整數,一併都是 double precision 64-bit 浮點數。但實際運作起來還是很討厭啊:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> b = parseInt('9007199254740992', 10); // 2^53
9007199254740992
> typeof(b);
'number'
> b + 1;
9007199254740992
> b = parseInt('9007199254740994', 10);
9007199254740994
> typeof(b);
'number'
> b + 1;
9007199254740996
> 'wtf?'
'wtf?'
> b = parseInt('18446744073709551616', 10); // 2^64
18446744073709552000
> isNaN(b)
false
> isFinite(b);
true

Reference: http://ecma262-5.com/ELS5_HTML.htm#Section_8.5

其實已經不準確了,但沒有錯誤訊息。這裡我本想做的事情是 JSON parse/stringify facebook user id,據 Facebook blog 說的長度是 64 bits. 當然會有人建議乾脆存成字串啦,但除非移民太空,不然其實不可能超過 64 了。在找支援的套件時,都不是很熱門,感覺怕怕的。後來看到 json-bignum,內部是直接用字串存,簡單,看了一下覺得還可以,但當然在比較之類的就要小心了,例如相等的話要先 toString() 之後才能比。

Ordered Spec in PyMongo

最近寫 Python 存取 mongoDB 時注意到一個問題,就是在下 find 時很自然的用了 dict 來下條件,但其實 mongoDB 的 find 會需要注意先後次序,用來跟index 搭 配在某些情況例如 hint,次序是有影響的。PyMongo 在這部份的說明其實蠻模糊 的,相關的文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pymongo.collection

find(self, *args, **kwargs)

:Parameters:
- `spec` (optional): a SON object specifying elements which
must be present for a document to be included in the
result set


bson.son

class SON(__builtin__.dict)
SON data.

A subclass of dict that maintains ordering of keys and provides a
few extra niceties for dealing with SON. SON objects can be
converted to and from BSON.

__init__(self, data=None, **kwargs)

所以若要保留順序,就要直接用 SON 物件來當 find 的參數。建立的方法跟 dict.items() 傳回來的東西一樣,是 “list of D’s (key, value) pairs, as 2-tuples”

1
2
3
4
5
6
>>> from bson import son
>>> a = son.SON([('a', 1), ('b', 1), ('c', 1), ('d', 1)])
>>> a
SON([('a', 1), ('b', 1), ('c', 1), ('d', 1)])
>>> a.to_dict()
{'a': 1, 'c': 1, 'b': 1, 'd': 1}

WXR Parser

WXR Parser 可用來分析 WordPress.com 匯出的 XML 檔案,是為了這次要搬出來然後用 Wintersmith 靜態產生 blog 頁面寫的,目前可以匯 出適合 Wintersmith 使用的目錄結構。不過因為設計上 parser 跟 backend 分 開,所以要擴充來產生其他格式也蠻簡單。

A simple WXR parser written in Python to parse the XML export from WordPress and store the information it in in Python’s basic data structures, i.e. dictionaries and lists. It also goes with a backend to export it in Markdown syntax suitable for Wintersmith. In its current form, it can simplify the migration from WordPress to Wintersmith, but it’s easy to be extended to export more formats.

It’s created because the author failed to find a simple one to use.

至於本來想讓 Wintersmith 支援 org-mode,這部份就不打算弄了。主要由於幾個原因:

  1. org-mode 輸出成 html 預設是 standalone 的,也就是會匯出一個結構完整 的 html 檔案。這在當成文件匯出時很不錯,但並不符合這類 static site generator 的預期。

  2. org-mode 新版本支援直接輸出為 markdown。

新居落成誌慶

張愛玲在「紅玫瑰與白玫瑰」中用了「心居落成誌喜」,好不容易搬完了家,也 該來慶祝一番。

這回動用不少,首先為了該用那一個 Static site generators 就著實煩惱 了好一陣子,一開始注意到 Jekyll,後來又發現 Octopress 弄得更漂亮,期間也看過 LogdownGhost。說實在話 如果考慮動態、hosting 的話,Ghost 應該是首選,界面很漂亮,又是 open source 可以自己修改。不過想來想去,為了知識管理,技術相關的文章還是在自 己電腦上有一份文字檔的來得好,比較容易搜尋,故最後還是決定用靜態產生, 然後丟到 github.io 的方式來做。

研究一陣 Octopress 之後決定放棄,雖然它預設產生出來的版面最順眼,但畢竟 Ruby 我不會寫,有問題也沒法改。接下來就是在 NikolaWintersmith 之間擺盪。決定的原因,是覺得說到 web,還是當紅的 javascript 資源最多,所以決定使用 Wintersmith。

其實不論哪個平台,直接拿來開始寫都是很簡單的。真正問題在於我也想順便把 原先的 blog 抓下來,看是要轉換成 org-mode 或是 markdown,免得要找以前寫的東西還得上網去查。另外也想寫個 功能比較完整的 wordpress xml parser,日後如果要弄 page, category, tag 這些東西也方便改。花了好些功夫終於用 python 寫出一份,可以先把 html 的 部份抽出來用 Pandoc 轉 markdown, 也可把文章中引用的圖片一併抓下備用。這部份完成了以後就是漫長的微調過程, markdown 本身就有數種不同的 flavor,pandoc 與 Wintersmith 用的 marked 預設並不相同。另外 wordpress 喜 歡用一些自己的 tag 例如 [sourcecode], [youtube], [slideshare] 這也會造 成一些麻煩。最終成果堪用,但還不滿意,之後有空整理一下再開放出來。

原先的文章本來就已經有一部份是從再前一個自己架的 blog 移到 wordpress.com 去的,小時候寫文章習慣不是很好,程式碼引用的語法也不太一 致,這次換到 markdown 以後全部整理一次,希望之後能夠就此定案。

目前版面,為了 markdown 的換行與中文美觀,採用了兩位朋友創作的 CJK-space-fix 以為換行修正, 以及 dualjustify 做縱橫對齊, 效果出來還不錯。可惜預設版面實在太難看,也只有等之後慢慢修正了。

想換 blog...

Wordpress 預設的這些版面說有多不配程式就有多不配,不付錢的話能客製程度又低(事實上我覺得非常爛,很後悔幹嘛用),但能直接上傳圖片什麼的還是有其方便處。這陣子一直在想要不要整個換 Octopress 然後放 github,不但簡單清爽而且能用版本管理系統來寫 blog 實在是很讚的一件事情。另一件麻煩事是雖然大家很推崇用 markdown 來寫,但我最常用的其實是 org-mode,從 org-mode 是可以輸出 markdown 沒錯啦,但繞那麼遠是要幹嘛… markdown 跟 org-mode 還差蠻多的,寫習慣 org-mode 以後換到 markdown 都還要去查語法,例如連結 org-mode 就是 [[link][description]] 然後 markdown 就是 [description](link) 或是 [description][footnote id] ,這種小地方真的蠻討厭的。然後譬如強調字體 org-mode 是 *bold*, /italic/, _underlined_, =code= and ~verbatim~ 這部份 markdown 就完全不一樣。

這陣子想簡化一切事情,譬如 blog 也該算是個人知識管理的一部分,不能快速搜尋翻找就不太對,而且最好是這類東西都有個共通界面去紀錄,Evernote 就是蠻好的想法,配上 postach.io 當 blog 就不錯,但真的不適合我。之前稍微嘗試過,但我的記事情方法是森林狀的,然後他整個散落各處,用筆記本跟 tag 去分反而找不到而且覺得超討厭。猜想這個跟另一種思維方式的人會很配,也說明為何他這麼紅吧。Anyway, 以前不會很在意在這類東西之間換來換去,但現在越來越覺得用熟悉的工具去盡量節省時間是很重要的。(這又牽涉到一些研發上的思考,一直以來常在換技術換語言之類的,專注某領域然後深耕是不是也很重要,然後這領域究竟該是像 web programming 這種很具象的領域還是說應該是某種抽象的「平行處理」之類的領域呢?似乎該是後者,但問題是我沒有後者,這就尷尬了…)

言歸正傳。所以說,為了簡化,反而現在會花很多時間想辦法去做「簡化」這件事(很弔詭吧),例如之前 org-mode 都隨便亂用,一直到最近因為要唸線代,一堆數學符號不知道怎麼作筆記很不爽(事實上之前重學機率的時候就碰到這問題,但就放著不管),貪快用紙筆的話鐵定沒過多久就不知道扔去哪了,於是就立下決心去看一下 LaTex 到底公式怎麼打,一學之下發現意外的簡單,而且直接 emacs 裡面熱鍵切換就可以看到結果,超方便的啊,到底以前幹嘛不學,學一下不就可以省事很多嗎(懊悔)。但這些就真的很奇怪,這些工具拖著想說先不要學,結果有一天就是會碰到然後還是得學。什麼都學的結果就是會一堆東西,但都是工具,會用工具根本就是沒屁用的事情啊,要會真的很硬的東西才有用吧。比如說今天我人工智慧學超強然後寫 lisp(隨便亂講的,不知道業界做 AI 會用什麼語言),寫論文用 LaTeX 這樣就很夠了吧。再不然寫 Java 用一堆 Apache 的東西專門弄雲端,或是只寫 JavaScript 然後一直寫 web,再不然寫 C 然後是 kernel developer 這樣都很好啊,但我會的一堆可就什麼都不是,東弄弄西弄弄的到現在 30 眼看 40 了到底在幹嘛啊(嘆氣)。

總之(上段言歸正傳明顯是失敗了),如果能有時間的話,完美解應該是寫個 wordpress.xml 的 parser 把過往文章好好的轉到 org-mode 去,然後再把 org-mode 跟 Octopress 整合起來,最後整個丟去 github,應該就 happily ever after 了吧。這簡直費工到炸,雖然很想弄但究竟什麼時候才會有時間啊(抱頭)… 更別說 wallagroup 那邊一大堆要看的 code 還沒看一堆答應的功能也還沒寫,這都是正職跟唸書以外的事情,但我光這兩件事就做不完了啊…

rxvt / xterm + freetype + 中文顯示 (Chinese)

.Xresources

1
2
3
4
5
6
7
8
9
10
11
12
13
XTerm*faceName: Ubuntu Mono
XTerm*faceNameDoublesize: WenQuanYi Micro Hei Mono:minspace=true
XTerm*faceSize: 12
XTerm*faceSize1: 8
XTerm*faceSize2: 10
XTerm*faceSize3: 12
XTerm*faceSize4: 14
XTerm*faceSize5: 16
XTerm*faceSize6: 24

Rxvt.font: xft:Ubuntu Mono:size=12,xft:WenQuanYi Micro Hei Mono:pixelsize=18:minspace=true
Rxvt.letterSpace: -1
Rxvt.lineSpace: 2

xterm 比較討厭的地方是 freetype 的 failover 做不是很好,顯示一些 unicode 的字型時在 faceName/faceNameDoubleSize 裡頭找不到的話,就會放棄變成方塊;為了避免,只好裝 rxvt-unicode。後來因為太喜歡 rxvt fading 的功能,就決定換用了。

其中 rxvt 的 letterSpace 是要配合第一字型(在此是 Ubuntu Mono)的特性去調整的,Ubuntu Mono 間距比較寬,所以用 -1 來減少,這樣在我筆電 X220 上垂直分為左右二欄還可以有清楚的 80 欄寬。lineSpace 則是因為 Ubuntu Mono 比較寬而高度不夠,會導致文泉驛 render 出來的字太小,而且整個螢幕都是字時閱讀起來很吃力,所以加一些高度給他。麻煩的是,高度好了以後,仍然有時會跑出方塊,urxvt 顯示錯誤是

1
2
3
urxvt: unable to calculate font width for 'WenQuanYi Micro Hei 
Mono:slant=0:weight=200:pixelsize=19:minspace=True', ignoring.
...

size 轉到 pixelsize 是由螢幕解析度決定的,所以是否會有這情況,以及這情況發生時出來的數字,都不一定。我的情況是 pixelsize=19 出問題,由於字體大小是由第一個字型,也就是 Ubuntu Mono 決定,所以增加 pixelsize 沒用,只能試減少。減到 18 時剛剛好,字型漂亮,欄寬也夠。

xrdb -merge ~/.Xresources 可以直接讀入改好的 .Xresources,這樣下一個開的 x-terminal-emulator 就會套用新的設定。

Two-Finger Scrolling on ThinkPad X220 + Ubuntu 12.04 (precise)

The TrackPoint on a ThinkPad laptop is one of the main reasons why I kept buying laptops from them. However, as a heavy laptop user who refused to carry around one extra mouse, the constant usage of TrackPoint can cause a significant amount of pain to my fingertip, which is very unpleasant. An once-in-a-while quick movement is okay, but scrolling up/down takes longer and requires more pressure, which is the main cause of discomfort.

As a possible solution, I’ve tried to enable TouchPad and two-finger scrolling. However, for some reason it didn’t work by setting it in gnome-control-center, so instead I used the old faithful xinput. From the output of xinput list-props "SynPS/2 Synaptics TouchPad", it’s easy to spot “Synaptics Two-Finger Scrolling”, and the two parameters can enable vertical and horizontal scrolling, respectively.

The default setting of two-finger scrolling was far from intuitive – normally people would expect it to work just like the way it works on touch devices: you touch the screen, then you can push the document up by moving your finger up. That means scrolling down when your finger is moving up. But on my laptop, moving two fingers up means scrolling up, which causes the document to move down!

To make this problem worse, there is no setting in gnome-control-center to inverse this. Again, this can be solved with xinput by simply changing the values of “Synaptics Scrolling Distance” from 100 100 to -100 -100.

Here is my current .xsessionrc:

1
2
3
4
5
xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation" 1
xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Button" 2
xinput set-prop "TPPS/2 IBM TrackPoint" "Device Accel Velocity Scaling" 50
xinput set-prop "SynPS/2 Synaptics TouchPad" "Synaptics Two-Finger Scrolling" 1 1
xinput set-prop "SynPS/2 Synaptics TouchPad" "Synaptics Scrolling Distance" -100 -100