02 February
2004

HTML2SafeHTML を XHTML対応(?)

先日のエントリで、COREBlog の XHTML対応 のような生意気なことを書いた。

ここで言いたかったのは、正しい XHTML は、すべてのエレメントに閉じタグが必要だと言う事。
たとえば、HTMLにおける、<br> タグは、<br></br> と記述するか、
<br /> と記述する必要がある。

原因は、stripogram/html2safehtml.py にあった。というよりも、safehtmlと言っている訳だから、これで良いのだ。safexhtmlを COREBlog が採用すべきなのである。

ということで、簡単なパッチを作ってみた。

(追記: 本日 9:40 patch の間違いを修正した。もし、9:40 以前に参考にされた方がいるなら、もう一度読み直していただきたい。)


以下の修正を、lib/python/Products/COREBlog/stripogram/html2safehtml.py に施す。

*** html2safehtml.py.org        Mon Feb  2 06:11:22 2004
--- html2safehtml.py    Mon Feb  2 09:00:11 2004
***************
*** 57,67 ****
              if tag not in self.never_close:
                  self.openTags.append(tag)

!             self.result = self.result + '>'

      def handle_endtag(self, tag):

          try:

              while tag != self.openTags[-1] and self.openTags[-1] in self.can_close:
                  self.openTags.pop()
--- 57,73 ----
              if tag not in self.never_close:
                  self.openTags.append(tag)

!             if tag in self.never_close:
!                 self.result = self.result + ' />'
!             else:
!                 self.result = self.result + '>'

      def handle_endtag(self, tag):

          try:
+
+             if tag in self.never_close:
+                 return

              while tag != self.openTags[-1] and self.openTags[-1] in self.can_close:
                  self.openTags.pop()

とりあえず、動いているみたいだが、しばらく様子を見ようと思っている。

パッチの意味

せっかくなので、簡単に説明しておこう。(非常に読みにくい文章だと思うので、ご注意を)

HTMLParse は XHTMLにも対応しており、<br /> のようなタグの場合、きちんと空のエレメントとして処理しようとしている。これが、HTMLParser::handle_startendtag メソッドだ。

    # Overridable -- finish processing of start+end tag: <tag.../>
    def handle_startendtag(self, tag, attrs):
        self.handle_starttag(tag, attrs)
        self.handle_endtag(tag)

一方、HTML2SafeHTMLのほうでは、handle_starttag メソッドがオーバーライドされていて、never_close リストに登録されたエレメントは、閉じタグを出力しないようにしている。(html2safehtml.py の 57行目)

            if tag not in self.never_close:
                self.openTags.append(tag)

また、self.never_close リストは、以下のようになっている。(html2safehtml.py の 15行目)

    never_close = ['br','wbr','hr','input','isindex','base','meta','img']

もう少し具体的に説明すると、閉じタグが必要なエレメントの場合、self.openTags リスト(スタック)に タグを登録しておき、handle_endtag (html2safehtml.py の 65行目) や、cleanup (html2safehtml.py の 78行目) で閉じタグを(openTagsスタックに登録されていれば)出力しているのだ。

そこで、never_close に登録されている タグは、全て <タグ /> のように出力するようにした。

これによって、handle_endtag で問題が発生する。問題の個所は、以下の部分である。(html2safehtml.py の 66行目)

            while tag != self.openTags[-1] and self.openTags[-1] in self.can_close:
                self.openTags.pop()

たとえば、<p>ほげほげ<br />はげはげ</p> の場合に、openTagsスタックに br エレメントが登録されていないため、openTagsスタックに登録されているpエレメントを pop してしまうのだ。これによって、pエレメントの閉じタグが出力されなくなる。

この問題点の対策として、私の作成した patch では、never_close に登録されたエレメントの場合、handle_endtagを処理しないようにした。

もう一点考えなければならないのは、<br></br> のようなケースだが、HTMLParser::handle_startendtag を呼び出す事と同じように、HTMLParser::handle_starttag, HTMLParser::handle_endtag が連続して呼び出される。従って、<br></br> は、<br /> のように変換される。今のところ、これは問題だとは思えないのでそのままにしておいた。

最後に注意

とりあえず、この patch をあてた状態では、正しい XHTMLしか処理できない。おかしな XHTMLを食わせた場合にはきちんとエラー処理をすべきだろう。この patch を参考にされる場合は、不具合などあればコメントいただきたい。

Posted by Satoshi at 07:30 | Comments (0) | Trackbacks (0) | このエントリーを含むはてなブックマーク
Comments
There is no comment.
Trackbacks
Please send trackback to:http://www.randynetwork.com/blog/32/tbping
COREBlog の XHTML対応 その後

とりあえず、Add Entry 時に、Body, Extend, Excerpt に正しい XHTML を入力したときにおかしなHTMLを吐き出してしまう問題は、HTML2SafeHTML を XHTML対応(?) のパッチで様子を見ようと思う。
あと、気...

Posted by: Satoshi's Blog at February 02,2004 09:43
XHTML & CSS 検証サービス

Plone のデフォルトフッターには、 W3C XHTML & CSS
検証サービスへのリンクが張られています。
そして、そのアイコンにマウスをかざすと、以下のような、宣伝をしてくれちゃいます。
 「このサイトは正しくXHTMLを使用しています」
 「このPloneサイトは正しくCSSを使用しています」
そんなわけで、W3C の XHTML & CSS の仕様に沿うように XHTML と CSS
の見直しをしました。 フッターにある W3C XHTML
アイコンをクリックすれば、リファラーをみて...

Posted by: Feel Fine! at June 17,2005 17:38
Post a comment