Compare commits

..

9 Commits

Author SHA1 Message Date
Rob Phillips 92ef17a63a Bump pod to v0.3 2016-10-12 15:05:14 -07:00
rob phillips 95a8027744 Merge pull request #11 from azeff/swift-3
Swift 3
2016-10-12 14:58:14 -07:00
Evgeny Kazakov f8e87aeb01 Travis config: use osx image with Xcode 8 2016-10-12 23:42:16 +03:00
Evgeny Kazakov fc5dfcc53f Use cmark's defines for options enum 2016-10-12 17:17:00 +03:00
Evgeny Kazakov d193007caf Swift 3 support 2016-10-12 17:16:52 +03:00
rob phillips ae3161caa5 Manual installation 2016-06-02 15:10:44 -07:00
rob phillips e11e164450 Merge pull request #7 from iwasrobbed/tests
Adds a few extra tests where possible
2016-06-02 14:49:36 -07:00
rob phillips af887d9c8d Adds a few extra tests where possible 2016-06-02 14:36:27 -07:00
rob phillips a410f58f78 Merge pull request #5 from iwasrobbed/downview
DownView rendering to close #3
2016-06-02 09:30:44 -07:00
23 changed files with 230 additions and 139 deletions
+1
View File
@@ -0,0 +1 @@
3.0
+2 -2
View File
@@ -1,4 +1,4 @@
osx_image: xcode7.3
osx_image: xcode8
language: objective-c
before_install:
- gem install xcpretty slather -N
@@ -6,4 +6,4 @@ before_install:
script:
- set -o pipefail && xcodebuild test -project Down.xcodeproj -scheme "Down" -destination "platform=iOS Simulator,name=iPhone 5,OS=9.3" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES | xcpretty -c
after_success:
- slather coverage --ignore "../**/*/Xcode*" --ignore "Source/cmark/*" --scheme "Down" Down.xcodeproj
- slather coverage --ignore "../**/*/Xcode*" --ignore "Source/cmark/*" --scheme "Down" Down.xcodeproj
+1 -1
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |spec|
spec.name = "Down"
spec.summary = "Blazing fast Markdown rendering in Swift, built upon cmark."
spec.version = "0.2"
spec.version = "0.3"
spec.homepage = "https://github.com/iwasrobbed/Down"
spec.license = { :type => "MIT", :file => "LICENSE" }
spec.authors = { "Rob Phillips" => "rob@desideratalabs.co" }
+29 -1
View File
@@ -49,6 +49,7 @@
D4201F431CFA5D63008EEC6E /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = D4201F1C1CFA5D63008EEC6E /* utf8.c */; settings = {COMPILER_FLAGS = "-w"; }; };
D4201F441CFA5D63008EEC6E /* utf8.h in Headers */ = {isa = PBXBuildFile; fileRef = D4201F1D1CFA5D63008EEC6E /* utf8.h */; };
D4201F451CFA5D63008EEC6E /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = D4201F1E1CFA5D63008EEC6E /* xml.c */; settings = {COMPILER_FLAGS = "-w"; }; };
D438696C1D00D27700E95A1F /* StringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D438696B1D00D27700E95A1F /* StringTests.swift */; };
D43AE5CA1CFFAE4D006E1522 /* NSAttributedString+HTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43AE5C91CFFAE4D006E1522 /* NSAttributedString+HTML.swift */; };
D43AE5DA1CFFD0D0006E1522 /* DownView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43AE5D91CFFD0D0006E1522 /* DownView.swift */; };
D43AE5DC1CFFD473006E1522 /* String+ToHTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43AE5DB1CFFD473006E1522 /* String+ToHTML.swift */; };
@@ -62,6 +63,7 @@
D486E99A1CFDE28B0059FD7C /* DownGroffRenderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D486E9991CFDE28B0059FD7C /* DownGroffRenderable.swift */; };
D4CF88981CFFAC2C00F07FD1 /* DownAttributedStringRenderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4CF88971CFFAC2C00F07FD1 /* DownAttributedStringRenderable.swift */; };
D4DC91141CFDED4B0091CE09 /* DownCommonMarkRenderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4DC91131CFDED4B0091CE09 /* DownCommonMarkRenderable.swift */; };
D4F948DC1D00A4A800C9C0F6 /* NSAttributedStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F948DB1D00A4A800C9C0F6 /* NSAttributedStringTests.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -120,6 +122,7 @@
D4201F1D1CFA5D63008EEC6E /* utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = "<group>"; };
D4201F1E1CFA5D63008EEC6E /* xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xml.c; sourceTree = "<group>"; };
D42869501CFF501200FACB4C /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
D438696B1D00D27700E95A1F /* StringTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringTests.swift; sourceTree = "<group>"; };
D43AE5C91CFFAE4D006E1522 /* NSAttributedString+HTML.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+HTML.swift"; sourceTree = "<group>"; };
D43AE5D91CFFD0D0006E1522 /* DownView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownView.swift; sourceTree = "<group>"; };
D43AE5DB1CFFD473006E1522 /* String+ToHTML.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+ToHTML.swift"; sourceTree = "<group>"; };
@@ -134,6 +137,7 @@
D4CF88961CFF94B300F07FD1 /* Down.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Down.h; sourceTree = "<group>"; };
D4CF88971CFFAC2C00F07FD1 /* DownAttributedStringRenderable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownAttributedStringRenderable.swift; sourceTree = "<group>"; };
D4DC91131CFDED4B0091CE09 /* DownCommonMarkRenderable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownCommonMarkRenderable.swift; sourceTree = "<group>"; };
D4F948DB1D00A4A800C9C0F6 /* NSAttributedStringTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSAttributedStringTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -172,7 +176,9 @@
D4201EC41CFA59A5008EEC6E /* Tests */,
D4201E811CFA5151008EEC6E /* Products */,
);
indentWidth = 4;
sourceTree = "<group>";
tabWidth = 4;
};
D4201E811CFA5151008EEC6E /* Products */ = {
isa = PBXGroup;
@@ -202,6 +208,8 @@
children = (
D4201EC51CFA59A5008EEC6E /* BindingTests.swift */,
D41689B21CFFE28200E5802B /* DownViewTests.swift */,
D4F948DB1D00A4A800C9C0F6 /* NSAttributedStringTests.swift */,
D438696B1D00D27700E95A1F /* StringTests.swift */,
);
path = Tests;
sourceTree = "<group>";
@@ -366,14 +374,17 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0730;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Glazed Donut, LLC.";
TargetAttributes = {
D4201E7F1CFA5151008EEC6E = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
ProvisioningStyle = Automatic;
};
D4201E891CFA5151008EEC6E = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
};
};
};
@@ -460,6 +471,8 @@
files = (
D41689B31CFFE28200E5802B /* DownViewTests.swift in Sources */,
D4201EEF1CFA59AD008EEC6E /* BindingTests.swift in Sources */,
D438696C1D00D27700E95A1F /* StringTests.swift in Sources */,
D4F948DC1D00A4A800C9C0F6 /* NSAttributedStringTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -489,8 +502,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -539,8 +554,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -560,6 +577,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@@ -572,7 +590,9 @@
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
@@ -585,6 +605,7 @@
SKIP_INSTALL = YES;
SWIFT_INCLUDE_PATHS = "${SRCROOT}/Source/cmark/**";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -593,7 +614,9 @@
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
@@ -605,6 +628,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_INCLUDE_PATHS = "${SRCROOT}/Source/cmark/**";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -612,9 +636,11 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
DEVELOPMENT_TEAM = "";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.glazeddonut.DownTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -622,9 +648,11 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
DEVELOPMENT_TEAM = "";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.glazeddonut.DownTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+10 -2
View File
@@ -1,9 +1,9 @@
## Down
[![Coverage Status](https://coveralls.io/repos/github/iwasrobbed/Down/badge.svg?branch=master)](https://coveralls.io/github/iwasrobbed/Down?branch=master)
[![Build Status](https://travis-ci.org/iwasrobbed/Down.svg?branch=master)](https://travis-ci.org/iwasrobbed/Down)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/iwasrobbed/Down/blob/master/LICENSE)
[![CocoaPods](https://img.shields.io/cocoapods/v/Down.svg?maxAge=2592000)]()
[![Swift](https://img.shields.io/badge/language-Swift-blue.svg)](https://swift.org)
[![Coverage Status](https://coveralls.io/repos/github/iwasrobbed/Down/badge.svg?branch=master)](https://coveralls.io/github/iwasrobbed/Down?branch=master)
Blazing fast Markdown rendering in Swift, built upon [cmark](https://github.com/jgm/cmark).
@@ -17,6 +17,14 @@ Quickly install using [CocoaPods](https://cocoapods.org):
pod 'Down'
```
Or manually install:
1. Clone this repository
2. Build the Down project
3. Add the resulting framework file to your project
4. ?
5. Profit
### Robust Performance
>[cmark](https://github.com/jgm/cmark) can render a Markdown version of War and Peace in the blink of an eye (127 milliseconds on a ten year old laptop, vs. 100-400 milliseconds for an eye blink). In our [benchmarks](https://github.com/jgm/cmark/blob/master/benchmarks.md), cmark is 10,000 times faster than the original Markdown.pl, and on par with the very fastest available Markdown processors.
@@ -181,4 +189,4 @@ Please feel free to fork and create a pull request for bug fixes or improvements
### Credit
This library is a wrapper around [cmark](https://github.com/jgm/cmark), which is built upon the [CommonMark](http://commonmark.org) Markdown specification.
[cmark](https://github.com/jgm/cmark) is Copyright (c) 2014, John MacFarlane. View [full license](https://github.com/jgm/cmark/blob/master/COPYING).
[cmark](https://github.com/jgm/cmark) is Copyright (c) 2014, John MacFarlane. View [full license](https://github.com/jgm/cmark/blob/master/COPYING).
+2 -2
View File
@@ -23,8 +23,8 @@ public struct Down: DownASTRenderable, DownHTMLRenderable, DownXMLRenderable,
- returns: An instance of Self
*/
@warn_unused_result
public init(markdownString: String) {
self.markdownString = markdownString
}
}
}
+5 -5
View File
@@ -8,19 +8,19 @@
import Foundation
public enum DownErrors: ErrorType {
public enum DownErrors: Error {
/**
Thrown when there was an issue converting the Markdown into an abstract syntax tree
*/
case MarkdownToASTError
case markdownToASTError
/**
Thrown when the abstract syntax tree could not be rendered into another format
*/
case ASTRenderingError
case astRenderingError
/**
Thrown when an HTML string cannot be converted into an `NSData` representation
*/
case HTMLDataConversionError
}
case htmlDataConversionError
}
+9 -8
View File
@@ -7,27 +7,28 @@
//
import Foundation
import libcmark
public struct DownOptions: OptionSetType {
public struct DownOptions: OptionSet {
public let rawValue: Int32
public init(rawValue: Int32) { self.rawValue = rawValue }
/**
Default options
*/
public static let Default = DownOptions(rawValue: 0)
public static let Default = DownOptions(rawValue: CMARK_OPT_DEFAULT)
// MARK: - Rendering Options
/**
Include a `data-sourcepos` attribute on all block elements
*/
public static let SourcePos = DownOptions(rawValue: 1 << 1)
public static let SourcePos = DownOptions(rawValue: CMARK_OPT_SOURCEPOS)
/**
Render `softbreak` elements as hard line breaks.
*/
public static let HardBreaks = DownOptions(rawValue: 1 << 2)
public static let HardBreaks = DownOptions(rawValue: CMARK_OPT_HARDBREAKS)
/**
Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,
@@ -36,24 +37,24 @@ public struct DownOptions: OptionSetType {
by a placeholder HTML comment. Unsafe links are replaced by
empty strings.
*/
public static let Safe = DownOptions(rawValue: 1 << 3)
public static let Safe = DownOptions(rawValue: CMARK_OPT_SAFE)
// MARK: - Parsing Options
/**
Normalize tree by consolidating adjacent text nodes.
*/
public static let Normalize = DownOptions(rawValue: 1 << 4)
public static let Normalize = DownOptions(rawValue: CMARK_OPT_NORMALIZE)
/**
Validate UTF-8 in the input before parsing, replacing illegal
sequences with the replacement character U+FFFD.
*/
public static let ValidateUTF8 = DownOptions(rawValue: 1 << 5)
public static let ValidateUTF8 = DownOptions(rawValue: CMARK_OPT_VALIDATE_UTF8)
/**
Convert straight quotes to curly, --- to em dashes, -- to en dashes.
*/
public static let Smart = DownOptions(rawValue: 1 << 6)
public static let Smart = DownOptions(rawValue: CMARK_OPT_SMART)
}
@@ -20,13 +20,16 @@ extension NSAttributedString {
- returns: An attributed string
*/
convenience init(htmlString: String) throws {
guard let data = htmlString.dataUsingEncoding(NSUTF8StringEncoding) else {
throw DownErrors.HTMLDataConversionError
guard let data = htmlString.data(using: String.Encoding.utf8) else {
throw DownErrors.htmlDataConversionError
}
let options = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: NSNumber(unsignedInteger:NSUTF8StringEncoding)]
let options: [String: Any] = [
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: NSNumber(value: String.Encoding.utf8.rawValue)
]
try self.init(data: data, options: options, documentAttributes: nil)
}
}
}
+1 -1
View File
@@ -20,7 +20,7 @@ extension String {
- returns: HTML string
*/
public func toHTML(options: DownOptions = .Default) throws -> String {
public func toHTML(_ options: DownOptions = .Default) throws -> String {
let ast = try DownASTRenderer.stringToAST(self, options: options)
let html = try DownHTMLRenderer.astToHTML(ast, options: options)
cmark_node_free(ast)
+8 -8
View File
@@ -19,8 +19,8 @@ public protocol DownASTRenderable: DownRenderable {
- returns: An abstract syntax tree representation of the Markdown input
*/
@warn_unused_result
func toAST(options: DownOptions) throws -> UnsafeMutablePointer<cmark_node>
func toAST(_ options: DownOptions) throws -> UnsafeMutablePointer<cmark_node>
}
public extension DownASTRenderable {
@@ -33,8 +33,8 @@ public extension DownASTRenderable {
- returns: An abstract syntax tree representation of the Markdown input
*/
@warn_unused_result
public func toAST(options: DownOptions = .Default) throws -> UnsafeMutablePointer<cmark_node> {
public func toAST(_ options: DownOptions = .Default) throws -> UnsafeMutablePointer<cmark_node> {
return try DownASTRenderer.stringToAST(markdownString, options: options)
}
}
@@ -51,8 +51,8 @@ public struct DownASTRenderer {
- returns: An abstract syntax tree representation of the Markdown input
*/
@warn_unused_result
public static func stringToAST(string: String, options: DownOptions = .Default) throws -> UnsafeMutablePointer<cmark_node> {
public static func stringToAST(_ string: String, options: DownOptions = .Default) throws -> UnsafeMutablePointer<cmark_node> {
var tree: UnsafeMutablePointer<cmark_node>?
string.withCString {
let stringLength = Int(strlen($0))
@@ -60,8 +60,8 @@ public struct DownASTRenderer {
}
guard let ast = tree else {
throw DownErrors.MarkdownToASTError
throw DownErrors.markdownToASTError
}
return ast
}
}
}
@@ -19,8 +19,8 @@ public protocol DownAttributedStringRenderable: DownHTMLRenderable {
- returns: An `NSAttributedString`
*/
@warn_unused_result
func toAttributedString(options: DownOptions) throws -> NSAttributedString
func toAttributedString(_ options: DownOptions) throws -> NSAttributedString
}
public extension DownAttributedStringRenderable {
@@ -33,9 +33,9 @@ public extension DownAttributedStringRenderable {
- returns: An `NSAttributedString`
*/
@warn_unused_result
public func toAttributedString(options: DownOptions = .Default) throws -> NSAttributedString {
public func toAttributedString(_ options: DownOptions = .Default) throws -> NSAttributedString {
let html = try self.toHTML(options)
return try NSAttributedString(htmlString: html)
}
}
}
+15 -14
View File
@@ -20,8 +20,8 @@ public protocol DownCommonMarkRenderable: DownRenderable {
- returns: CommonMark Markdown string
*/
@warn_unused_result
func toCommonMark(options: DownOptions, width: Int32) throws -> String
func toCommonMark(_ options: DownOptions, width: Int32) throws -> String
}
public extension DownCommonMarkRenderable {
@@ -35,8 +35,8 @@ public extension DownCommonMarkRenderable {
- returns: CommonMark Markdown string
*/
@warn_unused_result
public func toCommonMark(options: DownOptions = .Default, width: Int32 = 0) throws -> String {
public func toCommonMark(_ options: DownOptions = .Default, width: Int32 = 0) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let commonMark = try DownCommonMarkRenderer.astToCommonMark(ast, options: options, width: width)
cmark_node_free(ast)
@@ -57,18 +57,19 @@ public struct DownCommonMarkRenderer {
- returns: CommonMark Markdown string
*/
@warn_unused_result
public static func astToCommonMark(ast: UnsafeMutablePointer<cmark_node>,
public static func astToCommonMark(_ ast: UnsafeMutablePointer<cmark_node>,
options: DownOptions = .Default,
width: Int32 = 0) throws -> String {
let cCommonMarkString = cmark_render_commonmark(ast, options.rawValue, width)
let outputString = String(CString: cCommonMarkString, encoding: NSUTF8StringEncoding)
free(cCommonMarkString)
guard let commonMarkString = outputString else {
throw DownErrors.ASTRenderingError
guard let cCommonMarkString = cmark_render_commonmark(ast, options.rawValue, width) else {
throw DownErrors.astRenderingError
}
defer { free(cCommonMarkString) }
guard let commonMarkString = String(cString: cCommonMarkString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return commonMarkString
}
}
}
+15 -14
View File
@@ -20,8 +20,8 @@ public protocol DownGroffRenderable: DownRenderable {
- returns: groff man string
*/
@warn_unused_result
func toGroff(options: DownOptions, width: Int32) throws -> String
func toGroff(_ options: DownOptions, width: Int32) throws -> String
}
public extension DownGroffRenderable {
@@ -35,8 +35,8 @@ public extension DownGroffRenderable {
- returns: groff man string
*/
@warn_unused_result
public func toGroff(options: DownOptions = .Default, width: Int32 = 0) throws -> String {
public func toGroff(_ options: DownOptions = .Default, width: Int32 = 0) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let groff = try DownGroffRenderer.astToGroff(ast, options: options, width: width)
cmark_node_free(ast)
@@ -57,18 +57,19 @@ public struct DownGroffRenderer {
- returns: groff man string
*/
@warn_unused_result
public static func astToGroff(ast: UnsafeMutablePointer<cmark_node>,
public static func astToGroff(_ ast: UnsafeMutablePointer<cmark_node>,
options: DownOptions = .Default,
width: Int32 = 0) throws -> String {
let cGroffString = cmark_render_man(ast, options.rawValue, width)
let outputString = String(CString: cGroffString, encoding: NSUTF8StringEncoding)
free(cGroffString)
guard let groffString = outputString else {
throw DownErrors.ASTRenderingError
guard let cGroffString = cmark_render_man(ast, options.rawValue, width) else {
throw DownErrors.astRenderingError
}
defer { free(cGroffString) }
guard let groffString = String(cString: cGroffString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return groffString
}
}
}
+15 -14
View File
@@ -19,8 +19,8 @@ public protocol DownHTMLRenderable: DownRenderable {
- returns: HTML string
*/
@warn_unused_result
func toHTML(options: DownOptions) throws -> String
func toHTML(_ options: DownOptions) throws -> String
}
public extension DownHTMLRenderable {
@@ -33,8 +33,8 @@ public extension DownHTMLRenderable {
- returns: HTML string
*/
@warn_unused_result
public func toHTML(options: DownOptions = .Default) throws -> String {
public func toHTML(_ options: DownOptions = .Default) throws -> String {
return try markdownString.toHTML(options)
}
}
@@ -51,16 +51,17 @@ public struct DownHTMLRenderer {
- returns: HTML string
*/
@warn_unused_result
public static func astToHTML(ast: UnsafeMutablePointer<cmark_node>, options: DownOptions = .Default) throws -> String {
let cHTMLString = cmark_render_html(ast, options.rawValue)
let outputString = String(CString: cHTMLString, encoding: NSUTF8StringEncoding)
free(cHTMLString)
guard let htmlString = outputString else {
throw DownErrors.ASTRenderingError
public static func astToHTML(_ ast: UnsafeMutablePointer<cmark_node>, options: DownOptions = .Default) throws -> String {
guard let cHTMLString = cmark_render_html(ast, options.rawValue) else {
throw DownErrors.astRenderingError
}
defer { free(cHTMLString) }
guard let htmlString = String(cString: cHTMLString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return htmlString
}
}
}
+15 -14
View File
@@ -20,8 +20,8 @@ public protocol DownLaTeXRenderable: DownRenderable {
- returns: LaTeX string
*/
@warn_unused_result
func toLaTeX(options: DownOptions, width: Int32) throws -> String
func toLaTeX(_ options: DownOptions, width: Int32) throws -> String
}
public extension DownLaTeXRenderable {
@@ -35,8 +35,8 @@ public extension DownLaTeXRenderable {
- returns: LaTeX string
*/
@warn_unused_result
public func toLaTeX(options: DownOptions = .Default, width: Int32 = 0) throws -> String {
public func toLaTeX(_ options: DownOptions = .Default, width: Int32 = 0) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let latex = try DownLaTeXRenderer.astToLaTeX(ast, options: options, width: width)
cmark_node_free(ast)
@@ -57,18 +57,19 @@ public struct DownLaTeXRenderer {
- returns: LaTeX string
*/
@warn_unused_result
public static func astToLaTeX(ast: UnsafeMutablePointer<cmark_node>,
public static func astToLaTeX(_ ast: UnsafeMutablePointer<cmark_node>,
options: DownOptions = .Default,
width: Int32 = 0) throws -> String {
let cLatexString = cmark_render_latex(ast, options.rawValue, width)
let outputString = String(CString: cLatexString, encoding: NSUTF8StringEncoding)
free(cLatexString)
guard let latexString = outputString else {
throw DownErrors.ASTRenderingError
guard let cLatexString = cmark_render_latex(ast, options.rawValue, width) else {
throw DownErrors.astRenderingError
}
defer { free(cLatexString) }
guard let latexString = String(cString: cLatexString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return latexString
}
}
}
+15 -14
View File
@@ -19,8 +19,8 @@ public protocol DownXMLRenderable: DownRenderable {
- returns: XML string
*/
@warn_unused_result
func toXML(options: DownOptions) throws -> String
func toXML(_ options: DownOptions) throws -> String
}
public extension DownXMLRenderable {
@@ -33,8 +33,8 @@ public extension DownXMLRenderable {
- returns: XML string
*/
@warn_unused_result
public func toXML(options: DownOptions = .Default) throws -> String {
public func toXML(_ options: DownOptions = .Default) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let xml = try DownXMLRenderer.astToXML(ast, options: options)
cmark_node_free(ast)
@@ -54,16 +54,17 @@ public struct DownXMLRenderer {
- returns: XML string
*/
@warn_unused_result
public static func astToXML(ast: UnsafeMutablePointer<cmark_node>, options: DownOptions = .Default) throws -> String {
let cXMLString = cmark_render_xml(ast, options.rawValue)
let outputString = String(CString: cXMLString, encoding: NSUTF8StringEncoding)
free(cXMLString)
guard let xmlString = outputString else {
throw DownErrors.ASTRenderingError
public static func astToXML(_ ast: UnsafeMutablePointer<cmark_node>, options: DownOptions = .Default) throws -> String {
guard let cXMLString = cmark_render_xml(ast, options.rawValue) else {
throw DownErrors.astRenderingError
}
defer { free(cXMLString) }
guard let xmlString = String(cString: cXMLString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return xmlString
}
}
}
+23 -19
View File
@@ -10,7 +10,7 @@ import WebKit
// MARK: - Public API
public class DownView: WKWebView {
open class DownView: WKWebView {
/**
Initializes a web view with the results of rendering a CommonMark Markdown string
@@ -21,7 +21,7 @@ public class DownView: WKWebView {
- returns: An instance of Self
*/
@warn_unused_result
public init(frame: CGRect, markdownString: String, openLinksInBrowser: Bool = true) throws {
super.init(frame: frame, configuration: WKWebViewConfiguration())
@@ -29,16 +29,20 @@ public class DownView: WKWebView {
try loadHTMLView(markdownString)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Private Properties
private let bundle: NSBundle = {
let bundle = NSBundle(forClass: DownView.self)
let url = bundle.URLForResource("DownView", withExtension: "bundle")!
return NSBundle(URL: url)!
fileprivate let bundle: Bundle = {
let bundle = Bundle(for: DownView.self)
let url = bundle.url(forResource: "DownView", withExtension: "bundle")!
return Bundle(url: url)!
}()
private lazy var baseURL: NSURL = {
return self.bundle.URLForResource("index", withExtension: "html")!
fileprivate lazy var baseURL: URL = {
return self.bundle.url(forResource: "index", withExtension: "html")!
}()
}
@@ -46,15 +50,15 @@ public class DownView: WKWebView {
private extension DownView {
func loadHTMLView(markdownString: String) throws {
func loadHTMLView(_ markdownString: String) throws {
let htmlString = try markdownString.toHTML()
let pageHTMLString = try htmlFromTemplate(htmlString)
loadHTMLString(pageHTMLString, baseURL: baseURL)
}
func htmlFromTemplate(htmlString: String) throws -> String {
let template = try NSString(contentsOfURL: baseURL, encoding: NSUTF8StringEncoding)
return template.stringByReplacingOccurrencesOfString("DOWN_HTML", withString: htmlString)
func htmlFromTemplate(_ htmlString: String) throws -> String {
let template = try NSString(contentsOf: baseURL, encoding: String.Encoding.utf8.rawValue)
return template.replacingOccurrences(of: "DOWN_HTML", with: htmlString)
}
}
@@ -63,16 +67,16 @@ private extension DownView {
extension DownView: WKNavigationDelegate {
public func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
guard let url = navigationAction.request.URL else { return }
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard let url = navigationAction.request.url else { return }
switch navigationAction.navigationType {
case .LinkActivated:
decisionHandler(.Cancel)
UIApplication.sharedApplication().openURL(url)
case .linkActivated:
decisionHandler(.cancel)
UIApplication.shared.openURL(url)
default:
decisionHandler(.Allow)
decisionHandler(.allow)
}
}
}
}
-6
View File
@@ -47,11 +47,5 @@ class BindingTests: XCTestCase {
XCTAssertNotNil(commonMark)
XCTAssertTrue(commonMark == "## [Down](https://github.com/iwasrobbed/Down)\n")
}
func testAttributedStringBindingsWork() {
let attributedString = try? down.toAttributedString()
XCTAssertNotNil(attributedString)
XCTAssertTrue(attributedString!.string == "Down\n")
}
}
+2 -3
View File
@@ -12,9 +12,8 @@ import XCTest
class DownViewTests: XCTestCase {
func testInstantiation() {
let string = "## [Down](https://github.com/iwasrobbed/Down)"
let downView = try? DownView(frame: CGRectZero, markdownString: string)
let downView = try? DownView(frame: .zero, markdownString: "## [Down](https://github.com/iwasrobbed/Down)")
XCTAssertNotNil(downView)
}
}
}
+26
View File
@@ -0,0 +1,26 @@
//
// NSAttributedStringTests.swift
// Down
//
// Created by Rob Phillips on 6/2/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import XCTest
@testable import Down
class NSAttributedStringTests: XCTestCase {
func testAttributedStringBindingsWork() {
let attributedString = try? Down(markdownString: "## [Down](https://github.com/iwasrobbed/Down)").toAttributedString()
XCTAssertNotNil(attributedString)
XCTAssertTrue(attributedString!.string == "Down\n")
}
func testInstantiation() {
let attributedString = try? NSAttributedString(htmlString: "<html><body><p>Oh Hai</p></body></html>")
XCTAssertNotNil(attributedString)
XCTAssertTrue(attributedString!.string == "Oh Hai\n")
}
}
+22
View File
@@ -0,0 +1,22 @@
//
// StringTests.swift
// Down
//
// Created by Rob Phillips on 6/2/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import XCTest
@testable import Down
class StringTests: XCTestCase {
func testStringToHTML() {
// String is assumed to contain valid Markdown
let string = "## [Down](https://github.com/iwasrobbed/Down)"
let down = try? string.toHTML()
XCTAssertNotNil(down)
XCTAssertTrue(down == "<h2><a href=\"https://github.com/iwasrobbed/Down\">Down</a></h2>\n")
}
}