-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMarkup.m
338 lines (258 loc) · 11.2 KB
/
Markup.m
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
//***************************************************************************
#import "Markup.h"
#import "MarkupTextView.h"
#import "NSObjectAdditions.h"
#include <objc/runtime.h>
//***************************************************************************
@implementation Markup
static NSBundle* bundle = nil;
// TODO: Do we need to make this a singleton?
static Markup* sharedMarkupPlugin = nil;
+ (NSBundle*)sharedBundle {
return bundle;
}
- (id)init {
if (sharedMarkupPlugin != nil) {
[self autorelease];
self = [sharedMarkupPlugin retain];
} else {
if (self = [super init]) {
sharedMarkupPlugin = self;
}
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSApplicationDidFinishLaunchingNotification
object:nil];
[super dealloc];
}
+ (Markup*)sharedMarkupPlugin {
if (sharedMarkupPlugin == nil) {
sharedMarkupPlugin = [[self alloc] init];
}
return sharedMarkupPlugin;
}
// This method is called when the plugin is loaded, and the plugin's bundle is
// passed as an argument. If initialization fails, return NO, and if it goes
// alright, return YES.
+ (BOOL)initializeClass:(NSBundle*)theBundle {
bundle = theBundle;
[bundle retain];
return YES;
}
+ (void)initialize {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidFinishLaunching:)
name:NSApplicationDidFinishLaunchingNotification
object:nil];
}
+ (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
[self addMarkupMenuItem];
}
// This should return an NSEnumerator of all the plugins available, initialized
// and ready for use.
+ (NSEnumerator*)pluginsAvailable;
{ return nil; }
+ (NSString*)pluginType {
return @"Markup";
}
//// User Interface / Editing Front
+ (NSString*)pluginName {
return @"Markup";
}
// This should return the name of the plugin to appear in RapidWeaver's
// graphical user interface. This name should describe what the plugin does, if
// possible. For example, if you were making a plugin to maintain a blog, Blog,
// Journal, or Weblog would all make good plugin names.
+ (NSString*)pluginAuthor {
return @"Andre Pang <[email protected]>";
}
// The person and/or company responsible for writing the plugin.
+ (NSImage*)pluginIcon {
return nil;
}
// The plugin's 32 by 32 icon image for use in RapidWeaver's source list.
+ (NSString*)pluginDescription {
return @"Markup";
}
// This should return a human-readable description of what the plugin does.
- (NSString*)uniqueID {
return _uniqueID;
}
// Should return a unique page ID from setUniqueID:(NSString *)uniqueID.
- (void)setUniqueID:(NSString*)aUniqueID {
_uniqueID = aUniqueID;
[_uniqueID retain];
}
// RapidWeaver will call this when it creates a new page. The unique ID is
// currently used in the styled plugin.
static NSMenu* markupLanguagesMenu = nil;
+ (void)addMarkupMenuItem {
static BOOL addedMarkupTextMenuItem = NO;
if (addedMarkupTextMenuItem) return;
markupLanguagesMenu = [[NSMenu alloc] initWithTitle:@"Markup Languages"];
[markupLanguagesMenu setDelegate:[self sharedMarkupPlugin]];
[markupLanguagesMenu setAutoenablesItems:YES];
for (NSDictionary* markupStyleDefinition in [Markup markupStyles]) {
NSString* markupStyleName = [markupStyleDefinition objectForKey:kMarkupStyleName];
NSMenuItem* markupMenuItem =
[markupLanguagesMenu addItemWithTitle:markupStyleName
action:@selector(applyMarkupAttributeToSelection:)
keyEquivalent:@""];
[markupMenuItem setTag:kMarkupTextMenuItemTag];
}
[markupLanguagesMenu addItem:[NSMenuItem separatorItem]];
NSMenuItem* useSmartQuotesMenuItem =
[markupLanguagesMenu addItemWithTitle:@"Use Smart Quotes"
action:@selector(onToggleSmartQuotes:)
keyEquivalent:@""];
[useSmartQuotesMenuItem bind:@"value"
toObject:[self sharedMarkupPlugin]
withKeyPath:@"usingSmartQuotes"
options:nil];
[[self sharedMarkupPlugin] setValue:[NSNumber numberWithInteger:NSOnState]
forKey:@"usingSmartQuotes"];
[useSmartQuotesMenuItem setState:NSOnState];
[markupLanguagesMenu addItem:[NSMenuItem separatorItem]];
[markupLanguagesMenu addItemWithTitle:@"Dump Attributes"
action:@selector(onDumpAttributes:)
keyEquivalent:@""];
NSMenuItem* markupLanguagesMenuItem = [[NSMenuItem alloc] init];
[markupLanguagesMenuItem setTitle:@"Markup Language"];
[markupLanguagesMenuItem setAction:@selector(applyMarkupAttributeToSelection:)];
[markupLanguagesMenuItem setSubmenu:markupLanguagesMenu];
NSMenu* mainMenu = [[NSApplication sharedApplication] mainMenu];
NSMenu* formatMenu = [[mainMenu itemWithTitle:@"Format"] submenu];
NSMenuItem* htmlMenuItem = [formatMenu itemWithTitle:@"HTML"];
NSInteger htmlMenuItemIndex = [formatMenu indexOfItem:htmlMenuItem];
[formatMenu insertItem:markupLanguagesMenuItem atIndex:htmlMenuItemIndex + 1];
addedMarkupTextMenuItem = YES;
}
- (NSView*)userInteractionAndEditingView {
return nil;
}
static NSMutableArray* cachedMarkupStyles = nil;
+ (NSArray*)markupStyles {
if (cachedMarkupStyles == nil) {
NSString* filterStylesPropertyListPath =
[bundle pathForResource:@"MarkupFilters" ofType:@"plist" inDirectory:@"MarkupFilters"];
NSArray* filterStylesPropertyList =
[NSArray arrayWithContentsOfFile:filterStylesPropertyListPath];
cachedMarkupStyles = [[NSMutableArray alloc] init];
NSArray* keys = [NSArray arrayWithObjects:kMarkupStyleName, kMarkupStyleFilterCommand, nil];
for (NSDictionary* propertyListEntry in filterStylesPropertyList) {
NSString* name = [propertyListEntry objectForKey:@"Name"];
NSString* filterCommandPath = [propertyListEntry objectForKey:@"FilterCommand"];
NSString* path =
[bundle pathForResource:[filterCommandPath lastPathComponent]
ofType:[propertyListEntry objectForKey:@"FilterCommandExtension"]
inDirectory:[@"MarkupFilters"
stringByAppendingPathComponent:
[filterCommandPath stringByDeletingLastPathComponent]]];
NSArray* values = [NSArray arrayWithObjects:name, path, nil];
NSDictionary* markupStyle = [NSDictionary dictionaryWithObjects:values forKeys:keys];
[cachedMarkupStyles addObject:markupStyle];
}
}
return cachedMarkupStyles;
}
// This should return the view to be shown inside RapidWeaver for editing the
// attributes and content associated with your plugin. For example, for a blog
// plugin, this would be a view showing a table view of blog entries and text
// views for editing each entry.
//// Theme-Specific Options
- (id)valueForThemeSpecificOptionKey:(NSString*)key {
return nil;
}
// This method should return the stored value for a given theme-specific option
// key. See below for further information on these values and their use.
- (void)setValue:(id)value forThemeSpecificOptionKey:(NSString*)key {
}
// This method is called by RapidWeaver if your plugin has any theme-specific
// options available. These options are for customizing your plugin's output
// content-wise from theme to theme. For example, if you made a photo album
// plugin, this concept makes it possible for different themes to use custom
// picture frame graphics for the same plugin. The custom picture frame graphic
// would be specified in the theme's file format, where it might acknowledge
// certain plugins and specify options for them. If you have theme options, and
// your plugin does not get any input from the theme on how it should look, you
// should have defaults ready for use.
//// Plugin Output
+ (NSArray*)extraFilesNeededInExportFolder:(NSDictionary*)params {
return nil;
}
// This method has the same use as its instance counterpart below, except this
// class version should be used for copying files specific to the plugin itself,
// rather than the plugin instance. For example, the - (NSArray
// *)extraFilesNeededInExportFolder should return the user's photos, and +
// (NSArray *)extraFilesNeededInExportFolder should return a picture frame
// graphic.
- (NSArray*)extraFilesNeededInExportFolder:(NSDictionary*)params {
return nil;
}
// This should return an NSArray of NSString file paths if your plugin needs any
// files (such as images, audio, style sheets, and others) copied into the
// export folder when the user exports a site for publishing. The files should
// be located in some sort of temporary directory. Pass an array with no objects
// if you don't need any extra files copied.
- (NSString*)contentHTML:(NSDictionary*)params {
return nil;
}
// This should return all HTML code resulting from user-interaction. The code
// should be suitable to be placed inside RapidWeaver's content area.
- (NSString*)sidebarHTML:(NSDictionary*)params {
return nil;
}
// This should return all HTML code generated by the plugin. The code should be
// suitable to be placed inside RapidWeaver's sidebar area.
- (void)cancelExport {
}
// sent from RW to inform the plugin to gracefully cancel
//// Plugin Settings
// return a dirctionary describing the plugin and its exportable settings
- (NSDictionary*)pluginSettings {
return nil;
}
// apply the settings as returned from -pluginSettings to this plugin
- (void)setPluginSettings:(NSDictionary*)settings {
}
// return YES if this plugin will accept 'settings'
- (BOOL)acceptsPluginSettings:(NSDictionary*)settings {
return NO;
}
// return YES if this plugin can provide settings (default is NO)
- (BOOL)providesPluginSettings {
return NO;
}
- (void)encodeWithCoder:(NSCoder*)coder {
[super encodeWithCoder:coder];
}
- (id)initWithCoder:(NSCoder*)decoder {
self = [super initWithCoder:decoder];
self = [self init];
return self;
}
+ (NSNumber*)markupEnabledForFilterStyleInSelectedRange:(NSString*)markupStyleName {
NSResponder* firstResponder = [[[NSApplication sharedApplication] keyWindow] firstResponder];
if ([firstResponder respondsToSelector:@selector(markupEnabledForFilterStyleInSelectedRange:)])
return [firstResponder performSelector:@selector(markupEnabledForFilterStyleInSelectedRange:)
withObject:markupStyleName];
else
return nil;
}
- (void)menuNeedsUpdate:(NSMenu*)menu {
NSArray* menuItems = [markupLanguagesMenu itemArray];
for (NSMenuItem* menuItem in menuItems) {
if ([menuItem tag] != kMarkupTextMenuItemTag) continue;
[menuItem
setState:[[Markup markupEnabledForFilterStyleInSelectedRange:[menuItem title]] boolValue]];
}
}
@end
//***************************************************************************
const NSString* const kMarkupStyleFilterCommand = @"filterCommand";
const NSString* const kMarkupStyleName = @"name";
const NSInteger kMarkupTextMenuItemTag = 6002;
//***************************************************************************