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)
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);
}
}
}
// <N> 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);
}

View file

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

View file

@ -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

View file

@ -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 */

View file

@ -76,16 +76,38 @@ typedef void * GSRTFctxt;
/* <!><p> RTFtext values have to be freed */
%token <text> RTFtext
%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> RTFfontSize
%token <cmd> RTFpaperWidth
%token <cmd> RTFpaperHeight
%token <cmd> RTFmarginLeft
%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> RTFitalic
%token <cmd> RTFunderline
%token <cmd> RTFunderlineStop
%token <cmd> RTFsubscript
%token <cmd> RTFsuperscript
%token <cmd> RTFtabulator
%token <cmd> RTFparagraph
%token <cmd> RTFdefaultParagraph
%token <cmd> RTFOtherStatement
%token RTFfontListStart
@ -100,56 +122,156 @@ typedef void * GSRTFctxt;
%token RTFfamilyDecor
%token RTFfamilyTech
%type <number> rtfFontFamily rtfStatement rtfGeneralStatement rtfBlockStatement rtfFontStatement
%type <number> 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
*/

View file

@ -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); // <N> 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 <p>
{
if (probeCommand(lctxt) == YES)
{
lexUngetchar(lctxt, c);
break;
}
appendChar(&text, lexGetchar(lctxt));
}
else
{
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;
}
// 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 <A>
// no break <A>

View file

@ -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;