EHGSInterpreter

使用法など

obj = EHGSInterpreter.new(file_io)
で解釈器を生成して、
obj.start
でHTMLを出力します。
file_ioに与えるのはIOオブジェクト。

開発中のメモ

使える文字コードはSJISのみ

・必要な作業(#:実装)
#<, >, & のエスケープ(&lt; &gt; &amp;)
#段落の解釈
#空行の維持
#簡易なルビ振り
	これは|ふりがな[ルビ]です。
#<HR>の代替表現 -----
#見出し表現[* xxxxxx *]
	*を増やすとショボくなる
テーブル表の簡易表現
コメントの代替表現

#・ページのプロパティ設定
:BEGIN行と:END行の間に書く。
ファイルの頭の方に設ける
:BEGIN行がファイルの最後だと文法エラーになる
xxxx = yyyyのようにして、一行にひとつ、指定する
題名title
背景色back
テキスト色text
リンク色link
アクティブリンク色alink
訪問済リンク色vlink
フォントサイズfsize
フォント種類fface
	格納にはおそらくハッシュを用いる

EHGSInterpreterクラス

  require 'auto_kconv'
  require 'html_string'
  $KCODE = "s"
  
class EHGSInterpreter
  class EHGSSyntaxError < RuntimeError ; end
  
  def initialize(f, out_kcode="s")
    @file = f if f.is_a?(IO)
    @out_encode = out_kcode.slice(1,1)
    @block = ""
    @blank = ""
    @config = Hash.new
    @header = ""
    @fooder = ""
  end
  
  def output(str)
    case @out_encode
    when "s"
      print str.tosjis
    when "e"
      print str.toeuc
    when "j"
      print str.tojis
    else
      print str
    end
  end
  
  def start
    read_blank
    read_config
    read_blank
    
    head_set
    food_set
    output @header
    
    until @file.eof?
      read_block
      scan
      output @block
      read_blank
      output @blank
    end
    
    output @fooder
  end
  
  def read_block
    buf = ""
    while line = @file.gets
      break if line.chomp.empty?
      buf << line
    end
    @block = buf
  end
  
  def read_blank
    buf = ""
    while line = @file.gets
      break unless line.chomp.empty?
      buf << line.chomp << "<BR>\n"
    end
    @file.pos -= line.length if line  #一行読み戻す
    @blank = buf
  end
  
  def read_config
    while line = @file.gets
      break if /^(:BEGIN)$/ =~ line
    end
    if @file.eof?  #:BEGIN行なし
      @file.rewind
      return false
    end
    
    while line = @file.gets
      break if /^(:END)$/ =~ line
      #configのスキャン
      arr = line.split(/=/)
      next unless arr.length >= 2
      left = arr.shift.strip
      right = arr.join.strip
      @config[left] = right
    end
    if @file.eof?  #:END行なし(:BEGIN行があって)
      raise(EHGSSyntaxError, %Q|need ':END' for ':BEGIN'|)
    end
  end
  
  def scan
    #<,>,&などのエスケープ
    @block = @block.escape
    
    #テキストブロックを段落化
    @block.gsub!(/\n/, "<BR>\n")
    @block.slice!(-5, 5)
    @block << "\n"
    @block = "<p>\n" + @block + "</p>\n"
    
    #ルビ記法のスキャン
    @block.gsub!(/\|(.*?)\[.*?\]/){|m| ruby_gen(m) }
    
    #区切り記法のスキャン
    @block.gsub!(/^(-----|-----<BR>)$/, "<HR>")
    
    #見出し記法のスキャン
    @block.gsub!(/\[(\*+)(.*?)(\*+)\]/){|m| caption_gen(m) }
  end
  
  def head_set
    @header = <<EOS
<HTML>
<HEAD>
  <TITLE>#{@config["title"]}</TITLE>

</HEAD>
<BODY BGCOLOR = #{@config["back"]}
      TEXT    = #{@config["text"]}
      LINK    = #{@config["link"]}
      ALINK   = #{@config["alink"]}
      VLINK   = #{@config["vlink"]}
      >
<FONT SIZE = #{@config["fsize"]} FACE = #{@config["fface"]}>
EOS
  end
  
  def food_set
    @fooder = <<EOS

</FONT>
</BODY>
</HTML>
EOS
  end
  
  def caption_gen(m)
    /\[(\*+)(.*?)(\*+)\]/ =~ m
    "<h#{$1.length}>#{$2}</h#{$3.length}>"
  end
  
  def ruby_gen(set)
    /\|(.*?)\[(.*?)\]/ =~ set
    "<RUBY><RB>#{$1}</RB><RP>(</RP><RT>#{$2}</RT><RP>)</RP></RUBY>"
  end
  
end