# Copyright (C) 2003-2005 Kouichirou Eto, All rights reserved.

$LOAD_PATH.unshift("../../compat") unless $LOAD_PATH.include?("../../compat")
require "htree"
$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
require "qwik/htree-get"

module Qwik
  class HtmlToWikiText
    def translate(text)
      h = HTree(text)
      parse_block(h)
    end

    def html_to_wabisabi(str)
      html = "<html>"+str+"</html>"
      htree = HTree(html)
      first_child = htree.children[0]
      wabisabi = first_child.to_wabisabi       #pp wabisabi
      wabisabi_child = wabisabi.inside         #pp wabisabi_child
      v = wabisabi_child.check_valid
      if v == true
	return wabisabi_child
      else
	return "can not use ["+v.to_s+"]"
      end
    end

    private

    def parse_block(elem)
      str = ""
      elem.each_child {|e|
	case e
	when HTree::Text
	  t = e.to_s
	  next if t == "\r\n" || t == "\n"
	  qp "What? "+e.class.to_s+" : "+e.to_s
	when HTree::Elem
	  str << parse_block_elem(e)
	else
	  qp "What? "+e.class.to_s+" : "+e.to_s
	end
      }
      str
    end

    SIMPLE_BLOCK = {
      "H2"=>["* ", "\n"],
      "H3"=>["** ", "\n"],
      "H4"=>["*** ", "\n"],
      "H5"=>["**** ", "\n"],
      "H6"=>["***** ", "\n"],
      "P"=>["", "\n\n"],
    }

    def parse_block_elem(e)
      n = e.element_name.to_s

      if SIMPLE_BLOCK[n]
	head, tail = SIMPLE_BLOCK[n]
	return head+parse_span(e)+tail
      end

      case n
      when "PRE"
	return parse_pre(e)
      when "BLOCKQUOTE"
	return parse_blockquote(e)
      when "PLUGIN"
	attr = e.attributes_str
	param = attr["param"]
	method = attr["method"]
	#data = e.text
	data = e.extract_text.to_s
	str = ""
	str << "{{"+method
	str << "("+param+")" if param && param != ""
	str << "\n"+data+"\n" if data && data != ""
	str << "}}\n"
	return str
      else
#	qp "What? "+e.class.to_s+" : "+e.to_s
	return ""
      end
    end

    def parse_pre(elem)
      str = ""
      elem.each_child {|e|
	str << " "+e.to_s+"\n"
      }
      str
    end

    def parse_blockquote(elem)
      str = parse_block(elem)
      str.map {|line|
	"> "+line
      }.join
    end

    def parse_span(elem)
      str = ""
      elem.each_child {|e|
	case e
	when HTree::Text
	  str << e.to_s
	when HTree::Elem
	  str << parse_span_elem(e)
	else
	  qp "What? "+e.class.to_s+" : "+e.to_s
	end
      }
      str
    end

    def parse_span_elem(e)
      n = e.element_name.to_s
      case n
      when "A"
	attr = e.attributes_str
	href = attr["href"]
	if href =~ /\A([A-Za-z0-9]+)\.html\z/
	  href = $1
	end
	#text = e.text
	text = e.extract_text.to_s
	str = ""
	str << "[["+text
	str << "|"+href if href != text
	str << "]]"
	return str
      when "IMG"
	attr = e.attributes_str
	src = attr["src"]
	return "[["+src+"]]"
      when "EM"
	return "''"+parse_span(e)+"''"
      when "STRONG"
	return "'''"+parse_span(e)+"'''"
      when "DEL"
	return "=="+parse_span(e)+"=="
      else
	qp "What? "+e.class.to_s+" : "+e.to_s
	return ""
      end
    end

  end
end

if $0 == __FILE__
  $LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
  require "test/unit"
  $debug = true
end

if $debug
  class TC_HtmlToWikiText < Test::Unit::TestCase
    def assert(e, text)
      trans = Qwik::HtmlToWikiText.new
      str = trans.translate(text)
      assert_equal(e, str)
    end

    def test_html_to_wikitext
      # test div
      assert("* h\n", "<H2>h</H2>")
      assert("** h\n", "<H3>h</H3>")
      assert("p\n\n", "<P>p</P>")
      assert("p\n\np2\n\n", "<P>p</P><P>p2</P>")
      #assert("", "<UL><LI>li</LI></UL>")
      #assert("", "<UL><LI>li1</LI><UL><LI>li2</LI></UL></UL>")
      #assert("", "<DL><DT>dt<DD>dd</DD></DL>")
      #assert("", "<DL><DT>dt1<DD>dd1><DT>dt2<DD>dd2</DD></DL>")
      assert("> 引用。\n> \n", "<BLOCKQUOTE><P>引用。</P></BLOCKQUOTE>")
      assert("> * h\n", "<BLOCKQUOTE><H2>h</H2></BLOCKQUOTE>")
      assert("> x\n> \n> y\n> \n", "<BLOCKQUOTE><P>x</P><P>y</P></BLOCKQUOTE>")

      # test span
      assert("Go [[FrontPage]].\n\n",
	     '<P>Go <A href="FrontPage.html">FrontPage</A>.</P>')
      assert("Go [[qwikWeb|http://example.com/]].\n\n", '<P>Go <A href="http://example.com/">qwikWeb</A>.</P>')
      assert("''強調''、'''さらに強調'''、==取り消し線==\n\n", '<P><EM>強調</EM>、<STRONG>さらに強調</STRONG>、<DEL>取り消し線</DEL></P>')
      assert("[[http://example.com/.theme/new.png]]\n\n", '<P><IMG alt=new src="http://example.com/.theme/new.png"></P>')
      assert("[[FrontPage]] [[Yahoo!|http://www.yahoo.co.jp/]]\n\n{{recent(1)}}\n", '<P><A href="FrontPage.html">FrontPage</A> <A href="http://www.yahoo.co.jp/">Yahoo!</A></P><PLUGIN param="1" method="recent"></PLUGIN>')

      s = <<'EOT'
<H2>FrontPage</H2>
<P>これは新規qwikWebサイトの入口となるページです。</P>
<H3>使い方</H3>
<P>ページの上の方にある「編集」というリンクをたどると、このページの編集モードになります。</P>
<P>表示されたテキストの内容を変更し、「Save」ボタンをクリックすると、このページの内容が変更されます。</P>
<H3>記述方法</H3>
<P>ページの内容はテキストで書かれており、いくつかの記号によって見出しなどの指定をします。詳しい情報は、<A href="TextFormat.html">TextFormat</A>をご覧下さい。</P>
<H3>qwikWeb</H3>
<P>詳しくは、<A href="http://example.com/">qwikWeb</A>ホームページをご覧ください。</P>
EOT

      org = <<'EOT'
* FrontPage
これは新規qwikWebサイトの入口となるページです。

** 使い方
ページの上の方にある「編集」というリンクをたどると、
このページの編集モードになります。

表示されたテキストの内容を変更し、「Save」ボタンをクリックすると、
このページの内容が変更されます。

** 記述方法
ページの内容はテキストで書かれており、
いくつかの記号によって見出しなどの指定をします。
詳しい情報は、[[TextFormat]]をご覧下さい。

** qwikWeb
詳しくは、[[qwikWeb|http://example.com/]]ホームページをご覧ください。
EOT

      e = <<'EOT'
* FrontPage
これは新規qwikWebサイトの入口となるページです。

** 使い方
ページの上の方にある「編集」というリンクをたどると、このページの編集モードになります。

表示されたテキストの内容を変更し、「Save」ボタンをクリックすると、このページの内容が変更されます。

** 記述方法
ページの内容はテキストで書かれており、いくつかの記号によって見出しなどの指定をします。詳しい情報は、[[TextFormat]]をご覧下さい。

** qwikWeb
詳しくは、[[qwikWeb|http://example.com/]]ホームページをご覧ください。

EOT

      assert(e, s)

      s = <<'EOT'
<H2>書式一覧簡易版</H2>
<P>詳細な説明は<A href="TextFormat.html">TextFormat</A>をごらんください。</P>
<H3>見出し2</H3>
<H4>見出し3</H4>
<H5>見出し4</H5>
<H6>見出し5</H6>
<UL>
<LI>箇条書レベル1
<UL>
<LI>箇条書レベル2
<UL>
<LI>箇条書レベル3</LI></UL></LI></UL></LI></UL>
<OL>
<LI>順序リスト1
<OL>
<LI>順序リスト2
<OL>
<LI>順序リスト3</LI></OL></LI></OL></LI></OL><PRE>整形済みテキスト。</PRE>
<BLOCKQUOTE>
<P>引用。</P></BLOCKQUOTE>
<DL>
<DT>Wiki
<DD>書き込み可能なWebページ
<DT>QuickML
<DD>簡単に作れるメーリングリストシステム</DD></DL>
<TABLE>
<TBODY>
<TR>
<TD>項目1-1</TD>
<TD>項目1-2</TD>
<TD>項目1-3</TD></TR>
<TR>
<TD>項目2-1</TD>
<TD>項目2-2</TD>
<TD>項目2-3</TD></TR></TBODY></TABLE>
<P><EM>強調</EM>、<STRONG>さらに強調</STRONG>、<DEL>取り消し線</DEL> <IMG alt=new src="http://example.com/.theme/new.png"> <A href="FrontPage.html">FrontPage</A> <A href="http://www.yahoo.co.jp/">Yahoo!</A></P><PLUGIN param="1" method="recent"></PLUGIN>
EOT

      org = <<'EOT'
* 書式一覧簡易版
詳細な説明は[[TextFormat]]をごらんください。
** 見出し2
*** 見出し3
**** 見出し4
***** 見出し5
- 箇条書レベル1
-- 箇条書レベル2
--- 箇条書レベル3
+ 順序リスト1
++ 順序リスト2
+++ 順序リスト3
 整形済みテキスト。
> 引用。
:Wiki:書き込み可能なWebページ
:QuickML:簡単に作れるメーリングリストシステム
,項目1-1,項目1-2,項目1-3
,項目2-1,項目2-2,項目2-3
''強調''、'''さらに強調'''、==取り消し線==
[[new|http://example.com/.theme/new.png]]
[[FrontPage]]
[[Yahoo!|http://www.yahoo.co.jp/]]
{{recent(1)}}
EOT

      e = <<'EOT'
* 書式一覧簡易版
詳細な説明は[[TextFormat]]をごらんください。

** 見出し2
*** 見出し3
**** 見出し4
***** 見出し5
 整形済みテキスト。
> 引用。
> 
''強調''、'''さらに強調'''、==取り消し線== [[http://example.com/.theme/new.png]]

{{recent(1)}}
EOT

      assert(e, s)

#    page = @site.create_new
#    str = "{{show_history}}"
#    page.store(str)
    end
  end
end
