1module JISX0208 2 class Char 3 class << self 4 def from_sjis(sjis) 5 unless 0x8140 <= sjis && sjis <= 0xFCFC 6 raise ArgumentError, "out of the range of JIS X 0208: 0x#{sjis.to_s(16)}" 7 end 8 sjis_hi, sjis_lo = sjis >> 8, sjis & 0xFF 9 sjis_hi = (sjis_hi - ((sjis_hi <= 0x9F) ? 0x80 : 0xC0)) << 1 10 if sjis_lo <= 0x9E 11 sjis_hi -= 1 12 sjis_lo -= (sjis_lo <= 0x7E) ? 0x3F : 0x40 13 else 14 sjis_lo -= 0x9E 15 end 16 return self.new(sjis_hi, sjis_lo) 17 end 18 end 19 20 def initialize(row, cell=nil) 21 if cell 22 @code = row_cell_to_code(row, cell) 23 else 24 @code = row.to_int 25 end 26 end 27 28 def ==(other) 29 if self.class === other 30 return Integer(self) == Integer(other) 31 end 32 return super(other) 33 end 34 35 def to_int 36 return @code 37 end 38 39 def hi 40 Integer(self) >> 8 41 end 42 43 def lo 44 Integer(self) & 0xFF 45 end 46 47 def row 48 self.hi - 0x20 49 end 50 51 def cell 52 self.lo - 0x20 53 end 54 55 def succ 56 succ_hi, succ_lo = self.hi, self.lo + 1 57 if succ_lo > 0x7E 58 succ_lo = 0x21 59 succ_hi += 1 60 end 61 return self.class.new(succ_hi << 8 | succ_lo) 62 end 63 64 def to_sjis 65 h, l = self.hi, self.lo 66 h = (h + 1) / 2 + ((0x21..0x5E).include?(h) ? 0x70 : 0xB0) 67 l += self.hi.odd? ? 0x1F + ((l >= 0x60) ? 1 : 0) : 0x7E 68 return h << 8 | l 69 end 70 71 def inspect 72 "#<JISX0208::Char:#{self.object_id.to_s(16)} sjis=#{self.to_sjis.to_s(16)} jis=#{self.to_int.to_s(16)}>" 73 end 74 75 private 76 77 def row_cell_to_code(row, cell) 78 unless 0 < row && (1..94).include?(cell) 79 raise ArgumentError, "out of row-cell range: #{row}-#{cell}" 80 end 81 return (row + 0x20) << 8 | (cell + 0x20) 82 end 83 end 84end 85