# -*- encoding: cp932 -*- require 'cgi' file = ARGV[0] class StateMachine def initialize @state = 'defualt' @stack = [] end def push_block( b ) @stack.push(b) end def pop_block [@stack.pop] end def handle_line( line ) if $debug puts "----" p [@state,line] p @stack end send( 'handle_'+@state , line ) end ##========================================= def handle_html( line ) case line when /^#!}$/i @state = 'defualt' [pop_block] else [[:html_line,line]] end end ##========================================= def handle_pre( line ) case line when /^#!}$/i @state = 'defualt' [pop_block] else [[:pre_line,line]] end end ##========================================= def handle_defualt( line ) case line when /^■(.+)/ [[:section_line,$1]] when /^◆(.+)/ [[:subsection_line,$1]] when /^#!{$/i @state = 'pre' push_block(:end_code) [[:start_code]] when /^#!
{$/i @state = 'blockquote' push_block(:end_blockquote) push_block(:end_para) [[:start_blockquote],[:start_para]] when /^#!{$/i @state = 'pre' push_block(:end_plain) [[:start_plain,nil]] when /^#!{$/i @state = 'html' push_block(:end_html) [[:start_html]] when /^#!}$/i [pop_block] when /^#!{(.+)\t(.+)}/i push_block(:end_para) @state = 'para' [[:start_para],[:link_line,{:link=>$1,:text=>$2}]] when /^・(.+)/ push_block(:end_ul) push_block(:end_li) @state = 'ul' [[:start_ul],[:start_li],[:plain_line,$1]] when /^#(.+)/ push_block(:end_ol) push_block(:end_li) @state = 'ol' [[:start_ol],[:start_li],[:plain_line,$1]] when /^\s*$/ #nothing [] else push_block(:end_para) @state = 'para' [[:start_para],[:plain_line,line]] end end ##========================================= def handle_para( line ) case line when /^■(.+)/ @state = 'defualt' [pop_block,[:section_line,$1]] when /^◆(.+)/ @state = 'defualt' [pop_block,[:subsection_line,$1]] when /^#!{$/i @state = 'pre' b = pop_block push_block(:end_code) [b,[:start_code]] when /^#!
{$/i @state = 'blockquote' b = pop_block push_block(:end_blockquote) push_block(:end_para) [b,[:start_blockquote],[:start_para]] when /^#!{$/i @state = 'pre' b = pop_block push_block(:end_plain) [b,[:start_plain,nil]] when /^#!{$/i b = pop_block @state = 'html' push_block(:end_html) [b,[:start_html]] when /^#!}$/i @state = 'defualt' [pop_block,pop_block] when /^#!{(.+)\t(.+)}/i [[:link_line,{:link=>$1,:text=>$2}]] when /^・(.+)/ b = pop_block push_block(:end_ul) push_block(:end_li) @state = 'ul' [b,[:start_ul],[:start_li],[:plain_line,$1]] when /^#(.+)/ b = pop_block push_block(:end_ol) push_block(:end_li) @state = 'ol' [b,[:start_ol],[:start_li],[:plain_line,$1]] when /^\s*$/ b = pop_block @state = 'defualt' [b] else [[:plain_line,line]] end end ##========================================= def handle_ul( line ) case line when /^■(.+)/ @state = 'defualt' [pop_block,pop_block,[:section_line,$1]] when /^◆(.+)/ @state = 'defualt' [pop_block,pop_block,[:subsection_line,$1]] when /^#!{$/i @state = 'pre' b0 = pop_block b1 = pop_block push_block(:end_code) [b0,b1,[:start_code]] when /^#!
{$/i @state = 'blockquote' b0 = pop_block b1 = pop_block push_block(:end_blockquote) push_block(:end_para) [b0,b1,[:start_blockquote],[:start_para]] when /^#!{$/i @state = 'pre' b0 = pop_block b1 = pop_block push_block(:end_plain) [b0,b1,[:start_plain,nil]] when /^#!{$/i b0 = pop_block b1 = pop_block @state = 'html' push_block(:end_html) [b0,b1,[:start_html]] when /^#!}$/i @state = 'defualt' [pop_block,pop_block,pop_block] when /^#!{(.+)\t(.+)}/i [[:link_line,{:link=>$1,:text=>$2}]] when /^・(.+)/ b = pop_block push_block(:end_li) [b,[:start_li],[:plain_line,$1]] when /^#(.+)/ b0 = pop_block b1 = pop_block push_block(:end_ol) push_block(:end_li) @state = 'ol' [b0,b1,[:start_ol],[:start_li],[:plain_line,$1]] when /^\s*$/ @state = 'defualt' [pop_block,pop_block] else [[:plain_line,"\n"+line]] end end ##========================================= def handle_ol( line ) case line when /^■(.+)/ @state = 'defualt' [pop_block,pop_block,[:section_line,$1]] when /^◆(.+)/ @state = 'defualt' [pop_block,pop_block,[:subsection_line,$1]] when /^#!{$/i @state = 'pre' b0 = pop_block b1 = pop_block push_block(:end_code) [b0,b1,[:start_code]] when /^#!
{$/i @state = 'blockquote' b0 = pop_block b1 = pop_block push_block(:end_blockquote) push_block(:end_para) [b0,b1,[:start_blockquote],[:start_para]] when /^#!{$/i @state = 'pre' b0 = pop_block b1 = pop_block push_block(:end_plain) [b0,b1,[:start_plain,nil]] when /^#!{$/i b0 = pop_block b1 = pop_block @state = 'html' push_block(:end_html) [b0,b1,[:start_html]] when /^#!}$/i @state = 'defualt' [pop_block,pop_block,pop_block] when /^#!{(.+)\t(.+)}/i [[:link_line,{:link=>$1,:text=>$2}]] when /^・(.+)/ b0 = pop_block b1 = pop_block push_block(:end_ul) push_block(:end_li) @state = 'ul' [b0,b1,[:start_ul],[:start_li],[:plain_line,$1]] when /^#(.+)/ b = pop_block push_block(:end_li) [b,[:start_li],[:plain_line,$1]] when /^\s*$/ @state = 'defualt' [pop_block,pop_block] else [[:plain_line,"\n"+line]] end end ##========================================= def handle_blockquote( line ) case line when /^■(.+)/ @state = 'defualt' [pop_block,pop_block,[:section_line,$1]] when /^◆(.+)/ @state = 'defualt' [pop_block,pop_block,[:subsection_line,$1]] when /^#!{$/i @state = 'pre' b1 = pop_block b2 = pop_block push_block(:end_code) [b1,b2,[:start_code]] when /^#!{$/i @state = 'pre' b1 = pop_block b2 = pop_block push_block(:end_plain) [b1,b2,[:start_plain,nil]] when /^#!{$/i b1 = pop_block b2 = pop_block @state = 'html' push_block(:end_html) [b1,b2,[:start_html]] when /^#!}$/i @state = 'defualt' [pop_block,pop_block] when /^#!{(.+)\t(.+)}/i [[:link_line,{:link=>$1,:text=>$2}]] when /^・(.+)/ b1 = pop_block b2 = pop_block push_block(:end_ul) push_block(:end_li) @state = 'ul' [b1,b2,[:start_ul],[:start_li],[:plain_line,$1]] when /^#(.+)/ b1 = pop_block b2 = pop_block push_block(:end_ol) push_block(:end_li) @state = 'ol' [b1,b2,[:start_ol],[:start_li],[:plain_line,$1]] when /^\s*$/ b = pop_block push_block(:end_para) [b,[:start_para]] else [[:plain_line,line]] end end end class Parse def initialize( io ) @io = io end def parse( visitor ) @sm = StateMachine.new @io.each do |line| do_parse( line.chomp , visitor ) end end def do_parse( line , visitor ) commands = @sm.handle_line(line) commands.each do |param| f = param.shift arg = nil arg = param && param[0] visitor.send( f , arg ) end end end class Visitor def initialize @s = [] end def html @s.join("\n") end def h(line) CGI.escapeHTML(line) end def hb(line) h(line).split(/\n/).join('
') end def section_line(line) # @s << %!

#{h line}

! @s << %!

#{h line}

! end def subsection_line(line) # @s << %!

#{h line}

! @s << %!

#{h line}

! end def plain_line(line) @s << %!#{hb line}! end def html_line(line) @s << line end def pre_line(line) @s << line end def link_line(link_info) @s << ''+h(link_info[:text])+'' end def start_code(dumy) @s << '
'
  end
  def end_code(dumy)
	 @s << ''
	 @s << ''
     @s << '
' end def start_plain(dumy) @s << '
'
  end
  def end_plain(dumy)
	 @s << ''
	 @s << ''
     @s << '
' end def start_para(dumy) @s << '

' end def end_para(dumy) @s << '

' end def start_html(dumy) end def end_html(dumy) end def start_blockquote(dumy) @s << '
' end def end_blockquote(dumy) @s << '
' end def start_ul(dumy) @s << '
    ' end def end_ul(dumy) @s << '
' end def start_ol(dumy) @s << '
    ' end def end_ol(dumy) @s << '
' end def start_li(dumy) @s << '
  • ' end def end_li(dumy) @s << '
  • ' end end v = Visitor.new open(file,'rb') do |io| io.set_encoding 'cp932' parser = Parse.new(io) parser.parse(v) end puts v.html