UTF8 與 BIG5 的戰爭
用 Movable Type 架起來的新站已經兩個多月了, 雖然阿爽日記的運作還算順, 但是 MT 裡面有很多功能我都還沒有仔細去研究.
前幾天發現 MT 有匯入匯出的功能 (為了方便老婆使用, 裝了一個從簡體翻過來的中文語系檔, 結果 “import” 變成 “導入”…), 決定來試試把舊版寶寶日記的內容匯到阿爽日記裡, 然後把 Web Diary Pro 的那支 CGI 關掉. 現在駭客滿街都是, 多留一隻 CGI 就多一分風險, 再加上舊版寶寶日記已經很久沒有去動它了, 萬一哪一天被駭, 貼滿了色情圖片, 我也許要三個月後才會發現…
看了一下 Web Diary Pro 的工作目錄, 裡面有有一個叫 DIARY.LOG 的檔案, 所有的文章跟回應都存在這個檔裡. 用 UltraEdit看了一下, 格式不難懂, 其實是類似 tab split 的文字檔, 用 CHR(09) 分隔各欄位, 而用 LF 分隔各筆資料. 文章內容包含了
html tag 做為分行, 因此沒有 LF 混在裡面.
再看了一下 MT 3.2 的手冊, 裡面有一章是說明 import 時需要的檔案格式, 其實也不難, 各文章間以 ——– 加 LF 分開, 如果有多行的內容, 就用 —– 加 LF 分開, 而資訊欄位像作者, 標題等, 也有特定的語法.
搞懂格式後, 就可以來動工了. 用 VB6 寫了一隻小程式, 把 DIARY.LOG 的內容逐筆轉到一個字串陣列中, 再用 PRINT #x 的方法, 照著 MT 需要的格式輸出到另一個文字檔.
中間還遇到一個 Unix time stamp 格式轉換的問題: Web Diary Pro 的 post 只有日期, 但是 reply 有日期也有時間, 因此存在 DIARY.LOG 中時, post 是直接存日期的文字格式, 但是 reply 會存 Unix time stamp, 就是一個 10 位數, 看起來莫名其妙的數字, 是 Unix 上計時的標準格式. 在丟進 MT 前, 要把這個 time stamp 轉成文字格式的日期.
VB 的字串處理功能實在強得沒話說, 光是一個 INSTR() 就讓我遇到字串的時候打死都不會想用 C 去處理.
做好第一個測試檔, 用 ftp 傳到鳥站上要做測試時, 發現 MT 對這個明明照它要求做出來的檔案一點反應都沒有. 30 秒後, 我想到是 CR+LF 的問題了. 在 Windows 下做出來的文字檔, 斷行的時候有 CR 跟 LF, 但是 Unix 上只用 LF. 怎麼辦呢 ? 還好 UltraEdit 有 DOS->UNIX 轉碼的功能, 它會自動幫你把多出來的 CR 拿掉只留 LF.
把我的程式轉出來的文字檔用 UltraEdit 轉過後, 再用 FTP 的 binary 模式傳到鳥站上. 從 MT 裡 import 試試, 成功了耶!
不過… 中文都變成亂碼了.
原來我在把 Web Diary Pro 做中文化的時候, 網頁的 code page 設的是 BIG5 (因為原來的作者設的是 Shift-JIS, 改成 BIG5 最接近原來的行為), 因此在舊版寶寶日記中輸入的東西, 都會被 IE 根據網頁編碼的規則轉成 BIG5, 因此 DIARY.LOG 裡存的中文都是 BIG5 編碼. 這也就是為什麼一些 Windows XP 裡多出來的怪字, 在寶寶日記中仍然打不出來的原因. 而 MT 用的是 UTF8 型式的 Unicode, 所以我在日本遊記中可以混著打入一些日文的假名, 這在舊版寶寶日記是做不到的.
UltraEdit 居然也有 ASCII->UTF8 的轉碼功能:
用這個功能轉過後, 再丟上鳥站去 import, 中文就正常了. 不過在鳥站的 Linux 環境下, 用 vi 直接去開 UTF8 的文字檔時, 看到的都是亂碼. 因為 RedHat 裝中文的套件時, 用的還是 BIG5 編碼. 不知道新的 Linux 有沒有 Unicode 支援了呢 ?
為了這個問題, 我找了一大堆資料, 徹底的把 Unicode 的歷史好好了解一番, 也終於知道 UTF8 跟 Unicode 的關係. Windows XP 的 Unicode 核心真的蠻了不起的, 可以在我們完全不查覺得狀況下, 在各種不同語系的網頁間切來切去. 我終於知道為什麼在 Google 中用注音輸入法打中文, 可以搜尋日文網站的原因了… 偉哉 Unicode!
***
故事到這裡就結束了嗎 ? 才沒這麼簡單, 不然怎麼會花掉我兩天的時間… 第一次 import 進去後覺得沒問題, 再仔細看看後, 發現所有 import 進去的文章, 回應都連結到同一個頁面. 仔細研究後, 發現 MT 把 import 進去的所有文章 basename 都設成一樣的.
Basename 是 MT 3.2 引入的一個新功能, 它會自動根據文章的標題產生看起來比較有意義的檔名, 用來取代以前那種序號式的檔名. 我試了一下, 用像 “IVY School 的活動” 這種標題, 會自動產生 “IVY_SCHOOL.HTML” 這樣的檔名, 但是如果是第一個字就是中文的標題, 就會變成像 post_xx.html 這樣的命名.
不知道怎麼搞的, MT 在 import 時, 把所有的文章的 basename 都設成同一個, 因此在匯整的時候, 只有第一篇可以產生有效的連結, 後面的文章因為 basename 重覆, 都沒有辦法產生單篇匯整的 html 檔, 導致按月跟分類匯整的頁面也都不正確.
這個問題也搞了我好久, 最後的解決方法是… 在單篇匯整的檔名命名規則中, 加入 mm-dd 這樣的字首, 讓每篇文章的 basename 都保證會不一樣.
Anyway, 終於把舊版寶寶日記匯入成功.
原來我們已經幫阿爽寫了三百多篇日記了, 還蠻有成就感的說!
近期留言