% From the book % PROLOG PROGRAMMING IN DEPTH % by Michael A. Covington, Donald Nute, and Andre Vellino % (Prentice Hall, 1997). % Copyright 1997 Prentice-Hall, Inc. % For educational use only % File LOTUS.PL % Reads a Lotus .WKS spreadsheet, field by field. :- ensure_loaded('readbyte.pl'). % or use reconsult if necessary :- ensure_loaded('readi16.pl'). % or use reconsult if necessary :- ensure_loaded('readf64.pl'). % or use reconsult if necessary % Insert definition of atom_codes here if not built in atom_codes(Atom,Codes) :- name(Atom,Codes). % read_significant_field(-Field) % Reads a field from the spreadsheet (like read_field below), % but skips non--data fields. read_significant_field(Result) :- % like read_field, skips non-data repeat, read_field(R), \+ R == non_data_field, !, Result = R. % read_field(-Field) % Reads a field from the spreadsheet, returning one of the following: % % beginning_of_file -- Lotus beginning-of-file code % end_of_file -- Lotus end-of-file code % cell(Col,Row,integer,Value) -- An integer. Col and Row numbered from 0. % cell(Col,Row,float,Value) -- A floating-point number. % cell(Col,Row,formula,Value) -- The numerical value of a formula. % cell(Col,Row,text,Value) -- A text field (as a Prolog atom). % non_data_field -- Anything else (print formats, etc.). read_field(Result) :- read_u16(Opcode), read_field_aux(Opcode,Result). read_field_aux(0,beginning_of_file) :- !, read_u16(Length), skip_bytes(Length). read_field_aux(1,end_of_file) :- !. % no need to read the trivial bytes that follow read_field_aux(13,cell(Col,Row,integer,Value)) :- !, skip_bytes(3), % length and format information read_u16(Col), read_u16(Row), read_i16(Value). read_field_aux(14,cell(Col,Row,float,Value)) :- !, skip_bytes(3), % length and format information read_u16(Col), read_u16(Row), read_f64(Value). read_field_aux(15,cell(Col,Row,text,Value)) :- !, read_u16(Length), skip_bytes(1), % format code read_u16(Col), read_u16(Row), Rest is Length - 7, skip_bytes(1), % alignment code at beg. of string read_bytes(Rest,String), atom_codes(Value,String), skip_bytes(1). % final zero byte at end of string read_field_aux(16,cell(Col,Row,formula,Value)) :- !, skip_bytes(3), % length and format information read_u16(Col), read_u16(Row), read_f64(Value), % numeric value of formula read_u16(LengthOfRest), skip_bytes(LengthOfRest). % don't try to decode formula itself read_field_aux(_,non_data_field) :- read_u16(Length), skip_bytes(Length). % Demonstration wksdemo :- see('sample.wks'), repeat, read_significant_field(F), write(F), nl, F == end_of_file, !, seen.