宋高僧傳 精校版 XML 轉 PDF 作業備忘

出自DILA Wiki

概述

以 Python 程式將宋高僧傳 XML 轉為 OpenOffice Writer ODT 檔格式,再使用 doPDF 軟體,於 OpenOffice 中以「列印」功能產生 PDF 檔。

以下文件中會列出 ODT XML 碼供程式設計師參考,如果您不是程式設計師,可以忽略這些 XML 語法。


頁首

我們希望使用標題文字做為「頁首」,OpenOffice Writer 也有這個功能,但是當標題文字裡含有 footnote 的註標時,這個註標也會出現在頁首,這不是我們要的,Microsoft Word 沒有這種問題,感覺像是 OpenOffice Write 的 bug。

取巧的方式是使用「標題1」做為頁首,但是將「標題1」的 font-size 設為 1pt,顏色設為白色,也就是讓「標題1」不會在內文區裡面出現,語法如下:

<style:style style:name="Heading_20_1" style:display-name="Heading 1" style:family="paragraph"
  style:parent-style-name="Heading" style:next-style-name="Text_20_body"
  style:default-outline-level="1" style:class="text">
  <style:paragraph-properties fo:margin-top="0" fo:margin-bottom="0" fo:break-before="page"/>
  <style:text-properties fo:color="#ffffff"
    fo:font-size="1pt" style:font-size-asian="1pt" style:font-size-complex="1pt"/>
</style:style>

專名號 (底線)

OpenOffice Writer 可以在人名、地名等專有名詞下加底線(專名號),但是離文字太近,影響閱讀,底線也太粗,又沒有功能可以調整文字與底線之間的距離與底線的粗細。 目前找到的方法不是很理想,但是可以暫時解決這個問題。

方法是將整個段落的文字位置都設為「上標」,「相對的字型大小」設為 100%,「上昇/下降值」設為 15%,在 ODT 檔裡面的 style.xml 設定語法如下:

<style:text-properties style:text-position="15% 100%">

這樣還不行,因為文字往上移了,但是底線也跟著往上移,沒有達成所要的效果。
取巧的方式是在人名旁邊加一個空格,這個空格也有底線,但是它的「字元位置」不是「上標」而是「標準」,這樣一來,底線就會因為這個空白被固定在下方,而不是跟著上標文字上移。
這樣文字與底線之間的距離就會拉開了,但是空格太大的話,視覺效果也不好,所以將這個空白的「寬度顯示比例」設為 10%,
另外,底線我們也覺得太粗,而這個空格的 font-size 會影響底線的粗細,所以設為 6pt,語法如下:

<style:style style:name="underline_space" style:family="text">
  <style:text-properties 
    style:text-position="0% 100%" 
    fo:font-size="6pt" 
    style:text-underline-style="solid" 
    style:text-underline-width="auto" 
    style:text-underline-color="font-color" 
    style:font-size-asian="6pt" 
    style:font-size-complex="6pt" 
    style:text-scale="10%"/>
</style:style>

這樣已經接近完成了,如果人名或地名沒有跨行的話就沒問題,如果跨行的話,還是有問題。
如果空白是加在人名的後面,那麼跨行後的人名底線是正確的,但是跨行前的人名底線又跟文字黏在一起了。
所以在每個人名、地名的前後都加上空白,這樣即使人名、地名跨行也沒問題了。
當然這是指人名、地名只跨兩行的情況,如果人名、地名跨三行,那就麻煩了,中間那一行因為沒有空格把底線固定在下方,文字就又會與底線黏在一起。
目前只能希望不會有這樣跨三行的人名、地名了!

另外也考慮到 Adobe Indesign 有功能可以調整底線與文字之間的距離,或許由 XML 轉為 Adobe Indesign 可以接受的格式也是一種可能性,不過目前還沒有在這方面多做測試。

缺字圖檔

OpenOffice Writer 可以插入 SVG 圖檔,但是目前我們使用 Inkscape 0.48.2 製作的 SVG 缺字圖檔,某些字在各種 Browser 都可以正確呈現,但是插入 OpenOffice Writer 之後卻不能正確呈現。原因不明。

目前暫時的解法是使用 Indesign 讀入該 SVG 缺字圖檔,再另存成 SVG,插入 OpenOffice Writer 就沒問題了。


在 margin 顯示文字

我們希望在 PDF 的 margin 顯示《宋高僧傳》的大正藏頁碼,方法是在 margin 插入一個文字方塊,然後在這個文字方塊裡填入頁碼(來自宋高僧傳 XML 檔),語法如下:

<draw:frame text:anchor-type="char" draw:z-index="0"
    draw:style-name="gr1" draw:text-style-name="P1"
    svg:width="2cm" svg:height="0.5cm" 
    svg:x="0cm" svg:y="0cm">
  <draw:text-box>
    <text:p text:style-name="P1"><text:span text:style-name="T1">這裡放大正藏頁碼</text:span></text:p>
  </draw:text-box>
</draw:frame>

人名、地名索引

OpenOffice Writer 有製作索引的功能,如果要將某個人名加入索引,方法是在內文區選取人名後,選功能表「插入」=> 「目錄與表格」=> 「項目」,並設定一個自訂目錄名稱,例如「persName」。

然後在檔案最後要放索引的地方選功能表「插入」=> 「目錄與表格」=> 「目錄與表格」=> 目錄 => 類型選剛自訂的目錄名稱「persName」。

但是它的格式還不夠我們的需求:

  • 我們希望索引能按漢語拼音排序;
  • 同一個人名如果出現多次,只列一次人名,然後將多個頁碼列在一起;
  • 根據該人名或地名的 ID 從 DDBC Authority Database 讀取相關資料顯示在索引裡;
  • 文本裡的人名如果與 Authority DB 的常名不同,則另立常名索引條目,並於別名索引條目顯示參照常名條目。

為了達成以上功能,作業要分多階段進行:

  1. 執行 x2odt.py 產生第一階段的 ODT 檔
  2. 以 OpenOffice Writer 開啟該 ODT 檔,更新目錄、索引,取得索引條目在內文裡出現的頁碼,另存新檔。
  3. 執行 odt-phase2.py 處理新的 ODT 檔,進行索引排序、加入 Authoriy DB 資料等工作。
  4. 再次以 OpenOffice Writer 開啟 ODT 檔,更新目錄,列印成 PDF。

Endnotes

宋高僧傳精校版加入許多珍貴的註解,這些註解在 PDF 是以 Endnotes 形式呈現在書末。OpenOffice Writer 雖然也有 endnotes 功能,但是我們加的註解有個特別的地方,同一條註解可能會在內文裡被多次參考到。例如 [01] 這條註解,通常在內文裡的註標 [01] 只會出現一次,但是在宋高僧傳精校版內文裡可能會出現多次,因為是解釋相同的事情。

所以就不能使用 OpenOffice 的 endnotes 功能了,而是由程式自己產生註標、註解。

5碼 Unicode (Surrogate)

「匯出成 PDF」問題

目前在 MS Windows 7 + OpenOffice 3.4.1 環境下,如果使用 OpenOffice「匯出成 PDF」的功能來產生 PDF 檔,含有 Surrogate 字元的 5碼 Unicode 不會正確呈現,所以退而求其次,使用「列印」功能。

一行之中兩個 5碼Unicode

如果一行之中有兩個5碼Unicode,第二個字會呈現不出來,必須指定「新細明體-ExtB」字型才出得來。

重音符號

如果要設定某一個5碼Unicode字元的重音符號,雖僅設定一個字,但是連該字元後面的字元也會出現重音符號。

使用 OpenOffice 排版出書的問題

ODT 不支援巢狀樣式繼承

子元素不會繼承父元素的樣式, 這是個麻煩的問題, 像這樣的 HTML:

<span class="style1">aaa</span>
<span class="style2">aaa</span>
<span class="style1">
  aaa<span class="style2">bbb</span>ccc
</span>

在 HTML 只要定義 style1, style2 這兩種樣式. 在 ODT 中就要三種樣式:

<text:span text:style-name="style1">aaa</text:span>
<text:span text:style-name="style2">bbb</text:span>
<text:span text:style-name="style1">aaa</text:span>
<text:span text:style-name="style3">bbb</text:span>
<text:span text:style-name="style1">ccc</text:span>

其中的 style3 要定義成同時包含 style1, style2. 這只是兩種樣式, 樣式一多就複雜很多!!

讚歎設計 CSS 樣式巢狀套疊的人, 你們真是太有智慧了!

OpenOffice 做不到的事

  • 控制底線與文字的距離
  • 控制底線的粗細