< :the previous in number
^ :the list in numerical order
> :the next in number
P :the previous aricle (the previous thread)
N :the next (in thread)
|<:the previous thread
>|:the next thread
^ :the parent (reply-to)
_:the child (an article replying to this)
>:the elder article having the same parent
<:the youger article having the same parent
---:split window and show thread lists
| :split window (vertically) and show thread lists
~ :close the thread frame
.:the index
..:the index of indices
######################################################################
# Spreadsheet Alpha 2
#
# Changelog
# =========
# - Excel is now a subclass of File
# - Method write() was changed to write_data() to avoid IO confusion
# - Type checking in write_data() now done with kind_of? method instead
# - Uses big_endian? boolean instead of @byte_order value
######################################################################
module Spreadsheet
class OutOfRangeException < RuntimeError; end
class InvalidTypeException < RuntimeError; end
class Excel < File
RowMax = 65536
ColMax = 256
StrMax = 255
def initialize(filename)
super(filename,"w+")
@dim_offset = 0
@big_endian? = false
# Big Endian or Little Endian architecture?
if [1].pack("I") == [1].pack("N")
@big_endian? = true
end
write_bof()
write_dimensions()
end
def write_bof
name = 0x0809 # Record identifier
len = 0x0008 # Number of bytes
version = 0x0000
type = 0x0010 # Worksheet
build = 0x0000 # Set to zero
year = 0x0000 # Set to zero
header = [name,len].pack("vv")
data = [version,type,build,year].pack("vvvv")
hd = header + data
print(hd)
end
def write_dimensions(row_min=0,row_max=0,col_min=0,col_max=0)
row_max += 1
col_max += 1
name = 0x0000
len = 0x000A
res = 0x0000
header = [name,len].pack("vv")
data = [row_min,row_max,col_min,col_max,res].pack("vvvvv")
hd = header + data
@dim_offset = tell
print(hd)
end
def write_eof
name = 0x000A
len = 0x0000
header = [name,len].pack("vv")
print(header)
seek(@dim_offset,0)
write_dimensions()
end
def close
write_eof()
super
end
def write_data(row=0,col=0,data=nil)
if data.kind_of?(String)
write_string(row,col,data)
elsif data.kind_of(Fixnum)
write_number(row,col,data)
else
raise InvalidTypeException
end
end
def write_string(row,col,string)
raise OutOfRangeException if row > RowMax
raise OutOfRangeException if col > ColMax
name = 0x0204 # Record identifier
xf = 0x0000 # Cell format
strlen = string.length
string.slice!(0,StrMax) if strlen > StrMax
len = 0x0008 + strlen # Bytes to follow
header = [name,len].pack("vv")
data = [row,col,xf,strlen].pack("vvvv")
hds = header + data + string
print(hds)
end
def write_number(row,col,num)
raise OutOfRangeException if row > RowMax
raise OutOfRangeException if col > ColMax
name = 0x0203
len = 0x000E
xf = 0x0000
header = [name,len].pack("vv")
data = [row,col,xf].pack("vvv")
xld = [num].pack("d")
xld = xld.to_s.reverse if @big_endian?
hdx = header + data + xld
print(hdx)
end
end
end