Fixing issues with escaping and adding better defaults

This commit is contained in:
Simon Fairbairn 2016-03-05 18:41:01 +07:00
parent cdeceb53ff
commit b26b9660ef
18 changed files with 1465 additions and 87 deletions

View File

@ -1,2 +1,26 @@
# SwiftyMarkdown
Converts Markdown files and strings into NSAttributedString
SwiftyMarkdown converts Markdown files and strings into NSAttributedString using sensible defaults and a Swift-style syntax. It uses dynamic type to set the font size for whatever font you want
## Usage
Text string
let md = SwiftyMarkdown(string: "# Heading\nMy *Markdown* string")
md.attributedString()
URL
if let url = NSBundle.mainBundle().URLForResource("file", withExtension: "md"), md = SwiftyMarkdown(url: url ) {
md.attributedString()
}
## Customisation
// Setting the body name will use this font for all the heading styles as well, unless explicitly overridden
md.body.fontName = "AvenirNextCondensed-Medium"
md.h1.color = UIColor.redColor()
md.h1.fontName = "AvenirNextCondensed-Bold"

View File

@ -0,0 +1,310 @@
//: Playground - noun: a place where people can play
import UIKit
import XCPlayground
let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 400.0, height: 600))
XCPlaygroundPage.currentPage.liveView = containerView
let label = UITextView(frame: containerView.frame)
containerView.addSubview(label)
public protocol FontProperties {
var fontName : String { get set }
var color : UIColor { get set }
}
public struct BasicStyles : FontProperties {
public var fontName = UIFont.preferredFontForTextStyle(UIFontTextStyleBody).fontName
public var color = UIColor.blackColor()
}
enum LineType : Int {
case H1, H2, H3, H4, H5, H6, Body, Italic, Bold, Code
}
public class SwiftyMarkdown {
public var h1 = BasicStyles()
public var h2 = BasicStyles()
public var h3 = BasicStyles()
public var h4 = BasicStyles()
public var h5 = BasicStyles()
public var h6 = BasicStyles()
public var body = BasicStyles()
public var link = BasicStyles()
public var italic = BasicStyles()
public var code = BasicStyles()
public var bold = BasicStyles()
let string : String
let instructionSet = NSCharacterSet(charactersInString: "\\*_`")
public init(string : String ) {
self.string = string
}
public init?(url : NSURL ) {
do {
self.string = try NSString(contentsOfURL: url, encoding: NSUTF8StringEncoding) as String
} catch {
self.string = ""
fatalError("Couldn't read string")
return nil
}
}
public func attributedString() -> NSAttributedString {
let attributedString = NSMutableAttributedString(string: "")
let lines = self.string.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
var lineCount = 0
let headings = ["# ", "## ", "### ", "#### ", "##### ", "###### "]
var skipLine = false
for line in lines {
lineCount++
if skipLine {
skipLine = false
continue
}
var headingFound = false
for heading in headings {
if let range = line.rangeOfString(heading) where range.startIndex == line.startIndex {
let startHeadingString = line.stringByReplacingCharactersInRange(range, withString: "")
let endHeadingHash = " " + heading.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
let finalHeadingString = startHeadingString.stringByReplacingOccurrencesOfString(endHeadingHash, withString: "")
// Make Hx where x == current index
let string = attributedStringFromString(finalHeadingString, withType: LineType(rawValue: headings.indexOf(heading)!)!)
attributedString.appendAttributedString(string)
headingFound = true
}
}
if headingFound {
continue
}
if lineCount < lines.count {
let nextLine = lines[lineCount]
if let range = nextLine.rangeOfString("=") where range.startIndex == nextLine.startIndex {
// Make H1
let string = attributedStringFromString(line, withType: .H1)
attributedString.appendAttributedString(string)
skipLine = true
continue
}
if let range = nextLine.rangeOfString("-") where range.startIndex == nextLine.startIndex {
// Make H1
let string = attributedStringFromString(line, withType: .H2)
attributedString.appendAttributedString(string)
skipLine = true
continue
}
}
if line.characters.count > 0 {
let scanner = NSScanner(string: line)
scanner.charactersToBeSkipped = nil
while !scanner.atEnd {
var followingString : NSString?
var string : NSString?
// Get all the characters up to the ones we are interested in
if scanner.scanUpToCharactersFromSet(instructionSet, intoString: &string) {
if let hasString = string as? String {
let bodyString = attributedStringFromString(hasString, withType: .Body)
attributedString.appendAttributedString(bodyString)
var matchedCharacters = self.tagFromScanner(scanner)
let location = scanner.scanLocation
// If the next string after the characters is a space, then add it to the final string and continue
if !scanner.scanUpToString(" ", intoString: nil) {
let charAtts = attributedStringFromString(matchedCharacters, withType: .Body)
attributedString.appendAttributedString(charAtts)
} else {
scanner.scanLocation = location
scanner.scanUpToCharactersFromSet(instructionSet, intoString: &followingString)
if let hasString = followingString as? String {
let attString : NSAttributedString
if matchedCharacters.containsString("\\") {
attString = attributedStringFromString(matchedCharacters + hasString, withType: .Body)
} else if matchedCharacters == "**" || matchedCharacters == "__" {
attString = attributedStringFromString(hasString, withType: .Bold)
} else {
attString = attributedStringFromString(hasString, withType: .Italic)
}
attributedString.appendAttributedString(attString)
}
matchedCharacters = self.tagFromScanner(scanner)
if matchedCharacters.containsString("\\") {
let attString = attributedStringFromString(matchedCharacters, withType: .Body)
attributedString.appendAttributedString(attString)
}
}
}
} else {
var matchedCharacters = self.tagFromScanner(scanner)
scanner.scanUpToCharactersFromSet(instructionSet, intoString: &followingString)
if let hasString = followingString as? String {
let attString : NSAttributedString
if matchedCharacters.containsString("\\") {
attString = attributedStringFromString(matchedCharacters + hasString, withType: .Body)
} else if matchedCharacters == "**" || matchedCharacters == "__" {
attString = attributedStringFromString(hasString, withType: .Bold)
} else {
attString = attributedStringFromString(hasString, withType: .Italic)
}
attributedString.appendAttributedString(attString)
}
matchedCharacters = self.tagFromScanner(scanner)
if matchedCharacters.containsString("\\") {
let attString = attributedStringFromString(matchedCharacters, withType: .Body)
attributedString.appendAttributedString(attString)
}
}
}
}
attributedString.appendAttributedString(NSAttributedString(string: "\n"))
}
return attributedString
}
func tagFromScanner( scanner : NSScanner ) -> String {
var matchedCharacters : String = ""
var tempCharacters : NSString?
// Scan the ones we are interested in
while scanner.scanCharactersFromSet(instructionSet, intoString: &tempCharacters) {
if let chars = tempCharacters as? String {
matchedCharacters = matchedCharacters + chars
}
}
return matchedCharacters
}
// Make H1
func attributedStringFromString(string : String, withType type : LineType ) -> NSAttributedString {
var attributes : [String : AnyObject]
let textStyle : String
let fontName : String
var appendNewLine = true
switch type {
case .H1:
fontName = h1.fontName
textStyle = UIFontTextStyleTitle1
attributes = [NSForegroundColorAttributeName : h1.color]
case .H2:
fontName = h2.fontName
textStyle = UIFontTextStyleTitle2
attributes = [NSForegroundColorAttributeName : h2.color]
case .H3:
fontName = h3.fontName
textStyle = UIFontTextStyleTitle3
attributes = [NSForegroundColorAttributeName : h3.color]
case .H4:
fontName = h4.fontName
textStyle = UIFontTextStyleHeadline
attributes = [NSForegroundColorAttributeName : h4.color]
case .H5:
fontName = h5.fontName
textStyle = UIFontTextStyleSubheadline
attributes = [NSForegroundColorAttributeName : h5.color]
case .H6:
fontName = h6.fontName
textStyle = UIFontTextStyleFootnote
attributes = [NSForegroundColorAttributeName : h6.color]
case .Italic:
fontName = italic.fontName
attributes = [NSForegroundColorAttributeName : italic.color]
textStyle = UIFontTextStyleBody
appendNewLine = false
case .Bold:
fontName = bold.fontName
attributes = [NSForegroundColorAttributeName : bold.color]
appendNewLine = false
textStyle = UIFontTextStyleBody
default:
appendNewLine = false
fontName = body.fontName
textStyle = UIFontTextStyleBody
attributes = [NSForegroundColorAttributeName:body.color]
break
}
let font = UIFont.preferredFontForTextStyle(textStyle)
let styleDescriptor = font.fontDescriptor()
let styleSize = styleDescriptor.fontAttributes()[UIFontDescriptorSizeAttribute] as? CGFloat ?? CGFloat(14)
var finalFont : UIFont
if let font = UIFont(name: fontName, size: styleSize) {
finalFont = font
} else {
finalFont = UIFont.preferredFontForTextStyle(textStyle)
}
let finalFontDescriptor = finalFont.fontDescriptor()
if type == .Italic {
let italicDescriptor = finalFontDescriptor.fontDescriptorWithSymbolicTraits(.TraitItalic)
finalFont = UIFont(descriptor: italicDescriptor, size: styleSize)
}
if type == .Bold {
let boldDescriptor = finalFontDescriptor.fontDescriptorWithSymbolicTraits(.TraitBold)
finalFont = UIFont(descriptor: boldDescriptor, size: styleSize)
}
attributes[NSFontAttributeName] = finalFont
if appendNewLine {
return NSAttributedString(string: string + "\n", attributes: attributes)
} else {
return NSAttributedString(string: string, attributes: attributes)
}
}
}
if let url = NSBundle.mainBundle().URLForResource("test", withExtension: "md"), md = SwiftyMarkdown(url: url) {
label.attributedText = md.attributedString()
}

View File

@ -0,0 +1,24 @@
A Markdown Example
========
Headings
-----
# Heading 1
## Heading 2
### Heading 3 ###
#### Heading 4 ####
##### Heading 5 #####
###### Heading 6 ######
A simple paragraph with a random * in *the* middle. Now with ** **Added Bold**
A standard paragraph with an *italic*, * spaced asterisk, \*escaped asterisks\*, _underscored italics_, \_escaped underscores\_, **bold** \*\*escaped double asterisks\*\*, __underscored bold__, _ spaced underscore \_\_escaped double underscores\_\_.
This is a very basic implementation of markdown.
*This whole line is italic*
**This whole line is bold**
The End

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<timeline fileName='timeline.xctimeline'/>
</playground>

View File

@ -11,6 +11,9 @@
F4CE988C1C8A921300D735C1 /* SwiftyMarkdown.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4CE98811C8A921300D735C1 /* SwiftyMarkdown.framework */; };
F4CE98911C8A921300D735C1 /* SwiftyMarkdownTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CE98901C8A921300D735C1 /* SwiftyMarkdownTests.swift */; };
F4CE989C1C8A922E00D735C1 /* SwiftyMarkdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CE989B1C8A922E00D735C1 /* SwiftyMarkdown.swift */; };
F4CE98E91C8AF01300D735C1 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = F4CE98E61C8AF01300D735C1 /* LICENSE */; };
F4CE98EA1C8AF01300D735C1 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = F4CE98E71C8AF01300D735C1 /* README.md */; };
F4CE98EB1C8AF01300D735C1 /* SwiftyMarkdown.podspec in Resources */ = {isa = PBXBuildFile; fileRef = F4CE98E81C8AF01300D735C1 /* SwiftyMarkdown.podspec */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -31,6 +34,9 @@
F4CE98901C8A921300D735C1 /* SwiftyMarkdownTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftyMarkdownTests.swift; sourceTree = "<group>"; };
F4CE98921C8A921300D735C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F4CE989B1C8A922E00D735C1 /* SwiftyMarkdown.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftyMarkdown.swift; sourceTree = "<group>"; };
F4CE98E61C8AF01300D735C1 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
F4CE98E71C8AF01300D735C1 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
F4CE98E81C8AF01300D735C1 /* SwiftyMarkdown.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SwiftyMarkdown.podspec; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -58,6 +64,9 @@
F4CE98831C8A921300D735C1 /* SwiftyMarkdown */,
F4CE988F1C8A921300D735C1 /* SwiftyMarkdownTests */,
F4CE98821C8A921300D735C1 /* Products */,
F4CE98E61C8AF01300D735C1 /* LICENSE */,
F4CE98E71C8AF01300D735C1 /* README.md */,
F4CE98E81C8AF01300D735C1 /* SwiftyMarkdown.podspec */,
);
sourceTree = "<group>";
};
@ -180,6 +189,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4CE98E91C8AF01300D735C1 /* LICENSE in Resources */,
F4CE98EB1C8AF01300D735C1 /* SwiftyMarkdown.podspec in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -197,6 +208,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4CE98EA1C8AF01300D735C1 /* README.md in Sources */,
F4CE989C1C8A922E00D735C1 /* SwiftyMarkdown.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -385,6 +397,7 @@
F4CE98971C8A921300D735C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F4CE98981C8A921300D735C1 /* Build configuration list for PBXNativeTarget "SwiftyMarkdownTests" */ = {
isa = XCConfigurationList;
@ -393,6 +406,7 @@
F4CE989A1C8A921300D735C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};

View File

@ -9,57 +9,59 @@
import UIKit
protocol FontProperties {
public protocol FontProperties {
var fontName : String { get set }
var color : UIColor { get set }
}
struct BasicStyles : FontProperties {
var fontName = "AvenirNextCondensed-Medium"
var color = UIColor.blackColor()
public struct BasicStyles : FontProperties {
public var fontName = UIFont.preferredFontForTextStyle(UIFontTextStyleBody).fontName
public var color = UIColor.blackColor()
}
enum LineType : Int {
case H1, H2, H3, H4, H5, H6, Body, Italic, Bold
case H1, H2, H3, H4, H5, H6, Body, Italic, Bold, Code
}
class SwiftyMarkdown {
public class SwiftyMarkdown {
var h1 = BasicStyles()
var h2 = BasicStyles()
var h3 = BasicStyles()
var h4 = BasicStyles()
var h5 = BasicStyles()
var h6 = BasicStyles()
public var h1 = BasicStyles()
public var h2 = BasicStyles()
public var h3 = BasicStyles()
public var h4 = BasicStyles()
public var h5 = BasicStyles()
public var h6 = BasicStyles()
var body = BasicStyles()
var link = BasicStyles()
var italic = BasicStyles(fontName: "AvenirNextCondensed-MediumItalic", color: UIColor.blackColor())
var bold = BasicStyles(fontName: "AvenirNextCondensed-Bold", color: UIColor.blackColor())
public var body = BasicStyles()
public var link = BasicStyles()
public var italic = BasicStyles()
public var code = BasicStyles()
public var bold = BasicStyles()
let string : String
let instructionSet = NSCharacterSet(charactersInString: "\\*_`")
init(string : String ) {
public init(string : String ) {
self.string = string
}
init?(url : NSURL ) {
public init?(url : NSURL ) {
do {
self.string = try NSString(contentsOfURL: url, encoding: NSUTF8StringEncoding) as String
} catch {
self.string = ""
fatalError("Couldn't read string")
return nil
}
}
func attributedString() -> NSAttributedString {
public func attributedString() -> NSAttributedString {
let attributedString = NSMutableAttributedString(string: "")
let lines = self.string.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
var lineCount = 0
@ -120,88 +122,86 @@ class SwiftyMarkdown {
if line.characters.count > 0 {
let scanner = NSScanner(string: line)
let instructionSet = NSCharacterSet(charactersInString: "\\*_")
scanner.charactersToBeSkipped = nil
var finalString : String = ""
while !scanner.atEnd {
var followingString : NSString?
var string : NSString?
// Get all the characters up to the ones we are interested in
scanner.scanUpToCharactersFromSet(instructionSet, intoString: &string)
if let hasString = string as? String {
let bodyString = attributedStringFromString(hasString, withType: .Body)
attributedString.appendAttributedString(bodyString)
finalString = finalString + hasString
var matchedCharacters : String = ""
var tempCharacters : NSString?
// Scan the ones we are interested in
while scanner.scanCharactersFromSet(instructionSet, intoString: &tempCharacters) {
if let chars = tempCharacters as? String {
matchedCharacters = matchedCharacters + chars
if scanner.scanUpToCharactersFromSet(instructionSet, intoString: &string) {
if let hasString = string as? String {
let bodyString = attributedStringFromString(hasString, withType: .Body)
attributedString.appendAttributedString(bodyString)
let location = scanner.scanLocation
let matchedCharacters = tagFromScanner(scanner)
// If the next string after the characters is a space, then add it to the final string and continue
if !scanner.scanUpToString(" ", intoString: nil) {
let charAtts = attributedStringFromString(matchedCharacters, withType: .Body)
attributedString.appendAttributedString(charAtts)
} else {
scanner.scanLocation = location
attributedString.appendAttributedString(self.attributedStringFromScanner(scanner))
}
}
print("Matched Characters: \(matchedCharacters)")
let location = scanner.scanLocation
// If the next string after the characters is a space, then add it to the final string and continue
if !scanner.scanUpToString(" ", intoString: nil) {
let charAtts = attributedStringFromString(matchedCharacters, withType: .Body)
attributedString.appendAttributedString(charAtts)
} else {
scanner.scanLocation = location
scanner.scanUpToCharactersFromSet(instructionSet, intoString: &followingString)
if let hasString = followingString as? String {
let attString : NSAttributedString
if matchedCharacters.containsString("\\") {
attString = attributedStringFromString(matchedCharacters + hasString, withType: .Body)
} else if matchedCharacters == "**" || matchedCharacters == "__" {
attString = attributedStringFromString(hasString, withType: .Bold)
} else {
attString = attributedStringFromString(hasString, withType: .Italic)
}
attributedString.appendAttributedString(attString)
}
matchedCharacters = ""
while scanner.scanCharactersFromSet(instructionSet, intoString: &tempCharacters) {
if let chars = tempCharacters as? String {
matchedCharacters = matchedCharacters + chars
}
}
if matchedCharacters.containsString("\\") {
let attString = attributedStringFromString(matchedCharacters, withType: .Body)
attributedString.appendAttributedString(attString)
}
}
} else {
attributedString.appendAttributedString(self.attributedStringFromScanner(scanner))
}
}
}
attributedString.appendAttributedString(NSAttributedString(string: "\n"))
}
return attributedString
}
func attributedStringFromScanner( scanner : NSScanner) -> NSAttributedString {
var followingString : NSString?
var matchedCharacters = self.tagFromScanner(scanner)
let attributedString = NSMutableAttributedString(string: "")
scanner.scanUpToCharactersFromSet(instructionSet, intoString: &followingString)
if let hasString = followingString as? String {
let attString : NSAttributedString
if matchedCharacters.containsString("\\") {
attString = attributedStringFromString(matchedCharacters.stringByReplacingOccurrencesOfString("\\", withString: "") + hasString, withType: .Body)
} else if matchedCharacters == "**" || matchedCharacters == "__" {
attString = attributedStringFromString(hasString, withType: .Bold)
} else if matchedCharacters == "`" {
attString = attributedStringFromString(hasString, withType: .Code)
} else {
attString = attributedStringFromString(hasString, withType: .Italic)
}
attributedString.appendAttributedString(attString)
}
matchedCharacters = self.tagFromScanner(scanner)
if matchedCharacters.containsString("\\") {
let attString = attributedStringFromString(matchedCharacters.stringByReplacingOccurrencesOfString("\\", withString: ""), withType: .Body)
attributedString.appendAttributedString(attString)
}
return attributedString
}
func tagFromScanner( scanner : NSScanner ) -> String {
var matchedCharacters : String = ""
var tempCharacters : NSString?
// Scan the ones we are interested in
while scanner.scanCharactersFromSet(instructionSet, intoString: &tempCharacters) {
if let chars = tempCharacters as? String {
matchedCharacters = matchedCharacters + chars
}
}
return matchedCharacters
}
// Make H1
func attributedStringFromString(string : String, withType type : LineType ) -> NSAttributedString {
@ -246,6 +246,12 @@ class SwiftyMarkdown {
attributes = [NSForegroundColorAttributeName : bold.color]
appendNewLine = false
textStyle = UIFontTextStyleBody
case .Code:
fontName = code.fontName
attributes = [NSForegroundColorAttributeName : code.color]
appendNewLine = false
textStyle = UIFontTextStyleBody
default:
appendNewLine = false
fontName = body.fontName
@ -258,13 +264,24 @@ class SwiftyMarkdown {
let styleDescriptor = font.fontDescriptor()
let styleSize = styleDescriptor.fontAttributes()[UIFontDescriptorSizeAttribute] as? CGFloat ?? CGFloat(14)
let finalFont : UIFont
var finalFont : UIFont
if let font = UIFont(name: fontName, size: styleSize) {
finalFont = font
} else {
finalFont = UIFont.preferredFontForTextStyle(textStyle)
}
let finalFontDescriptor = finalFont.fontDescriptor()
if type == .Italic {
let italicDescriptor = finalFontDescriptor.fontDescriptorWithSymbolicTraits(.TraitItalic)
finalFont = UIFont(descriptor: italicDescriptor, size: styleSize)
}
if type == .Bold {
let boldDescriptor = finalFontDescriptor.fontDescriptorWithSymbolicTraits(.TraitBold)
finalFont = UIFont(descriptor: boldDescriptor, size: styleSize)
}
attributes[NSFontAttributeName] = finalFont
if appendNewLine {

View File

@ -0,0 +1,579 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
F421DD991C8AF4E900B86D66 /* example.md in Resources */ = {isa = PBXBuildFile; fileRef = F421DD951C8AF34F00B86D66 /* example.md */; };
F4CE98AC1C8AEF7D00D735C1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CE98AB1C8AEF7D00D735C1 /* AppDelegate.swift */; };
F4CE98AE1C8AEF7D00D735C1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CE98AD1C8AEF7D00D735C1 /* ViewController.swift */; };
F4CE98B11C8AEF7D00D735C1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F4CE98AF1C8AEF7D00D735C1 /* Main.storyboard */; };
F4CE98B31C8AEF7D00D735C1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4CE98B21C8AEF7D00D735C1 /* Assets.xcassets */; };
F4CE98B61C8AEF7D00D735C1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F4CE98B41C8AEF7D00D735C1 /* LaunchScreen.storyboard */; };
F4CE98C11C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CE98C01C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.swift */; };
F4CE98CC1C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CE98CB1C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.swift */; };
F4CE98E31C8AEFEC00D735C1 /* SwiftyMarkdown.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4CE98E01C8AEFE200D735C1 /* SwiftyMarkdown.framework */; };
F4CE98E51C8AEFFB00D735C1 /* SwiftyMarkdown.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = F4CE98E01C8AEFE200D735C1 /* SwiftyMarkdown.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
F4CE98BD1C8AEF7D00D735C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F4CE98A01C8AEF7D00D735C1 /* Project object */;
proxyType = 1;
remoteGlobalIDString = F4CE98A71C8AEF7D00D735C1;
remoteInfo = SwiftyMarkdownExample;
};
F4CE98C81C8AEF7D00D735C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F4CE98A01C8AEF7D00D735C1 /* Project object */;
proxyType = 1;
remoteGlobalIDString = F4CE98A71C8AEF7D00D735C1;
remoteInfo = SwiftyMarkdownExample;
};
F4CE98DF1C8AEFE200D735C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F4CE98DA1C8AEFE200D735C1 /* SwiftyMarkdown.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F4CE98811C8A921300D735C1;
remoteInfo = SwiftyMarkdown;
};
F4CE98E11C8AEFE200D735C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F4CE98DA1C8AEFE200D735C1 /* SwiftyMarkdown.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F4CE988B1C8A921300D735C1;
remoteInfo = SwiftyMarkdownTests;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
F4CE98E41C8AEFF000D735C1 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
F4CE98E51C8AEFFB00D735C1 /* SwiftyMarkdown.framework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
F421DD951C8AF34F00B86D66 /* example.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = example.md; sourceTree = "<group>"; };
F4CE98A81C8AEF7D00D735C1 /* SwiftyMarkdownExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftyMarkdownExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
F4CE98AB1C8AEF7D00D735C1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F4CE98AD1C8AEF7D00D735C1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
F4CE98B01C8AEF7D00D735C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
F4CE98B21C8AEF7D00D735C1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F4CE98B51C8AEF7D00D735C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F4CE98B71C8AEF7D00D735C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F4CE98BC1C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftyMarkdownExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
F4CE98C01C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftyMarkdownExampleTests.swift; sourceTree = "<group>"; };
F4CE98C21C8AEF7D00D735C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F4CE98C71C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftyMarkdownExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
F4CE98CB1C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftyMarkdownExampleUITests.swift; sourceTree = "<group>"; };
F4CE98CD1C8AEF7D00D735C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F4CE98DA1C8AEFE200D735C1 /* SwiftyMarkdown.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwiftyMarkdown.xcodeproj; path = ../SwiftyMarkdown.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
F4CE98A51C8AEF7D00D735C1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F4CE98E31C8AEFEC00D735C1 /* SwiftyMarkdown.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F4CE98B91C8AEF7D00D735C1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
F4CE98C41C8AEF7D00D735C1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
F4CE989F1C8AEF7D00D735C1 = {
isa = PBXGroup;
children = (
F4CE98DA1C8AEFE200D735C1 /* SwiftyMarkdown.xcodeproj */,
F4CE98AA1C8AEF7D00D735C1 /* SwiftyMarkdownExample */,
F4CE98BF1C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests */,
F4CE98CA1C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests */,
F4CE98A91C8AEF7D00D735C1 /* Products */,
);
sourceTree = "<group>";
};
F4CE98A91C8AEF7D00D735C1 /* Products */ = {
isa = PBXGroup;
children = (
F4CE98A81C8AEF7D00D735C1 /* SwiftyMarkdownExample.app */,
F4CE98BC1C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.xctest */,
F4CE98C71C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
F4CE98AA1C8AEF7D00D735C1 /* SwiftyMarkdownExample */ = {
isa = PBXGroup;
children = (
F4CE98AB1C8AEF7D00D735C1 /* AppDelegate.swift */,
F4CE98AD1C8AEF7D00D735C1 /* ViewController.swift */,
F4CE98AF1C8AEF7D00D735C1 /* Main.storyboard */,
F4CE98B21C8AEF7D00D735C1 /* Assets.xcassets */,
F4CE98B41C8AEF7D00D735C1 /* LaunchScreen.storyboard */,
F4CE98B71C8AEF7D00D735C1 /* Info.plist */,
F421DD951C8AF34F00B86D66 /* example.md */,
);
path = SwiftyMarkdownExample;
sourceTree = "<group>";
};
F4CE98BF1C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests */ = {
isa = PBXGroup;
children = (
F4CE98C01C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.swift */,
F4CE98C21C8AEF7D00D735C1 /* Info.plist */,
);
path = SwiftyMarkdownExampleTests;
sourceTree = "<group>";
};
F4CE98CA1C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests */ = {
isa = PBXGroup;
children = (
F4CE98CB1C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.swift */,
F4CE98CD1C8AEF7D00D735C1 /* Info.plist */,
);
path = SwiftyMarkdownExampleUITests;
sourceTree = "<group>";
};
F4CE98DB1C8AEFE200D735C1 /* Products */ = {
isa = PBXGroup;
children = (
F4CE98E01C8AEFE200D735C1 /* SwiftyMarkdown.framework */,
F4CE98E21C8AEFE200D735C1 /* SwiftyMarkdownTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F4CE98A71C8AEF7D00D735C1 /* SwiftyMarkdownExample */ = {
isa = PBXNativeTarget;
buildConfigurationList = F4CE98D01C8AEF7D00D735C1 /* Build configuration list for PBXNativeTarget "SwiftyMarkdownExample" */;
buildPhases = (
F4CE98A41C8AEF7D00D735C1 /* Sources */,
F4CE98A51C8AEF7D00D735C1 /* Frameworks */,
F4CE98A61C8AEF7D00D735C1 /* Resources */,
F4CE98E41C8AEFF000D735C1 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = SwiftyMarkdownExample;
productName = SwiftyMarkdownExample;
productReference = F4CE98A81C8AEF7D00D735C1 /* SwiftyMarkdownExample.app */;
productType = "com.apple.product-type.application";
};
F4CE98BB1C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = F4CE98D31C8AEF7D00D735C1 /* Build configuration list for PBXNativeTarget "SwiftyMarkdownExampleTests" */;
buildPhases = (
F4CE98B81C8AEF7D00D735C1 /* Sources */,
F4CE98B91C8AEF7D00D735C1 /* Frameworks */,
F4CE98BA1C8AEF7D00D735C1 /* Resources */,
);
buildRules = (
);
dependencies = (
F4CE98BE1C8AEF7D00D735C1 /* PBXTargetDependency */,
);
name = SwiftyMarkdownExampleTests;
productName = SwiftyMarkdownExampleTests;
productReference = F4CE98BC1C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
F4CE98C61C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = F4CE98D61C8AEF7D00D735C1 /* Build configuration list for PBXNativeTarget "SwiftyMarkdownExampleUITests" */;
buildPhases = (
F4CE98C31C8AEF7D00D735C1 /* Sources */,
F4CE98C41C8AEF7D00D735C1 /* Frameworks */,
F4CE98C51C8AEF7D00D735C1 /* Resources */,
);
buildRules = (
);
dependencies = (
F4CE98C91C8AEF7D00D735C1 /* PBXTargetDependency */,
);
name = SwiftyMarkdownExampleUITests;
productName = SwiftyMarkdownExampleUITests;
productReference = F4CE98C71C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F4CE98A01C8AEF7D00D735C1 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
ORGANIZATIONNAME = "Voyage Travel Apps";
TargetAttributes = {
F4CE98A71C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
};
F4CE98BB1C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
TestTargetID = F4CE98A71C8AEF7D00D735C1;
};
F4CE98C61C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
TestTargetID = F4CE98A71C8AEF7D00D735C1;
};
};
};
buildConfigurationList = F4CE98A31C8AEF7D00D735C1 /* Build configuration list for PBXProject "SwiftyMarkdownExample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F4CE989F1C8AEF7D00D735C1;
productRefGroup = F4CE98A91C8AEF7D00D735C1 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = F4CE98DB1C8AEFE200D735C1 /* Products */;
ProjectRef = F4CE98DA1C8AEFE200D735C1 /* SwiftyMarkdown.xcodeproj */;
},
);
projectRoot = "";
targets = (
F4CE98A71C8AEF7D00D735C1 /* SwiftyMarkdownExample */,
F4CE98BB1C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests */,
F4CE98C61C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
F4CE98E01C8AEFE200D735C1 /* SwiftyMarkdown.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = SwiftyMarkdown.framework;
remoteRef = F4CE98DF1C8AEFE200D735C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
F4CE98E21C8AEFE200D735C1 /* SwiftyMarkdownTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = SwiftyMarkdownTests.xctest;
remoteRef = F4CE98E11C8AEFE200D735C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
F4CE98A61C8AEF7D00D735C1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4CE98B61C8AEF7D00D735C1 /* LaunchScreen.storyboard in Resources */,
F4CE98B31C8AEF7D00D735C1 /* Assets.xcassets in Resources */,
F421DD991C8AF4E900B86D66 /* example.md in Resources */,
F4CE98B11C8AEF7D00D735C1 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F4CE98BA1C8AEF7D00D735C1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
F4CE98C51C8AEF7D00D735C1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
F4CE98A41C8AEF7D00D735C1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4CE98AE1C8AEF7D00D735C1 /* ViewController.swift in Sources */,
F4CE98AC1C8AEF7D00D735C1 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F4CE98B81C8AEF7D00D735C1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4CE98C11C8AEF7D00D735C1 /* SwiftyMarkdownExampleTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F4CE98C31C8AEF7D00D735C1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4CE98CC1C8AEF7D00D735C1 /* SwiftyMarkdownExampleUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
F4CE98BE1C8AEF7D00D735C1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F4CE98A71C8AEF7D00D735C1 /* SwiftyMarkdownExample */;
targetProxy = F4CE98BD1C8AEF7D00D735C1 /* PBXContainerItemProxy */;
};
F4CE98C91C8AEF7D00D735C1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F4CE98A71C8AEF7D00D735C1 /* SwiftyMarkdownExample */;
targetProxy = F4CE98C81C8AEF7D00D735C1 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
F4CE98AF1C8AEF7D00D735C1 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
F4CE98B01C8AEF7D00D735C1 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
F4CE98B41C8AEF7D00D735C1 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
F4CE98B51C8AEF7D00D735C1 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
F4CE98CE1C8AEF7D00D735C1 /* 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[sdk=iphoneos*]" = "iPhone Developer";
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;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
F4CE98CF1C8AEF7D00D735C1 /* 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[sdk=iphoneos*]" = "iPhone Developer";
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;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
F4CE98D11C8AEF7D00D735C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = SwiftyMarkdownExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
F4CE98D21C8AEF7D00D735C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = SwiftyMarkdownExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
F4CE98D41C8AEF7D00D735C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
INFOPLIST_FILE = SwiftyMarkdownExampleTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftyMarkdownExample.app/SwiftyMarkdownExample";
};
name = Debug;
};
F4CE98D51C8AEF7D00D735C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
INFOPLIST_FILE = SwiftyMarkdownExampleTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftyMarkdownExample.app/SwiftyMarkdownExample";
};
name = Release;
};
F4CE98D71C8AEF7D00D735C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
INFOPLIST_FILE = SwiftyMarkdownExampleUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_TARGET_NAME = SwiftyMarkdownExample;
USES_XCTRUNNER = YES;
};
name = Debug;
};
F4CE98D81C8AEF7D00D735C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
INFOPLIST_FILE = SwiftyMarkdownExampleUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_TARGET_NAME = SwiftyMarkdownExample;
USES_XCTRUNNER = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
F4CE98A31C8AEF7D00D735C1 /* Build configuration list for PBXProject "SwiftyMarkdownExample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4CE98CE1C8AEF7D00D735C1 /* Debug */,
F4CE98CF1C8AEF7D00D735C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F4CE98D01C8AEF7D00D735C1 /* Build configuration list for PBXNativeTarget "SwiftyMarkdownExample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4CE98D11C8AEF7D00D735C1 /* Debug */,
F4CE98D21C8AEF7D00D735C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F4CE98D31C8AEF7D00D735C1 /* Build configuration list for PBXNativeTarget "SwiftyMarkdownExampleTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4CE98D41C8AEF7D00D735C1 /* Debug */,
F4CE98D51C8AEF7D00D735C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F4CE98D61C8AEF7D00D735C1 /* Build configuration list for PBXNativeTarget "SwiftyMarkdownExampleUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4CE98D71C8AEF7D00D735C1 /* Debug */,
F4CE98D81C8AEF7D00D735C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F4CE98A01C8AEF7D00D735C1 /* Project object */;
}

View File

@ -0,0 +1,46 @@
//
// AppDelegate.swift
// SwiftyMarkdownExample
//
// Created by Simon Fairbairn on 05/03/2016.
// Copyright © 2016 Voyage Travel Apps. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}

View File

@ -0,0 +1,68 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="SwiftyMarkdownExample" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" usesAttributedText="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qZP-CU-74n">
<rect key="frame" x="20" y="20" width="560" height="580"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<attributedString key="attributedText"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="qZP-CU-74n" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" id="1yU-8N-26a"/>
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="qZP-CU-74n" secondAttribute="bottom" id="7lJ-OQ-4eh"/>
<constraint firstAttribute="trailingMargin" secondItem="qZP-CU-74n" secondAttribute="trailing" id="F5p-iG-zTB"/>
<constraint firstItem="qZP-CU-74n" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="srf-u0-j0n"/>
</constraints>
</view>
<connections>
<outlet property="textView" destination="qZP-CU-74n" id="VO1-kx-Lpd"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,40 @@
//
// ViewController.swift
// SwiftyMarkdownExample
//
// Created by Simon Fairbairn on 05/03/2016.
// Copyright © 2016 Voyage Travel Apps. All rights reserved.
//
import UIKit
import SwiftyMarkdown
class ViewController: UIViewController {
@IBOutlet weak var textView : UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if let url = NSBundle.mainBundle().URLForResource("example", withExtension: "md"), md = SwiftyMarkdown(url: url) {
md.h2.fontName = "AvenirNextCondensed-Bold"
md.h2.color = UIColor.redColor()
md.code.fontName = "CourierNewPSMT"
self.textView.attributedText = md.attributedString()
} else {
fatalError("Error loading file")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

View File

@ -0,0 +1,13 @@
# Swifty Markdown
SwiftyMarkdown is a Swift-based *Markdown* parser that converts *Markdown* files or strings into **NSAttributedStrings**. It uses sensible defaults and supports dynamic type, even if you use custom fonts.
## Features
Customise fonts and colours easily in a Swift like way:
`md.h1.fontName = "AvenirNextCondensed-Medium"`
*An italic line*
It ignores random * and correctly handles \*escaped\* asterisks.

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,36 @@
//
// SwiftyMarkdownExampleTests.swift
// SwiftyMarkdownExampleTests
//
// Created by Simon Fairbairn on 05/03/2016.
// Copyright © 2016 Voyage Travel Apps. All rights reserved.
//
import XCTest
@testable import SwiftyMarkdownExample
class SwiftyMarkdownExampleTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
// Put the code you want to measure the time of here.
}
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,36 @@
//
// SwiftyMarkdownExampleUITests.swift
// SwiftyMarkdownExampleUITests
//
// Created by Simon Fairbairn on 05/03/2016.
// Copyright © 2016 Voyage Travel Apps. All rights reserved.
//
import XCTest
class SwiftyMarkdownExampleUITests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
XCUIApplication().launch()
// In UI tests its important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
}