#include "rtfScanner.h"
/* this context is passed to the interface functions */
typedef void *GSRTFctxt;
/*#undef YYLSP_NEEDED*/
#define CTXT ctxt
#define YYERROR_VERBOSE
#define YYDEBUG 1
#include "RTFConsumerFunctions.h"
/*int GSRTFlex (YYSTYPE *lvalp, RTFscannerCtxt *lctxt); */
int GSRTFlex(void *lvalp, void *lctxt);
/* */
int fieldStart = 0;
%}
%parse-param {void *ctxt}
%parse-param {void *lctxt}
%lex-param {void *lctxt}
%union {
int number;
const char *text;
RTFcmd cmd;
}
/* RTFtext values have to be freed */
%token RTFtext
%token RTFstart
%token RTFansi
%token RTFmac
%token RTFpc
%token RTFpca
%token RTFignore
%token RTFinfo
%token RTFstylesheet
%token RTFfootnote
%token RTFheader
%token RTFfooter
%token RTFpict
%token RTFplain
%token RTFparagraph
%token RTFdefaultParagraph
%token RTFrow
%token RTFcell
%token RTFtabulator
%token RTFemdash
%token RTFendash
%token RTFemspace
%token RTFenspace
%token RTFbullet
%token RTFfield
%token RTFfldinst
%token RTFfldalt
%token RTFfldrslt
%token RTFflddirty
%token RTFfldedit
%token RTFfldlock
%token RTFfldpriv
%token RTFfttruetype
%token RTFlquote
%token RTFrquote
%token RTFldblquote
%token RTFrdblquote
%token RTFred
%token RTFgreen
%token RTFblue
%token RTFcolorbg
%token RTFcolorfg
%token RTFunderlinecolor
%token RTFcolortable
%token RTFfont
%token RTFfontSize
%token RTFNeXTGraphic
%token RTFNeXTGraphicWidth
%token RTFNeXTGraphicHeight
%token RTFNeXTHelpLink
%token RTFNeXTHelpMarker
%token RTFNeXTfilename
%token RTFNeXTmarkername
%token RTFNeXTlinkFilename
%token RTFNeXTlinkMarkername
%token RTFpaperWidth
%token RTFpaperHeight
%token RTFmarginLeft
%token RTFmarginRight
%token RTFmarginTop
%token RTFmarginButtom
%token RTFfirstLineIndent
%token RTFleftIndent
%token RTFrightIndent
%token RTFalignCenter
%token RTFalignJustified
%token RTFalignLeft
%token RTFalignRight
%token RTFlineSpace
%token RTFspaceAbove
%token RTFstyle
%token RTFbold
%token RTFitalic
%token RTFunderline
%token RTFunderlineDot
%token RTFunderlineDash
%token RTFunderlineDashDot
%token RTFunderlineDashDotDot
%token RTFunderlineDouble
%token RTFunderlineStop
%token RTFunderlineThick
%token RTFunderlineThickDot
%token RTFunderlineThickDash
%token RTFunderlineThickDashDot
%token RTFunderlineThickDashDotDot
%token RTFunderlineWord
%token RTFstrikethrough
%token RTFstrikethroughDouble
%token RTFunichar
%token RTFsubscript
%token RTFsuperscript
%token RTFtabstop
%token RTFfcharset
%token RTFfprq
%token RTFcpg
%token RTFansicpg
%token RTFOtherStatement
%token RTFfontListStart
// we assume token numbers to be sequential
// \fnil | \froman | \fswiss | \fmodern | \fscript | \fdecor | \ftech
// look at rtfScanner.h for enum definition
%token RTFfamilyNil
%token RTFfamilyRoman
%token RTFfamilySwiss
%token RTFfamilyModern
%token RTFfamilyScript
%token RTFfamilyDecor
%token RTFfamilyTech
%token RTFfamilyBiDi
%type rtfFontFamily rtfCharset rtfFontStatement
%type rtfFieldinst
/* let's go */
%%
rtfFile: '{' { GSRTFstart(CTXT); } RTFstart rtfIngredients { GSRTFstop(CTXT); } '}'
;
rtfCharset: RTFansi { GSRTFencoding(CTXT, 1); }
| RTFmac { GSRTFencoding(CTXT, 2); }
| RTFpc { GSRTFencoding(CTXT, 3); }
| RTFpca { GSRTFencoding(CTXT, 4); }
| rtfCharset RTFansicpg { GSRTFencoding(CTXT, $2.parameter); }
;
rtfIngredients: /* empty */
| rtfIngredients rtfCharset
| rtfIngredients rtfFontList
| rtfIngredients rtfColorDef
| rtfIngredients rtfStatement
| rtfIngredients RTFtext { GSRTFmangleText(CTXT, $2); free((void *)$2); }
| rtfIngredients rtfBlock
| rtfIngredients error
;
rtfBlock: '{' { GSRTFopenBlock(CTXT, NO); } rtfIngredients rtfNeXTstuff '}' { GSRTFcloseBlock(CTXT, NO); } /* may be empty */
| '{' { GSRTFopenBlock(CTXT, YES); } RTFignore rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); }
| '{' { GSRTFopenBlock(CTXT, YES); } RTFinfo rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); }
| '{' { GSRTFopenBlock(CTXT, YES); } RTFstylesheet rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); }
| '{' { GSRTFopenBlock(CTXT, YES); } RTFfootnote rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); }
| '{' { GSRTFopenBlock(CTXT, YES); } RTFheader rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); }
| '{' { GSRTFopenBlock(CTXT, YES); } RTFfooter rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); }
| '{' { GSRTFopenBlock(CTXT, YES); } RTFpict rtfIngredients '}' { GSRTFcloseBlock(CTXT, YES); }
| '{' { GSRTFopenBlock(CTXT, NO); } RTFfield rtfField '}' { GSRTFcloseBlock(CTXT, NO); }
| '{' error '}'
;
rtfField: { fieldStart = GSRTFgetPosition(CTXT);} rtfFieldMod rtfFieldinst rtfFieldrslt { GSRTFaddField(CTXT, fieldStart, $3); free((void *)$3); }
| error
;
rtfFieldMod: /* empty */
| rtfFieldMod RTFflddirty
| rtfFieldMod RTFfldedit
| rtfFieldMod RTFfldlock
| rtfFieldMod RTFfldpriv
;
rtfIgnore: /* empty */
| RTFignore
;
rtfFieldinst: '{' rtfIgnore RTFfldinst RTFtext rtfFieldalt '}' { $$ = $4;}
| '{' rtfIgnore RTFfldinst '{' { GSRTFopenBlock(CTXT, YES); } rtfStatementList RTFtext rtfFieldalt '}' { GSRTFcloseBlock(CTXT, YES); } '}' { $$ = $7;}
| '{' error '}' { $$ = NULL;}
;
rtfFieldalt: /* empty */
| RTFfldalt
;
rtfFieldrslt: '{' rtfIgnore RTFfldrslt rtfIngredients '}'
| '{' error '}'
;
rtfStatementList: /* empty */
| rtfStatementList rtfStatement
| rtfStatementList rtfBlock
;
/*
RTF statements start with a '\', have a alpha name and a number argument
*/
rtfStatement: RTFfont { int font;
if ($1.isEmpty)
font = 0;
else
font = $1.parameter;
GSRTFfontNumber(CTXT, font); }
| RTFfontSize { int size;
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); }
| RTFmarginTop { int margin;
if ($1.isEmpty)
margin = 1440;
else
margin = $1.parameter;
GSRTFmarginTop(CTXT, margin); }
| RTFmarginButtom { int margin;
if ($1.isEmpty)
margin = 1440;
else
margin = $1.parameter;
GSRTFmarginButtom(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);}
| RTFrightIndent { int indent;
if ($1.isEmpty)
indent = 0;
else
indent = $1.parameter;
GSRTFrightIndent(CTXT, indent);}
| RTFtabstop { int location;
if ($1.isEmpty)
location = 0;
else
location = $1.parameter;
GSRTFtabstop(CTXT, location);}
| RTFalignCenter { GSRTFalignCenter(CTXT); }
| RTFalignJustified { GSRTFalignJustified(CTXT); }
| RTFalignLeft { GSRTFalignLeft(CTXT); }
| RTFalignRight { GSRTFalignRight(CTXT); }
| RTFspaceAbove { int space;
if ($1.isEmpty)
space = 0;
else
space = $1.parameter;
GSRTFspaceAbove(CTXT, space); }
| RTFlineSpace { GSRTFlineSpace(CTXT, $1.parameter); }
| RTFdefaultParagraph { GSRTFdefaultParagraph(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); }
| RTFunderlinecolor { int color;
if ($1.isEmpty)
color = 0;
else
color = $1.parameter;
GSRTFunderlinecolor(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;
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, NSUnderlineStyleSingle | NSUnderlinePatternSolid); }
| RTFunderlineDot { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDot); }
| RTFunderlineDash { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDash); }
| RTFunderlineDashDot { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDashDot); }
| RTFunderlineDashDotDot { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternDashDotDot); }
| RTFunderlineDouble { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleDouble | NSUnderlinePatternSolid); }
| RTFunderlineStop { GSRTFunderline(CTXT, NO, NSUnderlineStyleNone); }
| RTFunderlineThick { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternSolid); }
| RTFunderlineThickDot { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDot); }
| RTFunderlineThickDash { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDash); }
| RTFunderlineThickDashDot { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDashDot); }
| RTFunderlineThickDashDotDot { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleThick | NSUnderlinePatternDashDotDot); }
| RTFunderlineWord { BOOL on;
if ($1.isEmpty || $1.parameter)
on = YES;
else
on = NO;
GSRTFunderline(CTXT, on, NSUnderlineStyleSingle | NSUnderlinePatternSolid | NSUnderlineByWordMask); }
| RTFstrikethrough { NSInteger style;
if ($1.isEmpty || $1.parameter)
style = NSUnderlineStyleSingle | NSUnderlinePatternSolid;
else
style = NSUnderlineStyleNone;
GSRTFstrikethrough(CTXT, style); }
| RTFstrikethroughDouble { GSRTFstrikethrough(CTXT, NSUnderlineStyleDouble | NSUnderlinePatternSolid); }
| RTFunichar { GSRTFunicode(CTXT, $1.parameter); }
| RTFplain { GSRTFdefaultCharacterStyle(CTXT); }
| RTFparagraph { GSRTFparagraph(CTXT); }
| RTFrow { GSRTFparagraph(CTXT); }
| RTFOtherStatement { GSRTFgenericRTFcommand(CTXT, $1);
free((void*)$1.name); }
;
rtfNeXTstuff: /* empty */
| rtfNeXTGraphic
| rtfNeXTHelpLink
| rtfNeXTHelpMarker
;
/*
NeXTGraphic (images)
This is a Apple/NeXT extension. The format of the command is
{{\NeXTGraphic attachment \widthN \heightN} string}
and the string is ignored (on OS X it is always 0xAC).
See the Section "RTF Files and Attributed Strings" in Apple's
Attributed Strings Programming Guide.
*/
rtfNeXTGraphic: '{' RTFNeXTGraphic RTFtext RTFNeXTGraphicWidth RTFNeXTGraphicHeight '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); }
{
GSRTFNeXTGraphic (CTXT, $3, $4.parameter, $5.parameter);
};
/*
NeXTHelpLink
This is a NeXT extension. The format of the command is
{{\NeXTHelpLinkN \markername markername; \linkFilename filename;
\linkMarkername markername;} string}
and the string is ignored (it is always 0xAC on NeXT).
Note that the {\NeXTHelpLink } group may itself be preceded by
other commands.
*/
rtfNeXTHelpLink: '{' RTFNeXTHelpLink RTFNeXTmarkername RTFtext RTFNeXTlinkFilename RTFtext RTFNeXTlinkMarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); }
{
GSRTFNeXTHelpLink (CTXT, $2.parameter, $4, $6, $8);
};
/*
NeXTHelpMarker
This is a NeXT extension. The format of the command is
{{\NeXTHelpMarkerN \markername markername;} string}
and the string is ignored (it is always 0xAC on NeXT).
Note that the {\NeXTHelpLink } group may itself be preceded by
other commands.
*/
rtfNeXTHelpMarker: '{' RTFNeXTHelpMarker RTFNeXTmarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); }
{
GSRTFNeXTHelpMarker (CTXT, $2.parameter, $4);
};
/*
Font description
*/
rtfFontList: '{' RTFfontListStart rtfFonts '}'
;
rtfFonts:
| rtfFonts rtfFontStatement
| rtfFonts '{' rtfFontStatement '}'
| rtfFonts '{' rtfFontStatement rtfBlock RTFtext '}'
{ free((void *)$5);}
;
/* the first RTFfont tags the font with a number */
/* RTFtext introduces the fontName */
rtfFontStatement: RTFfont rtfFontFamily rtfFontAttrs RTFtext { GSRTFregisterFont(CTXT, $4, $2, $1.parameter);
free((void *)$4); }
/* fbidi should be a font family, but it seems to be used differently */
| RTFfont RTFfamilyBiDi rtfFontFamily rtfFontAttrs RTFtext { GSRTFregisterFont(CTXT, $5, $3, $1.parameter);
free((void *)$5); }
/* Theme fonts */
| RTFOtherStatement RTFfont RTFfamilyBiDi rtfFontFamily rtfFontAttrs RTFtext { GSRTFregisterFont(CTXT, $6, $4, $2.parameter);
free((void *)$6); }
;
rtfFontAttrs: /* empty */
| rtfFontAttrs RTFfcharset
| rtfFontAttrs RTFfprq
| rtfFontAttrs RTFcpg
| rtfFontAttrs RTFfttruetype
| rtfFontAttrs rtfBlock
;
rtfFontFamily:
RTFfamilyNil { $$ = RTFfamilyNil - RTFfamilyNil; }
| RTFfamilyRoman { $$ = RTFfamilyRoman - RTFfamilyNil; }
| RTFfamilySwiss { $$ = RTFfamilySwiss - RTFfamilyNil; }
| RTFfamilyModern { $$ = RTFfamilyModern - RTFfamilyNil; }
| RTFfamilyScript { $$ = RTFfamilyScript - RTFfamilyNil; }
| RTFfamilyDecor { $$ = RTFfamilyDecor - RTFfamilyNil; }
| RTFfamilyTech { $$ = RTFfamilyTech - RTFfamilyNil; }
;
/*
Colour definition
*/
rtfColorDef: '{' RTFcolortable rtfColors '}'
;
rtfColors: /* empty */
| rtfColors rtfColorStatement
;
/* We get the ';' as RTFText */
rtfColorStatement: RTFred RTFgreen RTFblue RTFtext
{
GSRTFaddColor(CTXT, $1.parameter, $2.parameter, $3.parameter);
free((void *)$4);
}
| RTFtext
{
GSRTFaddDefaultColor(CTXT);
free((void *)$1);
}
;
/*
some cludgy trailer
dummyNonTerminal: '\\' { @1.first_line; } / * we introduce a @n to fix the lex attributes * /
;
*/
%%
/* some C code here */