Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92ef17a63a | |||
| 95a8027744 | |||
| f8e87aeb01 | |||
| fc5dfcc53f | |||
| d193007caf | |||
| ae3161caa5 | |||
| e11e164450 | |||
| af887d9c8d | |||
| a410f58f78 |
@@ -0,0 +1 @@
|
||||
3.0
|
||||
+2
-2
@@ -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
@@ -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" }
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
## Down
|
||||
[](https://coveralls.io/github/iwasrobbed/Down?branch=master)
|
||||
[](https://travis-ci.org/iwasrobbed/Down)
|
||||
[](https://github.com/iwasrobbed/Down/blob/master/LICENSE)
|
||||
[]()
|
||||
[](https://swift.org)
|
||||
[](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
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user