#
# ISO-2022-JP compact filter (fast version)
#
# Copyright (C) All right reserved by Kazuhiro NISHIYAMA <zn@mbf.nifty.com> 2001
# You can redistribute it and/or modify it under the same term as GPL2.
#
# http://homepage2.nifty.com/zn/jewel/FastJisCompactFilter.rb
# http://www.spc.gr.jp/mobiler/

module ISO_2022_JP
  TO_HALF = {
    '♯' => '#',
    '、' => ',',
    '。' => '.',
  }
  TO_FULL = {}
  HALF_WIDTH = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
  '　！”＃＄％＆’（）＊＋，−．／０１２３４５６７８９：；＜＝＞？＠ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ［￥］＾＿｀ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏｐｑｒｓｔｕｖｗｘｙｚ｛｜｝￣'.split(//).each_with_index do |ch,i|
    c = HALF_WIDTH[i].chr
    TO_HALF[ch] = c
    TO_FULL[c] = ch
  end

  MAP_CHARS = Regexp.quote HALF_WIDTH+TO_HALF.keys.join('')

  def to_half_width(str)
    str.split(//).collect do |ch|
      TO_HALF.key?(ch) ? TO_HALF[ch] : ch
    end.join('')
  end
  module_function :to_half_width

  def to_full_width(str)
    str.split(//).collect do |ch|
      TO_FULL.key?(ch) ? TO_FULL[ch] : ch
    end.join('')
  end
  module_function :to_full_width

  # iso-2022-jpでのバイト数を小さくする。
  def min(kcode_string)
    kcode_string.gsub(/[#{MAP_CHARS}]+/o) {
      to_half_width($&)
    }.gsub(/[^#{MAP_CHARS}][#{MAP_CHARS}]{1,5}(?=[^#{MAP_CHARS}])/o) {
      to_full_width($&)
    }
  end
  module_function :min
end

class FastJisCompactFilter < Filter
  def FastJisCompactFilter::description
    [
      'FastJisCompactFilter',
      '全角←→半角で小さくする',
      'iso-2022-jpでバイト数が少なくなるように英数字・記号を全角または半角にします。'
    ]
  end

  def body_filter( body )
    ISO_2022_JP.min( body )
  end
end

