Tue, 23 Feb 1999 21:56:04 +0900 頃の
   Mail-Count: 5538
      Subject: [ruby-dev:5538] Re: SimpleHtmlParse (Re: htmltree.rb)   
についてのお話にて Shin-ichiro Hara さん曰く… 
(S == Shin-ichiro Hara <sinara / blade.nagaokaut.ac.jp> さん)

|おお. 利用してもらってる(^_^)

In article 5538, <199902231256.VAA01564 / blade.nagaokaut.ac.jp>
S> いやあ、便利なものですね。作る方は大変でしょうが。

そう言っもらえると, たいへんうれしいです. 
# しょせん力業なんで作るのはそう大変ではないかも.

|ちなみにインタフェースについてはどんなものでしょうか?
S> 最初、コメントが "-" という名前のタグになっていたのがちょっと
S> 戸惑いましたが、あとは分かりやすかったですよ。

これは主にドキュメントがないせいですね. すいません. 

|Perl の HTML:Parser みたくコールバック的にするのも
|(その方が)よいかな〜なんて思ってみてるんですが. 
S> Perl の事はすっかり忘れちゃったなあ。(^^;

Perl の HTML::Parser は

        open(F, "foo.html") || die;
        $p->parse_file(\*F);

とすると $self->start($tag, $attr, $attrseq, $origtext) のようなのが
よばれるようです(英文を読みちがえてるかも ^_^;).
# でもこのあたりは htmltree.rb には影響ないようですね. 

In article 5489, <199902221722.CAA20756 / blade.nagaokaut.ac.jp>
S> --- simplehtmlparse.rb~	Mon Feb 22 16:11:07 1999
S> +++ simplehtmlparse.rb	Mon Feb 22 16:10:59 1999
S> @@ -238 +238 @@
S> -      tag_string.sub!(/^(\/?)([-!a-z]+)\s*(.*?[^<>]?)$/io, '\3')
S> +      tag_string.sub!(/^(\/?)([-!a-z0-9]+)\s*(.*?[^<>]?)$/io, '\3')

こっちは完全にミスです. 取り込ませてもらいました. 

S> @@ -264 +264 @@
S> -	attribute[nil] = tag_string
S> +	attribute[tag_string] = ""
…
S> いや、後者は意図的なものだったのかも...

こっちは多分, 意図的なものですね. 
でも, 現状うまくないようなので

  attribute[''] = tag_string

としてみました. (tag_string は不定なのでその方がよいかな? と)


んで, いろいろいじったので
うまく動くとよいな〜と思いつつ, 

  <URL:ftp://arika.org/pub/Tools/Ruby/SimpleHtmlParse.19990224.tar.gz>

なんてのを置いてみました. ちと長くなりますが README をつけます:
------------------------------------------------------------------------------
*簡易* HTML 解析ライブラリ

☆概要

基本的には「タグ」とそうでない部分を切り分けられるだけです. 

リンクチェッカーや単純な Web ロボットを作るのには
役立つのではないかとおもいます(というかそのために作ったので)が, 
たとえば, これを元に文法チェッカーを作ろうなんてのには
まだ結構しんどくて長い道程が待っているでしょう :-)


☆使い方

  t = SimpleHtmlParse.new(io) {|name, begin_end, attribute, orig_text|
    …
  }

  t = SimpleHtmlParse.new(io)
  t.each {|name, begin_end, attribute, orig_text|
    …
  }

  SimpleHtmlParse.foreach(io) {|name, begin_end, attribute, orig_text|
    …
  }

IO または File である io を読んで, それを解析します. 
与えられたブロックは解析の結果えられた個々の部品について
実行されます. この場合の部品と言うのは開始タグ(<FOO ...>), 
終了タグ(</FOO>), コメントの開始(<!--), コメントの終了(-->), 
それから通常のテキストを指します. 

これらの種別は name の値によって判別できます. 

  SimpleHtmlParse::COMMENT
    コメントの開始または終了
  SimpleHtmlParse::BANG
    DTD 宣言など(<!...>)
  SimpleHtmlParse:  :NULL
    単独の '<', '>' や '<>'
  それ以外
    タグ名を大文字にしたもの. 

また, 開始タグか終了タグかは begin_end の値で判別できます. 

  SimpleHtmlParse::TAG_BEGIN 開始
  SimpleHtmlParse::TAG_END   終了

attribute には(開始)タグにあるアトリビュートがハッシュとして格納され, 
orig_text には対象部分の元々のテキストが格納されています. 
ハッシュの中のアトリビュート名はすべて大文字になっています. 


次のような使い方も可能です. 

  t = SimpleHtmlParse.new(io)
  def t.begin_tag(name, attribute, orig_text)
    …
  end
  def t.end_tag(name, attribute)
    …
  end
  def t.text(orig_text)
    …
  end
  t.parse

このような場合には解析の結果見つかった部品に
応じたメソッドが呼び出されます. 

  開始タグ  begin_tag(name, attribute, orig_text)
  終了タグ  end_tag(name, orig_text)
  テキスト  text(orig_text)

これらのメソッドは標準的には定義されていませんので
用途に応じて定義してください. 

また, もしも SimpleHtmlParse.comment(comment, orig_text) が
定義されていればコメントと思われる部分については
同メソットが呼び出されます. 


SimpleHtmlParse オブジェクトを生成した場合
さらに以下のメソッドが提供されます. 

  author       <META NAME="author" ... CONTENT="…">
  base         <BASE HREF="…">
  content      ブロックの返り値の配列
  description  <META NAME="description" ... CONTENT="…">
  keywords     <META NAME="keywords" ... CONTENT="…">
  made         <LINK REV="made" ... HREF="…">
  robots       <META NAME="robots" ... CONTENT="…">
  title        <TITLE>…</TITLE>

また, すべての解析に先立って SimpleHtmlParse.pre_process(line) が
呼び出されます. line には io から読み込んだ内容が渡されます. 
解析はこのメソッドの返り値に対して行われます(orig_text の内容も
このメソッドの返り値をもとにしたもの). 
主な用途は文字コード変換になるでしょう. 

  require 'nkf'
  def SimpleHtmlParse.pre_process(line)
    return Nkf::nkf('-e', line)
  end
------------------------------------------------------------------------------

かなり日本語があやしいです. すいません. おいおい直しますんで. 

# 落ち着いたら contrib/ にいれてもらおう. 
-- 

 やまだ あきら <URL:http://arika.org/>
 (akira / arika.org or akira / nurs.or.jp)