# $Id: html_formatter.rb,v 1.5 2003-02-23 02:20:08 hitoshi Exp $ # Copyright (C) 2002-2003 TAKEUCHI Hitoshi require 'hiki/util' require 'hiki/interwiki' module Hiki class HTMLFormatter MAP = Hash::new MAP[:heading1_open] = '

' MAP[:heading1_close] = '

' MAP[:heading2_open] = '

' MAP[:heading2_close] = '

' MAP[:heading3_open] = '

' MAP[:heading3_close] = '

' MAP[:heading4_open] = '
' MAP[:heading4_close] = '
' MAP[:heading5_open] = '
' MAP[:heading5_close] = '
' MAP[:horizontal_rule] = '
' MAP[:unordered_list_open] = '' MAP[:ordered_list_open] = '
    ' MAP[:ordered_list_close] = '
' MAP[:listitem_open] = '
  • ' MAP[:listitem_close] = '' MAP[:blockquote_open] = '
    ' MAP[:blockquote_close] = '
    ' MAP[:definition_list_open] = '
    ' MAP[:definition_list_close]= '
    ' MAP[:definition_term_open] = '
    ' MAP[:definition_term_close]= '
    ' MAP[:definition_desc_open] = '
    ' MAP[:definition_desc_close]= '
    ' MAP[:pre_open] = '
    '
        MAP[:pre_close]            = '
    ' MAP[:p_open] = '

    ' MAP[:p_close] = '

    ' MAP[:emphasis_open] = '' MAP[:emphasis_close] = '' MAP[:strong_open] = '' MAP[:strong_close] = '' MAP[:delete_open] = '' MAP[:delete_close] = '' def initialize( s, db, plugin, suffix = 'l') @tokens = s @db = db @plugin = plugin @suffix = suffix @toc_cnt = 0 @toc = Array::new @references = Array::new @interwiki = InterWiki::new( @db ) end def HTMLFormatter::diff ( d ) s = '' d.each do |l| lines = l[2] case l[0] when :+ s << "#{lines.join.escapeHTML}\n" when :- s << "#{lines.join.escapeHTML}\n" end end s end def to_s html = '' toc_level = 0 toc_title = '' normal_text = '' pre = false @tokens.each do |t| if (normal_text.size > 0 && t[:e] != :normal_text) normal_text.chomp! html << normal_text html << "\n" if pre normal_text = '' end case t[:e] when :normal_text if pre html << "#{t[:s].escapeHTML}\n" else normal_text << "#{t[:s].escapeHTML}" toc_title << t[:s] if toc_level > 0 end when :reference html << %Q!#{t[:s].escapeHTML}! toc_title << t[:s] if toc_level > 0 when :wikiname if @db.exist?( t[:s] ) html << "#{t[:s].escapeHTML}" @references << t[:s] else html << "#{t[:s].escapeHTML}?" end toc_title << t[:s] if toc_level > 0 when :interwiki html << @interwiki.interwiki(t[:href], t[:s]) when :empty html << "\n" when :heading1_open, :heading2_open, :heading3_open, :heading4_open, :heading5_open toc_level = t[:lv] html << %Q!#{MAP[t[:e]]} ! when :heading1_close, :heading2_close, :heading3_close, :heading4_close, :heading5_close add_toc( toc_level, toc_title ) toc_level = 0 toc_title = '' html << "#{MAP[t[:e]]}\n" when :image html << %Q!#{t[:s].escapeHTML}! when :plugin, :inline_plugin tag = ( t[:e] == :plugin ) ? 'div' : 'span' begin s = call_plugin_method( t ) if s.class == String html << %Q!<#{tag} class = "plugin">\n! html << s html << "\n" end rescue Exception html << plugin_error( t[:method], $! ) end else if t[:e] == :pre_open pre = true elsif t[:e] == :pre_close pre = false end html << "#{MAP[t[:e]]}\n" end end html end def references @references.uniq end def toc s = "#{MAP[:unordered_list_open]}\n" lv = 1 @toc.each do |h| if h['level'] > lv s << ( "#{MAP[:unordered_list_open]}\n" * ( h['level'] - lv ) ) lv = h['level'] elsif h['level'] < lv s << ( "#{MAP[:unordered_list_close]}\n" * ( lv - h['level'] ) ) lv = h['level'] end s << %Q!#{MAP[:listitem_open]}#{h['title'].escapeHTML}\n! end s << ("#{MAP[:unordered_list_close]}\n" * lv) end private def add_toc( level, title ) @toc << {"level" => level, "title" => title, "index" => @toc_cnt} @toc_cnt = @toc_cnt + 1 end def call_plugin_method( t ) return nil unless $use_plugin method = t[:method] args = nil if t[:param] args = csv_split( t[:param] ).collect! do |a| case a when /^[-+]?\d+(\.\d+)?$/ $1 ? a.to_f : a.to_i when /^'(.+)'$/, /^"(.+)"$/ $1.escapeHTML else a end end end begin if @plugin.respond_to?( method ) && !Object.method_defined?( method ) if args @plugin.send( method, *args ) else @plugin.send( method ) end else raise PluginException, 'not plugin method' end rescue raise PluginException, $!.message end end end end