Add some support for help links and markers in RTF documents. These

end up as dedicated attachments in attributed strings.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@31828 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
wlux 2011-01-03 11:48:57 +00:00
parent 3346dd5d48
commit e86fae67c3
13 changed files with 1104 additions and 604 deletions

View file

@ -26,11 +26,12 @@
Boston, MA 02110-1301, USA.
*/
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>
#include "RTFConsumer.h"
#include "RTFConsumerFunctions.h"
#include "RTFProducer.h"
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <GNUstepGUI/GSHelpAttachment.h>
#import "RTFConsumer.h"
#import "RTFConsumerFunctions.h"
#import "RTFProducer.h"
/* we have to satisfy the scanner with a stream reading function */
typedef struct {
@ -266,6 +267,8 @@ static BOOL classInheritsFromNSMutableAttributedString (Class c)
- (void) push;
- (void) pop;
- (void) appendString: (NSString*)string;
- (void) appendHelpLink: (NSString*)fileName marker: (NSString *)markerName;
- (void) appendHelpMarker: (NSString*)markerName;
@end
@ -662,6 +665,84 @@ static BOOL classInheritsFromNSMutableAttributedString (Class c)
}
}
- (void) appendHelpLink: (NSString*)fileName marker: (NSString*)markerName
{
int oldPosition = [result length];
NSRange insertionRange = NSMakeRange(oldPosition,0);
if (!ignore)
{
GSHelpLinkAttachment* attachment;
RTFAttribute* attr = [self attr];
NSMutableDictionary* attributes = nil;
NSMutableAttributedString* str = nil;
attachment =
[[GSHelpLinkAttachment alloc]
initWithFileName: fileName
markerName: markerName];
if (attachment == nil)
{
NSLog(@"No attachment at %d", oldPosition);
return;
}
attributes = [[NSMutableDictionary alloc]
initWithObjectsAndKeys:
[attr currentFont], NSFontAttributeName,
attr->paragraph, NSParagraphStyleAttributeName,
nil];
str = (NSMutableAttributedString*) [NSMutableAttributedString
attributedStringWithAttachment: attachment];
[str addAttributes: attributes range: NSMakeRange (0, [str length])];
[result replaceCharactersInRange: insertionRange withAttributedString: str];
attr->changed = YES;
RELEASE(attributes);
RELEASE(attachment);
}
}
- (void) appendHelpMarker: (NSString*)markerName
{
int oldPosition = [result length];
NSRange insertionRange = NSMakeRange(oldPosition,0);
if (!ignore)
{
GSHelpMarkerAttachment* attachment;
RTFAttribute* attr = [self attr];
NSMutableDictionary* attributes = nil;
NSMutableAttributedString* str = nil;
attachment =
[[GSHelpMarkerAttachment alloc] initWithMarkerName: markerName];
if (attachment == nil)
{
NSLog(@"No attachment at %d", oldPosition);
return;
}
attributes = [[NSMutableDictionary alloc]
initWithObjectsAndKeys:
[attr currentFont], NSFontAttributeName,
attr->paragraph, NSParagraphStyleAttributeName,
nil];
str = (NSMutableAttributedString*) [NSMutableAttributedString
attributedStringWithAttachment: attachment];
[str addAttributes: attributes range: NSMakeRange (0, [str length])];
[result replaceCharactersInRange: insertionRange withAttributedString: str];
attr->changed = YES;
RELEASE(attributes);
RELEASE(attachment);
}
}
@end
#undef IGNORE
@ -1162,3 +1243,34 @@ void GSRTFNeXTGraphic (void *ctxt, const char *fileName, int width, int height)
[(RTFDConsumer *)ctxt appendImage: [NSString stringWithCString: fileName]];
}
void GSRTFNeXTHelpLink (void *ctxt, int num, const char *markername,
const char *linkFilename, const char *linkMarkername)
{
NSRange range;
NSString *fileName = [NSString stringWithCString: linkFilename];
NSString *markerName = [NSString stringWithCString: linkMarkername];
range = [fileName rangeOfString: @";"];
if (range.location != NSNotFound)
fileName = [fileName substringToIndex:range.location];
range = [markerName rangeOfString: @";"];
if (range.location == 0)
markerName = nil;
else if (range.location != NSNotFound)
markerName = [markerName substringToIndex:range.location];
[(RTFDConsumer *)ctxt appendHelpLink: fileName marker: markerName];
}
void GSRTFNeXTHelpMarker (void *ctxt, int num, const char *markername)
{
NSRange range;
NSString *markerName = [NSString stringWithCString: markername];
range = [markerName rangeOfString: @";"];
if (range.location != NSNotFound)
markerName = [markerName substringToIndex:range.location];
[(RTFDConsumer *)ctxt appendHelpMarker: markerName];
}

View file

@ -137,6 +137,11 @@ void GSRTFunderline(void *ctxt, BOOL on);
void GSRTFparagraph(void *ctxt);
/* NeXTGraphic */
void GSRTFNeXTGraphic(void *ctxt, const char *fileName, int width, int height);
/* NeXTHelpLink */
void GSRTFNeXTHelpLink(void *ctxt, int num, const char *markername,
const char *linkFilename, const char *linkMarkername);
/* NeXTHelpMarker */
void GSRTFNeXTHelpMarker(void *ctxt, int num, const char *markername);
#endif

View file

@ -30,9 +30,10 @@
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>
#include "RTFProducer.h"
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <GNUstepGUI/GSHelpAttachment.h>
#import "RTFProducer.h"
// FIXME: Should be defined in a central place
#define PAPERSIZE @"PaperSize"
@ -928,60 +929,93 @@
NSString *attachmentFilename;
NSSize cellSize;
attachmentFileWrapper = [attachment fileWrapper];
attachmentFilename = [attachmentFileWrapper filename];
if (! attachmentFilename)
{
attachmentFilename =
[attachmentFileWrapper preferredFilename];
if ([attachment isKindOfClass: [GSHelpLinkAttachment class]])
{
GSHelpLinkAttachment *link =
(GSHelpLinkAttachment *)attachment;
if (! attachmentFilename)
{
// If we do not have a proper filename, we set it here, incrementing
// the number of unnamed attachment so we do not overwrite existing ones.
[result appendString: @"{{\\NeXTHelpLink"];
[result appendString: @" \\markername "];
[result appendString: @";\\linkFilename "];
[result appendString: [link fileName]];
[result appendString: @";\\linkMarkername "];
[result appendString: [link markerName]];
[result appendString: @";}"];
}
else if ([attachment
isKindOfClass: [GSHelpMarkerAttachment class]])
{
GSHelpMarkerAttachment *marker =
(GSHelpMarkerAttachment *)attachment;
// FIXME: setting the filename extension to tiff is not that great, but as
// we anyway append \NeXTGraphic just after it makes sense... (without the
// extension the file is not loaded)
[result appendString: @"{{\\NeXTHelpMarker"];
[result appendString: @" \\markername "];
[result appendString: [marker markerName]];
[result appendString: @";}"];
}
else
{
attachmentFileWrapper = [attachment fileWrapper];
attachmentFilename = [attachmentFileWrapper filename];
if (! attachmentFilename)
{
attachmentFilename =
[attachmentFileWrapper preferredFilename];
attachmentFilename = [NSString stringWithFormat: @"__unnamed_file_%d.tiff",
unnamedAttachmentCounter++];
[attachmentFileWrapper setPreferredFilename:
attachmentFilename];
}
}
if (! attachmentFilename)
{
// If we do not have a proper filename, we set it
// here, incrementing the number of unnamed attachment
// so we do not overwrite existing ones.
/*
if ([attachmentFilename respondsToSelector:
@selector(fileSystemRepresentation)])
{
const char *fileSystemRepresentation;
// FIXME: setting the filename extension to tiff
// is not that great, but as we anyway append
// \NeXTGraphic just after it makes sense... (without
// the extension the file is not loaded)
fileSystemRepresentation =
[attachmentFilename fileSystemRepresentation];
attachmentFilename =
[NSString stringWithFormat:
@"__unnamed_file_%d.tiff",
unnamedAttachmentCounter++];
[attachmentFileWrapper
setPreferredFilename: attachmentFilename];
}
}
attachmentFilename = [self _encodedFilenameRepresentation:
fileSystemRepresentation];
}
else
*/
{
attachmentFilename =
[self _ASCIIfiedString: attachmentFilename];
}
/*
if ([attachmentFilename respondsToSelector:
@selector(fileSystemRepresentation)])
{
const char *fileSystemRepresentation;
cellSize = [[attachment attachmentCell] cellSize];
fileSystemRepresentation =
[attachmentFilename fileSystemRepresentation];
[result appendString: @"{{\\NeXTGraphic "];
[result appendString: [attachmentFilename lastPathComponent]];
[result appendFormat: @" \\width%d \\height%d}",
(short)points2twips(cellSize.width),
(short)points2twips(cellSize.height)];
attachmentFilename =
[self _encodedFilenameRepresentation:
fileSystemRepresentation];
}
else
*/
{
attachmentFilename =
[self _ASCIIfiedString: attachmentFilename];
}
[attachmentFileWrapper setFilename: attachmentFilename];
[attachmentFileWrapper setPreferredFilename: attachmentFilename];
if (attachmentFileWrapper)
[attachments addObject: attachmentFileWrapper];
cellSize = [[attachment attachmentCell] cellSize];
[result appendString: @"{{\\NeXTGraphic "];
[result appendString: [attachmentFilename lastPathComponent]];
[result appendFormat: @" \\width%d \\height%d}",
(short)points2twips(cellSize.width),
(short)points2twips(cellSize.height)];
[attachmentFileWrapper setFilename: attachmentFilename];
[attachmentFileWrapper
setPreferredFilename: attachmentFilename];
if (attachmentFileWrapper)
[attachments addObject: attachmentFileWrapper];
}
}
}
else

File diff suppressed because it is too large Load diff

View file

@ -78,42 +78,48 @@
RTFNeXTGraphic = 294,
RTFNeXTGraphicWidth = 295,
RTFNeXTGraphicHeight = 296,
RTFpaperWidth = 297,
RTFpaperHeight = 298,
RTFmarginLeft = 299,
RTFmarginRight = 300,
RTFmarginTop = 301,
RTFmarginButtom = 302,
RTFfirstLineIndent = 303,
RTFleftIndent = 304,
RTFrightIndent = 305,
RTFalignCenter = 306,
RTFalignJustified = 307,
RTFalignLeft = 308,
RTFalignRight = 309,
RTFlineSpace = 310,
RTFspaceAbove = 311,
RTFstyle = 312,
RTFbold = 313,
RTFitalic = 314,
RTFunderline = 315,
RTFunderlineStop = 316,
RTFunichar = 317,
RTFsubscript = 318,
RTFsuperscript = 319,
RTFtabstop = 320,
RTFfcharset = 321,
RTFfprq = 322,
RTFcpg = 323,
RTFOtherStatement = 324,
RTFfontListStart = 325,
RTFfamilyNil = 326,
RTFfamilyRoman = 327,
RTFfamilySwiss = 328,
RTFfamilyModern = 329,
RTFfamilyScript = 330,
RTFfamilyDecor = 331,
RTFfamilyTech = 332
RTFNeXTHelpLink = 297,
RTFNeXTHelpMarker = 298,
RTFNeXTfilename = 299,
RTFNeXTmarkername = 300,
RTFNeXTlinkFilename = 301,
RTFNeXTlinkMarkername = 302,
RTFpaperWidth = 303,
RTFpaperHeight = 304,
RTFmarginLeft = 305,
RTFmarginRight = 306,
RTFmarginTop = 307,
RTFmarginButtom = 308,
RTFfirstLineIndent = 309,
RTFleftIndent = 310,
RTFrightIndent = 311,
RTFalignCenter = 312,
RTFalignJustified = 313,
RTFalignLeft = 314,
RTFalignRight = 315,
RTFlineSpace = 316,
RTFspaceAbove = 317,
RTFstyle = 318,
RTFbold = 319,
RTFitalic = 320,
RTFunderline = 321,
RTFunderlineStop = 322,
RTFunichar = 323,
RTFsubscript = 324,
RTFsuperscript = 325,
RTFtabstop = 326,
RTFfcharset = 327,
RTFfprq = 328,
RTFcpg = 329,
RTFOtherStatement = 330,
RTFfontListStart = 331,
RTFfamilyNil = 332,
RTFfamilyRoman = 333,
RTFfamilySwiss = 334,
RTFfamilyModern = 335,
RTFfamilyScript = 336,
RTFfamilyDecor = 337,
RTFfamilyTech = 338
};
#endif
/* Tokens. */
@ -156,42 +162,48 @@
#define RTFNeXTGraphic 294
#define RTFNeXTGraphicWidth 295
#define RTFNeXTGraphicHeight 296
#define RTFpaperWidth 297
#define RTFpaperHeight 298
#define RTFmarginLeft 299
#define RTFmarginRight 300
#define RTFmarginTop 301
#define RTFmarginButtom 302
#define RTFfirstLineIndent 303
#define RTFleftIndent 304
#define RTFrightIndent 305
#define RTFalignCenter 306
#define RTFalignJustified 307
#define RTFalignLeft 308
#define RTFalignRight 309
#define RTFlineSpace 310
#define RTFspaceAbove 311
#define RTFstyle 312
#define RTFbold 313
#define RTFitalic 314
#define RTFunderline 315
#define RTFunderlineStop 316
#define RTFunichar 317
#define RTFsubscript 318
#define RTFsuperscript 319
#define RTFtabstop 320
#define RTFfcharset 321
#define RTFfprq 322
#define RTFcpg 323
#define RTFOtherStatement 324
#define RTFfontListStart 325
#define RTFfamilyNil 326
#define RTFfamilyRoman 327
#define RTFfamilySwiss 328
#define RTFfamilyModern 329
#define RTFfamilyScript 330
#define RTFfamilyDecor 331
#define RTFfamilyTech 332
#define RTFNeXTHelpLink 297
#define RTFNeXTHelpMarker 298
#define RTFNeXTfilename 299
#define RTFNeXTmarkername 300
#define RTFNeXTlinkFilename 301
#define RTFNeXTlinkMarkername 302
#define RTFpaperWidth 303
#define RTFpaperHeight 304
#define RTFmarginLeft 305
#define RTFmarginRight 306
#define RTFmarginTop 307
#define RTFmarginButtom 308
#define RTFfirstLineIndent 309
#define RTFleftIndent 310
#define RTFrightIndent 311
#define RTFalignCenter 312
#define RTFalignJustified 313
#define RTFalignLeft 314
#define RTFalignRight 315
#define RTFlineSpace 316
#define RTFspaceAbove 317
#define RTFstyle 318
#define RTFbold 319
#define RTFitalic 320
#define RTFunderline 321
#define RTFunderlineStop 322
#define RTFunichar 323
#define RTFsubscript 324
#define RTFsuperscript 325
#define RTFtabstop 326
#define RTFfcharset 327
#define RTFfprq 328
#define RTFcpg 329
#define RTFOtherStatement 330
#define RTFfontListStart 331
#define RTFfamilyNil 332
#define RTFfamilyRoman 333
#define RTFfamilySwiss 334
#define RTFfamilyModern 335
#define RTFfamilyScript 336
#define RTFfamilyDecor 337
#define RTFfamilyTech 338
@ -205,7 +217,7 @@ typedef union YYSTYPE
RTFcmd cmd;
}
/* Line 1529 of yacc.c. */
#line 209 "rtfGrammar.tab.h"
#line 221 "rtfGrammar.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1

View file

@ -399,7 +399,10 @@ rtfNeXTGraphic: '{' RTFNeXTGraphic RTFtext RTFNeXTGraphicWidth RTFNeXTGraphicHei
other commands.
*/
rtfNeXTHelpLink: '{' RTFNeXTHelpLink RTFNeXTmarkername RTFtext RTFNeXTlinkFilename RTFtext RTFNeXTlinkMarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); };
rtfNeXTHelpLink: '{' RTFNeXTHelpLink RTFNeXTmarkername RTFtext RTFNeXTlinkFilename RTFtext RTFNeXTlinkMarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); }
{
GSRTFNeXTHelpLink (CTXT, $2.parameter, $4, $6, $8);
};
/*
NeXTHelpMarker
@ -410,7 +413,10 @@ rtfNeXTHelpLink: '{' RTFNeXTHelpLink RTFNeXTmarkername RTFtext RTFNeXTlinkFilena
other commands.
*/
rtfNeXTHelpMarker: '{' RTFNeXTHelpMarker RTFNeXTmarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); };
rtfNeXTHelpMarker: '{' RTFNeXTHelpMarker RTFNeXTmarkername RTFtext '}' { GSRTFopenBlock(CTXT, YES); } rtfIngredients { GSRTFcloseBlock(CTXT, YES); }
{
GSRTFNeXTHelpMarker (CTXT, $2.parameter, $4);
};
/*
Font description