天天看點

關于docbook sgml的中文字元支援

最近在參與PostgreSQL中國社群的文檔中文化。PG的文檔是一堆基于docbook的sgml檔案。這些sgml可以通過工具轉成html,pdf等各種不同格式。

這即是docbook所倡導的“内容和格式的分離”。然而當我嘗試把翻譯好的一個sgml檔案用openjade轉成html時,發現openjade報一堆類似的錯誤:"non SGML character number nnn"。

針對這一問題,經過調查,得到下面這些線索。

類似于xml的 <?xml version="1.0" encoding="UTF-8" ?>,sgml也可以指定字元集,但形式上要複雜的多。

以下是docbook 4.2預設的字元集定義:

docbook.dcl

...

    BASESET

  "ISO 646:1983//CHARSET International Reference Version (IRV)//ESC 2/5 4/0"

    DESCSET

                    0 9 UNUSED

                    9 2 9

                   11 2 UNUSED

                   13 1 13

                   14 18 UNUSED

                   32 95 32

                  127 1 UNUSED

  "ISO Registration Number 100//CHARSET ECMA-94 Right Part of Latin Alphabet Nr. 1//ESC 2/13 4/1"

                  128 32 UNUSED

                  160 96 32

在上面标有"UNUSED"的code範圍的字元為非法字元,遇到這些字元sgml解釋器就會報錯:"non SGML character number nnn"。

這也就是前面提到的錯誤的原因。

http://www.postgresql.org/message-id/[email protected]

we cannot use UTF8 because SGML Docbook

        does not support it

          http://www.pemberley.com/janeinfo/latin1.html#latexta

我一開始沒充分了解它的含義,我以為它絕了中文字元在sgml中出現可能性,我覺得這不太可能,于是沒有太理會。

linux 中文doc計劃使用字元替換的方式回避中文字元問題。

http://www.linux.org.tw/CLDP/OLD/zh-sgmltools-1.html

套件中包含一工具程式 mb2a, 可自標準輸入或檔案中讀取資料,將其中的 BIG5 或 GB 字元編碼成 @=XXXX 

的形式,其中 XXXX 就是該字的 BIG5 或 GB 碼。 這個程式同時也能將這種編碼的資料予以解碼。

我相信這個方法一定可以回避中文不能識别的問題,但我覺得這個方法有點土,應該有更優雅的方法。

而且我查到的資料比較老了,也許他們現在也不這麼幹了。

看到有日本人嘗試使用環境變量SP_ENCODING=utf-8,加上包含日文字元集自定義SGML聲明實作轉換,但是對某些SP_ENCODING=utf-8 處理不了的字元仍然會出錯。

http://listserv.linux.or.jp/pipermail/vine-users/2010-October/000330.html

環境変數 SP_ENCODING に utf-8 をセットして,

添付ファイルを文書型(DOCTYPE)が書いてある

ファイルの先頭に挿入すると,日本語で書いてある

UTF-8のDocBook SGML文書をjadeで処理できました.

いくつか警告が表示されます.またリリースノートなどに

書いてある人名のいくつかに SP_ENCODING=utf-8 では

扱えない文字があるようです.その部分を直さないと日本語の

有無に関わらず"非SGML數字"と表示されてエラーになりました.

japan-docbook.dcl

CHARSET

BASESET

"ISO Registration Number 1//CHARSET C0 set of ISO 646//ESC 2/1 4/0"

DESCSET 0 9 UNUSED

     9 2 9

     11 2 UNUSED

     13 1 13

     14 18 UNUSED

"ISO Registration Number 14//CHARSET ISO 646 Japanese Version//ESC 2/8 4/10"

DESCSET

32 95 32

127 1 UNUSED

"ISO Registration Number 87//CHARSET JIS X 0208-1990//ESC 2/6 4/0 ESC 2/4 4/2"

41344 33 UNUSED

41377 94 8481

這個方法似乎是一條不錯的思路。我做了些嘗試,試圖修改字元集的定義去欺騙openjade,最終發現這不太容易(也許這條路可行,誰知道呢?)。

最後的最後,無意中用GBK編碼(之前一直使用UTF8編碼)的sgml檔案嘗試,驚訝的發現openjade居然安靜地完成了到html的轉換。

什麼個情況?再研究一下GBK的字元集定義,發現了其中的奧秘。

GBK的編碼範圍見下表,其中的GBK/1和GBK/2水準的漢字,即GB 2312-80用通常方法編碼的區域,

正好落在docbook預設字元集的合法編碼範圍内。是以在GBK編碼下這部分漢字會被openjade誤以為是合法的擴充ACSII碼,而欣然接受。

但是其他漢字就唬弄不了openjade了。幸運的是我們常用的漢字都在GBK/1和GBK/2(或者說gb2312)範圍内,GBK相對于gb2312擴充的

漢字沒那麼常用,比如繁體字。至少對于PG文檔的中文化,這些漢字應該夠用了。

GBK的編碼範圍:

範圍

第1位元組

第2位元組

編碼數

字數

水準 GBK/1

A1–A9

A1–FE

846

717

水準 GBK/2

B0–F7

6,768

6,763

水準 GBK/3

81–A0

40–FE (7F除外)

6,080

水準 GBK/4

AA–FE

40–A0 (7F除外)

8,160

水準 GBK/5

A8–A9

192

166

使用者定義

AA–AF

564

F8–FE

658

A1–A7

672

合計:

23,940

21,886

問題算是解決,翻好的sgml檔案使用GBK(或gb2312)編碼而不是utf8存檔,隻要是gb2312編碼範圍内的字元都沒有問題。

到此我突然明白了日本PG社群翻譯後的sgml檔案為什麼是euc_jp編碼而不是sjis或utf8,原來他們也是這麼幹的呀!

此外,最新的docbook5.0已經隻有xml格式了,也許什麼時候pg社群也會與時俱進放棄sgml改用xml。

我們知道xml要支援不同編碼很容易,如果使用xml格式的docbook的話,中文字元的支援就簡單了。

http://xml.coverpages.org/wlw11.html

http://zh.wikipedia.org/wiki/GBK

http://www.worldhello.net/doc/docbook_howto/

http://www.study-area.org/tips/docw/docwrite.html

繼續閱讀