From 034448c1719ff9ac3b162d8307fd5090a1b7d6ae Mon Sep 17 00:00:00 2001 From: Fred Kiefer Date: Sun, 23 Apr 2000 22:28:46 +0000 Subject: [PATCH] Update of parser git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@6500 72102866-910b-0410-8b05-ffd578937521 --- Source/Parsers/attributedStringConsumer.m | 449 +++++++++++++------ Source/Parsers/rtfConsumer.h | 4 + Source/Parsers/rtfConsumerFunctions.h | 50 ++- Source/Parsers/rtfGrammer.tab.c | 510 +++++++++++++++------- Source/Parsers/rtfGrammer.y | 187 ++++++-- Source/Parsers/rtfScanner.c | 130 +++++- Source/Parsers/rtfScanner.h | 7 +- 7 files changed, 992 insertions(+), 345 deletions(-) diff --git a/Source/Parsers/attributedStringConsumer.m b/Source/Parsers/attributedStringConsumer.m index d259ee599..deed10b0a 100644 --- a/Source/Parsers/attributedStringConsumer.m +++ b/Source/Parsers/attributedStringConsumer.m @@ -53,215 +53,384 @@ readNSString(StringContext *ctxt) we must implement from the rtfConsumerSkeleton.h file (Supporting files) this includes the yacc error handling and output */ +#define GSfontDictName @"fonts" +#define GScurrentTextPosition @"textPosition" +#define GSresultName @"result" +#define GSchanged @"changed" + +#define GSparagraph @"paragraph" +#define GSfontName @"fontName" +#define GSfontSize @"fontSize" +#define GSbold @"bold" +#define GSitalic @"italic" +#define GSunderline @"underline" +#define GSscript @"script" + +#define GSdocumentAttributes @"documentAttributes" + #define CTXT ((NSMutableDictionary *)ctxt) -#define FONTS [CTXT objectForKey:GSRTFfontDictName] -#define RESULT [CTXT objectForKey:GSRTFresultName] +#define FONTS [CTXT objectForKey: GSfontDictName] +#define RESULT [CTXT objectForKey: GSresultName] +#define CHANGED [[CTXT objectForKey: GSchanged] boolValue] +#define SETCHANGED(flag) [CTXT setObject: [NSNumber numberWithBool: flag] forKey: GSchanged] +#define PARAGRAPH [CTXT objectForKey: GSparagraph] -#define GSRTFfontDictName @"fonts" -#define GSRTFcurrentTextPosition @"textPosition" -#define GSRTFresultName @"result" -#define GSRTFboldRange @"boldOn" -#define GSRTFitalicRange @"italicOn" -#define GSRTFunderlineRange @"underlineOn" -#define GSRTFcurrentFont @"currentFont" -#define GSRTFdocumentAttributes @"documentAttributes" +#define halfpoints2points(a) ((a)/2.0) +// FIXME: How to convert twips to points??? +#define twips2points(a) ((a)/500.0) -static NSRange MakeRangeFromAbs(int a1,int a2) + +static int textPosition(void *ctxt) { - if(a1< a2) return NSMakeRange(a1,a2-a1); - else return NSMakeRange(a2,a1-a2); + return [[CTXT objectForKey: GScurrentTextPosition] intValue]; } -/* handle errors (this is the yacc error mech) */ -void GSRTFerror(const char *msg) +static NSFont *currentFont(void *ctxt) +{ + NSFont *font; + BOOL boldOn; + BOOL italicOn; + NSString *name; + float size; + NSFontTraitMask traits = 0; + int weight; + + name = [CTXT objectForKey: GSfontName]; + size = [[CTXT objectForKey: GSfontSize] floatValue]; + boldOn = [[CTXT objectForKey: GSbold] boolValue]; + italicOn = [[CTXT objectForKey: GSitalic] boolValue]; + + if (boldOn) + { + weight = 9; + traits |= NSBoldFontMask; + } + else + { + weight = 6; + traits |= NSUnboldFontMask; + } + + if (italicOn) + { + traits |= NSItalicFontMask; + } + else + { + traits |= NSUnitalicFontMask; + } + + font = [[NSFontManager sharedFontManager] fontWithFamily: name + traits: traits + weight: weight + size: size]; + return font; +} + +/* handle errors (this is the yacc error mech) */ +void GSRTFerror(const char *msg) { [NSException raise:NSInvalidArgumentException format:@"Syntax error in RTF:%s", msg]; } -void GSRTFgenericRTFcommand(void *ctxt, RTFcmd cmd) +void GSRTFgenericRTFcommand(void *ctxt, RTFcmd cmd) { - fprintf(stderr, "encountered rtf cmd:%s", cmd.name); - if (cmd.isEmpty) fprintf(stderr, " argument is empty\n"); - else fprintf(stderr, " argument is %d\n", cmd.parameter); + NSLog(@"encountered rtf cmd:%s", cmd.name); + if (cmd.isEmpty) + NSLog(@" argument is empty\n"); + else + NSLog(@" argument is %d\n", cmd.parameter); } //Start: we're doing some initialization -void GSRTFstart(void *ctxt) +void GSRTFstart(void *ctxt) { - [CTXT setObject:[NSNumber numberWithInt:0] forKey: GSRTFcurrentTextPosition]; - [CTXT setObject:[NSFont userFontOfSize:12] forKey: GSRTFcurrentFont]; - [CTXT setObject:[NSMutableDictionary dictionary] forKey: GSRTFfontDictName]; + NSFont *font = [NSFont userFontOfSize:12]; + + [CTXT setObject: [NSNumber numberWithInt:0] forKey: GScurrentTextPosition]; + [CTXT setObject: [NSMutableDictionary dictionary] forKey: GSfontDictName]; + SETCHANGED(YES); + + [CTXT setObject: [NSMutableParagraphStyle defaultParagraphStyle] + forKey: GSparagraph]; + + [CTXT setObject: [font familyName] forKey: GSfontName]; + [CTXT setObject: [NSNumber numberWithFloat: 12.0] forKey: GSfontSize]; + [CTXT setObject: [NSNumber numberWithBool: NO] forKey: GSbold]; + [CTXT setObject: [NSNumber numberWithBool: NO] forKey: GSitalic]; + [CTXT setObject: [NSNumber numberWithBool: NO] forKey: GSunderline]; + [CTXT setObject: [NSNumber numberWithInt: 0] forKey: GSscript]; + [RESULT beginEditing]; } // Finished to parse one piece of RTF. -void GSRTFstop(void *ctxt) +void GSRTFstop(void *ctxt) { // close all open bolds et al. - [RESULT beginEditing]; + [RESULT endEditing]; } -void GSRTFopenBlock(void *ctxt) +void GSRTFopenBlock(void *ctxt) { + // FIXME: Should push the current state on a stack } -void GSRTFcloseBlock(void *ctxt) +void GSRTFcloseBlock(void *ctxt) { + // FIXME: Should pop the current state from a stack } -void GSRTFmangleText(void *ctxt, const char *text) +void GSRTFmangleText(void *ctxt, const char *text) { - int oldPosition=[[CTXT objectForKey: GSRTFcurrentTextPosition] intValue], - textlen=strlen(text), - newPosition=oldPosition + textlen; - NSRange insertionRange=NSMakeRange(oldPosition,0); - NSDictionary *attributes=[NSDictionary dictionaryWithObjectsAndKeys: - [CTXT objectForKey:GSRTFcurrentFont], - NSFontAttributeName,nil]; - - [CTXT setObject:[NSNumber numberWithInt:newPosition] - forKey: GSRTFcurrentTextPosition]; - - [RESULT replaceCharactersInRange:insertionRange - withString:[NSString stringWithCString:text]]; - [RESULT setAttributes:attributes range:NSMakeRange(oldPosition,textlen)]; + int oldPosition = textPosition(ctxt); + int textlen = strlen(text); + int newPosition = oldPosition + textlen; + NSRange insertionRange = NSMakeRange(oldPosition,0); + NSDictionary *attributes; + NSFont *font; + + if (textlen) + { + [CTXT setObject:[NSNumber numberWithInt: newPosition] + forKey: GScurrentTextPosition]; + + [RESULT replaceCharactersInRange: insertionRange + withString: [NSString stringWithCString:text]]; + + if (CHANGED) + { + font = currentFont(ctxt); + attributes = [NSDictionary dictionaryWithObjectsAndKeys: + font, NSFontAttributeName, + [CTXT objectForKey: GSscript], NSSuperscriptAttributeName, + PARAGRAPH, NSParagraphStyleAttributeName, + nil]; + [RESULT setAttributes: attributes range: + NSMakeRange(oldPosition, textlen)]; + SETCHANGED(NO); + } + } } -void GSRTFregisterFont(void *ctxt, const char *fontName, - RTFfontFamily family, int fontNumber) +void GSRTFregisterFont(void *ctxt, const char *fontName, + RTFfontFamily family, int fontNumber) { - NSMutableDictionary *fonts = FONTS; NSString *fontNameString; - NSNumber *fontId = [NSNumber numberWithInt:fontNumber]; + NSNumber *fontId = [NSNumber numberWithInt: fontNumber]; - if (!fontName || !*fontName || !fontId) // fontId ist nie null + if (!fontName || !*fontName) { [NSException raise:NSInvalidArgumentException format:@"Error in RTF (font omitted?), position:%d", - [[CTXT objectForKey:GSRTFcurrentTextPosition] intValue]]; + textPosition(ctxt)]; } - // exclude trailing ';' from fontName - fontNameString = [NSString stringWithCString:fontName length:strlen(fontName)-1]; - [fonts setObject:fontNameString forKey:fontId]; + // exclude trailing ';' from fontName + fontNameString = [NSString stringWithCString: fontName + length: strlen(fontName)-1]; + [FONTS setObject: fontNameString forKey: fontId]; } -void GSRTFchangeFontTo(void *ctxt, int fontNumber) +void GSRTFfontNumber(void *ctxt, int fontNumber) { - NSDictionary *fonts = FONTS; - NSNumber *fontId = [NSNumber numberWithInt:fontNumber]; - NSFont *font=[NSFont fontWithName:[fonts objectForKey:fontId] - size:[[CTXT objectForKey:GSRTFcurrentFont] pointSize]]; + NSNumber *fontId = [NSNumber numberWithInt: fontNumber]; + NSString *fontName = [FONTS objectForKey: fontId]; - if (!font) /* we're about to set an unknown font */ + if (fontName == nil) { - [NSException raise:NSInvalidArgumentException - format:@"Error in RTF (referring to undefined font \\f%d), position:%d", + /* we're about to set an unknown font */ + [NSException raise: NSInvalidArgumentException + format: @"Error in RTF (referring to undefined font \\f%d), position:%d", fontNumber, - [[CTXT objectForKey:GSRTFcurrentTextPosition] intValue]]; - } else { - font=[[NSFontManager sharedFontManager] - convertFont:[CTXT objectForKey:GSRTFcurrentFont] - toFamily:[font familyName]]; - [CTXT setObject:font forKey: GSRTFcurrentFont]; + textPosition(ctxt)]; + } + else + { + if (![fontName isEqual: [CTXT objectForKey: GSfontName]]) + { + [CTXT setObject: fontName forKey: GSfontName]; + SETCHANGED(YES); + } } } // fontSize is in halfpoints according to spec -#define fs2points(a) ((a)/2.0) -void GSRTFchangeFontSizeTo(void *ctxt, int fontSize) +void GSRTFfontSize(void *ctxt, int fontSize) { - [CTXT setObject:[[NSFontManager sharedFontManager] - convertFont:[CTXT objectForKey:GSRTFcurrentFont] - toSize:fs2points(fontSize)] - forKey:GSRTFcurrentFont]; -} - - -static NSRange rangeForContextAndAttribute(void *ctxt, NSString *attrib) -{ - NSString *attribStartString=[CTXT objectForKey:GSRTFboldRange]; + float size = halfpoints2points(fontSize); - if(!attribStartString) + if (size != [[CTXT objectForKey: GSfontSize] floatValue]) { - NSLog(@"RTF anomality (attribute:%@ off statement unpaired with on statement), position:%d", - attrib, [[CTXT objectForKey:GSRTFcurrentTextPosition] intValue]); - return NSMakeRange(0, 0); - } - return MakeRangeFromAbs([attribStartString intValue], - [[CTXT objectForKey:GSRTFcurrentTextPosition] intValue]); -} - -void GSRTFhandleItalicAttribute(void *ctxt, BOOL state) -{ - if(!state) // this indicates a bold off - { - [RESULT addAttribute:NSFontAttributeName - value:[[NSFontManager sharedFontManager] - convertFont:[CTXT objectForKey:GSRTFcurrentFont] - toHaveTrait:NSItalicFontMask] - range:rangeForContextAndAttribute(ctxt,GSRTFboldRange)]; - } else { - [CTXT setObject:[CTXT objectForKey:GSRTFcurrentTextPosition] forKey:GSRTFitalicRange]; + [CTXT setObject: [NSNumber numberWithFloat: size] + forKey: GSfontSize]; + SETCHANGED(YES); } } -void GSRTFhandleBoldAttribute(void *ctxt, BOOL state) -{ - if(!state) // this indicates a bold off - { - [RESULT addAttribute:NSFontAttributeName - value:[[NSFontManager sharedFontManager] - convertFont:[CTXT objectForKey:GSRTFcurrentFont] - toHaveTrait:NSBoldFontMask] - range:rangeForContextAndAttribute(ctxt,GSRTFboldRange)]; - } else { - [CTXT setObject:[CTXT objectForKey:GSRTFcurrentTextPosition] - forKey:GSRTFboldRange]; - } -} - -void GSRTFhandleDocumentAttribute(void *ctxt, int attrib) +void GSRTFpaperWidth(void *ctxt, int width) { } -NSMutableAttributedString *attributedStringFromRTF(NSString *rtfString) +void GSRTFpaperHeight(void *ctxt, int height) +{ +} + +void GSRTFmarginLeft(void *ctxt, int margin) +{ +} + +void GSRTFmarginRight(void *ctxt, int margin) +{ +} + +void GSRTFfirstLineIndent(void *ctxt, int indent) +{ + NSMutableParagraphStyle *para = PARAGRAPH; + float findent = twips2points(indent); + + if ([para firstLineHeadIndent] != findent) + { + [para setFirstLineHeadIndent: findent]; + SETCHANGED(YES); + } +} + +void GSRTFleftIndent(void *ctxt, int indent) +{ + NSMutableParagraphStyle *para = PARAGRAPH; + float findent = twips2points(indent); + + if ([para headIndent] != findent) + { + [para setHeadIndent: findent]; + SETCHANGED(YES); + } +} + +void GSRTFalignCenter(void *ctxt) +{ + NSMutableParagraphStyle *para = PARAGRAPH; + + if ([para alignment] != NSCenterTextAlignment) + { + [para setAlignment: NSCenterTextAlignment]; + SETCHANGED(YES); + } +} + +void GSRTFalignLeft(void *ctxt) +{ + NSMutableParagraphStyle *para = PARAGRAPH; + + if ([para alignment] != NSLeftTextAlignment) + { + [para setAlignment: NSLeftTextAlignment]; + SETCHANGED(YES); + } +} + +void GSRTFalignRight(void *ctxt) +{ + NSMutableParagraphStyle *para = PARAGRAPH; + + if ([para alignment] != NSRightTextAlignment) + { + [para setAlignment: NSRightTextAlignment]; + SETCHANGED(YES); + } +} + +void GSRTFstyle(void *ctxt, int style) +{ +} + +void GSRTFcolorbg(void *ctxt, int color) +{ +} + +void GSRTFcolorfg(void *ctxt, int color) +{ +} + +void GSRTFsubscript(void *ctxt, int script) +{ + script = (int) -halfpoints2points(script); + + if (script != [[CTXT objectForKey: GSscript] intValue]) + { + [CTXT setObject: [NSNumber numberWithInt: script] + forKey: GSscript]; + SETCHANGED(YES); + } +} + +void GSRTFsuperscript(void *ctxt, int script) +{ + script = (int) halfpoints2points(script); + + if (script != [[CTXT objectForKey: GSscript] intValue]) + { + [CTXT setObject: [NSNumber numberWithInt: script] + forKey: GSscript]; + SETCHANGED(YES); + } +} + +void GSRTFitalic(void *ctxt, BOOL state) +{ + if (state != [[CTXT objectForKey: GSitalic] boolValue]) + { + [CTXT setObject: [NSNumber numberWithBool: state] forKey: GSitalic]; + SETCHANGED(YES); + } +} + +void GSRTFbold(void *ctxt, BOOL state) +{ + if (state != [[CTXT objectForKey: GSbold] boolValue]) + { + [CTXT setObject: [NSNumber numberWithBool: state] forKey: GSbold]; + SETCHANGED(YES); + } +} + +void GSRTFunderline(void *ctxt, BOOL state) +{ + if (state != [[CTXT objectForKey: GSunderline] boolValue]) + { + [CTXT setObject: [NSNumber numberWithBool: state] forKey: GSunderline]; + SETCHANGED(YES); + } +} + + + +BOOL parseRTFintoAttributedString(NSString *rtfString, + NSMutableAttributedString *result, + NSDictionary **dict) { RTFscannerCtxt scanner; StringContext stringCtxt; NSMutableDictionary *myDict = [NSMutableDictionary dictionary]; - NSMutableAttributedString *result=[[NSMutableAttributedString alloc] init]; - [myDict setObject:result forKey: GSRTFresultName]; + [myDict setObject: result forKey: GSresultName]; initStringContext(&stringCtxt, rtfString); lexInitContext(&scanner, &stringCtxt, (int (*)(void*))readNSString); GSRTFparse(myDict, &scanner); - - return [result autorelease]; + + // document attributes + if (dict) + (*dict)=[myDict objectForKey: GSdocumentAttributes]; + + return YES; } -@implementation NSAttributedString (RTFParser) - -- (id) initWithRTF: (NSData*)data - documentAttributes: (NSDictionary**)dict +NSMutableAttributedString *attributedStringFromRTF(NSString *rtfString) { - RTFscannerCtxt scanner; - StringContext stringCtxt; - NSMutableDictionary *myDict = [NSMutableDictionary dictionary]; - NSString *parseString = [NSString stringWithCString:[data bytes] - length:[data length]]; - NSMutableAttributedString *result = - [[[NSMutableAttributedString alloc] init] autorelease]; + NSMutableAttributedString *result = [[NSMutableAttributedString alloc] init]; - [myDict setObject:result forKey: GSRTFresultName]; - initStringContext(&stringCtxt, parseString); - lexInitContext(&scanner, &stringCtxt, (int (*)(void*))readNSString); - GSRTFparse(myDict, &scanner); - - if (dict && [myDict objectForKey:GSRTFdocumentAttributes]) - (*dict)=[myDict objectForKey:GSRTFdocumentAttributes]; // document - [self autorelease]; - return [[[self class] alloc] initWithAttributedString:result]; -} + parseRTFintoAttributedString(rtfString, result, NULL); -@end + return AUTORELEASE(result); +} diff --git a/Source/Parsers/rtfConsumer.h b/Source/Parsers/rtfConsumer.h index efdabca5a..d8ba04609 100644 --- a/Source/Parsers/rtfConsumer.h +++ b/Source/Parsers/rtfConsumer.h @@ -32,4 +32,8 @@ /* external symbols from the grammer */ int GSRTFparse(void *ctxt, RTFscannerCtxt *lctxt); +BOOL parseRTFintoAttributedString(NSString *rtfString, + NSMutableAttributedString *result, + NSDictionary **dict); + #endif diff --git a/Source/Parsers/rtfConsumerFunctions.h b/Source/Parsers/rtfConsumerFunctions.h index 9887629f6..ed1e645a3 100644 --- a/Source/Parsers/rtfConsumerFunctions.h +++ b/Source/Parsers/rtfConsumerFunctions.h @@ -60,17 +60,49 @@ void GSRTFmangleText(void *ctxt, const char *text); font functions */ -/* get noticed that a particular font is introduced the font number is - introduced by an prededing GSRTFchangeFontTo call this state - can be recognized by the fact that the fontNumber in question - is unseen by then */ +/* get noticed that a particular font is introduced */ void GSRTFregisterFont(void *ctxt, const char *fontName, RTFfontFamily family, int fontNumber); -/* this function is twofold: change font in character stream [you must - maintain stream info in ctxt]; introduce fonts in the first place */ -void GSRTFchangeFontTo(void *ctxt, int fontNumber); -/* subject says it all */ -void GSRTFchangeFontSizeTo(void *ctxt, int fontSize); +/* change font number */ +void GSRTFfontNumber(void *ctxt, int fontNumber); +/* change font size in half points*/ +void GSRTFfontSize(void *ctxt, int fontSize); + +/* set paper width in twips */ +void GSRTFpaperWidth(void *ctxt, int width); +/* set paper height in twips */ +void GSRTFpaperHeight(void *ctxt, int height); +/* set left margin in twips */ +void GSRTFmarginLeft(void *ctxt, int margin); +/* set right margin in twips */ +void GSRTFmarginRight(void *ctxt, int margin); +/* set first line indent */ +void GSRTFfirstLineIndent(void *ctxt, int indent); +/* set left indent */ +void GSRTFleftIndent(void *ctxt, int indent); +/* set center alignment */ +void GSRTFalignCenter(void *ctxt); +/* set left alignment */ +void GSRTFalignLeft(void *ctxt); +/* set right alignment */ +void GSRTFalignRight(void *ctxt); +/* set paragraph style */ +void GSRTFstyle(void *ctxt, int style); +/* set background colour */ +void GSRTFcolorbg(void *ctxt, int color); +/* set foreground colour */ +void GSRTFcolorfg(void *ctxt, int color); +/* set subscript in half points */ +void GSRTFsubscript(void *ctxt, int script); +/* set superscript in half points */ +void GSRTFsuperscript(void *ctxt, int script); +/* Switch bold mode on or off */ +void GSRTFbold(void *ctxt, BOOL on); +/* Switch italic mode on or off */ +void GSRTFitalic(void *ctxt, BOOL on); +/* Switch underline mode on or off */ +void GSRTFunderline(void *ctxt, BOOL on); #endif + diff --git a/Source/Parsers/rtfGrammer.tab.c b/Source/Parsers/rtfGrammer.tab.c index 13db5e7aa..13d9304c5 100644 --- a/Source/Parsers/rtfGrammer.tab.c +++ b/Source/Parsers/rtfGrammer.tab.c @@ -1,6 +1,6 @@ /* A Bison parser, made from Parsers/rtfGrammer.y - by GNU Bison version 1.27 + by GNU Bison version 1.25 */ #define YYBISON 1 /* Identify Bison output. */ @@ -14,27 +14,49 @@ #define yynerrs GSRTFnerrs #define YYLSP_NEEDED -#define RTFtext 257 -#define RTFstart 258 -#define RTFfont 259 -#define RTFfontSize 260 -#define RTFpaperWidth 261 -#define RTFpaperHeight 262 -#define RTFmarginLeft 263 -#define RTFmarginRight 264 -#define RTFbold 265 -#define RTFitalic 266 -#define RTFunderline 267 -#define RTFunderlineStop 268 -#define RTFOtherStatement 269 -#define RTFfontListStart 270 -#define RTFfamilyNil 271 -#define RTFfamilyRoman 272 -#define RTFfamilySwiss 273 -#define RTFfamilyModern 274 -#define RTFfamilyScript 275 -#define RTFfamilyDecor 276 -#define RTFfamilyTech 277 +#define RTFtext 258 +#define RTFstart 259 +#define RTFansi 260 +#define RTFmac 261 +#define RTFpc 262 +#define RTFpca 263 +#define RTFignore 264 +#define RTFred 265 +#define RTFgreen 266 +#define RTFblue 267 +#define RTFcolorbg 268 +#define RTFcolorfg 269 +#define RTFcolortable 270 +#define RTFfont 271 +#define RTFfontSize 272 +#define RTFpaperWidth 273 +#define RTFpaperHeight 274 +#define RTFmarginLeft 275 +#define RTFmarginRight 276 +#define RTFfirstLineIndent 277 +#define RTFleftIndent 278 +#define RTFalignCenter 279 +#define RTFalignLeft 280 +#define RTFalignRight 281 +#define RTFstyle 282 +#define RTFbold 283 +#define RTFitalic 284 +#define RTFunderline 285 +#define RTFunderlineStop 286 +#define RTFsubscript 287 +#define RTFsuperscript 288 +#define RTFtabulator 289 +#define RTFparagraph 290 +#define RTFdefaultParagraph 291 +#define RTFOtherStatement 292 +#define RTFfontListStart 293 +#define RTFfamilyNil 294 +#define RTFfamilyRoman 295 +#define RTFfamilySwiss 296 +#define RTFfamilyModern 297 +#define RTFfamilyScript 298 +#define RTFfamilyDecor 299 +#define RTFfamilyTech 300 #line 35 "Parsers/rtfGrammer.y" @@ -104,11 +126,11 @@ typedef -#define YYFINAL 41 +#define YYFINAL 74 #define YYFLAG -32768 -#define YYNTBASE 27 +#define YYNTBASE 49 -#define YYTRANSLATE(x) ((unsigned)(x) <= 277 ? yytranslate[x] : 37) +#define YYTRANSLATE(x) ((unsigned)(x) <= 300 ? yytranslate[x] : 65) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -120,10 +142,10 @@ static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 26, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 48, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 24, 2, 25, 2, 2, 2, 2, 2, + 2, 2, 46, 2, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -136,39 +158,50 @@ static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23 + 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45 }; #if YYDEBUG != 0 static const short yyprhs[] = { 0, - 0, 1, 4, 5, 10, 11, 14, 17, 20, 22, - 24, 28, 30, 32, 34, 36, 38, 40, 42, 44, - 46, 48, 50, 52, 54, 57, 58, 61, 66, 70, - 72, 74, 76, 78, 80, 82, 84 + 0, 1, 2, 10, 12, 14, 16, 18, 19, 22, + 25, 28, 31, 34, 35, 40, 41, 47, 49, 51, + 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, + 73, 75, 77, 79, 81, 83, 85, 87, 89, 94, + 95, 98, 103, 107, 109, 111, 113, 115, 117, 119, + 121, 126, 127, 130, 135, 137 }; static const short yyrhs[] = { -1, - 28, 29, 0, 0, 24, 30, 31, 25, 0, 0, - 31, 32, 0, 31, 3, 0, 31, 29, 0, 0, - 0, 32, 0, 24, 32, 25, 0, 4, 0, 33, - 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, - 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, - 0, 15, 0, 16, 34, 0, 0, 34, 35, 0, - 34, 24, 35, 25, 0, 5, 36, 3, 0, 17, - 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, - 0, 23, 0, 26, 0 + 0, 46, 50, 4, 52, 53, 51, 47, 0, 5, + 0, 6, 0, 7, 0, 8, 0, 0, 53, 58, + 0, 53, 62, 0, 53, 57, 0, 53, 3, 0, + 53, 54, 0, 0, 46, 55, 53, 47, 0, 0, + 46, 56, 9, 53, 47, 0, 16, 0, 17, 0, + 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, + 23, 0, 24, 0, 25, 0, 26, 0, 27, 0, + 13, 0, 14, 0, 32, 0, 33, 0, 28, 0, + 29, 0, 30, 0, 31, 0, 37, 0, 46, 38, + 59, 47, 0, 0, 59, 60, 0, 59, 46, 60, + 47, 0, 16, 61, 3, 0, 39, 0, 40, 0, + 41, 0, 42, 0, 43, 0, 44, 0, 45, 0, + 46, 15, 63, 47, 0, 0, 63, 64, 0, 10, + 11, 12, 3, 0, 3, 0, 48, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 109, 109, 112, 112, 115, 116, 117, 118, 126, 127, - 130, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 152, 155, 156, 157, 163, 168, - 170, 171, 172, 173, 174, 175, 186 + 131, 131, 132, 134, 135, 136, 137, 140, 141, 142, + 143, 144, 145, 148, 148, 149, 149, 157, 164, 171, + 178, 185, 192, 199, 206, 213, 214, 215, 216, 217, + 224, 231, 238, 245, 252, 259, 266, 267, 274, 277, + 278, 279, 285, 289, 291, 292, 293, 294, 295, 296, + 304, 307, 308, 312, 313, 319 }; #endif @@ -176,69 +209,103 @@ static const short yyrline[] = { 0, #if YYDEBUG != 0 || defined (YYERROR_VERBOSE) static const char * const yytname[] = { "$","error","$undefined.","RTFtext", -"RTFstart","RTFfont","RTFfontSize","RTFpaperWidth","RTFpaperHeight","RTFmarginLeft", -"RTFmarginRight","RTFbold","RTFitalic","RTFunderline","RTFunderlineStop","RTFOtherStatement", -"RTFfontListStart","RTFfamilyNil","RTFfamilyRoman","RTFfamilySwiss","RTFfamilyModern", -"RTFfamilyScript","RTFfamilyDecor","RTFfamilyTech","'{'","'}'","'\\\\'","rtfText", -"@1","rtfBlock","@2","rtfIngredients","rtfStatement","rtfFontList","rtfFonts", -"rtfFontStatement","rtfFontFamily", NULL +"RTFstart","RTFansi","RTFmac","RTFpc","RTFpca","RTFignore","RTFred","RTFgreen", +"RTFblue","RTFcolorbg","RTFcolorfg","RTFcolortable","RTFfont","RTFfontSize", +"RTFpaperWidth","RTFpaperHeight","RTFmarginLeft","RTFmarginRight","RTFfirstLineIndent", +"RTFleftIndent","RTFalignCenter","RTFalignLeft","RTFalignRight","RTFstyle","RTFbold", +"RTFitalic","RTFunderline","RTFunderlineStop","RTFsubscript","RTFsuperscript", +"RTFtabulator","RTFparagraph","RTFdefaultParagraph","RTFOtherStatement","RTFfontListStart", +"RTFfamilyNil","RTFfamilyRoman","RTFfamilySwiss","RTFfamilyModern","RTFfamilyScript", +"RTFfamilyDecor","RTFfamilyTech","'{'","'}'","'\\'","rtfFile","@1","@2","rtfCharset", +"rtfIngredients","rtfBlock","@3","@4","rtfStatement","rtfFontList","rtfFonts", +"rtfFontStatement","rtfFontFamily","rtfColorDef","rtfColors","rtfColorStatement", NULL }; #endif static const short yyr1[] = { 0, - 28, 27, 30, 29, 31, 31, 31, 31, -1, -1, - -1, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 33, 34, 34, 34, 35, 36, - 36, 36, 36, 36, 36, 36, -1 + 50, 51, 49, 52, 52, 52, 52, 53, 53, 53, + 53, 53, 53, 55, 54, 56, 54, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 58, 59, + 59, 59, 60, 61, 61, 61, 61, 61, 61, 61, + 62, 63, 63, 64, 64, -1 }; static const short yyr2[] = { 0, - 0, 2, 0, 4, 0, 2, 2, 2, 1, 1, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 0, 2, 4, 3, 1, - 1, 1, 1, 1, 1, 1, 1 + 0, 0, 7, 1, 1, 1, 1, 0, 2, 2, + 2, 2, 2, 0, 4, 0, 5, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 4, 0, + 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, + 4, 0, 2, 4, 1, 1 }; -static const short yydefact[] = { 1, - 0, 3, 2, 5, 0, 7, 12, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 26, 4, - 8, 6, 13, 25, 0, 0, 27, 30, 31, 32, - 33, 34, 35, 36, 0, 0, 29, 28, 0, 0, - 0 +static const short yydefact[] = { 0, + 1, 0, 0, 4, 5, 6, 7, 8, 2, 12, + 30, 31, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 34, 35, 36, 37, 32, 33, + 38, 14, 0, 13, 11, 9, 10, 52, 40, 8, + 0, 3, 0, 0, 0, 8, 55, 0, 51, 53, + 0, 0, 39, 41, 15, 0, 0, 44, 45, 46, + 47, 48, 49, 50, 0, 0, 17, 0, 43, 42, + 54, 0, 0, 0 }; -static const short yydefgoto[] = { 39, - 1, 3, 4, 5, 22, 23, 24, 27, 35 +static const short yydefgoto[] = { 72, + 2, 33, 8, 9, 34, 40, 41, 35, 36, 44, + 54, 65, 37, 43, 50 }; -static const short yypact[] = {-32768, - -9,-32768,-32768,-32768, -3,-32768,-32768,-32768,-32768,-32768, +static const short yypact[] = { -45, +-32768, 8, 66,-32768,-32768,-32768,-32768,-32768, 67,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768, 9, 6, 11,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768, 14, -7,-32768,-32768, 19, 20, --32768 +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768, 92, -10,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 30,-32768, 28, -14, -3,-32768,-32768, 29,-32768,-32768, + -36, 25,-32768,-32768,-32768, 32, 35,-32768,-32768,-32768, +-32768,-32768,-32768,-32768, 63, 20,-32768, 65,-32768,-32768, +-32768, 76, 77,-32768 }; static const short yypgoto[] = {-32768, --32768, 25,-32768,-32768,-32768,-32768,-32768, 5,-32768 +-32768,-32768,-32768, -4,-32768,-32768,-32768,-32768,-32768,-32768, + 50,-32768,-32768,-32768,-32768 }; -#define YYLAST 33 +#define YYLAST 130 -static const short yytable[] = { 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 25, 2, 25, 37, 38, 40, 41, - 2, 20, 28, 29, 30, 31, 32, 33, 34, 21, - 36, 0, 26 +static const short yytable[] = { 10, + 1, 51, 58, 59, 60, 61, 62, 63, 64, 11, + 12, 3, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 47, 52, 53, 31, 10, 45, 42, 48, 46, 57, + 51, 56, 32, 55, 11, 12, 68, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 69, 70, 71, 31, 10, + 4, 5, 6, 7, 49, 73, 74, 32, 67, 11, + 12, 0, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + -16, 66, 0, 31, 0, 0, 38, 0, 0, 0, + 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 39 }; static const short yycheck[] = { 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 5, 24, 5, 3, 25, 0, 0, - 24, 25, 17, 18, 19, 20, 21, 22, 23, 5, - 26, -1, 24 + 46, 16, 39, 40, 41, 42, 43, 44, 45, 13, + 14, 4, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 3, 46, 47, 37, 3, 40, 47, 10, 9, 11, + 16, 46, 46, 47, 13, 14, 12, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 3, 47, 3, 37, 3, + 5, 6, 7, 8, 47, 0, 0, 46, 47, 13, + 14, -1, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 9, 52, -1, 37, -1, -1, 15, -1, -1, -1, + -1, -1, 46, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 38 }; #define YYPURE 1 @@ -742,117 +809,266 @@ yyreduce: switch (yyn) { case 1: -#line 109 "Parsers/rtfGrammer.y" +#line 131 "Parsers/rtfGrammer.y" { GSRTFstart(ctxt); ; break;} case 2: -#line 109 "Parsers/rtfGrammer.y" +#line 131 "Parsers/rtfGrammer.y" { GSRTFstop(ctxt); ; break;} -case 3: -#line 112 "Parsers/rtfGrammer.y" -{ GSRTFopenBlock(ctxt); ; - break;} case 4: -#line 112 "Parsers/rtfGrammer.y" -{ GSRTFcloseBlock(ctxt); ; +#line 134 "Parsers/rtfGrammer.y" +{ yyval.number = 1; ; + break;} +case 5: +#line 135 "Parsers/rtfGrammer.y" +{ yyval.number = 2; ; + break;} +case 6: +#line 136 "Parsers/rtfGrammer.y" +{ yyval.number = 3; ; break;} case 7: -#line 117 "Parsers/rtfGrammer.y" -{ GSRTFmangleText(ctxt, yyvsp[0].text); free((void *)yyvsp[0].text); ; - break;} -case 11: -#line 130 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 137 "Parsers/rtfGrammer.y" +{ yyval.number = 4; ; break;} case 12: -#line 133 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; - break;} -case 13: -#line 134 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 144 "Parsers/rtfGrammer.y" +{ GSRTFmangleText(ctxt, yyvsp[0].text); free((void *)yyvsp[0].text); ; break;} case 14: -#line 135 "Parsers/rtfGrammer.y" -{ yyval.number=0; GSRTFchangeFontTo(ctxt, yyvsp[0].cmd.parameter); ; +#line 148 "Parsers/rtfGrammer.y" +{ GSRTFopenBlock(ctxt); ; break;} case 15: -#line 136 "Parsers/rtfGrammer.y" -{ yyval.number=0; GSRTFchangeFontSizeTo(ctxt, yyvsp[0].cmd.parameter); ; +#line 148 "Parsers/rtfGrammer.y" +{ GSRTFcloseBlock(ctxt); ; break;} case 16: -#line 137 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 149 "Parsers/rtfGrammer.y" +{ GSRTFopenBlock(ctxt); ; break;} case 17: -#line 138 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 149 "Parsers/rtfGrammer.y" +{ GSRTFcloseBlock(ctxt); ; break;} case 18: -#line 139 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 157 "Parsers/rtfGrammer.y" +{ int font; + + if (yyvsp[0].cmd.isEmpty) + font = 0; + else + font = yyvsp[0].cmd.parameter; + GSRTFfontNumber(ctxt, font); ; break;} case 19: -#line 140 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 164 "Parsers/rtfGrammer.y" +{ int size; + + if (yyvsp[0].cmd.isEmpty) + size = 24; + else + size = yyvsp[0].cmd.parameter; + GSRTFfontSize(ctxt, size); ; break;} case 20: -#line 141 "Parsers/rtfGrammer.y" -{ yyval.number=0; GSRTFhandleBoldAttribute(ctxt, yyvsp[0].cmd.isEmpty || !!yyvsp[0].cmd.parameter); ; +#line 171 "Parsers/rtfGrammer.y" +{ int width; + + if (yyvsp[0].cmd.isEmpty) + width = 12240; + else + width = yyvsp[0].cmd.parameter; + GSRTFpaperWidth(ctxt, width);; break;} case 21: -#line 142 "Parsers/rtfGrammer.y" -{ yyval.number=0; GSRTFhandleItalicAttribute(ctxt, yyvsp[0].cmd.isEmpty || !!yyvsp[0].cmd.parameter); ; +#line 178 "Parsers/rtfGrammer.y" +{ int height; + + if (yyvsp[0].cmd.isEmpty) + height = 15840; + else + height = yyvsp[0].cmd.parameter; + GSRTFpaperHeight(ctxt, height);; break;} case 22: -#line 143 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 185 "Parsers/rtfGrammer.y" +{ int margin; + + if (yyvsp[0].cmd.isEmpty) + margin = 1800; + else + margin = yyvsp[0].cmd.parameter; + GSRTFmarginLeft(ctxt, margin);; break;} case 23: -#line 144 "Parsers/rtfGrammer.y" -{ yyval.number=0; ; +#line 192 "Parsers/rtfGrammer.y" +{ int margin; + + if (yyvsp[0].cmd.isEmpty) + margin = 1800; + else + margin = yyvsp[0].cmd.parameter; + GSRTFmarginRight(ctxt, margin); ; break;} case 24: -#line 145 "Parsers/rtfGrammer.y" -{ yyval.number=0; GSRTFgenericRTFcommand(ctxt, yyvsp[0].cmd); ; +#line 199 "Parsers/rtfGrammer.y" +{ int indent; + + if (yyvsp[0].cmd.isEmpty) + indent = 0; + else + indent = yyvsp[0].cmd.parameter; + GSRTFfirstLineIndent(ctxt, indent); ; + break;} +case 25: +#line 206 "Parsers/rtfGrammer.y" +{ int indent; + + if (yyvsp[0].cmd.isEmpty) + indent = 0; + else + indent = yyvsp[0].cmd.parameter; + GSRTFleftIndent(ctxt, indent);; + break;} +case 26: +#line 213 "Parsers/rtfGrammer.y" +{ GSRTFalignCenter(ctxt); ; + break;} +case 27: +#line 214 "Parsers/rtfGrammer.y" +{ GSRTFalignLeft(ctxt); ; + break;} +case 28: +#line 215 "Parsers/rtfGrammer.y" +{ GSRTFalignRight(ctxt); ; break;} case 29: -#line 163 "Parsers/rtfGrammer.y" -{ yyval.number=0; GSRTFregisterFont(ctxt, yyvsp[0].text, yyvsp[-1].number, yyvsp[-2].cmd.parameter); - free((void *)yyvsp[0].text); - ; +#line 216 "Parsers/rtfGrammer.y" +{ GSRTFstyle(ctxt, yyvsp[0].cmd.parameter); ; break;} case 30: -#line 169 "Parsers/rtfGrammer.y" -{ yyval.number = RTFfamilyNil - RTFfamilyNil; ; +#line 217 "Parsers/rtfGrammer.y" +{ int color; + + if (yyvsp[0].cmd.isEmpty) + color = 0; + else + color = yyvsp[0].cmd.parameter; + GSRTFcolorbg(ctxt, color); ; break;} case 31: -#line 170 "Parsers/rtfGrammer.y" -{ yyval.number = RTFfamilyRoman - RTFfamilyNil; ; +#line 224 "Parsers/rtfGrammer.y" +{ int color; + + if (yyvsp[0].cmd.isEmpty) + color = 0; + else + color = yyvsp[0].cmd.parameter; + GSRTFcolorfg(ctxt, color); ; break;} case 32: -#line 171 "Parsers/rtfGrammer.y" -{ yyval.number = RTFfamilySwiss - RTFfamilyNil; ; +#line 231 "Parsers/rtfGrammer.y" +{ int script; + + if (yyvsp[0].cmd.isEmpty) + script = 6; + else + script = yyvsp[0].cmd.parameter; + GSRTFsubscript(ctxt, script); ; break;} case 33: -#line 172 "Parsers/rtfGrammer.y" -{ yyval.number = RTFfamilyModern - RTFfamilyNil; ; +#line 238 "Parsers/rtfGrammer.y" +{ int script; + + if (yyvsp[0].cmd.isEmpty) + script = 6; + else + script = yyvsp[0].cmd.parameter; + GSRTFsuperscript(ctxt, script); ; break;} case 34: -#line 173 "Parsers/rtfGrammer.y" -{ yyval.number = RTFfamilyScript - RTFfamilyNil; ; +#line 245 "Parsers/rtfGrammer.y" +{ BOOL on; + + if (yyvsp[0].cmd.isEmpty || yyvsp[0].cmd.parameter) + on = YES; + else + on = NO; + GSRTFbold(ctxt, on); ; break;} case 35: -#line 174 "Parsers/rtfGrammer.y" -{ yyval.number = RTFfamilyDecor - RTFfamilyNil; ; +#line 252 "Parsers/rtfGrammer.y" +{ BOOL on; + + if (yyvsp[0].cmd.isEmpty || yyvsp[0].cmd.parameter) + on = YES; + else + on = NO; + GSRTFitalic(ctxt, on); ; break;} case 36: -#line 175 "Parsers/rtfGrammer.y" -{ yyval.number = RTFfamilyTech - RTFfamilyNil; ; +#line 259 "Parsers/rtfGrammer.y" +{ BOOL on; + + if (yyvsp[0].cmd.isEmpty || yyvsp[0].cmd.parameter) + on = YES; + else + on = NO; + GSRTFunderline(ctxt, on); ; break;} case 37: -#line 186 "Parsers/rtfGrammer.y" +#line 266 "Parsers/rtfGrammer.y" +{ GSRTFunderline(ctxt, NO); ; + break;} +case 38: +#line 267 "Parsers/rtfGrammer.y" +{ GSRTFgenericRTFcommand(ctxt, yyvsp[0].cmd); ; + break;} +case 43: +#line 285 "Parsers/rtfGrammer.y" +{ GSRTFregisterFont(ctxt, yyvsp[0].text, yyvsp[-1].number, yyvsp[-2].cmd.parameter); + free((void *)yyvsp[0].text); ; + break;} +case 44: +#line 290 "Parsers/rtfGrammer.y" +{ yyval.number = RTFfamilyNil - RTFfamilyNil; ; + break;} +case 45: +#line 291 "Parsers/rtfGrammer.y" +{ yyval.number = RTFfamilyRoman - RTFfamilyNil; ; + break;} +case 46: +#line 292 "Parsers/rtfGrammer.y" +{ yyval.number = RTFfamilySwiss - RTFfamilyNil; ; + break;} +case 47: +#line 293 "Parsers/rtfGrammer.y" +{ yyval.number = RTFfamilyModern - RTFfamilyNil; ; + break;} +case 48: +#line 294 "Parsers/rtfGrammer.y" +{ yyval.number = RTFfamilyScript - RTFfamilyNil; ; + break;} +case 49: +#line 295 "Parsers/rtfGrammer.y" +{ yyval.number = RTFfamilyDecor - RTFfamilyNil; ; + break;} +case 50: +#line 296 "Parsers/rtfGrammer.y" +{ yyval.number = RTFfamilyTech - RTFfamilyNil; ; + break;} +case 54: +#line 312 "Parsers/rtfGrammer.y" +{ free((void *)yyvsp[0].text);; + break;} +case 55: +#line 313 "Parsers/rtfGrammer.y" +{ free((void *)yyvsp[0].text);; + break;} +case 56: +#line 319 "Parsers/rtfGrammer.y" { yylsp[0].first_line; ; break;} } @@ -1053,7 +1269,7 @@ yyerrhandle: yystate = yyn; goto yynewstate; } -#line 189 "Parsers/rtfGrammer.y" +#line 322 "Parsers/rtfGrammer.y" /* some C code here */ diff --git a/Source/Parsers/rtfGrammer.y b/Source/Parsers/rtfGrammer.y index b2322d4b8..39e579f4c 100644 --- a/Source/Parsers/rtfGrammer.y +++ b/Source/Parsers/rtfGrammer.y @@ -76,16 +76,38 @@ typedef void * GSRTFctxt; /*

RTFtext values have to be freed */ %token RTFtext %token RTFstart +%token RTFansi +%token RTFmac +%token RTFpc +%token RTFpca +%token RTFignore +%token RTFred +%token RTFgreen +%token RTFblue +%token RTFcolorbg +%token RTFcolorfg +%token RTFcolortable %token RTFfont %token RTFfontSize %token RTFpaperWidth %token RTFpaperHeight %token RTFmarginLeft %token RTFmarginRight +%token RTFfirstLineIndent +%token RTFleftIndent +%token RTFalignCenter +%token RTFalignLeft +%token RTFalignRight +%token RTFstyle %token RTFbold %token RTFitalic %token RTFunderline %token RTFunderlineStop +%token RTFsubscript +%token RTFsuperscript +%token RTFtabulator +%token RTFparagraph +%token RTFdefaultParagraph %token RTFOtherStatement %token RTFfontListStart @@ -100,56 +122,156 @@ typedef void * GSRTFctxt; %token RTFfamilyDecor %token RTFfamilyTech -%type rtfFontFamily rtfStatement rtfGeneralStatement rtfBlockStatement rtfFontStatement +%type rtfFontFamily rtfCharset rtfFontStatement /* let's go */ %% -rtfText: { GSRTFstart(ctxt); } rtfBlock { GSRTFstop(ctxt); } +rtfFile: '{' { GSRTFstart(ctxt); } RTFstart rtfCharset rtfIngredients { GSRTFstop(ctxt); } '}' ; -rtfBlock: '{' { GSRTFopenBlock(ctxt); } rtfIngredients '}' { GSRTFcloseBlock(ctxt); } +rtfCharset: RTFansi { $$ = 1; } + | RTFmac { $$ = 2; } + | RTFpc { $$ = 3; } + | RTFpca { $$ = 4; } ; rtfIngredients: /* empty */ + | rtfIngredients rtfFontList + | rtfIngredients rtfColorDef | rtfIngredients rtfStatement | rtfIngredients RTFtext { GSRTFmangleText(ctxt, $2); free((void *)$2); } | rtfIngredients rtfBlock ; +rtfBlock: '{' { GSRTFopenBlock(ctxt); } rtfIngredients '}' { GSRTFcloseBlock(ctxt); } + | '{' { GSRTFopenBlock(ctxt); } RTFignore rtfIngredients '}' { GSRTFcloseBlock(ctxt); } + ; + /* RTF statements start with a '\', have a alpha name and a number argument */ -rtfGeneralStatement: rtfBlockStatement - | rtfStatement - ; +rtfStatement: RTFfont { int font; + + if ($1.isEmpty) + font = 0; + else + font = $1.parameter; + GSRTFfontNumber(ctxt, font); } + | RTFfontSize { int size; -rtfBlockStatement: '{' rtfStatement '}' { $$=0; } - ; + if ($1.isEmpty) + size = 24; + else + size = $1.parameter; + GSRTFfontSize(ctxt, size); } + | RTFpaperWidth { int width; + + if ($1.isEmpty) + width = 12240; + else + width = $1.parameter; + GSRTFpaperWidth(ctxt, width);} + | RTFpaperHeight { int height; + + if ($1.isEmpty) + height = 15840; + else + height = $1.parameter; + GSRTFpaperHeight(ctxt, height);} + | RTFmarginLeft { int margin; + + if ($1.isEmpty) + margin = 1800; + else + margin = $1.parameter; + GSRTFmarginLeft(ctxt, margin);} + | RTFmarginRight { int margin; + + if ($1.isEmpty) + margin = 1800; + else + margin = $1.parameter; + GSRTFmarginRight(ctxt, margin); } + | RTFfirstLineIndent { int indent; + + if ($1.isEmpty) + indent = 0; + else + indent = $1.parameter; + GSRTFfirstLineIndent(ctxt, indent); } + | RTFleftIndent { int indent; + + if ($1.isEmpty) + indent = 0; + else + indent = $1.parameter; + GSRTFleftIndent(ctxt, indent);} + | RTFalignCenter { GSRTFalignCenter(ctxt); } + | RTFalignLeft { GSRTFalignLeft(ctxt); } + | RTFalignRight { GSRTFalignRight(ctxt); } + | RTFstyle { GSRTFstyle(ctxt, $1.parameter); } + | RTFcolorbg { int color; + + if ($1.isEmpty) + color = 0; + else + color = $1.parameter; + GSRTFcolorbg(ctxt, color); } + | RTFcolorfg { int color; + + if ($1.isEmpty) + color = 0; + else + color = $1.parameter; + GSRTFcolorfg(ctxt, color); } + | RTFsubscript { int script; + + if ($1.isEmpty) + script = 6; + else + script = $1.parameter; + GSRTFsubscript(ctxt, script); } + | RTFsuperscript { int script; + + if ($1.isEmpty) + script = 6; + else + script = $1.parameter; + GSRTFsuperscript(ctxt, script); } + | RTFbold { BOOL on; -rtfStatement: RTFstart { $$=0; } - | rtfFontList { $$=0; } - | RTFfont { $$=0; GSRTFchangeFontTo(ctxt, $1.parameter); } - | RTFfontSize { $$=0; GSRTFchangeFontSizeTo(ctxt, $1.parameter); } - | RTFpaperWidth { $$=0; } - | RTFpaperHeight { $$=0; } - | RTFmarginLeft { $$=0; } - | RTFmarginRight { $$=0; } - | RTFbold { $$=0; GSRTFhandleBoldAttribute(ctxt, $1.isEmpty || !!$1.parameter); } - | RTFitalic { $$=0; GSRTFhandleItalicAttribute(ctxt, $1.isEmpty || !!$1.parameter); } - | RTFunderline { $$=0; } - | RTFunderlineStop { $$=0; } - | RTFOtherStatement { $$=0; GSRTFgenericRTFcommand(ctxt, $1); } + if ($1.isEmpty || $1.parameter) + on = YES; + else + on = NO; + GSRTFbold(ctxt, on); } + | RTFitalic { BOOL on; + + if ($1.isEmpty || $1.parameter) + on = YES; + else + on = NO; + GSRTFitalic(ctxt, on); } + | RTFunderline { BOOL on; + + if ($1.isEmpty || $1.parameter) + on = YES; + else + on = NO; + GSRTFunderline(ctxt, on); } + | RTFunderlineStop { GSRTFunderline(ctxt, NO); } + | RTFOtherStatement { GSRTFgenericRTFcommand(ctxt, $1); } ; /* Font description */ -rtfFontList: RTFfontListStart rtfFonts +rtfFontList: '{' RTFfontListStart rtfFonts '}' ; rtfFonts: @@ -158,11 +280,10 @@ rtfFonts: ; - /* the first RTFfont tags the font with a number */ - /* RTFtext introduces the fontName */ -rtfFontStatement: RTFfont rtfFontFamily RTFtext { $$=0; GSRTFregisterFont(ctxt, $3, $2, $1.parameter); - free((void *)$3); - } +/* the first RTFfont tags the font with a number */ +/* RTFtext introduces the fontName */ +rtfFontStatement: RTFfont rtfFontFamily RTFtext { GSRTFregisterFont(ctxt, $3, $2, $1.parameter); + free((void *)$3); } ; rtfFontFamily: @@ -180,6 +301,18 @@ rtfFontFamily: Font description end */ +rtfColorDef: '{' RTFcolortable rtfColors '}' + ; + +rtfColors: /* empty */ + | rtfColors rtfColorStatement + ; + +/* We get the ';' as RTFText */ +rtfColorStatement: RTFred RTFgreen RTFblue RTFtext { free((void *)$4);} + | RTFtext { free((void *)$1);} + ; + /* some cludgy trailer */ diff --git a/Source/Parsers/rtfScanner.c b/Source/Parsers/rtfScanner.c index ecba2d8ae..7384c8a64 100644 --- a/Source/Parsers/rtfScanner.c +++ b/Source/Parsers/rtfScanner.c @@ -74,16 +74,20 @@ void lexInitContext(RTFscannerCtxt *lctxt, void *customContext, lctxt->lgetchar = getcharFunction; lctxt->customContext = customContext; } + int lexGetchar(RTFscannerCtxt *lctxt) { int c; if (lctxt->pushbackCount) { lctxt->pushbackCount--; - return lctxt->pushbackBuffer[lctxt->pushbackCount]; + c = lctxt->pushbackBuffer[lctxt->pushbackCount]; + } + else + { + lctxt->streamPosition++; + c = lctxt->lgetchar(lctxt->customContext); } - lctxt->streamPosition++; - c = lctxt->lgetchar(lctxt->customContext); if (c == '\n') lctxt->streamLineNumber++; return c; @@ -137,9 +141,16 @@ int findStringFromKeywordArray(const char *string, const LexKeyword *array, // must be sorted LexKeyword RTFcommands[]={ + "ansi", token(RTFansi), "b", token(RTFbold), + "blue", token(RTFblue), + "cb", token(RTFcolorbg), + "cf", token(RTFcolorfg), + "colortbl", token(RTFcolortable), + "dn", token(RTFsubscript), "f", token(RTFfont), "fdecor", token(RTFfamilyDecor), + "fi", token(RTFfirstLineIndent), "fmodern", token(RTFfamilyModern), "fnil", token(RTFfamilyNil), "fonttbl", token(RTFfontListStart), @@ -148,14 +159,28 @@ LexKeyword RTFcommands[]={ "fscript", token(RTFfamilyScript), "fswiss", token(RTFfamilySwiss), "ftech", token(RTFfamilyTech), + "green", token(RTFgreen), "i", token(RTFitalic), + "li", token(RTFleftIndent), + "mac", token(RTFmac), "margl", token(RTFmarginLeft), "margr", token(RTFmarginRight), "paperh", token(RTFpaperHeight), "paperw", token(RTFpaperWidth), + "par", token(RTFparagraph), + "pard", token(RTFdefaultParagraph), + "pc", token(RTFpc), + "pca", token(RTFpca), + "qc", token(RTFalignCenter), + "ql", token(RTFalignLeft), + "qr", token(RTFalignRight), + "red", token(RTFred), "rtf", token(RTFstart), + "s", token(RTFstyle), + "tab", token(RTFtabulator), "ul", token(RTFunderline), - "ulnone", token(RTFunderlineStop) + "ulnone", token(RTFunderlineStop), + "up", token(RTFsuperscript) }; BOOL probeCommand(RTFscannerCtxt *lctxt) @@ -212,7 +237,8 @@ GSLexError readCommand(RTFscannerCtxt *lctxt, YYSTYPE *lvalp, int *token) // the lexUngetchar(lctxt, c); // ungetc non-digit // the consumption of the space seems necessary on NeXT but // is not according to spec - lvalp->cmd.isEmpty = NO, lvalp->cmd.parameter = atoi(argumentBf); + lvalp->cmd.isEmpty = NO; + lvalp->cmd.parameter = atoi(argumentBf); } else { @@ -234,20 +260,11 @@ GSLexError readText(RTFscannerCtxt *lctxt, YYSTYPE *lvalp) { c = lexGetchar(lctxt); - if (c == EOF || c == '{' || c == '}') + if (c == EOF || c == '{' || c == '}' || c == '\\') { lexUngetchar(lctxt, c); break; } - if (c == '\\') // see

- { - if (probeCommand(lctxt) == YES) - { - lexUngetchar(lctxt, c); - break; - } - appendChar(&text, lexGetchar(lctxt)); - } else { if (c != '\n' && c != '\r') // newline and cr are ignored if not quoted @@ -259,10 +276,41 @@ GSLexError readText(RTFscannerCtxt *lctxt, YYSTYPE *lvalp) return NoError; } +// read in a character as two hex digit +static int gethex(RTFscannerCtxt *lctxt) +{ + int c = 0; + int i; + + for (i = 0; i < 2; i++) + { + int c1 = lexGetchar(lctxt); + + if (!isxdigit(c1)) + { + lexUngetchar(lctxt, c1); + break; + } + else + { + c = c * 16; + if (isdigit(c1)) + c += c1 - '0'; + else if (isupper(c1)) + c += c1 - 'A'; + else + c += c1 - 'a'; + } + } + + return c; +} + int GSRTFlex(YYSTYPE *lvalp, YYLTYPE *llocp, RTFscannerCtxt *lctxt) /* provide value and position in the params */ { int c; int token = 0; + char *cv; do c = lexGetchar(lctxt); @@ -280,7 +328,57 @@ int GSRTFlex(YYSTYPE *lvalp, YYLTYPE *llocp, RTFscannerCtxt *lctxt) /* provide v if (probeCommand(lctxt) == YES) { readCommand(lctxt, lvalp, &token); - break; + if (token == RTFparagraph || token == RTFdefaultParagraph) + { + // release is up to the consumer + cv = calloc(1, 2); + cv[0] = '\n'; + cv[1] = '\0'; + lvalp->text = cv; + token = RTFtext; + return token; + } + else if (token == RTFtabulator) + c = '\t'; + else + break; + } + else + { + c = lexGetchar(lctxt); + switch (c) + { + case EOF: token = 0; + return token; + case '\'': + // Convert the next two hex digits into a char + c = gethex(lctxt); + break; + case '*': return RTFignore; + case '|': + case '-': + case ':': + // Ignore these characters + c = lexGetchar(lctxt); + break; + case '_': c = '-'; + break; + case '~': c = ' '; + break; + case '\n': + // release is up to the consumer + cv = calloc(1, 2); + cv[0] = '\n'; + cv[1] = '\0'; + lvalp->text = cv; + token = RTFtext; + return token; + case '{': + case '}': + case '\\': + default: + // fall through + } } // else fall through to default: read text // no break diff --git a/Source/Parsers/rtfScanner.h b/Source/Parsers/rtfScanner.h index 090683b13..3f606e5ee 100644 --- a/Source/Parsers/rtfScanner.h +++ b/Source/Parsers/rtfScanner.h @@ -37,18 +37,13 @@ typedef enum { NoError, LEXoutOfMemory, LEXsyntaxError } GSLexError; typedef struct _RTFscannerCtxt { int (*lgetchar)(void *); - char pushbackBuffer[2]; // gaurantee 2 chars of pushback + char pushbackBuffer[4]; // gaurantee 4 chars of pushback int pushbackCount; int streamPosition; int streamLineNumber; void *customContext; } RTFscannerCtxt; -typedef struct { - BOOL isEmpty; - int number; -} RTFparameter; - typedef struct { BOOL isEmpty; int parameter;