Skip to content

Commit

Permalink
Adds attributed string render for #2
Browse files Browse the repository at this point in the history
  • Loading branch information
rob phillips committed Jun 2, 2016
1 parent 9c28de3 commit 01858a2
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 1 deletion.
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")
}

}

0 comments on commit 01858a2

Please sign in to comment.