diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5f8a14a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,185 @@
+#########################
+# .gitignore file for Xcode4 and Xcode5 Source projects
+#
+# Apple bugs, waiting for Apple to fix/respond:
+#
+# 15564624 - what does the xccheckout file in Xcode5 do? Where's the documentation?
+#
+# Version 2.1
+# For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects
+#
+# 2013 updates:
+# - fixed the broken "save personal Schemes"
+# - added line-by-line explanations for EVERYTHING (some were missing)
+#
+# NB: if you are storing "built" products, this WILL NOT WORK,
+# and you should use a different .gitignore (or none at all)
+# This file is for SOURCE projects, where there are many extra
+# files that we want to exclude
+#
+#########################
+
+#####
+# OS X temporary files that should never be committed
+#
+# c.f. http://www.westwind.com/reference/os-x/invisibles.html
+
+.DS_Store
+
+# c.f. http://www.westwind.com/reference/os-x/invisibles.html
+
+.Trashes
+
+# c.f. http://www.westwind.com/reference/os-x/invisibles.html
+
+*.swp
+
+# *.lock - this is used and abused by many editors for many different things.
+# For the main ones I use (e.g. Eclipse), it should be excluded
+# from source-control, but YMMV
+
+*.lock
+
+#
+# profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?)
+#profile
+
+
+####
+# Xcode temporary files that should never be committed
+#
+# NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
+
+*~.nib
+
+
+####
+# Xcode build files -
+#
+# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData"
+
+DerivedData/
+
+# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build"
+
+build/
+
+
+#####
+# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups)
+#
+# This is complicated:
+#
+# SOMETIMES you need to put this file in version control.
+# Apple designed it poorly - if you use "custom executables", they are
+# saved in this file.
+# 99% of projects do NOT use those, so they do NOT want to version control this file.
+# ..but if you're in the 1%, comment out the line "*.pbxuser"
+
+# .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html
+
+*.pbxuser
+
+# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
+
+*.mode1v3
+
+# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
+
+*.mode2v3
+
+# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file
+
+*.perspectivev3
+
+# NB: also, whitelist the default ones, some projects need to use these
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+
+
+####
+# Xcode 4 - semi-personal settings
+#
+#
+# OPTION 1: ---------------------------------
+# throw away ALL personal settings (including custom schemes!
+# - unless they are "shared")
+#
+# NB: this is exclusive with OPTION 2 below
+xcuserdata
+
+# OPTION 2: ---------------------------------
+# get rid of ALL personal settings, but KEEP SOME OF THEM
+# - NB: you must manually uncomment the bits you want to keep
+#
+# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X,
+# or manually install git over the top of the OS X version
+# NB: this is exclusive with OPTION 1 above
+#
+#xcuserdata/**/*
+
+# (requires option 2 above): Personal Schemes
+#
+#!xcuserdata/**/xcschemes/*
+
+####
+# XCode 4 workspaces - more detailed
+#
+# Workspaces are important! They are a core feature of Xcode - don't exclude them :)
+#
+# Workspace layout is quite spammy. For reference:
+#
+# /(root)/
+# /(project-name).xcodeproj/
+# project.pbxproj
+# /project.xcworkspace/
+# contents.xcworkspacedata
+# /xcuserdata/
+# /(your name)/xcuserdatad/
+# UserInterfaceState.xcuserstate
+# /xcsshareddata/
+# /xcschemes/
+# (shared scheme name).xcscheme
+# /xcuserdata/
+# /(your name)/xcuserdatad/
+# (private scheme).xcscheme
+# xcschememanagement.plist
+#
+#
+
+####
+# Xcode 4 - Deprecated classes
+#
+# Allegedly, if you manually "deprecate" your classes, they get moved here.
+#
+# We're using source-control, so this is a "feature" that we do not want!
+
+*.moved-aside
+
+####
+# UNKNOWN: recommended by others, but I can't discover what these files are
+#
+# ...none. Everything is now explained.
+
+
+####
+# Other files
+#
+
+# This needs to be included explicitly because we excluded *.lock previously.
+!Podfile.lock
+
+Build/
+Pods/
+Dependency/version/version.h
+Dependency/peg-markdown-highlight/pmh_parser_core.c
+Dependency/peg-markdown-highlight/pmh_parser.c
+Dependency/peg-markdown-highlight/*.o
+Dependency/peg-markdown-highlight/greg/*.o
+Dependency/peg-markdown-highlight/greg/*.o-*
+Dependency/peg-markdown-highlight/greg/greg
+
+# Generated by build script
+MacDown/Resources/Prism/*
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7029006
--- /dev/null
+++ b/README.md
@@ -0,0 +1,67 @@
+Gist it! for MacDown
+=====================
+
+This repository illustrates a basic example of a plug-in for [MacDown], the open source Markdown editor for OS X. It provides a menu item "Gist it!" that uploads the current document (if available) as a public [GitHub Gist].
+
+> Note: Plug-ins are available in MacDown 0.6+ only. This particular plug-in works only under OS X 10.9 or later, not 10.8.
+
+[MacDown]: http://macdown.uranusjr.com
+[GitHub Gist]: https://gist.github.com
+
+### Installation
+
+Put the `macdown-gistit.plugin` file in `~/Library/Application Support/MacDown/PlugIns`.
+
+### Usage
+
+Open a document, and select menu item **Plug-ins → Gist it!** to upload. An alert dialog will appear to indicate whether the operation is successful. If the gist is creation successfully, its URL will be copied automatically into your
+clipboard, so that you can easily share, or open it inside a browser.
+
+### License
+
+[![Created Commons License](https://i.creativecommons.org/l/by-sa/3.0/88x31.png)](http://creativecommons.org/licenses/by-sa/3.0/)
+This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/).
+
+
+## The MacDown Plug-in Architecture
+
+This section serves as a simple walkthrough to how plug-ins work in MacDown until proper documentation is written. Hopefully not by myself. :p
+
+### Introduction
+
+A plugin in MacDown is a regular Cocoa [dynamic-loading bundle], with extension `.plugin`. MacDown searches `~/Library/Application Support/MacDown/PlugIns`, and build menu items for loadable bundles inside the directory. A plug-in in invoked when the user clicks on its corresponding menu item.
+
+[dynamic-loading bundle]: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/LoadingCode/LoadingCode.html#//apple_ref/doc/uid/10000052-SW1
+
+
+### Plug-in Architecture
+
+A plug-in project can be created via Xcode’s **OS X → Framework & Library → Bundle** project template. You should set up the project meta data according to Apple’s documentation, specifically provide a *Principle Class* config that points to the appropriate class inside the project as your plug-in’s entry class.
+
+A plug-in should provide two methods inside the principle class:
+
+**`- (NSString *)name`**
+
+This indicates the name of the plug-in. MacDown will use the value returned by this method as the menu item’s title for your plug-in.
+
+**`- (BOOL)run:(id)sender`**
+
+This method will be invoked when your plug-in is run. the `sender` argument indicates the UI item that triggers the invocation—usually the `NSMenuItem` object the user clicked on, but could also be `nil` if the plug-in is triggered programmatically.
+
+The return value indicates whether the plug-in is invoked successfully.
+
+This method may be invoked in the UI thread. Therefore, it is strongly recommended you push long operations into background threads, and/or run them asynchronously.
+
+### Tips
+
+MacDown uses the standard OS X document-based application structure. This means that you can get almost all information via the standard `NSDocumentController` API. Refer to the official documentation for more detail.
+
+A document instance in MacDown provides two additional properties:
+
+**`@property (nonatomic, readwrite) NSString *markdown`**
+
+This holds the string inside the editor. Writing to this property modifies the editor content.
+
+**`@property (nonatomic, readonly) NSString *html`**
+
+This holds the *rendered* HTML content.
diff --git a/macdown-gistit.xcodeproj/project.pbxproj b/macdown-gistit.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..f96629d
--- /dev/null
+++ b/macdown-gistit.xcodeproj/project.pbxproj
@@ -0,0 +1,258 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1F62698C1C8E98B000E87C30 /* MacDownGistItController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F62698B1C8E98B000E87C30 /* MacDownGistItController.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 1F6269811C8E987F00E87C30 /* macdown-gistit.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "macdown-gistit.plugin"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1F6269841C8E987F00E87C30 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 1F62698A1C8E98B000E87C30 /* MacDownGistItController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacDownGistItController.h; sourceTree = ""; };
+ 1F62698B1C8E98B000E87C30 /* MacDownGistItController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MacDownGistItController.m; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1F62697E1C8E987F00E87C30 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 1F6269781C8E987F00E87C30 = {
+ isa = PBXGroup;
+ children = (
+ 1F6269831C8E987F00E87C30 /* macdown-gistit */,
+ 1F6269821C8E987F00E87C30 /* Products */,
+ );
+ sourceTree = "";
+ };
+ 1F6269821C8E987F00E87C30 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1F6269811C8E987F00E87C30 /* macdown-gistit.plugin */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 1F6269831C8E987F00E87C30 /* macdown-gistit */ = {
+ isa = PBXGroup;
+ children = (
+ 1F6269841C8E987F00E87C30 /* Info.plist */,
+ 1F62698A1C8E98B000E87C30 /* MacDownGistItController.h */,
+ 1F62698B1C8E98B000E87C30 /* MacDownGistItController.m */,
+ );
+ path = "macdown-gistit";
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1F6269801C8E987F00E87C30 /* macdown-gistit */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1F6269871C8E987F00E87C30 /* Build configuration list for PBXNativeTarget "macdown-gistit" */;
+ buildPhases = (
+ 1F62697D1C8E987F00E87C30 /* Sources */,
+ 1F62697E1C8E987F00E87C30 /* Frameworks */,
+ 1F62697F1C8E987F00E87C30 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "macdown-gistit";
+ productName = "macdown-gistit";
+ productReference = 1F6269811C8E987F00E87C30 /* macdown-gistit.plugin */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 1F6269791C8E987F00E87C30 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0720;
+ ORGANIZATIONNAME = uranusjr;
+ TargetAttributes = {
+ 1F6269801C8E987F00E87C30 = {
+ CreatedOnToolsVersion = 7.2.1;
+ };
+ };
+ };
+ buildConfigurationList = 1F62697C1C8E987F00E87C30 /* Build configuration list for PBXProject "macdown-gistit" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 1F6269781C8E987F00E87C30;
+ productRefGroup = 1F6269821C8E987F00E87C30 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 1F6269801C8E987F00E87C30 /* macdown-gistit */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1F62697F1C8E987F00E87C30 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1F62697D1C8E987F00E87C30 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1F62698C1C8E98B000E87C30 /* MacDownGistItController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1F6269851C8E987F00E87C30 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 1F6269861C8E987F00E87C30 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ 1F6269881C8E987F00E87C30 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = "macdown-gistit/Info.plist";
+ INSTALL_PATH = "$(USER_LIBRARY_DIR)/Application Support/MacDown/PlugIns";
+ PRODUCT_BUNDLE_IDENTIFIER = "com.uranusjr.macdown-gistit";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ WRAPPER_EXTENSION = plugin;
+ };
+ name = Debug;
+ };
+ 1F6269891C8E987F00E87C30 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = "macdown-gistit/Info.plist";
+ INSTALL_PATH = "$(USER_LIBRARY_DIR)/Application Support/MacDown/PlugIns";
+ PRODUCT_BUNDLE_IDENTIFIER = "com.uranusjr.macdown-gistit";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ WRAPPER_EXTENSION = plugin;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1F62697C1C8E987F00E87C30 /* Build configuration list for PBXProject "macdown-gistit" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1F6269851C8E987F00E87C30 /* Debug */,
+ 1F6269861C8E987F00E87C30 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1F6269871C8E987F00E87C30 /* Build configuration list for PBXNativeTarget "macdown-gistit" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1F6269881C8E987F00E87C30 /* Debug */,
+ 1F6269891C8E987F00E87C30 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 1F6269791C8E987F00E87C30 /* Project object */;
+}
diff --git a/macdown-gistit.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/macdown-gistit.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..59f553f
--- /dev/null
+++ b/macdown-gistit.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/macdown-gistit/Info.plist b/macdown-gistit/Info.plist
new file mode 100644
index 0000000..6068f0c
--- /dev/null
+++ b/macdown-gistit/Info.plist
@@ -0,0 +1,28 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ NSHumanReadableCopyright
+ Copyright © 2016 uranusjr. All rights reserved.
+ NSPrincipalClass
+ MacDownGistItController
+
+
diff --git a/macdown-gistit/MacDownGistItController.h b/macdown-gistit/MacDownGistItController.h
new file mode 100644
index 0000000..b91c745
--- /dev/null
+++ b/macdown-gistit/MacDownGistItController.h
@@ -0,0 +1,15 @@
+//
+// MacDownGistItController.h
+// macdown-gistit
+//
+// Created by Tzu-ping Chung on 08/3.
+// Copyright © 2016 uranusjr. All rights reserved.
+//
+
+#import
+
+@interface MacDownGistItController : NSObject
+
+@property (readonly) NSString *name;
+
+@end
diff --git a/macdown-gistit/MacDownGistItController.m b/macdown-gistit/MacDownGistItController.m
new file mode 100644
index 0000000..336cfaa
--- /dev/null
+++ b/macdown-gistit/MacDownGistItController.m
@@ -0,0 +1,121 @@
+//
+// MacDownGistItController.m
+// macdown-gistit
+//
+// Created by Tzu-ping Chung on 08/3.
+// Copyright © 2016 uranusjr. All rights reserved.
+//
+
+#import
+#import "MacDownGistItController.h"
+
+
+static NSString * const MacDownGistListLink = @"https://api.github.com/gists";
+
+
+@protocol MacDownMarkdownSource
+
+@property (readonly) NSString *markdown;
+
+@end
+
+
+@implementation MacDownGistItController
+
+- (NSString *)name
+{
+ return @"Gist It!";
+}
+
+- (BOOL)run:(id)sender
+{
+ NSDocumentController *dc = [NSDocumentController sharedDocumentController];
+ return [self gistify:dc.currentDocument];
+}
+
+- (BOOL)gistify:(NSDocument *)document
+{
+ id markdownSource = (id)document;
+ NSString *markdown = markdownSource.markdown;
+ if (!markdown.length)
+ return NO;
+ NSString *fileName = document.fileURL.path.lastPathComponent;
+ if (!fileName.length)
+ fileName = @"Untitled";
+
+ NSURL * url = [NSURL URLWithString:MacDownGistListLink];
+ NSMutableURLRequest *req =
+ [NSMutableURLRequest requestWithURL:url
+ cachePolicy:NSURLRequestReloadIgnoringCacheData
+ timeoutInterval:0.0];
+ [req addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
+ [req addValue:@"application/json" forHTTPHeaderField:@"Accept"];
+
+ NSDictionary *object = @{
+ @"description": @"Uploaded by MacDown. http://macdown.uranusjr.com",
+ @"public": @YES,
+ @"files": @{fileName: @{@"content": markdown}},
+ };
+ NSData *data = [NSJSONSerialization dataWithJSONObject:object
+ options:0 error:NULL];
+ if (!data)
+ return NO;
+
+ req.HTTPMethod = @"POST";
+ req.HTTPBody = data;
+
+ NSURLSessionConfiguration *conf =
+ [NSURLSessionConfiguration defaultSessionConfiguration];
+ NSURLSession *session = [NSURLSession sessionWithConfiguration:conf];
+ NSURLSessionTask *task = [session dataTaskWithRequest:req
+ completionHandler:^(
+ NSData *data, NSURLResponse *res, NSError *error) {
+
+ NSHTTPURLResponse *r = (id)res;
+ NSString *json = data ?
+ [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] :
+ nil;
+ NSDictionary *object = data ?
+ [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL] :
+ nil;
+ NSString *urlstring = object[@"html_url"];
+
+ NSAlert *alert = [[NSAlert alloc] init];
+ if (error)
+ {
+ alert = [NSAlert alertWithError:error];
+ }
+ else if (![res respondsToSelector:@selector(statusCode)])
+ {
+ alert.alertStyle = NSWarningAlertStyle;
+ alert.messageText = @"Unknown error";
+ }
+ else if (r.statusCode != 201 || !urlstring)
+ {
+ alert.alertStyle = NSWarningAlertStyle;
+ NSString *f = @"Unexpection return code %ld";
+ alert.messageText = [NSString stringWithFormat:f, r.statusCode];
+ if (json)
+ alert.informativeText = json;
+ }
+
+ alert.alertStyle = NSInformationalAlertStyle;
+ alert.messageText = @"Gist created";
+ alert.informativeText = [NSString stringWithFormat:
+ @"You gist is at %@\nThe URL has been copied into your clipboard.",
+ urlstring];
+
+ NSPasteboard *pb = [NSPasteboard generalPasteboard];
+ [pb clearContents];
+ [pb writeObjects:@[urlstring]];
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [alert runModal];
+ });
+ }];
+ [task resume];
+
+ return YES;
+}
+
+@end