天天看點

《重構HTML:改善Web應用的設計(修訂版)》——2.5 Tidy

本節書摘來自異步社群《重構html:改善web應用的設計(修訂版)》一書中的第2章,第2.5節,作者: 【美】elliotte rusty harold 更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

正規表達式對于獨立的自定義的修改來說确實不錯,但對于大量的修改來說難免乏味和困難。特别是,它們更大程度上是用來處理純文字的,而不是處理半結構化的html文本的。為了批量改變和自動修複常見的錯誤,需要有能識别html标記的工具。第一個這樣的工具是dave raggett的tidy,它是一個原創的html修複器。tidy作為一個簡單的多平台的指令行工具,可以用來修正大量的html錯誤。

2.5.1 -asxhtml

為了達到本書的目的,你需要使用-asxhtml指令行選項。例如,這個指令會把index.html轉化成一個良構的xhtml并把結果儲存到原檔案上(-m選項的作用)。

坦白地說,你有可能做出比在所有html檔案上運作一遍tidy就結束更糟糕的事,請不要停止繼續往下閱讀。tidy的有些選項能夠更好地改善代碼,但也有處理不了或者處理不當的地方。比如,當在一個我至少5年沒動過的頁面上使用-asxhtml指令時,産生的錯誤資訊如下所示:

這些問題tidy通常處理不了。它本應該提供doctype,因為我指定了xhtml這個已知的doctype模式。它也不知道該如何處理 bgcolor="#fffffff" ,這個問題源于一個應當删除的多餘的f,或者說整個bgcolor屬性應該删掉并使用css替換。

提示

一旦發現了類似的問題,那麼這個問題完全有可能出現在多個文檔中。一個檔案中出現的問題,就有必要在整個目錄樹中進行搜尋和替換,不要放過任何一個可能出現的地方。多用代碼的複制和粘貼,有些錯誤就隻會出現一次。

後面的兩個問題是缺少summary屬性的table。這是一個關于可通路性的問題,你應該修複它。tidy實際上還會列印出更多的細節:

表格摘要當然是好東西,并且你應該加上它。但tidy本身不能幫你做摘要,你需要自己來。

最後一個警告資訊是,tidy發現一個空的段落元素而且将它抛棄。這個常見問題可能是騙人的,絕對需要再檢查一遍。在這種情況下(你将看到的大部分情況也是如此),它指的是< p >标簽被當做結束标簽而不是起始标簽來使用。就是說,像這樣的标記:

tidy看成了這樣:

是以它把最後的空段落元素丢棄了。但幾乎可以肯定的是,你需要的代碼是這樣的:

這種問題很難搜尋和替換,盡管xhtml嚴格的驗證會至少警告你問題所發生的檔案。你可以使用xslt(稍後會讨論)來修正部分問題,但是問題不是太多的話,手工編輯這些檔案會更安全,而且也不見得很繁重。

如果指定--enclose-text yes選項,tidy會把所有未閉合的文本包裹到一個p元素中。比如:

tidy還能提醒你其他一些需要手工修複的嚴重問題,包括:

屬性值漏掉了右引号,如< p id="c1>;

漏掉了閉合标簽的>,如< p或 p ;

拼錯的元素和屬性名,如把< table >寫成了< tabel >。

2.5.2 -clean

另一個重要的選項是-clean。它把如i和font等廢棄的表現性元素替換為css标記。比如當我在相同的文檔上使用-clean時,tidy為我的檔案添加下面這些css規則:

同時也為之前使用了center的元素加上了必要的class屬性。比如:

tidy處理css隻能做到這一步,但你還是可以重新審視這些檔案,看是否能提取一個通用的外部檔案供網站文檔共享,而不是在每個單獨的頁面都引入這些css規則。更進一步說,你應該考慮使用一些語義更清楚的類名稱取代tidy那些多少有些平凡的預設名稱。

比如,有時我使用i元素來指明我談論而不是使用某個詞,比如:

這裡斜體并不表示強調,是以使用em來替換并不合适。相反應該替換為一個帶class的span,像這樣:

接着,為樣式表添加一條css規則,使它變為斜體樣式:

雖然tidy不可能聰明到這個地步,它需要你的幫忙才行,但它終究是一個不錯的開始。

2.5.3 編碼

令人吃驚的是,tidy不善于檢測html文檔的字元集編碼,盡管大部分html文檔相對豐富的中繼資料都精确地指出了編碼。如果你的内容不是ascii或iso-8859-1(latin-1),你最好使用--input-encoding選項告訴tidy文檔的編碼。比如要把文檔儲存為utf-8編碼,可以這樣運作tidy:

不指定編碼的話,tidy預設生成的是ascii文本。如果可以,它會把非ascii字元轉義為指定的實體符号,否則轉為數字字元。雖然tidy支援多種常見的編碼,但我隻推薦utf-8。使用--output-encoding選項能實作這個目的:

輸入的編碼可以跟輸出的不一緻。然而如果想要一緻的編碼,隻需指定-utf8選項:

從多個方面綜合考量,我強烈建議使用ascii或utf-8編碼,因為其他編碼不能保證文檔在不同作業系統和語言環境下能夠可靠地遷移。

2.5.4 整潔的格式

tidy當然還有很多不會對html本身産生修改的選項,它們能讓文檔看起來更整潔,進而使文本編輯器中代碼的編輯更容易。

-i選項會縮進文本,這樣就可以容易地看到元素的嵌套層次。tidy足夠聰明,不會縮進那些空白是有效的元素,比如pre元素。

-wrap選項會以指定的列數限制文本,通常80列左右比較合适:

2.5.5 生成的代碼

tidy對運作在php、jsp和asp等技術上的頁面的支援是有限的。基本上,它會忽略php、asp或jsp部分中的内容,隻能對剩下的html标記作處理。但這非常麻煩,特别是大部分的模闆系統并不會注意元素邊界。如果代碼生成的是半個元素,或者隻是一個起始标簽,而又在最後使用文本标簽來結束,就能把tidy搞迷糊。我并不推薦直接在這些頁面上使用tidy。

相反,從網站上下載下傳經過模闆引擎處理的已經顯示完畢的頁面,在這些抽樣頁面上運作tidy,然後把結果跟原有頁面進行比較。通過觀察差別所在,通常可以找出模闆中需要修改的地方,然後手工完成這些修改。

雖然這不需要更多的手工勞動和腦力,但如果是由一個模闆負責生成多個靜态頁面的話,比起大量靜态html頁面的半自動化處理來,這個過程更迅速。

2.5.6 當做庫來用

tidylib是tidy的c庫版本,你可以将它內建到你的程式中。例如,這對編寫處理整站的腳本來說是有用的。但從我個人角度看來,對于簡單腳本來說c并不是很友善。我通常是編寫shell或perl腳本直接調用tidy的指令行。