Update of parser

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@6500 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2000-04-23 22:28:46 +00:00
parent db9b061353
commit 034448c171
7 changed files with 992 additions and 345 deletions

View file

@ -53,215 +53,384 @@ readNSString(StringContext *ctxt)
we must implement from the rtfConsumerSkeleton.h file (Supporting files) we must implement from the rtfConsumerSkeleton.h file (Supporting files)
this includes the yacc error handling and output 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 CTXT ((NSMutableDictionary *)ctxt)
#define FONTS [CTXT objectForKey:GSRTFfontDictName] #define FONTS [CTXT objectForKey: GSfontDictName]
#define RESULT [CTXT objectForKey:GSRTFresultName] #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 halfpoints2points(a) ((a)/2.0)
#define GSRTFcurrentTextPosition @"textPosition" // FIXME: How to convert twips to points???
#define GSRTFresultName @"result" #define twips2points(a) ((a)/500.0)
#define GSRTFboldRange @"boldOn"
#define GSRTFitalicRange @"italicOn"
#define GSRTFunderlineRange @"underlineOn"
#define GSRTFcurrentFont @"currentFont"
#define GSRTFdocumentAttributes @"documentAttributes"
static NSRange MakeRangeFromAbs(int a1,int a2)
static int textPosition(void *ctxt)
{ {
if(a1< a2) return NSMakeRange(a1,a2-a1); return [[CTXT objectForKey: GScurrentTextPosition] intValue];
else return NSMakeRange(a2,a1-a2);
} }
/* handle errors (this is the yacc error mech) */ static NSFont *currentFont(void *ctxt)
void GSRTFerror(const char *msg) {
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 [NSException raise:NSInvalidArgumentException
format:@"Syntax error in RTF:%s", msg]; 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); NSLog(@"encountered rtf cmd:%s", cmd.name);
if (cmd.isEmpty) fprintf(stderr, " argument is empty\n"); if (cmd.isEmpty)
else fprintf(stderr, " argument is %d\n", cmd.parameter); NSLog(@" argument is empty\n");
else
NSLog(@" argument is %d\n", cmd.parameter);
} }
//Start: we're doing some initialization //Start: we're doing some initialization
void GSRTFstart(void *ctxt) void GSRTFstart(void *ctxt)
{ {
[CTXT setObject:[NSNumber numberWithInt:0] forKey: GSRTFcurrentTextPosition]; NSFont *font = [NSFont userFontOfSize:12];
[CTXT setObject:[NSFont userFontOfSize:12] forKey: GSRTFcurrentFont];
[CTXT setObject:[NSMutableDictionary dictionary] forKey: GSRTFfontDictName]; [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]; [RESULT beginEditing];
} }
// Finished to parse one piece of RTF. // Finished to parse one piece of RTF.
void GSRTFstop(void *ctxt) void GSRTFstop(void *ctxt)
{ {
//<!> close all open bolds et al. //<!> 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], int oldPosition = textPosition(ctxt);
textlen=strlen(text), int textlen = strlen(text);
newPosition=oldPosition + textlen; int newPosition = oldPosition + textlen;
NSRange insertionRange=NSMakeRange(oldPosition,0); NSRange insertionRange = NSMakeRange(oldPosition,0);
NSDictionary *attributes=[NSDictionary dictionaryWithObjectsAndKeys: NSDictionary *attributes;
[CTXT objectForKey:GSRTFcurrentFont], NSFont *font;
NSFontAttributeName,nil];
if (textlen)
[CTXT setObject:[NSNumber numberWithInt:newPosition] {
forKey: GSRTFcurrentTextPosition]; [CTXT setObject:[NSNumber numberWithInt: newPosition]
forKey: GScurrentTextPosition];
[RESULT replaceCharactersInRange:insertionRange
withString:[NSString stringWithCString:text]]; [RESULT replaceCharactersInRange: insertionRange
[RESULT setAttributes:attributes range:NSMakeRange(oldPosition,textlen)]; 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, void GSRTFregisterFont(void *ctxt, const char *fontName,
RTFfontFamily family, int fontNumber) RTFfontFamily family, int fontNumber)
{ {
NSMutableDictionary *fonts = FONTS;
NSString *fontNameString; 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 [NSException raise:NSInvalidArgumentException
format:@"Error in RTF (font omitted?), position:%d", format:@"Error in RTF (font omitted?), position:%d",
[[CTXT objectForKey:GSRTFcurrentTextPosition] intValue]]; textPosition(ctxt)];
} }
// exclude trailing ';' from fontName // exclude trailing ';' from fontName
fontNameString = [NSString stringWithCString:fontName length:strlen(fontName)-1]; fontNameString = [NSString stringWithCString: fontName
[fonts setObject:fontNameString forKey:fontId]; 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];
NSNumber *fontId = [NSNumber numberWithInt:fontNumber]; NSString *fontName = [FONTS objectForKey: fontId];
NSFont *font=[NSFont fontWithName:[fonts objectForKey:fontId]
size:[[CTXT objectForKey:GSRTFcurrentFont] pointSize]];
if (!font) /* we're about to set an unknown font */ if (fontName == nil)
{ {
[NSException raise:NSInvalidArgumentException /* we're about to set an unknown font */
format:@"Error in RTF (referring to undefined font \\f%d), position:%d", [NSException raise: NSInvalidArgumentException
format: @"Error in RTF (referring to undefined font \\f%d), position:%d",
fontNumber, fontNumber,
[[CTXT objectForKey:GSRTFcurrentTextPosition] intValue]]; textPosition(ctxt)];
} else { }
font=[[NSFontManager sharedFontManager] else
convertFont:[CTXT objectForKey:GSRTFcurrentFont] {
toFamily:[font familyName]]; if (![fontName isEqual: [CTXT objectForKey: GSfontName]])
[CTXT setObject:font forKey: GSRTFcurrentFont]; {
[CTXT setObject: fontName forKey: GSfontName];
SETCHANGED(YES);
}
} }
} }
// <N> fontSize is in halfpoints according to spec // <N> fontSize is in halfpoints according to spec
#define fs2points(a) ((a)/2.0) void GSRTFfontSize(void *ctxt, int fontSize)
void GSRTFchangeFontSizeTo(void *ctxt, int fontSize)
{ {
[CTXT setObject:[[NSFontManager sharedFontManager] float size = halfpoints2points(fontSize);
convertFont:[CTXT objectForKey:GSRTFcurrentFont]
toSize:fs2points(fontSize)]
forKey:GSRTFcurrentFont];
}
static NSRange rangeForContextAndAttribute(void *ctxt, NSString *attrib)
{
NSString *attribStartString=[CTXT objectForKey:GSRTFboldRange];
if(!attribStartString) if (size != [[CTXT objectForKey: GSfontSize] floatValue])
{ {
NSLog(@"RTF anomality (attribute:%@ off statement unpaired with on statement), position:%d", [CTXT setObject: [NSNumber numberWithFloat: size]
attrib, [[CTXT objectForKey:GSRTFcurrentTextPosition] intValue]); forKey: GSfontSize];
return NSMakeRange(0, 0); SETCHANGED(YES);
}
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];
} }
} }
void GSRTFhandleBoldAttribute(void *ctxt, BOOL state) void GSRTFpaperWidth(void *ctxt, int width)
{
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)
{ {
} }
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; RTFscannerCtxt scanner;
StringContext stringCtxt; StringContext stringCtxt;
NSMutableDictionary *myDict = [NSMutableDictionary dictionary]; NSMutableDictionary *myDict = [NSMutableDictionary dictionary];
NSMutableAttributedString *result=[[NSMutableAttributedString alloc] init];
[myDict setObject:result forKey: GSRTFresultName]; [myDict setObject: result forKey: GSresultName];
initStringContext(&stringCtxt, rtfString); initStringContext(&stringCtxt, rtfString);
lexInitContext(&scanner, &stringCtxt, (int (*)(void*))readNSString); lexInitContext(&scanner, &stringCtxt, (int (*)(void*))readNSString);
GSRTFparse(myDict, &scanner); GSRTFparse(myDict, &scanner);
return [result autorelease]; // document attributes
if (dict)
(*dict)=[myDict objectForKey: GSdocumentAttributes];
return YES;
} }
@implementation NSAttributedString (RTFParser) NSMutableAttributedString *attributedStringFromRTF(NSString *rtfString)
- (id) initWithRTF: (NSData*)data
documentAttributes: (NSDictionary**)dict
{ {
RTFscannerCtxt scanner; NSMutableAttributedString *result = [[NSMutableAttributedString alloc] init];
StringContext stringCtxt;
NSMutableDictionary *myDict = [NSMutableDictionary dictionary];
NSString *parseString = [NSString stringWithCString:[data bytes]
length:[data length]];
NSMutableAttributedString *result =
[[[NSMutableAttributedString alloc] init] autorelease];
[myDict setObject:result forKey: GSRTFresultName]; parseRTFintoAttributedString(rtfString, result, NULL);
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];
}
@end return AUTORELEASE(result);
}

View file

@ -32,4 +32,8 @@
/* external symbols from the grammer */ /* external symbols from the grammer */
int GSRTFparse(void *ctxt, RTFscannerCtxt *lctxt); int GSRTFparse(void *ctxt, RTFscannerCtxt *lctxt);
BOOL parseRTFintoAttributedString(NSString *rtfString,
NSMutableAttributedString *result,
NSDictionary **dict);
#endif #endif

View file

@ -60,17 +60,49 @@ void GSRTFmangleText(void *ctxt, const char *text);
font functions font functions
*/ */
/* get noticed that a particular font is introduced the font number is /* get noticed that a particular font is introduced */
introduced by an prededing GSRTFchangeFontTo call this state
can be recognized by the fact that the fontNumber in question
is unseen by then */
void GSRTFregisterFont(void *ctxt, const char *fontName, void GSRTFregisterFont(void *ctxt, const char *fontName,
RTFfontFamily family, int fontNumber); RTFfontFamily family, int fontNumber);
/* this function is twofold: change font in character stream [you must /* change font number */
maintain stream info in ctxt]; introduce fonts in the first place */ void GSRTFfontNumber(void *ctxt, int fontNumber);
void GSRTFchangeFontTo(void *ctxt, int fontNumber); /* change font size in half points*/
/* subject says it all */ void GSRTFfontSize(void *ctxt, int fontSize);
void GSRTFchangeFontSizeTo(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 #endif

View file

@ -1,6 +1,6 @@
/* A Bison parser, made from Parsers/rtfGrammer.y /* 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. */ #define YYBISON 1 /* Identify Bison output. */
@ -14,27 +14,49 @@
#define yynerrs GSRTFnerrs #define yynerrs GSRTFnerrs
#define YYLSP_NEEDED #define YYLSP_NEEDED
#define RTFtext 257 #define RTFtext 258
#define RTFstart 258 #define RTFstart 259
#define RTFfont 259 #define RTFansi 260
#define RTFfontSize 260 #define RTFmac 261
#define RTFpaperWidth 261 #define RTFpc 262
#define RTFpaperHeight 262 #define RTFpca 263
#define RTFmarginLeft 263 #define RTFignore 264
#define RTFmarginRight 264 #define RTFred 265
#define RTFbold 265 #define RTFgreen 266
#define RTFitalic 266 #define RTFblue 267
#define RTFunderline 267 #define RTFcolorbg 268
#define RTFunderlineStop 268 #define RTFcolorfg 269
#define RTFOtherStatement 269 #define RTFcolortable 270
#define RTFfontListStart 270 #define RTFfont 271
#define RTFfamilyNil 271 #define RTFfontSize 272
#define RTFfamilyRoman 272 #define RTFpaperWidth 273
#define RTFfamilySwiss 273 #define RTFpaperHeight 274
#define RTFfamilyModern 274 #define RTFmarginLeft 275
#define RTFfamilyScript 275 #define RTFmarginRight 276
#define RTFfamilyDecor 276 #define RTFfirstLineIndent 277
#define RTFfamilyTech 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" #line 35 "Parsers/rtfGrammer.y"
@ -104,11 +126,11 @@ typedef
#define YYFINAL 41 #define YYFINAL 74
#define YYFLAG -32768 #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, 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,
@ -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, 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, 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, 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, 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, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
17, 18, 19, 20, 21, 22, 23 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 #if YYDEBUG != 0
static const short yyprhs[] = { 0, static const short yyprhs[] = { 0,
0, 1, 4, 5, 10, 11, 14, 17, 20, 22, 0, 1, 2, 10, 12, 14, 16, 18, 19, 22,
24, 28, 30, 32, 34, 36, 38, 40, 42, 44, 25, 28, 31, 34, 35, 40, 41, 47, 49, 51,
46, 48, 50, 52, 54, 57, 58, 61, 66, 70, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71,
72, 74, 76, 78, 80, 82, 84 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, static const short yyrhs[] = { -1,
28, 29, 0, 0, 24, 30, 31, 25, 0, 0, 0, 46, 50, 4, 52, 53, 51, 47, 0, 5,
31, 32, 0, 31, 3, 0, 31, 29, 0, 0, 0, 6, 0, 7, 0, 8, 0, 0, 53, 58,
0, 32, 0, 24, 32, 25, 0, 4, 0, 33, 0, 53, 62, 0, 53, 57, 0, 53, 3, 0,
0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 53, 54, 0, 0, 46, 55, 53, 47, 0, 0,
0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 46, 56, 9, 53, 47, 0, 16, 0, 17, 0,
0, 15, 0, 16, 34, 0, 0, 34, 35, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0,
34, 24, 35, 25, 0, 5, 36, 3, 0, 17, 23, 0, 24, 0, 25, 0, 26, 0, 27, 0,
0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 13, 0, 14, 0, 32, 0, 33, 0, 28, 0,
0, 23, 0, 26, 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 #endif
#if YYDEBUG != 0 #if YYDEBUG != 0
static const short yyrline[] = { 0, static const short yyrline[] = { 0,
109, 109, 112, 112, 115, 116, 117, 118, 126, 127, 131, 131, 132, 134, 135, 136, 137, 140, 141, 142,
130, 133, 134, 135, 136, 137, 138, 139, 140, 141, 143, 144, 145, 148, 148, 149, 149, 157, 164, 171,
142, 143, 144, 145, 152, 155, 156, 157, 163, 168, 178, 185, 192, 199, 206, 213, 214, 215, 216, 217,
170, 171, 172, 173, 174, 175, 186 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 #endif
@ -176,69 +209,103 @@ static const short yyrline[] = { 0,
#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
static const char * const yytname[] = { "$","error","$undefined.","RTFtext", static const char * const yytname[] = { "$","error","$undefined.","RTFtext",
"RTFstart","RTFfont","RTFfontSize","RTFpaperWidth","RTFpaperHeight","RTFmarginLeft", "RTFstart","RTFansi","RTFmac","RTFpc","RTFpca","RTFignore","RTFred","RTFgreen",
"RTFmarginRight","RTFbold","RTFitalic","RTFunderline","RTFunderlineStop","RTFOtherStatement", "RTFblue","RTFcolorbg","RTFcolorfg","RTFcolortable","RTFfont","RTFfontSize",
"RTFfontListStart","RTFfamilyNil","RTFfamilyRoman","RTFfamilySwiss","RTFfamilyModern", "RTFpaperWidth","RTFpaperHeight","RTFmarginLeft","RTFmarginRight","RTFfirstLineIndent",
"RTFfamilyScript","RTFfamilyDecor","RTFfamilyTech","'{'","'}'","'\\\\'","rtfText", "RTFleftIndent","RTFalignCenter","RTFalignLeft","RTFalignRight","RTFstyle","RTFbold",
"@1","rtfBlock","@2","rtfIngredients","rtfStatement","rtfFontList","rtfFonts", "RTFitalic","RTFunderline","RTFunderlineStop","RTFsubscript","RTFsuperscript",
"rtfFontStatement","rtfFontFamily", NULL "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 #endif
static const short yyr1[] = { 0, static const short yyr1[] = { 0,
28, 27, 30, 29, 31, 31, 31, 31, -1, -1, 50, 51, 49, 52, 52, 52, 52, 53, 53, 53,
-1, 32, 32, 32, 32, 32, 32, 32, 32, 32, 53, 53, 53, 55, 54, 56, 54, 57, 57, 57,
32, 32, 32, 32, 33, 34, 34, 34, 35, 36, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
36, 36, 36, 36, 36, 36, -1 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, static const short yyr2[] = { 0,
0, 2, 0, 4, 0, 2, 2, 2, 1, 1, 0, 0, 7, 1, 1, 1, 1, 0, 2, 2,
3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 0, 4, 0, 5, 1, 1, 1,
1, 1, 1, 1, 2, 0, 2, 4, 3, 1, 1, 1, 1, 1, 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, static const short yydefact[] = { 0,
0, 3, 2, 5, 0, 7, 12, 14, 15, 16, 1, 0, 0, 4, 5, 6, 7, 8, 2, 12,
17, 18, 19, 20, 21, 22, 23, 24, 26, 4, 30, 31, 18, 19, 20, 21, 22, 23, 24, 25,
8, 6, 13, 25, 0, 0, 27, 30, 31, 32, 26, 27, 28, 29, 34, 35, 36, 37, 32, 33,
33, 34, 35, 36, 0, 0, 29, 28, 0, 0, 38, 14, 0, 13, 11, 9, 10, 52, 40, 8,
0 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, static const short yydefgoto[] = { 72,
1, 3, 4, 5, 22, 23, 24, 27, 35 2, 33, 8, 9, 34, 40, 41, 35, 36, 44,
54, 65, 37, 43, 50
}; };
static const short yypact[] = {-32768, static const short yypact[] = { -45,
-9,-32768,-32768,-32768, -3,-32768,-32768,-32768,-32768,-32768, -32768, 8, 66,-32768,-32768,-32768,-32768,-32768, 67,-32768,
-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-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,-32768,-32768,-32768,-32768,-32768,-32768,
-32768,-32768,-32768,-32768, 14, -7,-32768,-32768, 19, 20, -32768, 92, -10,-32768,-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, 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, static const short yytable[] = { 10,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 51, 58, 59, 60, 61, 62, 63, 64, 11,
17, 18, 19, 25, 2, 25, 37, 38, 40, 41, 12, 3, 13, 14, 15, 16, 17, 18, 19, 20,
2, 20, 28, 29, 30, 31, 32, 33, 34, 21, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
36, 0, 26 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, static const short yycheck[] = { 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 16, 39, 40, 41, 42, 43, 44, 45, 13,
14, 15, 16, 5, 24, 5, 3, 25, 0, 0, 14, 4, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 17, 18, 19, 20, 21, 22, 23, 5, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
26, -1, 24 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 #define YYPURE 1
@ -742,117 +809,266 @@ yyreduce:
switch (yyn) { switch (yyn) {
case 1: case 1:
#line 109 "Parsers/rtfGrammer.y" #line 131 "Parsers/rtfGrammer.y"
{ GSRTFstart(ctxt); ; { GSRTFstart(ctxt); ;
break;} break;}
case 2: case 2:
#line 109 "Parsers/rtfGrammer.y" #line 131 "Parsers/rtfGrammer.y"
{ GSRTFstop(ctxt); ; { GSRTFstop(ctxt); ;
break;} break;}
case 3:
#line 112 "Parsers/rtfGrammer.y"
{ GSRTFopenBlock(ctxt); ;
break;}
case 4: case 4:
#line 112 "Parsers/rtfGrammer.y" #line 134 "Parsers/rtfGrammer.y"
{ GSRTFcloseBlock(ctxt); ; { 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;} break;}
case 7: case 7:
#line 117 "Parsers/rtfGrammer.y" #line 137 "Parsers/rtfGrammer.y"
{ GSRTFmangleText(ctxt, yyvsp[0].text); free((void *)yyvsp[0].text); ; { yyval.number = 4; ;
break;}
case 11:
#line 130 "Parsers/rtfGrammer.y"
{ yyval.number=0; ;
break;} break;}
case 12: case 12:
#line 133 "Parsers/rtfGrammer.y" #line 144 "Parsers/rtfGrammer.y"
{ yyval.number=0; ; { GSRTFmangleText(ctxt, yyvsp[0].text); free((void *)yyvsp[0].text); ;
break;}
case 13:
#line 134 "Parsers/rtfGrammer.y"
{ yyval.number=0; ;
break;} break;}
case 14: case 14:
#line 135 "Parsers/rtfGrammer.y" #line 148 "Parsers/rtfGrammer.y"
{ yyval.number=0; GSRTFchangeFontTo(ctxt, yyvsp[0].cmd.parameter); ; { GSRTFopenBlock(ctxt); ;
break;} break;}
case 15: case 15:
#line 136 "Parsers/rtfGrammer.y" #line 148 "Parsers/rtfGrammer.y"
{ yyval.number=0; GSRTFchangeFontSizeTo(ctxt, yyvsp[0].cmd.parameter); ; { GSRTFcloseBlock(ctxt); ;
break;} break;}
case 16: case 16:
#line 137 "Parsers/rtfGrammer.y" #line 149 "Parsers/rtfGrammer.y"
{ yyval.number=0; ; { GSRTFopenBlock(ctxt); ;
break;} break;}
case 17: case 17:
#line 138 "Parsers/rtfGrammer.y" #line 149 "Parsers/rtfGrammer.y"
{ yyval.number=0; ; { GSRTFcloseBlock(ctxt); ;
break;} break;}
case 18: case 18:
#line 139 "Parsers/rtfGrammer.y" #line 157 "Parsers/rtfGrammer.y"
{ yyval.number=0; ; { int font;
if (yyvsp[0].cmd.isEmpty)
font = 0;
else
font = yyvsp[0].cmd.parameter;
GSRTFfontNumber(ctxt, font); ;
break;} break;}
case 19: case 19:
#line 140 "Parsers/rtfGrammer.y" #line 164 "Parsers/rtfGrammer.y"
{ yyval.number=0; ; { int size;
if (yyvsp[0].cmd.isEmpty)
size = 24;
else
size = yyvsp[0].cmd.parameter;
GSRTFfontSize(ctxt, size); ;
break;} break;}
case 20: case 20:
#line 141 "Parsers/rtfGrammer.y" #line 171 "Parsers/rtfGrammer.y"
{ yyval.number=0; GSRTFhandleBoldAttribute(ctxt, yyvsp[0].cmd.isEmpty || !!yyvsp[0].cmd.parameter); ; { int width;
if (yyvsp[0].cmd.isEmpty)
width = 12240;
else
width = yyvsp[0].cmd.parameter;
GSRTFpaperWidth(ctxt, width);;
break;} break;}
case 21: case 21:
#line 142 "Parsers/rtfGrammer.y" #line 178 "Parsers/rtfGrammer.y"
{ yyval.number=0; GSRTFhandleItalicAttribute(ctxt, yyvsp[0].cmd.isEmpty || !!yyvsp[0].cmd.parameter); ; { int height;
if (yyvsp[0].cmd.isEmpty)
height = 15840;
else
height = yyvsp[0].cmd.parameter;
GSRTFpaperHeight(ctxt, height);;
break;} break;}
case 22: case 22:
#line 143 "Parsers/rtfGrammer.y" #line 185 "Parsers/rtfGrammer.y"
{ yyval.number=0; ; { int margin;
if (yyvsp[0].cmd.isEmpty)
margin = 1800;
else
margin = yyvsp[0].cmd.parameter;
GSRTFmarginLeft(ctxt, margin);;
break;} break;}
case 23: case 23:
#line 144 "Parsers/rtfGrammer.y" #line 192 "Parsers/rtfGrammer.y"
{ yyval.number=0; ; { int margin;
if (yyvsp[0].cmd.isEmpty)
margin = 1800;
else
margin = yyvsp[0].cmd.parameter;
GSRTFmarginRight(ctxt, margin); ;
break;} break;}
case 24: case 24:
#line 145 "Parsers/rtfGrammer.y" #line 199 "Parsers/rtfGrammer.y"
{ yyval.number=0; GSRTFgenericRTFcommand(ctxt, yyvsp[0].cmd); ; { 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;} break;}
case 29: case 29:
#line 163 "Parsers/rtfGrammer.y" #line 216 "Parsers/rtfGrammer.y"
{ yyval.number=0; GSRTFregisterFont(ctxt, yyvsp[0].text, yyvsp[-1].number, yyvsp[-2].cmd.parameter); { GSRTFstyle(ctxt, yyvsp[0].cmd.parameter); ;
free((void *)yyvsp[0].text);
;
break;} break;}
case 30: case 30:
#line 169 "Parsers/rtfGrammer.y" #line 217 "Parsers/rtfGrammer.y"
{ yyval.number = RTFfamilyNil - RTFfamilyNil; ; { int color;
if (yyvsp[0].cmd.isEmpty)
color = 0;
else
color = yyvsp[0].cmd.parameter;
GSRTFcolorbg(ctxt, color); ;
break;} break;}
case 31: case 31:
#line 170 "Parsers/rtfGrammer.y" #line 224 "Parsers/rtfGrammer.y"
{ yyval.number = RTFfamilyRoman - RTFfamilyNil; ; { int color;
if (yyvsp[0].cmd.isEmpty)
color = 0;
else
color = yyvsp[0].cmd.parameter;
GSRTFcolorfg(ctxt, color); ;
break;} break;}
case 32: case 32:
#line 171 "Parsers/rtfGrammer.y" #line 231 "Parsers/rtfGrammer.y"
{ yyval.number = RTFfamilySwiss - RTFfamilyNil; ; { int script;
if (yyvsp[0].cmd.isEmpty)
script = 6;
else
script = yyvsp[0].cmd.parameter;
GSRTFsubscript(ctxt, script); ;
break;} break;}
case 33: case 33:
#line 172 "Parsers/rtfGrammer.y" #line 238 "Parsers/rtfGrammer.y"
{ yyval.number = RTFfamilyModern - RTFfamilyNil; ; { int script;
if (yyvsp[0].cmd.isEmpty)
script = 6;
else
script = yyvsp[0].cmd.parameter;
GSRTFsuperscript(ctxt, script); ;
break;} break;}
case 34: case 34:
#line 173 "Parsers/rtfGrammer.y" #line 245 "Parsers/rtfGrammer.y"
{ yyval.number = RTFfamilyScript - RTFfamilyNil; ; { BOOL on;
if (yyvsp[0].cmd.isEmpty || yyvsp[0].cmd.parameter)
on = YES;
else
on = NO;
GSRTFbold(ctxt, on); ;
break;} break;}
case 35: case 35:
#line 174 "Parsers/rtfGrammer.y" #line 252 "Parsers/rtfGrammer.y"
{ yyval.number = RTFfamilyDecor - RTFfamilyNil; ; { BOOL on;
if (yyvsp[0].cmd.isEmpty || yyvsp[0].cmd.parameter)
on = YES;
else
on = NO;
GSRTFitalic(ctxt, on); ;
break;} break;}
case 36: case 36:
#line 175 "Parsers/rtfGrammer.y" #line 259 "Parsers/rtfGrammer.y"
{ yyval.number = RTFfamilyTech - RTFfamilyNil; ; { BOOL on;
if (yyvsp[0].cmd.isEmpty || yyvsp[0].cmd.parameter)
on = YES;
else
on = NO;
GSRTFunderline(ctxt, on); ;
break;} break;}
case 37: 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; ; { yylsp[0].first_line; ;
break;} break;}
} }
@ -1053,7 +1269,7 @@ yyerrhandle:
yystate = yyn; yystate = yyn;
goto yynewstate; goto yynewstate;
} }
#line 189 "Parsers/rtfGrammer.y" #line 322 "Parsers/rtfGrammer.y"
/* some C code here */ /* some C code here */

View file

@ -76,16 +76,38 @@ typedef void * GSRTFctxt;
/* <!><p> RTFtext values have to be freed */ /* <!><p> RTFtext values have to be freed */
%token <text> RTFtext %token <text> RTFtext
%token RTFstart %token RTFstart
%token RTFansi
%token RTFmac
%token RTFpc
%token RTFpca
%token RTFignore
%token <cmd> RTFred
%token <cmd> RTFgreen
%token <cmd> RTFblue
%token <cmd> RTFcolorbg
%token <cmd> RTFcolorfg
%token <cmd> RTFcolortable
%token <cmd> RTFfont %token <cmd> RTFfont
%token <cmd> RTFfontSize %token <cmd> RTFfontSize
%token <cmd> RTFpaperWidth %token <cmd> RTFpaperWidth
%token <cmd> RTFpaperHeight %token <cmd> RTFpaperHeight
%token <cmd> RTFmarginLeft %token <cmd> RTFmarginLeft
%token <cmd> RTFmarginRight %token <cmd> RTFmarginRight
%token <cmd> RTFfirstLineIndent
%token <cmd> RTFleftIndent
%token <cmd> RTFalignCenter
%token <cmd> RTFalignLeft
%token <cmd> RTFalignRight
%token <cmd> RTFstyle
%token <cmd> RTFbold %token <cmd> RTFbold
%token <cmd> RTFitalic %token <cmd> RTFitalic
%token <cmd> RTFunderline %token <cmd> RTFunderline
%token <cmd> RTFunderlineStop %token <cmd> RTFunderlineStop
%token <cmd> RTFsubscript
%token <cmd> RTFsuperscript
%token <cmd> RTFtabulator
%token <cmd> RTFparagraph
%token <cmd> RTFdefaultParagraph
%token <cmd> RTFOtherStatement %token <cmd> RTFOtherStatement
%token RTFfontListStart %token RTFfontListStart
@ -100,56 +122,156 @@ typedef void * GSRTFctxt;
%token RTFfamilyDecor %token RTFfamilyDecor
%token RTFfamilyTech %token RTFfamilyTech
%type <number> rtfFontFamily rtfStatement rtfGeneralStatement rtfBlockStatement rtfFontStatement %type <number> rtfFontFamily rtfCharset rtfFontStatement
/* let's go */ /* 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: /* empty */
| rtfIngredients rtfFontList
| rtfIngredients rtfColorDef
| rtfIngredients rtfStatement | rtfIngredients rtfStatement
| rtfIngredients RTFtext { GSRTFmangleText(ctxt, $2); free((void *)$2); } | rtfIngredients RTFtext { GSRTFmangleText(ctxt, $2); free((void *)$2); }
| rtfIngredients rtfBlock | 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 RTF statements start with a '\', have a alpha name and a number argument
*/ */
rtfGeneralStatement: rtfBlockStatement rtfStatement: RTFfont { int font;
| rtfStatement
; 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; } if ($1.isEmpty || $1.parameter)
| rtfFontList { $$=0; } on = YES;
| RTFfont { $$=0; GSRTFchangeFontTo(ctxt, $1.parameter); } else
| RTFfontSize { $$=0; GSRTFchangeFontSizeTo(ctxt, $1.parameter); } on = NO;
| RTFpaperWidth { $$=0; } GSRTFbold(ctxt, on); }
| RTFpaperHeight { $$=0; } | RTFitalic { BOOL on;
| RTFmarginLeft { $$=0; }
| RTFmarginRight { $$=0; } if ($1.isEmpty || $1.parameter)
| RTFbold { $$=0; GSRTFhandleBoldAttribute(ctxt, $1.isEmpty || !!$1.parameter); } on = YES;
| RTFitalic { $$=0; GSRTFhandleItalicAttribute(ctxt, $1.isEmpty || !!$1.parameter); } else
| RTFunderline { $$=0; } on = NO;
| RTFunderlineStop { $$=0; } GSRTFitalic(ctxt, on); }
| RTFOtherStatement { $$=0; GSRTFgenericRTFcommand(ctxt, $1); } | 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 Font description
*/ */
rtfFontList: RTFfontListStart rtfFonts rtfFontList: '{' RTFfontListStart rtfFonts '}'
; ;
rtfFonts: rtfFonts:
@ -158,11 +280,10 @@ rtfFonts:
; ;
/* the first RTFfont tags the font with a number */ /* the first RTFfont tags the font with a number */
/* RTFtext introduces the fontName */ /* RTFtext introduces the fontName */
rtfFontStatement: RTFfont rtfFontFamily RTFtext { $$=0; GSRTFregisterFont(ctxt, $3, $2, $1.parameter); rtfFontStatement: RTFfont rtfFontFamily RTFtext { GSRTFregisterFont(ctxt, $3, $2, $1.parameter);
free((void *)$3); free((void *)$3); }
}
; ;
rtfFontFamily: rtfFontFamily:
@ -180,6 +301,18 @@ rtfFontFamily:
Font description end 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 some cludgy trailer
*/ */

View file

@ -74,16 +74,20 @@ void lexInitContext(RTFscannerCtxt *lctxt, void *customContext,
lctxt->lgetchar = getcharFunction; lctxt->lgetchar = getcharFunction;
lctxt->customContext = customContext; lctxt->customContext = customContext;
} }
int lexGetchar(RTFscannerCtxt *lctxt) int lexGetchar(RTFscannerCtxt *lctxt)
{ {
int c; int c;
if (lctxt->pushbackCount) if (lctxt->pushbackCount)
{ {
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') if (c == '\n')
lctxt->streamLineNumber++; lctxt->streamLineNumber++;
return c; return c;
@ -137,9 +141,16 @@ int findStringFromKeywordArray(const char *string, const LexKeyword *array,
// <!> must be sorted // <!> must be sorted
LexKeyword RTFcommands[]={ LexKeyword RTFcommands[]={
"ansi", token(RTFansi),
"b", token(RTFbold), "b", token(RTFbold),
"blue", token(RTFblue),
"cb", token(RTFcolorbg),
"cf", token(RTFcolorfg),
"colortbl", token(RTFcolortable),
"dn", token(RTFsubscript),
"f", token(RTFfont), "f", token(RTFfont),
"fdecor", token(RTFfamilyDecor), "fdecor", token(RTFfamilyDecor),
"fi", token(RTFfirstLineIndent),
"fmodern", token(RTFfamilyModern), "fmodern", token(RTFfamilyModern),
"fnil", token(RTFfamilyNil), "fnil", token(RTFfamilyNil),
"fonttbl", token(RTFfontListStart), "fonttbl", token(RTFfontListStart),
@ -148,14 +159,28 @@ LexKeyword RTFcommands[]={
"fscript", token(RTFfamilyScript), "fscript", token(RTFfamilyScript),
"fswiss", token(RTFfamilySwiss), "fswiss", token(RTFfamilySwiss),
"ftech", token(RTFfamilyTech), "ftech", token(RTFfamilyTech),
"green", token(RTFgreen),
"i", token(RTFitalic), "i", token(RTFitalic),
"li", token(RTFleftIndent),
"mac", token(RTFmac),
"margl", token(RTFmarginLeft), "margl", token(RTFmarginLeft),
"margr", token(RTFmarginRight), "margr", token(RTFmarginRight),
"paperh", token(RTFpaperHeight), "paperh", token(RTFpaperHeight),
"paperw", token(RTFpaperWidth), "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), "rtf", token(RTFstart),
"s", token(RTFstyle),
"tab", token(RTFtabulator),
"ul", token(RTFunderline), "ul", token(RTFunderline),
"ulnone", token(RTFunderlineStop) "ulnone", token(RTFunderlineStop),
"up", token(RTFsuperscript)
}; };
BOOL probeCommand(RTFscannerCtxt *lctxt) BOOL probeCommand(RTFscannerCtxt *lctxt)
@ -212,7 +237,8 @@ GSLexError readCommand(RTFscannerCtxt *lctxt, YYSTYPE *lvalp, int *token) // the
lexUngetchar(lctxt, c); // <N> ungetc non-digit lexUngetchar(lctxt, c); // <N> ungetc non-digit
// the consumption of the space seems necessary on NeXT but // the consumption of the space seems necessary on NeXT but
// is not according to spec // is not according to spec
lvalp->cmd.isEmpty = NO, lvalp->cmd.parameter = atoi(argumentBf); lvalp->cmd.isEmpty = NO;
lvalp->cmd.parameter = atoi(argumentBf);
} }
else else
{ {
@ -234,20 +260,11 @@ GSLexError readText(RTFscannerCtxt *lctxt, YYSTYPE *lvalp)
{ {
c = lexGetchar(lctxt); c = lexGetchar(lctxt);
if (c == EOF || c == '{' || c == '}') if (c == EOF || c == '{' || c == '}' || c == '\\')
{ {
lexUngetchar(lctxt, c); lexUngetchar(lctxt, c);
break; break;
} }
if (c == '\\') // see <p>
{
if (probeCommand(lctxt) == YES)
{
lexUngetchar(lctxt, c);
break;
}
appendChar(&text, lexGetchar(lctxt));
}
else else
{ {
if (c != '\n' && c != '\r') // <N> newline and cr are ignored if not quoted if (c != '\n' && c != '\r') // <N> newline and cr are ignored if not quoted
@ -259,10 +276,41 @@ GSLexError readText(RTFscannerCtxt *lctxt, YYSTYPE *lvalp)
return NoError; 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 GSRTFlex(YYSTYPE *lvalp, YYLTYPE *llocp, RTFscannerCtxt *lctxt) /* provide value and position in the params */
{ {
int c; int c;
int token = 0; int token = 0;
char *cv;
do do
c = lexGetchar(lctxt); c = lexGetchar(lctxt);
@ -280,7 +328,57 @@ int GSRTFlex(YYSTYPE *lvalp, YYLTYPE *llocp, RTFscannerCtxt *lctxt) /* provide v
if (probeCommand(lctxt) == YES) if (probeCommand(lctxt) == YES)
{ {
readCommand(lctxt, lvalp, &token); 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 <A> // else fall through to default: read text <A>
// no break <A> // no break <A>

View file

@ -37,18 +37,13 @@ typedef enum { NoError, LEXoutOfMemory, LEXsyntaxError } GSLexError;
typedef struct _RTFscannerCtxt { typedef struct _RTFscannerCtxt {
int (*lgetchar)(void *); int (*lgetchar)(void *);
char pushbackBuffer[2]; // gaurantee 2 chars of pushback char pushbackBuffer[4]; // gaurantee 4 chars of pushback
int pushbackCount; int pushbackCount;
int streamPosition; int streamPosition;
int streamLineNumber; int streamLineNumber;
void *customContext; void *customContext;
} RTFscannerCtxt; } RTFscannerCtxt;
typedef struct {
BOOL isEmpty;
int number;
} RTFparameter;
typedef struct { typedef struct {
BOOL isEmpty; BOOL isEmpty;
int parameter; int parameter;