ciderpress/reformat/AppleWorks.h

246 lines
8.3 KiB
C
Raw Normal View History

2007-03-27 17:47:10 +00:00
/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* Reformat AppleWorks documents.
*/
#ifndef __LR_APPLEWORKS__
#define __LR_APPLEWORKS__
#include "ReformatBase.h"
/*
* Reformat an AppleWorks WP document into formatted text.
*/
class ReformatAWP : public ReformatText {
public:
ReformatAWP(void) { fShowEmbeds = true; }
virtual ~ReformatAWP(void) {}
virtual void Examine(ReformatHolder* pHolder);
virtual int Process(const ReformatHolder* pHolder,
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
ReformatOutput* pOutput);
private:
typedef unsigned char uchar;
/*
* Constants.
*/
enum {
kFileHeaderSize = 300, /* expected size of FileHeader */
kSeventyNine = 79, /* value of FileHeader.seventyNine */
kSFMinVers30 = 30, /* indicates AW 3.0 */
kTabFlagsIsRuler = 0xff, /* compare against byte 2 of text record */
kCRatEOL = 0x80, /* flag on byte 3 of the text record */
kMinTextChar = 0x20, /* values from 0x01 - 0x1f are special */
kEOFMarker = 0xff, /* two of these found at end of file */
kLineRecordText = 0x00,
kLineRecordCarriageReturn = 0xd0,
kLineRecordCommandMin = 0xd4,
kLineRecordCommandMax = 0xff,
kLineRecordCommandPageHeaderEnd = 0xd5,
kLineRecordCommandPageFooterEnd = 0xd6,
kLineRecordCommandRightJustify = 0xd7,
kLineRecordCommandPlatenWidth = 0xd8, // 10ths of an inch
kLineRecordCommandLeftMargin = 0xd9, // 10ths of an inch
kLineRecordCommandRightMargin = 0xda, // 10ths of an inch
kLineRecordCommandCharsPerInch = 0xdb,
kLineRecordCommandProportional1 = 0xdc,
kLineRecordCommandProportional2 = 0xdd,
kLineRecordCommandIndent = 0xde,
kLineRecordCommandJustify = 0xdf,
kLineRecordCommandUnjustify = 0xe0,
kLineRecordCommandCenter = 0xe1,
kLineRecordCommandPaperLength = 0xe2,
kLineRecordCommandTopMargin = 0xe3,
kLineRecordCommandBottomMargin = 0xe4,
kLineRecordCommandLinesPerInch = 0xe5,
kLineRecordCommandSingleSpace = 0xe6,
kLineRecordCommandDoubleSpace = 0xe7,
kLineRecordCommandTripleSpace = 0xe8,
kLineRecordCommandNewPage = 0xe9,
kLineRecordCommandGroupBegin = 0xea,
kLineRecordCommandGroupEnd = 0xeb,
kLineRecordCommandPageHeader = 0xec,
kLineRecordCommandPageFooter = 0xed,
kLineRecordCommandSkipLines = 0xee,
kLineRecordCommandPageNumber = 0xef,
kLineRecordCommandPauseEachPage = 0xf0,
kLineRecordCommandPauseHere = 0xf1,
kLineRecordCommandSetMarker = 0xf2,
kLineRecordCommandSetPageNumber = 0xf3,
kLineRecordCommandPageBreak = 0xf4,
kLineRecordCommandPageBreak256 = 0xf5,
kLineRecordCommandPageBreakPara = 0xf6,
kLineRecordCommandPageBreakPara256 = 0xf7,
// end of file is 0xff
kSpecialCharBoldBegin = 0x01,
kSpecialCharBoldEnd = 0x02,
kSpecialCharSuperscriptBegin = 0x03,
kSpecialCharSuperscriptEnd = 0x04,
kSpecialCharSubscriptBegin = 0x05,
kSpecialCharSubscriptEnd = 0x06,
kSpecialCharUnderlineBegin = 0x07,
kSpecialCharUnderlineEnd = 0x08,
kSpecialCharPrintPageNumber = 0x09,
kSpecialCharEnterKeyboard = 0x0a,
kSpecialCharStickySpace = 0x0b,
kSpecialCharMailMerge = 0x0c,
// reserved = 0x0d,
kSpecialCharPrintDate = 0x0e,
kSpecialCharPrintTime = 0x0f,
// Special Code N = 0x10-15
kSpecialCharTab = 0x16,
kSpecialCharTabFill = 0x17, /* tab fill char, not vis in doc */
// reserved = 0x18
kMaxSoftFailures = 8, /* give up if it looks like junk */
};
/*
* File header, mapped directly on top of the input. This structure must
* be exactly 300 bytes.
*/
typedef struct FileHeader {
uchar unused1[4]; /* 000 - 003: not used */
uchar seventyNine; /* 004 : $4f (79) */
uchar tabStops[80]; /* 005 - 084: tab stops, one of "=<^>.|" */
uchar zoomFlag; /* 085 : boolean Zoom flag */
uchar unused2[4]; /* 086 - 089: not used */
uchar paginatedFlag; /* 090 : boolean Paginated flag */
uchar minLeftMargin; /* 091 : minimum "unseen" left margin */
uchar mailMergeFlag; /* 092 : boolean - file has merge cmds */
uchar unused3[83]; /* 093 - 175: not used, reserved */
uchar multiRulerFlag; /* 176 : (3.0) boolean Multiple Rulers */
uchar tabRulers[6]; /* 177 - 182: (3.0) used internally */
uchar sfMinVers; /* 183 : (3.0) min version of AW req */
uchar unused4[66]; /* 184 - 249: reserved */
uchar unused5[50]; /* 250 - 299: available */
} FileHeader;
/*
* Current state of the document.
*/
typedef struct DocState {
long softFailures;
long line;
/* not using these yet */
int leftMargin;
} DocState;
void InitDocState(void);
int ProcessLineRecord(uchar lineRecData, uchar lineRecCode,
const unsigned char** pSrcPtr, long* pLength);
int HandleTextRecord(uchar lineRecData,
const unsigned char** pSrcPtr, long* pLength);
FileHeader fFileHeader;
DocState fDocState;
bool fShowEmbeds;
};
/*
* Reformat an AppleWorks DB document into CSV.
*/
class ReformatADB : public ReformatText {
public:
ReformatADB(void) {}
virtual ~ReformatADB(void) {}
virtual void Examine(ReformatHolder* pHolder);
virtual int Process(const ReformatHolder* pHolder,
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
ReformatOutput* pOutput);
private:
enum {
kOffsetToFirstCatHeader = 357,
kMinHeaderLen = 379,
kReportRecordLen = 600,
kCatNameLen = 20,
kCatHeaderLen = 22,
};
};
/*
* Reformat an AppleWorks SS document into CSV.
*/
class ReformatASP : public ReformatText {
public:
ReformatASP(void) { fCurrentRow = fCurrentCol = 1; }
virtual ~ReformatASP(void) {}
virtual void Examine(ReformatHolder* pHolder);
virtual int Process(const ReformatHolder* pHolder,
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
ReformatOutput* pOutput);
private:
enum {
kFileHeaderSize = 300,
kPropCount = 8,
kSANELen = 8,
};
typedef unsigned char uchar;
/*
* File header, mapped directly on top of the input. This structure must
* be exactly 300 bytes.
*/
typedef struct FileHeader {
uchar unused1[4]; /* 000-003: not used */
uchar colWidth[127]; /* 004-130: column width for each column */
uchar recalcOrder; /* 131 : recalc order ('R' or 'C') */
uchar recalcFreq; /* 132 : recalc frequency ('A' or 'M') */
uchar lastRowRef[2]; /* 133-134: last row referenced */
uchar lastColRef; /* 135 : last column referenced */
uchar numWindows; /* 136 : '1'/'S'/'T' */
uchar windowSync; /* 137 : if two windows, are sync'ed? */
uchar winInfo1[24]; /* 138-161: struct with info for 1st window */
uchar winInfo2[24]; /* 162-185: struct with info for 2nd window */
uchar unused2[27]; /* 186-212: not used */
uchar cellProt; /* 213 : cell protection on/off */
uchar unused3; /* 214 : not used */
uchar platenWidth; /* 215 : platen width */
uchar leftMargin; /* 216 : left margin, in 1/10th inches */
uchar rightMargin; /* 217 : right margin */
uchar cpi; /* 218 : characters per inch */
uchar paperLength; /* 219 : paper length, 1/10th inches */
uchar topMargin; /* 220 : top margin */
uchar bottomMargin; /* 221 : bottom margin */
uchar lpi; /* 222 : lines per inch (6 or 8) */
uchar spacing; /* 223 : 'S'ingle, 'D'ouble, or 'T'riple */
uchar printerCodes[14];/*224-237: "special codes" for printer */
uchar printDash; /* 238 : print dash when entry is blank */
uchar reportHeader; /* 239 : print report header */
uchar zoomed; /* 240 : zoomed to show formulas */
uchar reserved1; /* 241 : used internally (v2.1) */
uchar ssMinVers; /* 242 : holds 0 for AW2.x, 0x1e for AW3.x */
uchar reserved2[7]; /* 243-249: reserved */
uchar available[50]; /* 250-299: available for non-AW app use */
} FileHeader;
int fCurrentRow, fCurrentCol;
char fPrintColBuf[3];
int ProcessRow(int rowNum, const unsigned char** pSrcPtr,
long* pLength);
void ProcessCell(const unsigned char* srcPtr, long cellLength);
void PrintToken(const unsigned char** pSrcPtr, long* pLength);
const char* PrintCol(int col);
double ConvertSANEDouble(const unsigned char* srcPtr);
};
#endif /*__LR_APPLEWORKS__*/