Skip to content

Commit

Permalink
Experimental TOC rendering support
Browse files Browse the repository at this point in the history
See #63

This implementation does NOT render TOC at a specific tag, but
just prepends the TOC portion in front of the content (but after
front-matter). The TOC syntax might be more difficult. Still
considering options.
  • Loading branch information
uranusjr committed Jul 30, 2014
1 parent 9476885 commit f6e0c10
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 8 deletions.
2 changes: 2 additions & 0 deletions MacDown.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
1F51C9A1194564670015A96F /* libPods-MacDown-PAPreferences.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-MacDown-PAPreferences.a"; path = "../../../../Library/Developer/Xcode/DerivedData/MacDown-ggdtxvuybojeqbhjydkhilziizrv/Build/Products/Debug/libPods-MacDown-PAPreferences.a"; sourceTree = "<group>"; };
1F64CCC7195F5AB900CE619A /* MPAsset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAsset.h; sourceTree = "<group>"; };
1F64CCC8195F5AB900CE619A /* MPAsset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAsset.m; sourceTree = "<group>"; };
1F70CCD81978F03E00703429 /* MPAutosaving.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPAutosaving.h; sourceTree = "<group>"; };
1F8A82D819533E9300B6BF69 /* Prism */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Prism; path = Resources/Prism; sourceTree = "<group>"; };
1F8A83571953454F00B6BF69 /* HGMarkdownHighlighter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HGMarkdownHighlighter.h; path = "Dependency/peg-markdown-highlight/HGMarkdownHighlighter.h"; sourceTree = SOURCE_ROOT; };
1F8A83581953454F00B6BF69 /* HGMarkdownHighlighter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HGMarkdownHighlighter.m; path = "Dependency/peg-markdown-highlight/HGMarkdownHighlighter.m"; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -219,6 +220,7 @@
children = (
1F0D9D63194AC7CF008E1856 /* MPUtilities.h */,
1F0D9D64194AC7CF008E1856 /* MPUtilities.m */,
1F70CCD81978F03E00703429 /* MPAutosaving.h */,
);
name = Utility;
path = Code/Utility;
Expand Down
2 changes: 1 addition & 1 deletion MacDown.xcworkspace/xcshareddata/MacDown.xccheckout
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>26AD1539-E91F-48E0-A3E7-3E54BF601AA9</string>
<string>24769B53-F963-4503-96C3-3E34905014BD</string>
<key>IDESourceControlProjectName</key>
<string>MacDown</string>
<key>IDESourceControlProjectOriginsDictionary</key>
Expand Down
2 changes: 2 additions & 0 deletions MacDown/Code/Document/MPDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@

@property (nonatomic, readonly) MPPreferences *preferences;

- (IBAction)toggleTOCRendering:(id)sender;

@end
60 changes: 58 additions & 2 deletions MacDown/Code/Document/MPDocument.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@
#import "hoedown_html_patch.h"
#import "HGMarkdownHighlighter.h"
#import "MPUtilities.h"
#import "MPAutosaving.h"
#import "NSString+Lookup.h"
#import "NSTextView+Autocomplete.h"
#import "MPPreferences.h"
#import "MPRenderer.h"
#import "MPExportPanelAccessoryViewController.h"


static NSString * const kMPRendersTOCPropertyKey = @"Renders TOC";


static NSString *MPEditorPreferenceKeyWithValueKey(NSString *key)
{
if (!key.length)
Expand All @@ -46,6 +50,14 @@
return keys;
}

static NSString *MPAutosavePropertyKey(
id<MPAutosaving> object, NSString *propertyName)
{
NSString *className = NSStringFromClass([object class]);
return [NSString stringWithFormat:@"%@ %@ %@", className, propertyName,
object.autosaveName];
}


@implementation NSString (WordCount)

Expand Down Expand Up @@ -172,7 +184,7 @@ - (NSString *)nodeText


@interface MPDocument ()
<NSTextViewDelegate, MPRendererDataSource, MPRendererDelegate>
<NSTextViewDelegate, MPAutosaving, MPRendererDataSource, MPRendererDelegate>

typedef NS_ENUM(NSUInteger, MPWordCountType) {
MPWordCountTypeWord,
Expand All @@ -185,10 +197,12 @@ typedef NS_ENUM(NSUInteger, MPWordCountType) {
@property (weak) IBOutlet NSLayoutConstraint *editorPaddingBottom;
@property (weak) IBOutlet WebView *preview;
@property (weak) IBOutlet NSPopUpButton *wordCountWidget;
@property (copy, nonatomic) NSString *autosaveName;
@property (strong) HGMarkdownHighlighter *highlighter;
@property (strong) MPRenderer *renderer;
@property BOOL manualRender;
@property BOOL previewFlushDisabled;
@property (nonatomic) BOOL rendersTOC;
@property (readonly) BOOL previewVisible;
@property (nonatomic) NSUInteger totalWords;
@property (nonatomic) NSUInteger totalCharacters;
Expand Down Expand Up @@ -249,6 +263,25 @@ - (void)setTotalCharactersNoSpaces:(NSUInteger)value
usingPluralRule:rule localizeNumeral:NO];
}

- (void)setAutosaveName:(NSString *)autosaveName
{
_autosaveName = autosaveName;
self.splitView.autosaveName = autosaveName;
}

- (BOOL)rendersTOC
{
NSString *key = MPAutosavePropertyKey(self, kMPRendersTOCPropertyKey);
BOOL value = [[NSUserDefaults standardUserDefaults] boolForKey:key];
return value;
}

- (void)setRendersTOC:(BOOL)rendersTOC
{
NSString *key = MPAutosavePropertyKey(self, kMPRendersTOCPropertyKey);
[[NSUserDefaults standardUserDefaults] setBool:rendersTOC forKey:key];
}


#pragma mark - Override

Expand All @@ -268,7 +301,7 @@ - (void)windowControllerDidLoadNib:(NSWindowController *)controller
if (self.fileURL)
autosaveName = self.fileURL.absoluteString;
controller.window.frameAutosaveName = autosaveName;
self.splitView.autosaveName = autosaveName;
self.autosaveName = autosaveName;

self.highlighter =
[[HGMarkdownHighlighter alloc] initWithTextView:self.editor
Expand Down Expand Up @@ -411,6 +444,16 @@ - (BOOL)prepareSavePanel:(NSSavePanel *)savePanel
}


#pragma mark - NSMenuValidation

- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
if (menuItem.action == @selector(toggleTOCRendering:))
menuItem.state = self.rendersTOC ? NSOnState : NSOffState;
return YES;
}


#pragma mark - NSTextViewDelegate

- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
Expand Down Expand Up @@ -613,6 +656,11 @@ - (BOOL)rendererHasSmartyPants:(MPRenderer *)renderer
return self.preferences.extensionSmartyPants;
}

- (BOOL)rendererRendersTOC:(MPRenderer *)renderer
{
return self.rendersTOC;
}

- (NSString *)rendererStyleName:(MPRenderer *)renderer
{
return self.preferences.htmlStyleName;
Expand Down Expand Up @@ -978,6 +1026,14 @@ - (IBAction)render:(id)sender
[self.renderer parseAndRenderLater];
}

- (IBAction)toggleTOCRendering:(id)sender
{
BOOL nextState = NO;
if ([sender state] == NSOffState)
nextState = YES;
self.rendersTOC = nextState;
}


#pragma mark - Private

Expand Down
1 change: 1 addition & 0 deletions MacDown/Code/Document/MPRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

- (int)rendererExtensions:(MPRenderer *)renderer;
- (BOOL)rendererHasSmartyPants:(MPRenderer *)renderer;
- (BOOL)rendererRendersTOC:(MPRenderer *)renderer;
- (NSString *)rendererStyleName:(MPRenderer *)renderer;
- (BOOL)rendererDetectsFrontMatter:(MPRenderer *)renderer;
- (BOOL)rendererHasSyntaxHighlighting:(MPRenderer *)renderer;
Expand Down
40 changes: 35 additions & 5 deletions MacDown/Code/Document/MPRenderer.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@

static NSString *MPHTMLFromMarkdown(
NSString *text, int flags, BOOL smartypants, NSString *frontMatter,
hoedown_renderer *renderer)
hoedown_renderer *htmlRenderer, hoedown_renderer *tocRenderer)
{
NSData *inputData = [text dataUsingEncoding:NSUTF8StringEncoding];
hoedown_markdown *markdown = hoedown_markdown_new(flags, 15, renderer);
hoedown_markdown *markdown = hoedown_markdown_new(flags, 15, htmlRenderer);
hoedown_buffer *ob = hoedown_buffer_new(64);
hoedown_markdown_render(ob, inputData.bytes, inputData.length, markdown);
if (smartypants)
Expand All @@ -75,8 +75,21 @@
NSString *result = [NSString stringWithUTF8String:hoedown_buffer_cstr(ob)];
hoedown_markdown_free(markdown);
hoedown_buffer_free(ob);

if (tocRenderer)
{
markdown = hoedown_markdown_new(flags, 15, tocRenderer);
ob = hoedown_buffer_new(64);
hoedown_markdown_render(
ob, inputData.bytes, inputData.length, markdown);
NSString *toc = [NSString stringWithUTF8String:hoedown_buffer_cstr(ob)];
result = [NSString stringWithFormat:@"%@\n%@", toc, result];
hoedown_markdown_free(markdown);
hoedown_buffer_free(ob);
}
if (frontMatter)
result = [NSString stringWithFormat:@"%@\n%@", frontMatter, result];

return result;
}

Expand Down Expand Up @@ -117,6 +130,7 @@

@interface MPRenderer ()

@property (nonatomic, unsafe_unretained) hoedown_renderer *tocRenderer;
@property (nonatomic, unsafe_unretained) hoedown_renderer *htmlRenderer;
@property (strong) NSMutableArray *currentLanguages;
@property (readonly) NSArray *baseStylesheets;
Expand All @@ -129,6 +143,7 @@ @interface MPRenderer ()
@property (strong) NSTimer *parseDelayTimer;
@property int extensions;
@property BOOL smartypants;
@property BOOL TOC;
@property (copy) NSString *styleName;
@property BOOL frontMatter;
@property BOOL mathjax;
Expand Down Expand Up @@ -222,13 +237,15 @@ - (instancetype)init

self.currentHtml = @"";
self.currentLanguages = [NSMutableArray array];
self.htmlRenderer = hoedown_html_renderer_new(0, 0);
self.tocRenderer = hoedown_html_toc_renderer_new(6);
self.htmlRenderer = hoedown_html_renderer_new(0, 6);

return self;
}

- (void)dealloc
{
self.tocRenderer = NULL;
self.htmlRenderer = NULL;
}

Expand All @@ -245,6 +262,13 @@ - (void)setRendererFlags:(int)rendererFlags
state->flags = rendererFlags;
}

- (void)setTocRenderer:(hoedown_renderer *)tocRenderer
{
if (_tocRenderer)
hoedown_html_renderer_free(_tocRenderer);
_tocRenderer = tocRenderer;
}

- (void)setHtmlRenderer:(hoedown_renderer *)htmlRenderer
{
if (_htmlRenderer)
Expand Down Expand Up @@ -374,6 +398,7 @@ - (void)parseIfPreferencesChanged
id<MPRendererDelegate> delegate = self.delegate;
if ([delegate rendererExtensions:self] != self.extensions
|| [delegate rendererHasSmartyPants:self] != self.smartypants
|| [delegate rendererRendersTOC:self] != self.TOC
|| [delegate rendererDetectsFrontMatter:self] != self.frontMatter)
[self parse];
}
Expand All @@ -393,6 +418,7 @@ - (void)parse
int extensions = [delegate rendererExtensions:self];
BOOL smartypants = [delegate rendererHasSmartyPants:self];
BOOL hasFrontMatter = [delegate rendererDetectsFrontMatter:self];
BOOL hasTOC = [delegate rendererRendersTOC:self];

NSString *frontMatter = nil;
NSString *markdown = [self.dataSource rendererMarkdown:self];
Expand All @@ -404,12 +430,16 @@ - (void)parse
if (frontMatter.length)
markdown = [markdown substringWithRange:restRange];
}

hoedown_renderer *tocRenderer = NULL;
if (hasTOC)
tocRenderer = self.tocRenderer;
self.currentHtml = MPHTMLFromMarkdown(
markdown, extensions, smartypants, frontMatter, self.htmlRenderer);
markdown, extensions, smartypants, frontMatter, self.htmlRenderer,
tocRenderer);

self.extensions = extensions;
self.smartypants = smartypants;
self.TOC = hasTOC;
self.frontMatter = hasFrontMatter;

if (nextAction)
Expand Down
15 changes: 15 additions & 0 deletions MacDown/Code/Utility/MPAutosaving.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// MPAutosaving.h
// MacDown
//
// Created by Tzu-ping Chung on 18/7.
// Copyright (c) 2014 Tzu-ping Chung . All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol MPAutosaving <NSObject>

- (NSString *)autosaveName;

@end
6 changes: 6 additions & 0 deletions MacDown/Localization/Base.lproj/MainMenu.xib
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,12 @@
<binding destination="LEY-zf-22t" name="enabled" keyPath="self.currentDocument.previewVisible" id="5e7-rJ-oX2"/>
</connections>
</menuItem>
<menuItem title="Renders TOC" id="v6B-Cb-FlX">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleTOCRendering:" target="-1" id="CfY-Zz-Yyy"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="onf-Mq-Pah"/>
<menuItem title="Left 1:3 Right" id="VW7-VH-9yl">
<modifierMask key="keyEquivalentModifierMask"/>
Expand Down

0 comments on commit f6e0c10

Please sign in to comment.