Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds attributed string rendering #4

Merged
merged 1 commit into from
Jun 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Down.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,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"; }; };
D43AE5CA1CFFAE4D006E1522 /* NSAttributedString+HTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43AE5C91CFFAE4D006E1522 /* NSAttributedString+HTML.swift */; };
D44875E41CFA6B200037A624 /* DownRenderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44875E31CFA6B200037A624 /* DownRenderable.swift */; };
D44875E61CFA6B660037A624 /* DownHTMLRenderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44875E51CFA6B660037A624 /* DownHTMLRenderable.swift */; };
D44875EA1CFA6CF30037A624 /* DownErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44875E81CFA6CF30037A624 /* DownErrors.swift */; };
Expand All @@ -55,6 +56,7 @@
D486E9961CFDD4860059FD7C /* DownASTRenderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D486E9951CFDD4860059FD7C /* DownASTRenderable.swift */; };
D486E9981CFDE2730059FD7C /* DownLaTeXRenderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D486E9971CFDE2730059FD7C /* DownLaTeXRenderable.swift */; };
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 */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -112,6 +114,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>"; };
D43AE5C91CFFAE4D006E1522 /* NSAttributedString+HTML.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+HTML.swift"; sourceTree = "<group>"; };
D44875E31CFA6B200037A624 /* DownRenderable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownRenderable.swift; sourceTree = "<group>"; };
D44875E51CFA6B660037A624 /* DownHTMLRenderable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownHTMLRenderable.swift; sourceTree = "<group>"; };
D44875E81CFA6CF30037A624 /* DownErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownErrors.swift; sourceTree = "<group>"; };
Expand All @@ -121,6 +124,7 @@
D486E9971CFDE2730059FD7C /* DownLaTeXRenderable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownLaTeXRenderable.swift; sourceTree = "<group>"; };
D486E9991CFDE28B0059FD7C /* DownGroffRenderable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownGroffRenderable.swift; sourceTree = "<group>"; };
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>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -168,6 +172,7 @@
D4CF88961CFF94B300F07FD1 /* Down.h */,
D4201EF01CFA59F2008EEC6E /* Down.swift */,
D44875E71CFA6CF30037A624 /* Enums & Options */,
D43AE5C81CFFAE39006E1522 /* Extensions */,
D44875E21CFA6B120037A624 /* Renderers */,
D4201EF61CFA5D63008EEC6E /* cmark */,
);
Expand Down Expand Up @@ -227,10 +232,19 @@
path = cmark;
sourceTree = "<group>";
};
D43AE5C81CFFAE39006E1522 /* Extensions */ = {
isa = PBXGroup;
children = (
D43AE5C91CFFAE4D006E1522 /* NSAttributedString+HTML.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
D44875E21CFA6B120037A624 /* Renderers */ = {
isa = PBXGroup;
children = (
D486E9951CFDD4860059FD7C /* DownASTRenderable.swift */,
D4CF88971CFFAC2C00F07FD1 /* DownAttributedStringRenderable.swift */,
D4DC91131CFDED4B0091CE09 /* DownCommonMarkRenderable.swift */,
D486E9991CFDE28B0059FD7C /* DownGroffRenderable.swift */,
D44875E51CFA6B660037A624 /* DownHTMLRenderable.swift */,
Expand Down Expand Up @@ -379,11 +393,13 @@
D486E9941CFDD33C0059FD7C /* DownXMLRenderable.swift in Sources */,
D4201F361CFA5D63008EEC6E /* iterator.c in Sources */,
D4201F391CFA5D63008EEC6E /* man.c in Sources */,
D4CF88981CFFAC2C00F07FD1 /* DownAttributedStringRenderable.swift in Sources */,
D4201F3D1CFA5D63008EEC6E /* references.c in Sources */,
D4201F301CFA5D63008EEC6E /* houdini_html_e.c in Sources */,
D4201F3F1CFA5D63008EEC6E /* render.c in Sources */,
D486E9981CFDE2730059FD7C /* DownLaTeXRenderable.swift in Sources */,
D4201F2A1CFA5D63008EEC6E /* commonmark.c in Sources */,
D43AE5CA1CFFAE4D006E1522 /* NSAttributedString+HTML.swift in Sources */,
D4201EF11CFA59F2008EEC6E /* Down.swift in Sources */,
D4201F2F1CFA5D63008EEC6E /* houdini_href_e.c in Sources */,
D4201F451CFA5D63008EEC6E /* xml.c in Sources */,
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pod 'Down'
* LaTeX
* groff man
* CommonMark Markdown
* NSAttributedString
* AST (abstract syntax tree)

### API
Expand Down Expand Up @@ -58,6 +59,10 @@ let latex = try? down.toLaTeX()
let commonMark = try? down.toCommonMark()
// "## [Down](https://github.com/iwasrobbed/Down)\n"

// Convert to an attributed string
let attributedString = try? down.toAttributedString()
// NSAttributedString representation of the rendered HTML

// Convert to abstract syntax tree
let ast = try? down.toAST()
// Returns pointer to AST that you can manipulate
Expand All @@ -74,6 +79,7 @@ If you'd like more granularity for the output types you want to support, you can
* DownGroffRenderable
* DownCommonMarkRenderable
* DownASTRenderable
* DownAttributedStringRenderable

Example:

Expand Down
3 changes: 2 additions & 1 deletion Source/Down.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import Foundation

public struct Down: DownASTRenderable, DownHTMLRenderable, DownXMLRenderable,
DownLaTeXRenderable, DownGroffRenderable, DownCommonMarkRenderable {
DownLaTeXRenderable, DownGroffRenderable, DownCommonMarkRenderable,
DownAttributedStringRenderable {
/**
A string containing CommonMark Markdown
*/
Expand Down
5 changes: 5 additions & 0 deletions Source/Enums & Options/DownErrors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@ public enum DownErrors: ErrorType {
Thrown when the abstract syntax tree could not be rendered into another format
*/
case ASTRenderingError

/**
Thrown when an HTML string cannot be converted into an `NSData` representation
*/
case HTMLDataConversionError
}
32 changes: 32 additions & 0 deletions Source/Extensions/NSAttributedString+HTML.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// NSAttributedString+HTML.swift
// Down
//
// Created by Rob Phillips on 6/1/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//

import UIKit

extension NSAttributedString {

/**
Instantiates an attributed string with the given HTML string

- parameter htmlString: An HTML string

- throws: `HTMLDataConversionError` or an instantiation error

- returns: An attributed string
*/
convenience init(htmlString: String) throws {
guard let data = htmlString.dataUsingEncoding(NSUTF8StringEncoding) else {
throw DownErrors.HTMLDataConversionError
}

let options = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: NSNumber(unsignedInteger:NSUTF8StringEncoding)]
try self.init(data: data, options: options, documentAttributes: nil)
}

}
41 changes: 41 additions & 0 deletions Source/Renderers/DownAttributedStringRenderable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// DownAttributedStringRenderable.swift
// Down
//
// Created by Rob Phillips on 6/1/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//

import Foundation
import libcmark

public protocol DownAttributedStringRenderable: DownHTMLRenderable {
/**
Generates an `NSAttributedString` from the `markdownString` property

- parameter options: `DownOptions` to modify parsing or rendering

- throws: `DownErrors` depending on the scenario

- returns: An `NSAttributedString`
*/
@warn_unused_result
func toAttributedString(options: DownOptions) throws -> NSAttributedString
}

public extension DownAttributedStringRenderable {
/**
Generates an `NSAttributedString` from the `markdownString` property

- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`

- throws: `DownErrors` depending on the scenario

- returns: An `NSAttributedString`
*/
@warn_unused_result
public func toAttributedString(options: DownOptions = .Default) throws -> NSAttributedString {
let html = try self.toHTML(options)
return try NSAttributedString(htmlString: html)
}
}
6 changes: 6 additions & 0 deletions Tests/BindingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,11 @@ class RenderableTests: 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")
}

}