Add vestigal support for Gutenberg Word Processor formatting

This commit is contained in:
David Schmidt 2009-01-05 02:11:31 +00:00
parent abd3515424
commit 5637461d8a
9 changed files with 1401 additions and 1293 deletions

View File

@ -2644,6 +2644,8 @@ MainWindow::ConfigureReformatFromPreferences(ReformatHolder* pReformat)
pPreferences->GetPrefBool(kPrConvGWP)); pPreferences->GetPrefBool(kPrConvGWP));
pReformat->SetReformatAllowed(ReformatHolder::kReformatMagicWindow, pReformat->SetReformatAllowed(ReformatHolder::kReformatMagicWindow,
pPreferences->GetPrefBool(kPrConvText8)); pPreferences->GetPrefBool(kPrConvText8));
pReformat->SetReformatAllowed(ReformatHolder::kReformatGutenberg,
pPreferences->GetPrefBool(kPrConvGutenberg));
pReformat->SetReformatAllowed(ReformatHolder::kReformatAWP, pReformat->SetReformatAllowed(ReformatHolder::kReformatAWP,
pPreferences->GetPrefBool(kPrConvAWP)); pPreferences->GetPrefBool(kPrConvAWP));
pReformat->SetReformatAllowed(ReformatHolder::kReformatAWP, pReformat->SetReformatAllowed(ReformatHolder::kReformatAWP,
@ -2707,7 +2709,13 @@ MainWindow::ConfigureReformatFromPreferences(ReformatHolder* pReformat)
/*static*/ ReformatHolder::SourceFormat /*static*/ ReformatHolder::SourceFormat
MainWindow::ReformatterSourceFormat(DiskImg::FSFormat format) MainWindow::ReformatterSourceFormat(DiskImg::FSFormat format)
{ {
if (DiskImg::UsesDOSFileStructure(format)) /*
* Gutenberg both UsesDOSFileStructure and is formatted with
* kFormatGutenberg, so check for the latter first.
*/
if (format == DiskImg::kFormatGutenberg)
return ReformatHolder::kSourceFormatGutenberg;
else if (DiskImg::UsesDOSFileStructure(format))
return ReformatHolder::kSourceFormatDOS; return ReformatHolder::kSourceFormatDOS;
else if (format == DiskImg::kFormatCPM) else if (format == DiskImg::kFormatCPM)
return ReformatHolder::kSourceFormatCPM; return ReformatHolder::kSourceFormatCPM;

View File

@ -118,6 +118,7 @@ const Preferences::PrefMap Preferences::fPrefMaps[kPrefNumLastEntry] = {
{ kPrConvBusiness, kBool, kPrefsSect, _T("conv-business") }, { kPrConvBusiness, kBool, kPrefsSect, _T("conv-business") },
{ kPrConvGWP, kBool, kPrefsSect, _T("conv-gwp") }, { kPrConvGWP, kBool, kPrefsSect, _T("conv-gwp") },
{ kPrConvText8, kBool, kPrefsSect, _T("conv-text8") }, { kPrConvText8, kBool, kPrefsSect, _T("conv-text8") },
{ kPrConvGutenberg, kBool, kPrefsSect, _T("conv-gutenberg") },
{ kPrConvAWP, kBool, kPrefsSect, _T("conv-awp") }, { kPrConvAWP, kBool, kPrefsSect, _T("conv-awp") },
{ kPrConvADB, kBool, kPrefsSect, _T("conv-adb") }, { kPrConvADB, kBool, kPrefsSect, _T("conv-adb") },
{ kPrConvASP, kBool, kPrefsSect, _T("conv-asp") }, { kPrConvASP, kBool, kPrefsSect, _T("conv-asp") },
@ -227,6 +228,7 @@ Preferences::Preferences(void)
SetPrefBool(kPrConvBusiness, true); SetPrefBool(kPrConvBusiness, true);
SetPrefBool(kPrConvGWP, true); SetPrefBool(kPrConvGWP, true);
SetPrefBool(kPrConvText8, true); SetPrefBool(kPrConvText8, true);
SetPrefBool(kPrConvGutenberg, true);
SetPrefBool(kPrConvAWP, true); SetPrefBool(kPrConvAWP, true);
SetPrefBool(kPrConvADB, true); SetPrefBool(kPrConvADB, true);
SetPrefBool(kPrConvASP, true); SetPrefBool(kPrConvASP, true);

View File

@ -171,6 +171,7 @@ typedef enum {
kPrConvBusiness, // bool kPrConvBusiness, // bool
kPrConvGWP, // bool kPrConvGWP, // bool
kPrConvText8, // bool kPrConvText8, // bool
kPrConvGutenberg, // bool
kPrConvAWP, // bool kPrConvAWP, // bool
kPrConvADB, // bool kPrConvADB, // bool
kPrConvASP, // bool kPrConvASP, // bool

View File

@ -86,6 +86,7 @@ ReformatHolder::GetReformatInstance(ReformatID id)
case kReformatSHR_DG3200: pReformat = new ReformatDG3200SHR; break; case kReformatSHR_DG3200: pReformat = new ReformatDG3200SHR; break;
case kReformatPrintShop: pReformat = new ReformatPrintShop; break; case kReformatPrintShop: pReformat = new ReformatPrintShop; break;
case kReformatMacPaint: pReformat = new ReformatMacPaint; break; case kReformatMacPaint: pReformat = new ReformatMacPaint; break;
case kReformatGutenberg: pReformat = new ReformatGutenberg; break;
case kReformatUnknown: case kReformatUnknown:
case kReformatMAX: case kReformatMAX:
default: assert(false); break; default: assert(false); break;
@ -191,6 +192,9 @@ ReformatHolder::GetReformatName(ReformatID id)
case kReformatMagicWindow: case kReformatMagicWindow:
descr = "Magic Window"; descr = "Magic Window";
break; break;
case kReformatGutenberg:
descr = "Gutenberg Word Processor";
break;
case kReformatAWP: case kReformatAWP:
descr = "AppleWorks Word Processor"; descr = "AppleWorks Word Processor";
break; break;

View File

@ -1,5 +1,6 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2009 by CiderPress authors. All Rights Reserved.
* Copyright (C) 2007, 2008 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2007, 2008 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms. * See the file LICENSE for distribution terms.
*/ */
@ -96,6 +97,7 @@ public:
kReformatGWP, kReformatGWP,
kReformatMagicWindow, kReformatMagicWindow,
kReformatGutenberg,
kReformatAWP, kReformatAWP,
kReformatADB, kReformatADB,
@ -182,12 +184,14 @@ public:
* *
* We want to know if it's DOS so we can relax some file-type checking, * We want to know if it's DOS so we can relax some file-type checking,
* and we want to know if it's CP/M so we can adjust the way we think * and we want to know if it's CP/M so we can adjust the way we think
* about text files. * about text files. We want to know if it's Gutenberg because they only
* have one type of file, and it's indistingusihable from any other text file!
*/ */
typedef enum SourceFormat { typedef enum SourceFormat {
kSourceFormatGeneric = 0, kSourceFormatGeneric = 0,
kSourceFormatDOS, kSourceFormatDOS,
kSourceFormatCPM, kSourceFormatCPM,
kSourceFormatGutenberg,
} SourceFormat; } SourceFormat;
@ -268,6 +272,7 @@ public:
friend class ReformatTeach; friend class ReformatTeach;
friend class ReformatGWP; friend class ReformatGWP;
friend class ReformatMagicWindow; friend class ReformatMagicWindow;
friend class ReformatGutenberg;
friend class ReformatAWP; friend class ReformatAWP;
friend class ReformatADB; friend class ReformatADB;
friend class ReformatASP; friend class ReformatASP;

File diff suppressed because it is too large Load Diff

View File

@ -314,6 +314,8 @@ protected:
void ConvertEOL(const unsigned char* srcBuf, long srcLen, void ConvertEOL(const unsigned char* srcBuf, long srcLen,
bool stripHiBits); bool stripHiBits);
void ConvertEOL(const unsigned char* srcBuf, long srcLen,
bool stripHiBits, bool stripNulls);
void BufHexDump(const unsigned char* srcBuf, long srcLen); void BufHexDump(const unsigned char* srcBuf, long srcLen);
void SetResultBuffer(ReformatOutput* pOutput, bool multiFont = false); void SetResultBuffer(ReformatOutput* pOutput, bool multiFont = false);

View File

@ -1,174 +1,225 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2009 by CiderPress authors. All Rights Reserved.
* See the file LICENSE for distribution terms. * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
*/ * See the file LICENSE for distribution terms.
/* */
* Convert 8-bit word processor files. /*
* * Convert 8-bit word processor files.
* Most formats convert reasonably well with "Converted Text", but this *
* allows the files to be handled more transparently (e.g. Magic Window * Most formats convert reasonably well with "Converted Text", but this
* "formatted files", which can be mistaken for code. * allows the files to be handled more transparently (e.g. Magic Window
*/ * "formatted files", which can be mistaken for code.
#include "StdAfx.h" */
#include "Text8.h" #include "StdAfx.h"
#include "Text8.h"
/*
* =========================================================================== /*
* Magic Window / Magic Window II * ===========================================================================
* =========================================================================== * Magic Window / Magic Window II
*/ * ===========================================================================
*/
/*
* Magic Window and Magic Window II appear to use the same format for their /*
* "formatted files". The files are of type 'B', with a valid address field, * Magic Window and Magic Window II appear to use the same format for their
* and what looks like junk in the length field. The files have a 256-byte * "formatted files". The files are of type 'B', with a valid address field,
* header that seems to hold some sort of title string as well as some * and what looks like junk in the length field. The files have a 256-byte
* binary goodies that I'm not sure what they are. * header that seems to hold some sort of title string as well as some
* * binary goodies that I'm not sure what they are.
* The data from offset 256 on is entirely mixed-case high-ASCII text. It *
* may contain printer-specific escape codes for bold, italic, etc. * The data from offset 256 on is entirely mixed-case high-ASCII text. It
* * may contain printer-specific escape codes for bold, italic, etc.
* A ".MW" filename suffix is enforced by the program. *
*/ * A ".MW" filename suffix is enforced by the program.
*/
/*
* Decide whether or not we want to handle this file. /*
*/ * Decide whether or not we want to handle this file.
void */
ReformatMagicWindow::Examine(ReformatHolder* pHolder) void
{ ReformatMagicWindow::Examine(ReformatHolder* pHolder)
if (pHolder->GetFileType() == kTypeBIN) { {
bool isMW = ReformatMagicWindow::IsFormatted(pHolder); if (pHolder->GetFileType() == kTypeBIN) {
bool isDotMW = strcasecmp(pHolder->GetNameExt(), ".MW") == 0; bool isMW = ReformatMagicWindow::IsFormatted(pHolder);
bool isDotMW = strcasecmp(pHolder->GetNameExt(), ".MW") == 0;
if (isMW && isDotMW) {
/* gotta be */ if (isMW && isDotMW) {
pHolder->SetApplic(ReformatHolder::kReformatMagicWindow, /* gotta be */
ReformatHolder::kApplicYes, pHolder->SetApplic(ReformatHolder::kReformatMagicWindow,
ReformatHolder::kApplicNot, ReformatHolder::kApplicNot); ReformatHolder::kApplicYes,
} else if (isDotMW) { ReformatHolder::kApplicNot, ReformatHolder::kApplicNot);
/* right type and name; maybe our test is broken? */ } else if (isDotMW) {
pHolder->SetApplic(ReformatHolder::kReformatMagicWindow, /* right type and name; maybe our test is broken? */
ReformatHolder::kApplicProbably, pHolder->SetApplic(ReformatHolder::kReformatMagicWindow,
ReformatHolder::kApplicNot, ReformatHolder::kApplicNot); ReformatHolder::kApplicProbably,
} else if (isMW) { ReformatHolder::kApplicNot, ReformatHolder::kApplicNot);
/* not likely, but offer it as non-default option */ } else if (isMW) {
pHolder->SetApplic(ReformatHolder::kReformatMagicWindow, /* not likely, but offer it as non-default option */
ReformatHolder::kApplicProbablyNot, pHolder->SetApplic(ReformatHolder::kReformatMagicWindow,
ReformatHolder::kApplicNot, ReformatHolder::kApplicNot); ReformatHolder::kApplicProbablyNot,
} else { ReformatHolder::kApplicNot, ReformatHolder::kApplicNot);
/* not one of ours */ } else {
pHolder->SetApplic(ReformatHolder::kReformatMagicWindow, /* not one of ours */
ReformatHolder::kApplicNot, pHolder->SetApplic(ReformatHolder::kReformatMagicWindow,
ReformatHolder::kApplicNot, ReformatHolder::kApplicNot); ReformatHolder::kApplicNot,
} ReformatHolder::kApplicNot, ReformatHolder::kApplicNot);
} else { }
/* "unformatted" text even if ".MW"; nothing special required */ } else {
pHolder->SetApplic(ReformatHolder::kReformatMagicWindow, /* "unformatted" text even if ".MW"; nothing special required */
ReformatHolder::kApplicNot, pHolder->SetApplic(ReformatHolder::kReformatMagicWindow,
ReformatHolder::kApplicNot, ReformatHolder::kApplicNot); ReformatHolder::kApplicNot,
} ReformatHolder::kApplicNot, ReformatHolder::kApplicNot);
} }
}
/*
* Figure out if this is a Magic Window "formatted" file. /*
* * Figure out if this is a Magic Window "formatted" file.
* I don't know much about the format, so this is based on the similarities *
* observed between half a dozen documents from different sources. * I don't know much about the format, so this is based on the similarities
*/ * observed between half a dozen documents from different sources.
/*static*/ bool */
ReformatMagicWindow::IsFormatted(const ReformatHolder* pHolder) /*static*/ bool
{ ReformatMagicWindow::IsFormatted(const ReformatHolder* pHolder)
const unsigned char* ptr = pHolder->GetSourceBuf(ReformatHolder::kPartData); {
long srcLen = pHolder->GetSourceLen(ReformatHolder::kPartData); const unsigned char* ptr = pHolder->GetSourceBuf(ReformatHolder::kPartData);
int i, count00, count20; long srcLen = pHolder->GetSourceLen(ReformatHolder::kPartData);
int i, count00, count20;
/* want 256-byte header, plus a few bytes to check text */
if (srcLen < kHeaderLen+8) /* want 256-byte header, plus a few bytes to check text */
return false; if (srcLen < kHeaderLen+8)
return false;
/*
* First byte always seems to be 0x8d. /*
*/ * First byte always seems to be 0x8d.
if (ptr[0x00] != 0x8d) */
return false; if (ptr[0x00] != 0x8d)
return false;
/*
* 0x58 - 0xa0 is mostly filled with 0x00 (for Magic Window) or 0x20 /*
* (for Magic Window II). Both seem to have space for the title in the * 0x58 - 0xa0 is mostly filled with 0x00 (for Magic Window) or 0x20
* preceeding part, but it's high-ASCII for MW and low-ASCII for MW2. * (for Magic Window II). Both seem to have space for the title in the
* * preceeding part, but it's high-ASCII for MW and low-ASCII for MW2.
* Expect 50 out of 72 to match. If this is actually just uninitialized *
* data then this test will be bogus. * Expect 50 out of 72 to match. If this is actually just uninitialized
*/ * data then this test will be bogus.
count00 = count20 = 0; */
for (i = 0x58; i < 0xa0; i++) { count00 = count20 = 0;
if (ptr[i] == 0x00) for (i = 0x58; i < 0xa0; i++) {
count00++; if (ptr[i] == 0x00)
if (ptr[i] == 0x20) count00++;
count20++; if (ptr[i] == 0x20)
} count20++;
if (count00 < 50 && count20 < 50) }
return false; if (count00 < 50 && count20 < 50)
return false;
/*
* 0xa2 has some recognizeable bytes; sample values: /*
* MW 42 06 36 50 08 40 * 0xa2 has some recognizeable bytes; sample values:
* MW2 42 06 36 55 08 40 * MW 42 06 36 50 08 40
* MW2 42 04 3a 50 00 50 * MW2 42 06 36 55 08 40
* Not really sure what to make of these. If we can bracket these * MW2 42 04 3a 50 00 50
* values we might have something. * Not really sure what to make of these. If we can bracket these
*/ * values we might have something.
if (ptr[0xa2] != 0x42 || */
(ptr[0xa3] < 2 && ptr[0xa3] > 10) || if (ptr[0xa2] != 0x42 ||
(ptr[0xa4] < 0x30 && ptr[0xa4] > 0x40)) (ptr[0xa3] < 2 && ptr[0xa3] > 10) ||
return false; (ptr[0xa4] < 0x30 && ptr[0xa4] > 0x40))
return false;
/*
* Make sure the rest of the file is 100% high ASCII. /*
*/ * Make sure the rest of the file is 100% high ASCII.
ptr += kHeaderLen; */
srcLen -= kHeaderLen; ptr += kHeaderLen;
while (srcLen--) { srcLen -= kHeaderLen;
if ((*ptr & 0x80) == 0) while (srcLen--) {
return false; if ((*ptr & 0x80) == 0)
} return false;
}
return true;
} return true;
}
/*
* Skip the header and text-convert the reset. /*
*/ * Skip the header and text-convert the rest.
int */
ReformatMagicWindow::Process(const ReformatHolder* pHolder, int
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part, ReformatMagicWindow::Process(const ReformatHolder* pHolder,
ReformatOutput* pOutput) ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
{ ReformatOutput* pOutput)
const unsigned char* srcPtr = pHolder->GetSourceBuf(part); {
long srcLen = pHolder->GetSourceLen(part); const unsigned char* srcPtr = pHolder->GetSourceBuf(part);
long length = srcLen; long srcLen = pHolder->GetSourceLen(part);
int retval = -1; long length = srcLen;
int retval = -1;
fUseRTF = false;
fUseRTF = false;
RTFBegin();
RTFBegin();
if (srcLen <= kHeaderLen)
goto bail; if (srcLen <= kHeaderLen)
goto bail;
ConvertEOL(srcPtr + kHeaderLen, srcLen - kHeaderLen, true);
ConvertEOL(srcPtr + kHeaderLen, srcLen - kHeaderLen, true);
//done:
RTFEnd(); //done:
RTFEnd();
SetResultBuffer(pOutput);
retval = 0; SetResultBuffer(pOutput);
retval = 0;
bail:
return retval; bail:
} return retval;
}
/*
* ===========================================================================
* Gutenberg Word Processor
* ===========================================================================
*/
/*
* Decide whether or not we want to handle this file.
*/
void
ReformatGutenberg::Examine(ReformatHolder* pHolder)
{
if ((pHolder->GetFileType() == kTypeTXT) &&
(pHolder->GetSourceFormat() == ReformatHolder::kSourceFormatGutenberg)) {
pHolder->SetApplic(ReformatHolder::kReformatGutenberg,
ReformatHolder::kApplicYes,
ReformatHolder::kApplicNot, ReformatHolder::kApplicNot);
}
}
/*
* Convert the text.
*/
int
ReformatGutenberg::Process(const ReformatHolder* pHolder,
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
ReformatOutput* pOutput)
{
const unsigned char* srcPtr = pHolder->GetSourceBuf(part);
long srcLen = pHolder->GetSourceLen(part);
long length = srcLen;
int retval = -1;
fUseRTF = false;
RTFBegin();
ConvertEOL(srcPtr, srcLen, true, true);
RTFEnd();
SetResultBuffer(pOutput);
retval = 0;
return retval;
}

View File

@ -1,33 +1,49 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2009 by Ciderpress authors. All Rights Reserved.
* See the file LICENSE for distribution terms. * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
*/ * See the file LICENSE for distribution terms.
/* */
* Reformat 8-bit word processor files. /*
*/ * Reformat 8-bit word processor files.
#ifndef __LR_TEXT8__ */
#define __LR_TEXT8__ #ifndef __LR_TEXT8__
#define __LR_TEXT8__
#include "ReformatBase.h"
#include "ReformatBase.h"
/*
* Magic Window / Magic Window II /*
*/ * Magic Window / Magic Window II
class ReformatMagicWindow : public ReformatText { */
public: class ReformatMagicWindow : public ReformatText {
ReformatMagicWindow(void) {} public:
virtual ~ReformatMagicWindow(void) {} ReformatMagicWindow(void) {}
virtual ~ReformatMagicWindow(void) {}
virtual void Examine(ReformatHolder* pHolder);
virtual int Process(const ReformatHolder* pHolder, virtual void Examine(ReformatHolder* pHolder);
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part, virtual int Process(const ReformatHolder* pHolder,
ReformatOutput* pOutput); ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
ReformatOutput* pOutput);
private:
static bool IsFormatted(const ReformatHolder* pHolder); private:
static bool IsFormatted(const ReformatHolder* pHolder);
enum { kHeaderLen = 256 };
}; enum { kHeaderLen = 256 };
};
#endif /*__LR_TEXT8__*/
/*
* Guterberg Word Processor
*/
class ReformatGutenberg : public ReformatText {
public:
ReformatGutenberg(void) {}
virtual ~ReformatGutenberg(void) {}
virtual void Examine(ReformatHolder* pHolder);
virtual int Process(const ReformatHolder* pHolder,
ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
ReformatOutput* pOutput);
};
#endif /*__LR_TEXT8__*/