2013/02/26

Silent Block -- Firefox 過濾 URL 的擴充套件

介紹一個 Firefox 的擴充套件 -- Silent Block,可以用來過濾你指定的 URL。這個套件很好用 (過濾能力又強又有彈性),但不容易用。因為你要自訂 regular expression 來定義 URL, 而且要自己用 editor 寫。此套件網址如下:
https://addons.mozilla.org/en-US/firefox/addon/silentblock/
簡單舉一個使用情境:你經常需要連到網頁 A,此頁面又會顯示一些大又無用的圖案,造成頁面顯示緩慢。這時,你就可以用 Silent Block 不聲不響的濾掉這些圖檔。

使用此擴充套件你必須在自己的 profile 目錄編輯一個 contentblock-regex.txt 檔案。檔案內容就是一條條想要擋下的 URL。套件的官方網址如下 (間單扼要,跟套件的實作風格一樣):
http://www.schuzak.jp/fx/silentblock.html

頁面最底下有一個設定範例。沒用過 regular expression 的人,看過之後肯定馬上放棄。有興趣挑戰的人,可以參考 Mozilla 的文件:
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions#Writing_a_Regular_Expression_Pattern

2013/02/13

Epson Stylus Office TX610FW @ Ubuntu

在 Ubuntu 要列印到 Epson Stylus Office TX610FW?沒問題,方法如下:
  1. 到 http://www.openprinting.org/driver/epson-stylus-office-tx610fw-series 下載 Epson 提供的 package,我試過 1.0.0 (DEB for LSB 3.2) 這一個。注意!請正確選擇 32bit 或 64bit 版本,而且必須先安裝 lsb 套件。
  2. 安裝指令 sudo dpkg -i epson-inkjet-printer-stylus-office-tx610fw-series_1.0.0-1lsb3.2_amd64.deb
  3. 安裝好之後,打開 Epson 印表機電源。然後執行印表機設定程式 (非 Unity:系統>管理>列印;Unity:點左上的 Ubuntu logo,輸入 printer 搜尋就會出現)
  4. 在印表機程式畫面點「加入」,再點「網路印表機」。一開始只會出現各種 protocol 的選項,稍等一兩分鐘之後,就會出現 Epson Stylus Office TX610FW 選項。點這個選項,再按「下一步」便會出現印表機的名稱設定,直接「套用」就完成了。
在 Ubuntu 上有一個好處:任何支援列印的程式,你都可以用「列印到檔案」的方式來產生 PDF 文件。我經常使用這項功能,但自從安裝 TX610FW 相關套件之後就有一個小麻煩:每次開啟列印的時候都要等很久。因為系統要讀 TX610FW 印表機的狀態,而我只有想列印的時候才會開這台印表機,所以只能等系統 timeout 放棄之後,我才能去選列印到檔案。

這問題有一個簡單的解法,就是新增一台假的本地印表機來當作預設印表機:
  1. 執行印表機設定程式,點選「加入」
  2. 序列埠 #1 > Generic > text-only printer > 輸入你想要的名稱
  3. 選這台剛新增的印表機,印表機 > 設為預設值
這樣下次開啟列印的時候就不會有等待的時間,你可以馬上選擇列印到檔案或 TX610FW。

2013/02/02

不用條件指令,找出兩數中的較大者

這是一個動腦用的程式設計題目,網路上有不少問答。我發現有不少人誤解「不用條件指令 (without conditional operator)」,這部份要用 assembly 的觀點來看比較清楚。簡單說,指令執行時不能有 branch 的動作,但 compare 是允許的。

錯的答案:
larger = max(a, b);
回答的人可能在搞笑。若 max() 符合要求,這個問題就是要問怎麼作到的。
larger = (a + b + abs(a - b)) / 2;
這個答案看起來有點學問,但本質跟前一個答案一樣,要依賴 abs() 的實作方法。另外,(a-b) 也有 overflow 的問題。
larger = (a > b) ? a : b;
這個不用解釋吧?這只是 if else 的變形,一樣是條件指令。
larger = a;
(void)((a < b) && (larger = b));
這個答案利用 short-circuit and 來決定是否令 larger = b,骨子裡一樣需要條件指令。
#include
unsigned d = b - a;
m = -(d >> (sizeof(int) * CHAR_BIT - 1));
larger = (a & m) | (b & ~m);
這個答案很用心,考慮到可攜性。但用到 b - a,就會有 overflow 的問題。

對的答案:
m = -(a > b);
larger = (a & m) | (b & ~m);
這個方法跟前一個接近,但不會有 overflow 的問題,看起來也清爽多了。小瑕疵是有前提:此計算機系統必須採用二的補數 (2's complement) 來表示有號數。但這個假設,目前「幾乎」都會成立。
larger = ((a ^ b) & -(a > b)) ^ b;
這個方法是前一個的再簡化版本,不是一眼可以懂,但乾淨俐落。同樣也有相同的前提。
larger = (a > b) * a + (a <= b) * b;
這個方法不需任何前提,但我不喜歡那兩個乘法。不知有誰可以改掉?
int p[] = { a, b };
larger = p[a < b];
這個方法除了需複製變數之外,其他都很完美。

組合兩個 bitmap 的方法

寫程式的時候,我們經常需要將兩個 bitmap 組合起來。譬如,取 A 的前三 bit 和 B 的後五 bit 組成一個新的 bitmap。通常我們會這麼寫:
M= 0xE0;
C = (A & M) | (B & ~M);
整理舊書時,看到以前唸大學時的筆記有另一個有趣的方法:
M = 0xE0;
C = ((A ^ B) & M) ^ B;
第二個方法沒那麼直覺,但可以省下一個 ~ 運算。

2013/01/11

變數內容對調的方法

一般我們都是用以下的方法來對調變數的內容:
int temp;
temp = var1;
var1 = var2;
var2 = temp;
今天學到一個有趣的新方法:
var1 ^= var2;
var2 ^= var1;
var1 ^= var2;
蠻酷的。


2012/12/04

自建 Ubuntu 的動態 Wallpaper

Ubuntu 真的好用,當然也有缺點。其中之一,就是想對桌面作一些調整時會比較麻煩。譬如,動態 Wallpaper 是既有的功能,但你想建立自己的版本,就要花一點心思。發行較久的 Ubuntu,可能已經有人開發 GUI 來簡化這個程序。但這套 GUI 又不見得可以適用於最新的 Ubuntu 發行版。我在 Ubuntu 12.10 就遇到這個問題。底下是我的解決方法。

首先,建立動態 wallpaper 的定義,譬如:~/wallpaper.xml:
<background>
  <starttime>
    <year>2003</year>
    <month>6</month>
    <day>14</day>
    <hour>05</hour>
    <minute>30</minute>
    <second>00</second>
  </starttime>
  <static>
    <duration>1795.0</duration>
    <file>/path/to/picture-1.png</file>
  </static>
  <transition>
    <duration>5.0</duration>
    <from>/path/to/picture-1.png</from>
    <to>/path/to/picture-2.png</to>
  </transition>
  <static>
    <duration>1795.0</duration>
    <file>/path/to/picture-2.png</file>
  </static>
  <transition>
    <duration>5.0</duration>
    <from>/path/to/picture-2.png</from>
    <to>/path/to/picture-1.png</to>
  </transition>
</background>
其中:
  • 可以是過去或未來。若是未來,就是等到那個時間才會更換 wallpaper;若是過去,設好就馬上生效。
  • 就是設定要顯示哪一個圖形?要顯示多少秒數?
  • 就是設定從一個圖形轉換到另外一個圖形要轉換多久?轉換到哪一個圖形?
  • 和 要成對出現,而且要設成可以頭尾連接。
Wallpaper.xml 設定檔完成之後,就要告訴系統以此作為 wallpaper:
gsettings set org.gnome.desktop.background picture-uri 'file:///path/to/wallpaper.xml'

2012/08/02

將 HTML 轉成 PDF 檔 (支援中文)

在 Ubuntu 上將 HTML 轉成 PDF 檔非常簡單。用 Firefox 或 Chromium 打開這個 HTML 檔 (或連上該網站),然後「列印至 PDF 檔案」即可。不過,你若在其他平台,或想自動完成這項工作,就比需要有其他工具了。

網路上這類工具還不少,不過不是安裝複雜就是不支援中文。在這裡推薦一套安裝簡單又好用的轉換工具,wkhtmltopdf。

安裝有多簡單?下載之後解開即可 (我只在 Ubuntu 上試過)。

有多好用?這類轉換工具對 HTML 檔的處理能力參差不齊,若加上需要支援中文,就更難找到讓人滿意的解決方案。但 wkhtmlpdf 是以 WebKit/QT 為核心,而 WebKit 是 Apple Safari 和 Google Chrome 的網頁處理器,所以處理能力毋庸置疑。

最簡單的執行範例:
wkhtmltopdf http://news.chinatimes.com/ news.pdf
若你想加上封面、頁首、頁尾等也可以,請自行參閱 wkhtmltopdf -H 的說明。

新版 Ubuntu 使用者注意事項

直接下載上述網頁編譯完成的 binary 在較新版本的 Ubuntu,譬如 12.04,似乎無法執行:
QSslSocket: cannot call unresolved function SSLv23_client_method4%
QSslSocket: cannot call unresolved function SSL_CTX_new
QSslSocket: cannot call unresolved function SSL_library_init
QSslSocket: cannot call unresolved function ERR_get_error
QSslSocket: cannot call unresolved function SSLv23_client_method
QSslSocket: cannot call unresolved function SSL_CTX_new
QSslSocket: cannot call unresolved function SSL_library_init
QSslSocket: cannot call unresolved function ERR_get_error
解決辦法是下載 source 自己編譯。不要擔心,編譯非常簡單:
$ sudo apt-get install qt4-dev-tools
$ wget http://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.11.0_rc1.tar.bz2
$ tar xvjf wkhtmltopdf-0.11.0_rc1.tar.bz2
$ cd wkhtmltopdf-0.11.0_rc1/
$ qmake && make
$ sudo apt-get make install

Keywords: html2pdf, html-to-pdf, web2pdf, web-to-pdf