/* ** RenderHandler.m ** ** Copyright (c) 2003 ** ** Author: Yen-Ju ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "HRCell.h" #include "NoteCell.h" #include "RenderHandler.h" #include "GNUstep.h" #include @interface NSString (MyWikiAddition) - (NSString *) substringWithinQuotation; @end @implementation RenderHandler - (void) addNote: (NSAttributedString *) string withImage: (NSImage *) img withColor: (NSColor *) color { NSTextAttachment *at = [[NSTextAttachment alloc] init]; NoteCell *attachCell = [[NoteCell alloc] init]; [attachCell setImage: img]; [attachCell setColor: color]; [attachCell setText: string]; [at setAttachmentCell: attachCell]; NSAttributedString *as = [NSAttributedString attributedStringWithAttachment: at]; //NSAttributedString *astring = [[NSAttributedString alloc] initWithString: @"\n"]; //[_result appendAttributedString: astring]; [_result appendAttributedString: as]; RELEASE(attachCell); RELEASE(at); } - (void) addStringWithAttributes: (NSString *) element { { // Handle font type NSFont* font; NSFontTraitMask fontMask = 0; if (fontType & BoldFontType) fontMask |= NSBoldFontMask; if (fontType & ItalicFontType) fontMask |= NSItalicFontMask; if (fontType & FixedPitchFontType) { font = [[NSFontManager sharedFontManager] convertFont: [NSFont userFixedPitchFontOfSize: 12] toHaveTrait: fontMask]; } else { font = [[NSFontManager sharedFontManager] convertFont: [NSFont userFontOfSize: 12] toHaveTrait: fontMask]; } // NSLog(@"font %@, %d", font, [[NSFontManager sharedFontManager] traitsOfFont: font]); [attributes setValue: font forKey: NSFontAttributeName]; } if (tagType != CodeTagType) { if (tagType == UrefTagType) { [contentOfTag appendString: element]; #ifdef GNUSTEP [attributes setValue: [NSColor blueColor] forKey: NSForegroundColorAttributeName]; #endif } if (tagType == NoteTagType) { [contentOfTag appendString: element]; return; // Don't append string } } NSAttributedString *as; as = [[NSAttributedString alloc] initWithString: element attributes: attributes]; [_result appendAttributedString: as]; [as release]; } - (void) special: (NSString *) element { NSString *s; if (tagType == CodeTagType) s = AUTORELEASE([element copy]); else if ([element isEqualToString: @"<<"]) s = @"<"; else if ([element isEqualToString: @">>"]) s = @">"; else s = AUTORELEASE([element copy]); [self addStringWithAttributes: s]; } - (void) content: (NSString *) element { [self addStringWithAttributes: element]; } - (void) tag: (NSString *) element { if ([element isEqualToString: @"code"]) { fontType |= FixedPitchFontType; tagType = CodeTagType; } else if ([element isEqualToString: @"/code"]) { fontType &= ~FixedPitchFontType; tagType = OtherTagType; } else if (tagType == CodeTagType) { [self addStringWithAttributes: [NSString stringWithFormat: @"<%@>", element]]; return; } if ([element isEqualToString: @"b"]) { fontType |= BoldFontType; } else if ([element isEqualToString: @"/b"]) { fontType &= ~BoldFontType; } else if ([element isEqualToString: @"i"]) { fontType |= ItalicFontType; } else if ([element isEqualToString: @"/i"]) { fontType &= ~ItalicFontType; } else if ([element isEqualToString: @"link"]) { tagType = LinkTagType; rangeOfTag.location = [_result length]; } else if ([element isEqualToString: @"/link"]) { tagType = OtherTagType; rangeOfTag.length = [_result length] - rangeOfTag.location; [_result addAttribute: NSLinkAttributeName value: @"Link" range: rangeOfTag]; #ifdef GNUSTEP [_result addAttribute: NSForegroundColorAttributeName value: [NSColor blueColor] range: rangeOfTag]; [_result addAttribute: NSUnderlineStyleAttributeName value: [NSNumber numberWithInt: NSSingleUnderlineStyle] range: rangeOfTag]; #endif } else if ([element isEqualToString: @"hr/"]) { NSTextAttachment *ta = [[NSTextAttachment alloc] init]; HRCell *hr = [HRCell sharedHRCell]; [ta setAttachmentCell: hr]; NSAttributedString *as = [NSAttributedString attributedStringWithAttachment: ta]; [_result appendAttributedString: as]; RELEASE(ta); } else if (([element isEqualToString: @"note"]) || ([element isEqualToString: @"caution"]) || ([element isEqualToString: @"Information"])) { tagType = NoteTagType; } else if ([element isEqualToString: @"/note"]) { tagType = OtherTagType; // Put up the graphics [self addNote: AUTORELEASE([[NSAttributedString alloc] initWithString: contentOfTag]) withImage: [NSImage imageNamed: @"note.png"] withColor: [NSColor colorWithCalibratedRed: 0.81 green: 0.84 blue: 0.88 alpha: 1.0]]; [contentOfTag setString: @""]; } else if ([element isEqualToString: @"/caution"]) { tagType = OtherTagType; // Put up the graphics [self addNote: AUTORELEASE([[NSAttributedString alloc] initWithString: contentOfTag]) withImage: [NSImage imageNamed: @"caution.png"] withColor: [NSColor colorWithCalibratedRed: 0.88 green: 0.78 blue: 0.78 alpha: 1.0]]; [contentOfTag setString: @""]; } else if ([element isEqualToString: @"/information"]) { tagType = OtherTagType; // Put up the graphics [self addNote: AUTORELEASE([[NSAttributedString alloc] initWithString: contentOfTag]) withImage: [NSImage imageNamed: @"information.png"] withColor: [NSColor colorWithCalibratedRed: 0.79 green: 0.89 blue: 0.78 alpha: 1.0]]; [contentOfTag setString: @""]; } else if (([element isEqualToString: @"uref"]) || ([element isEqualToString: @"email"]) || ([element isEqualToString: @"file"])) { tagType = UrefTagType; rangeOfTag.location = [_result length]; } else if ([element isEqualToString: @"/uref"]) { tagType = OtherTagType; rangeOfTag.length = [_result length] - rangeOfTag.location; if ([value isEqualToString: @""]) [value setString: AUTORELEASE([contentOfTag copy])]; NSURL *url = [NSURL URLWithString: value]; if (url == nil) { NSRunAlertPanel(@"Invalid URL format", [NSString stringWithFormat: @"\"%@\" is invalid URL format. Please revise it.", value], @"OK", nil, nil, nil); } else { [_result addAttribute: NSLinkAttributeName value: [NSURL URLWithString: value] range: rangeOfTag]; #ifdef GNUSTEP [_result addAttribute: NSForegroundColorAttributeName value: [NSColor blueColor] range: rangeOfTag]; [_result addAttribute: NSUnderlineStyleAttributeName value: [NSNumber numberWithInt: NSSingleUnderlineStyle] range: rangeOfTag]; #endif } [contentOfTag setString: @""]; [value setString: @""]; } else if ([element isEqualToString: @"/email"]) { tagType = OtherTagType; rangeOfTag.length = [_result length] - rangeOfTag.location; if ([value isEqualToString: @""]) [value setString: AUTORELEASE([contentOfTag copy])]; [_result addAttribute: NSLinkAttributeName value: [NSString stringWithFormat: @"<%@>", value] range: rangeOfTag]; #ifdef GNUSTEP [_result addAttribute: NSForegroundColorAttributeName value: [NSColor blueColor] range: rangeOfTag]; [_result addAttribute: NSUnderlineStyleAttributeName value: [NSNumber numberWithInt: NSSingleUnderlineStyle] range: rangeOfTag]; #endif [contentOfTag setString: @""]; [value setString: @""]; } else if ([element isEqualToString: @"/file"]) { tagType = OtherTagType; rangeOfTag.length = [_result length] - rangeOfTag.location; if ([value isEqualToString: @""]) [value setString: AUTORELEASE([contentOfTag copy])]; [_result addAttribute: NSLinkAttributeName value: [NSString stringWithFormat: @"%@", value] range: rangeOfTag]; #ifdef GNUSTEP [_result addAttribute: NSForegroundColorAttributeName value: [NSColor blueColor] range: rangeOfTag]; [_result addAttribute: NSUnderlineStyleAttributeName value: [NSNumber numberWithInt: NSSingleUnderlineStyle] range: rangeOfTag]; #endif [contentOfTag setString: @""]; [value setString: @""]; } else { // Digest tag to get value of attributes if ([element hasPrefix: @"uref"]) { // Search string between '"' symbol tagType = UrefTagType; rangeOfTag.location = [_result length]; [value setString: [element substringWithinQuotation]]; if ([element hasSuffix: @"/"]) { [self addStringWithAttributes: value]; rangeOfTag.length = [_result length] - rangeOfTag.location; [contentOfTag setString: AUTORELEASE([value copy])]; [_result addAttribute: NSLinkAttributeName value: [NSURL URLWithString: value] range: rangeOfTag]; [value setString: @""]; [contentOfTag setString: @""]; tagType = OtherTagType; } } else if ([element hasPrefix: @"email"]) { // Search string between '"' symbol tagType = UrefTagType; rangeOfTag.location = [_result length]; [value setString: [element substringWithinQuotation]]; if ([element hasSuffix: @"/"]) { [self addStringWithAttributes: value]; rangeOfTag.length = [_result length] - rangeOfTag.location; [contentOfTag setString: AUTORELEASE([value copy])]; [_result addAttribute: NSLinkAttributeName value: [NSString stringWithFormat: @"<%@>", value] range: rangeOfTag]; [value setString: @""]; [contentOfTag setString: @""]; tagType = OtherTagType; } } else if ([element hasPrefix: @"file"]) { // Assume it is file // Search string between '"' symbol tagType = UrefTagType; rangeOfTag.location = [_result length]; [value setString: [element substringWithinQuotation]]; if ([element hasSuffix: @"/"]) { [self addStringWithAttributes: value]; rangeOfTag.length = [_result length] - rangeOfTag.location; [contentOfTag setString: AUTORELEASE([value copy])]; [_result addAttribute: NSLinkAttributeName value: [NSString stringWithFormat: @"%@", value] range: rangeOfTag]; [value setString: @""]; [contentOfTag setString: @""]; tagType = OtherTagType; } } } } - (id) init { self = [super init]; _result = [[NSMutableAttributedString alloc] init]; attributes = [[NSMutableDictionary alloc] init]; [attributes setValue: [NSFont userFontOfSize: 12] forKey: NSFontAttributeName]; [attributes setValue: [NSColor blackColor] forKey: NSForegroundColorAttributeName]; value = [[NSMutableString alloc] init]; fontType = NormalFontType;; tagType = OtherTagType; rangeOfTag = NSMakeRange(NSNotFound,0); contentOfTag = [[NSMutableString alloc] init]; return self; } - (void) dealloc { RELEASE(_result); RELEASE(attributes); RELEASE(value); RELEASE(contentOfTag); [super dealloc]; } - (NSAttributedString *) renderedString { [_result fixAttributesInRange: NSMakeRange(0, [_result length])]; return _result; } @end @implementation NSString (MyWikiAddition) - (NSString *) substringWithinQuotation { NSString *substring; NSRange resultRange, searchRange, finalRange;; resultRange = [self rangeOfString: @"\""]; if (resultRange.location == NSNotFound) NSLog(@"Error: can't find symbol \""); finalRange = resultRange; searchRange = NSMakeRange(NSMaxRange(resultRange), [self length]-NSMaxRange(resultRange)); resultRange = [self rangeOfString: @"\"" options: 0 range: searchRange]; if (resultRange.location == NSNotFound) NSLog(@"Error: can't find symbol \""); finalRange.location++; // take off the first '"' symbol finalRange.length = resultRange.location - finalRange.location; substring = [self substringWithRange: finalRange]; return AUTORELEASE([substring copy]); } @end