# $Id: formatter.rb,v 1.5 2004/04/22 02:37:45 eto Exp $
# Copyright (C) 2002-2003 TAKEUCHI Hitoshi <hitoshi@namaraii.com>
# imported from Hiki, modified by Kouichirou Eto 2003-2004

require 'qwik/util'

module Hiki
  class HTMLFormatter
    MAP = {}
    MAP[:heading1_open]        = '<h2>'
    MAP[:heading1_close]       = '</h2>'
    MAP[:heading2_open]        = '<h3>'
    MAP[:heading2_close]       = '</h3>'
    MAP[:heading3_open]        = '<h4>'
    MAP[:heading3_close]       = '</h4>'
    MAP[:heading4_open]        = '<h5>'
    MAP[:heading4_close]       = '</h5>'
    MAP[:heading5_open]        = '<h6>'
    MAP[:heading5_close]       = '</h6>'
    MAP[:horizontal_rule]      = '<hr />'
    MAP[:unordered_list_open]  = '<ul>'
    MAP[:unordered_list_close] = '</ul>'
    MAP[:ordered_list_open]    = '<ol>'
    MAP[:ordered_list_close]   = '</ol>'
    MAP[:listitem_open]        = '<li>'
    MAP[:listitem_close]       = '</li>'
    MAP[:blockquote_open]      = '<blockquote>'
    MAP[:blockquote_close]     = '</blockquote>'
    MAP[:definition_list_open] = '<dl>'
    MAP[:definition_list_close]= '</dl>'
    MAP[:definition_term_open] = '<dt>'
    MAP[:definition_term_close]= '</dt>'
    MAP[:definition_desc_open] = '<dd>'
    MAP[:definition_desc_close]= '</dd>'
    MAP[:pre_open]             = '<pre>'
    MAP[:pre_close]            = '</pre>'
    MAP[:p_open]               = '<p>'
    MAP[:p_close]              = '</p>'

    MAP[:p_enhance_open]       = '<p class="enhance">'
    MAP[:p_enhance_close]      = '</p>'
    MAP[:p_short_open]         = '<p>'
    MAP[:p_short_close]        = '</p>'
    MAP[:div_center_open]      = '<div class="center">'
    MAP[:div_center_close]     = '</div>'

    MAP[:emphasis_open]        = '<em>'
    MAP[:emphasis_close]       = '</em>'
    MAP[:strong_open]          = '<strong>'
    MAP[:strong_close]         = '</strong>'
    MAP[:delete_open]          = '<del>'
    MAP[:delete_close]         = '</del>'
    MAP[:table_open]           = '<div class="table"><table>'
    MAP[:table_close]          = '</table></div>'
    MAP[:table_row_open]       = '<tr>'
    MAP[:table_row_close]      = '</tr>'
    MAP[:table_data_open]      = '<td>'
    MAP[:table_data_close]     = '</td>'

    def initialize(tokens)
      @tokens = tokens
    end

    def flush_normal_text(text, pre)
      return text + "\n" if pre
      text
    end
    private :flush_normal_text

    def to_s
      html        = ''
      normal_text = ''
      pre         = false

      @tokens.each {|t|
	if (normal_text.size > 0 && t[:e] != :normal_text)
	  html << flush_normal_text(normal_text.chomp, pre)
	  normal_text = ''
	end
	case t[:e]
	when :normal_text
	  if pre
	    html << "#{t[:s].escapeHTML}\n"
	  else
	    normal_text << "#{t[:s].escapeHTML}"
	  end
	when :reference
	  s, href = t[:s], t[:href]
	  html << %Q!<a href="#{href}">#{s.escapeHTML}</a>!
	when :bracketname
	  s, href = t[:s], t[:href]
	  html << %Q!<a href="#{href.escape}.html">#{s.escapeHTML}</a>!
	when :interwiki
	  wiki, page, text = t[:href], t[:p], t[:s]
	  html << %Q!<interwiki wiki='#{wiki}' page='#{page}'>#{text}</interwiki>!
	when :empty
	  html << "\n"
	when :heading1_open, :heading2_open, :heading3_open, :heading4_open, :heading5_open
	  html << %Q!#{MAP[t[:e]]}!
	when :heading1_close, :heading2_close, :heading3_close, :heading4_close, :heading5_close
	  html << "#{MAP[t[:e]]}\n"
	when :image
	  html << %Q!<img src="#{t[:href]}" alt="#{t[:s].escapeHTML}" />!
	when :plugin, :inline_plugin
	  method = t[:method]
	  param  = t[:param]
	  data   = t[:data]
	  data = "" if data.nil?
	  html << %Q!<plugin method="#{method}" param="#{param}">#{data.escapeHTML}</plugin>!
	else
	  if t[:e] == :pre_open
	    pre = true
	  elsif t[:e] == :pre_close
	    pre = false
	  end

	  html << "#{MAP[t[:e]]}"
	  if [:emphasis_close, :strong_close, :delete_close].index(t[:e]) == nil and
	    /_close\z/ =~ t[:e].to_s
	    html <<  "\n"
	  end
	end
      }
      if (normal_text.size > 0)
	html << flush_normal_text(normal_text.chomp, pre)
      end
      html
    end
  end
end
