Compare commits

..

42 Commits

Author SHA1 Message Date
Simon Fairbairn e653548441 Version Bump 2017-01-21 09:51:30 +02:00
Simon Fairbairn ff0fce7eb7 Updating podspec 2017-01-21 09:51:30 +02:00
Simon Fairbairn 99726212be Rolling back a change made in pr 37 that was causing tests to fail 2017-01-21 09:50:16 +02:00
Simon Fairbairn 0bfeba8188 Merge branch 'master' of https://github.com/SimonFairbairn/SwiftyMarkdown 2017-01-21 09:44:38 +02:00
Simon Fairbairn 7985b57341 Updating bundle 2017-01-21 09:44:25 +02:00
Simon Fairbairn cb0ecbd67d Merge pull request #37 from qdequele/master
Fix last \n and empty lines. 

Thanks very much for this!
2017-01-21 09:39:11 +02:00
Simon Fairbairn 1d4fb92429 Fixes issue #36 2017-01-21 09:36:51 +02:00
Quentin_dQ 7f276de733 fix the possible error in range on tagFromScanner 2017-01-12 14:02:44 +01:00
Quentin_dQ 5870b838e7 change empty line by one space for NSString.boundingRect parsing 2017-01-06 10:26:49 +01:00
Quentin_dQ b2dc325510 remove \n on the last line 2017-01-06 10:24:32 +01:00
Simon Fairbairn 195f1a5491 Merge pull request #34 from stupergenius/feature/carthage
Adding shared scheme for Carthage
2016-11-23 11:38:08 +01:00
Benjamin Snider cac0c00e0f enabling bitcode. 2016-11-18 20:33:54 -07:00
Benjamin Snider e211af53f5 Setting codesign to developer and enabling WMO on all build types. 2016-11-18 20:16:51 -07:00
Benjamin Snider 15c6b77288 Adding the BITCODE_GENERATION_MODE=bitcode setting for Carthage builds. 2016-11-18 19:49:19 -07:00
Simon Fairbairn 4c0a60faa0 Version Bump 2016-11-04 15:04:18 +01:00
Simon Fairbairn b0bcb587cb Updating podspec 2016-11-04 15:04:18 +01:00
Simon Fairbairn 02837925b9 Updating fastfile 2016-11-04 15:02:13 +01:00
Simon Fairbairn cc2ea97b4c Fixes issue #35 2016-11-04 09:16:46 +01:00
Benjamin Snider 0ab154977a Adding shared scheme for Carthage to pickup. 2016-10-27 15:36:04 -06:00
Simon Fairbairn ac99c2efba Version Bump to 14 2016-10-04 17:59:37 +02:00
Simon Fairbairn 39073280de Updating podspec 2016-10-04 17:59:36 +02:00
Simon Fairbairn 0bca66728f Updating fastfile 2016-10-04 17:58:34 +02:00
Simon Fairbairn 38e2c0d733 Adding Gemfile 2016-10-04 17:56:34 +02:00
Simon Fairbairn f4f7c7bd55 Updating fastfile 2016-10-04 17:54:35 +02:00
Simon Fairbairn cd30189674 Merge branch 'swift3' of https://github.com/SimonFairbairn/SwiftyMarkdown into swift3 2016-10-04 17:49:29 +02:00
Simon Fairbairn b51f13054c Fixing for Swift 3 2016-10-04 17:48:46 +02:00
Simon Fairbairn 6487a98d90 Fixing for Swift 3 2016-08-29 15:05:04 +02:00
Simon Fairbairn b9a01c7f87 Merge pull request #21 from CocoaBob/master
Good to know! Thanks for testing it out!

Added support of tvOS in podspec
2016-06-24 13:44:15 +02:00
CocoaBob c70c5671c8 Update SwiftyMarkdown.podspec 2016-06-23 15:16:05 +02:00
Simon Fairbairn 7bdd5d35ad Merge pull request #18 from mrigdon/patch-1
show that it's on cocoapods in readme
2016-06-02 16:20:59 +02:00
mrigdon 76b27f4571 show that it's on cocoapods in readme 2016-06-01 08:41:17 -07:00
Simon Fairbairn c27ff1d9a5 Merge pull request #13 from ranunez/patch-1
Updates README to specify supported features. Thanks to @ranunez.
2016-04-11 09:21:02 +07:00
Ricardo Nunez 0ff9fe8c1c Updates README to specify supported features 2016-04-08 23:14:50 -07:00
Simon Fairbairn eb63a4ea5e Updating podspec 2016-04-08 10:18:08 +07:00
Simon Fairbairn aa01b6bc58 Version Bump to 13 2016-04-08 10:18:07 +07:00
Simon Fairbairn 37f08f09ae Updating build 2016-04-08 10:17:53 +07:00
Simon Fairbairn c96f17edd0 Merge pull request #10 from mightea/fix-swift3-warnings
Fix swift3 warnings. Thanks to @mightea.
2016-04-08 10:13:41 +07:00
Tobias Herrmann 6288214d26 adds .DS_Store to gitignore 2016-04-07 13:40:03 +02:00
Tobias Herrmann 66f5db3d74 fixes various Swift 3.0 depreciation warnings 2016-04-07 13:38:14 +02:00
Simon Fairbairn 057cf6a4e9 Merge pull request #9 from ravidsrk/patch-1
Added code syntax highlighting to Readme.
2016-04-06 15:45:27 +07:00
Ravindra Kumar 1a4cfe06aa Added code syntax highlighting to Readme 2016-04-04 09:00:16 -04:00
Simon Fairbairn 455a844912 Fixing incorrect homepage 2016-03-23 12:56:32 +07:00
18 changed files with 860 additions and 535 deletions
+3
View File
@@ -61,3 +61,6 @@ Carthage/Build
fastlane/report.xml
fastlane/screenshots
# OS X
.DS_Store
+1
View File
@@ -0,0 +1 @@
3.0
+7
View File
@@ -0,0 +1,7 @@
# frozen_string_literal: true
# A sample Gemfile
source "https://rubygems.org"
# gem "rails"
gem "cocoapods", ">= 1.1.0.beta.2"
gem 'fastlane'
+188
View File
@@ -0,0 +1,188 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.4)
activesupport (4.2.7.1)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.5.0)
public_suffix (~> 2.0, >= 2.0.2)
babosa (1.0.2)
claide (1.0.1)
cocoapods (1.2.0.rc.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.1, < 2.0)
cocoapods-core (= 1.2.0.rc.1)
cocoapods-deintegrate (>= 1.0.1, < 2.0)
cocoapods-downloader (>= 1.1.3, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.1.2, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored (~> 1.2)
escape (~> 0.0.4)
fourflusher (~> 2.0.1)
gh_inspector (~> 1.0)
molinillo (~> 0.5.5)
nap (~> 1.0)
ruby-macho (~> 0.2.5)
xcodeproj (>= 1.4.1, < 2.0)
cocoapods-core (1.2.0.rc.1)
activesupport (>= 4.0.2, < 5)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.1)
cocoapods-downloader (1.1.3)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.1.2)
nap (>= 0.8, < 2.0)
netrc (= 0.7.8)
cocoapods-try (1.1.0)
colored (1.2)
commander (4.4.3)
highline (~> 1.7.2)
domain_name (0.5.20161129)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.1.2)
escape (0.0.4)
excon (0.54.0)
faraday (0.11.0)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.11.0)
faraday (>= 0.7.4, < 1.0)
fastimage (2.0.1)
addressable (~> 2)
fastlane (2.9.0)
activesupport (< 5)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (~> 1.12)
colored
commander (>= 4.4.0, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
fastimage (>= 1.6)
gh_inspector (>= 1.0.1, < 2.0.0)
google-api-client (~> 0.9.2)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
mini_magick (~> 4.5.1)
multi_json
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 1.1.0, < 2.0.0)
security (= 0.1.3)
slack-notifier (>= 1.3, < 2.0.0)
terminal-notifier (>= 1.6.2, < 2.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 0.20, < 2.0.0)
xcpretty (>= 0.2.4, < 1.0.0)
xcpretty-travis-formatter (>= 0.0.3)
fourflusher (2.0.1)
fuzzy_match (2.0.4)
gh_inspector (1.0.3)
google-api-client (0.9.23)
addressable (~> 2.3)
googleauth (~> 0.5)
httpclient (~> 2.7)
hurley (~> 0.1)
memoist (~> 0.11)
mime-types (>= 1.6)
representable (~> 2.3.0)
retriable (~> 2.0)
googleauth (0.5.1)
faraday (~> 0.9)
jwt (~> 1.4)
logging (~> 2.0)
memoist (~> 0.12)
multi_json (~> 1.11)
os (~> 0.9)
signet (~> 0.7)
highline (1.7.8)
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.3)
hurley (0.2)
i18n (0.7.0)
json (1.8.6)
jwt (1.5.6)
little-plugger (1.1.4)
logging (2.1.0)
little-plugger (~> 1.1)
multi_json (~> 1.10)
memoist (0.15.0)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_magick (4.5.1)
minitest (5.10.1)
molinillo (0.5.5)
multi_json (1.12.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.3)
nap (1.1.0)
netrc (0.7.8)
os (0.9.6)
plist (3.2.0)
public_suffix (2.0.5)
representable (2.3.0)
uber (~> 0.0.7)
retriable (2.1.0)
rouge (1.11.1)
ruby-macho (0.2.6)
rubyzip (1.2.0)
security (0.1.3)
signet (0.7.3)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (~> 1.5)
multi_json (~> 1.10)
slack-notifier (1.5.1)
terminal-notifier (1.7.1)
terminal-table (1.7.3)
unicode-display_width (~> 1.1.1)
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uber (0.0.15)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.2)
unicode-display_width (1.1.3)
word_wrap (1.0.0)
xcodeproj (1.4.2)
CFPropertyList (~> 2.3.3)
activesupport (>= 3)
claide (>= 1.0.1, < 2.0)
colored (~> 1.2)
nanaimo (~> 0.2.3)
xcpretty (0.2.4)
rouge (~> 1.8)
xcpretty-travis-formatter (0.0.4)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (>= 1.1.0.beta.2)
fastlane
BUNDLED WITH
1.13.2
+37 -12
View File
@@ -2,28 +2,53 @@
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 correctly with whatever font you'd like to use
## Installation
CocoaPods:
`pod 'SwiftyMarkdown'`
## Usage
Text string
let md = SwiftyMarkdown(string: "# Heading\nMy *Markdown* string")
md.attributedString()
```swift
let md = SwiftyMarkdown(string: "# Heading\nMy *Markdown* string")
md.attributedString()
```
URL
```swift
if let url = NSBundle.mainBundle().URLForResource("file", withExtension: "md"), md = SwiftyMarkdown(url: url ) {
md.attributedString()
}
```
if let url = NSBundle.mainBundle().URLForResource("file", withExtension: "md"), md = SwiftyMarkdown(url: url ) {
md.attributedString()
}
## Supported Features
*italics* or _italics_
**bold** or __bold__
# Header 1
## Header 2
### Header 3
#### Header 4
##### Header 5
###### Header 6
`code`
[Links](http://voyagetravelapps.com/)
## Customisation
```swift
md.body.fontName = "AvenirNextCondensed-Medium"
md.body.fontName = "AvenirNextCondensed-Medium"
md.h1.color = UIColor.redColor()
md.h1.fontName = "AvenirNextCondensed-Bold"
md.h1.color = UIColor.redColor()
md.h1.fontName = "AvenirNextCondensed-Bold"
```
md.italic.color = UIColor.blueColor()
## Screenshot
![Screenshot](http://f.cl.ly/items/12332k3f2s0s0C281h2u/swiftymarkdown.png)
![Screenshot](http://f.cl.ly/items/12332k3f2s0s0C281h2u/swiftymarkdown.png)
+310 -301
View File
@@ -9,305 +9,314 @@ 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 }
var foundCharacters : String = ""
var matchedCharacters : String = "\\Some string ''\\"
if let hasRange = matchedCharacters.range(of: "\\") {
let newRange = hasRange.lowerBound..<hasRange.upperBound
foundCharacters = foundCharacters + matchedCharacters.substring(with: newRange)
matchedCharacters.removeSubrange(newRange)
}
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
if #available(iOS 9, *) {
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()
}
//
//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
//
// if #available(iOS 9, *) {
// 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()
//}
//
+4 -3
View File
@@ -1,14 +1,15 @@
Pod::Spec.new do |s|
s.name = "SwiftyMarkdown"
s.version = "0.2.2"
s.version = "0.3.2"
s.summary = "Converts Markdown to NSAttributed String"
s.homepage = "https://github.com/SimonFairbairn/Stormcloud"
s.homepage = "https://github.com/SimonFairbairn/SwiftyMarkdown"
s.license = 'MIT'
s.author = { "Simon Fairbairn" => "simon@voyagetravelapps.com" }
s.source = { :git => "https://github.com/SimonFairbairn/SwiftyMarkdown.git", :tag => s.version }
s.social_media_url = 'https://twitter.com/SimonFairbairn'
s.ios.deployment_target = '8.0'
s.ios.deployment_target = "8.0"
s.tvos.deployment_target = "9.0"
s.requires_arc = true
s.source_files = 'SwiftyMarkdown/'
+25 -6
View File
@@ -154,11 +154,12 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Voyage Travel Apps";
TargetAttributes = {
F4CE98801C8A921300D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 0800;
};
F4CE988A1C8A921300D735C1 = {
CreatedOnToolsVersion = 7.2.1;
@@ -243,13 +244,15 @@
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";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 14;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -291,13 +294,15 @@
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";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 12;
CURRENT_PROJECT_VERSION = 14;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -312,6 +317,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@@ -322,37 +328,48 @@
F4CE98961C8A921300D735C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BITCODE_GENERATION_MODE = bitcode;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 12;
DYLIB_CURRENT_VERSION = 14;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = SwiftyMarkdown/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_CFLAGS = "-fembed-bitcode";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdown;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
F4CE98971C8A921300D735C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BITCODE_GENERATION_MODE = bitcode;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 12;
DYLIB_CURRENT_VERSION = 14;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = SwiftyMarkdown/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_CFLAGS = "-fembed-bitcode";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdown;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -363,6 +380,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -373,6 +391,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4CE98801C8A921300D735C1"
BuildableName = "SwiftyMarkdown.framework"
BlueprintName = "SwiftyMarkdown"
ReferencedContainer = "container:SwiftyMarkdown.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4CE988A1C8A921300D735C1"
BuildableName = "SwiftyMarkdownTests.xctest"
BlueprintName = "SwiftyMarkdownTests"
ReferencedContainer = "container:SwiftyMarkdown.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4CE98801C8A921300D735C1"
BuildableName = "SwiftyMarkdown.framework"
BlueprintName = "SwiftyMarkdown"
ReferencedContainer = "container:SwiftyMarkdown.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4CE98801C8A921300D735C1"
BuildableName = "SwiftyMarkdown.framework"
BlueprintName = "SwiftyMarkdown"
ReferencedContainer = "container:SwiftyMarkdown.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4CE98801C8A921300D735C1"
BuildableName = "SwiftyMarkdown.framework"
BlueprintName = "SwiftyMarkdown"
ReferencedContainer = "container:SwiftyMarkdown.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+2 -2
View File
@@ -15,11 +15,11 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.2.1</string>
<string>0.3.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>12</string>
<string>14</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
+125 -118
View File
@@ -21,78 +21,78 @@ A struct defining the styles that can be applied to the parsed Markdown. The `fo
If that is not set, then the system default will be used.
*/
public struct BasicStyles : FontProperties {
public var fontName : String? = UIFont.preferredFontForTextStyle(UIFontTextStyleBody).fontName
public var color = UIColor.blackColor()
public var fontName : String? = UIFont.preferredFont(forTextStyle: UIFontTextStyle.body).fontName
public var color = UIColor.black
}
enum LineType : Int {
case H1, H2, H3, H4, H5, H6, Body
case h1, h2, h3, h4, h5, h6, body
}
enum LineStyle : Int {
case None
case Italic
case Bold
case Code
case Link
case none
case italic
case bold
case code
case link
static func styleFromString(string : String ) -> LineStyle {
static func styleFromString(_ string : String ) -> LineStyle {
if string == "**" || string == "__" {
return .Bold
return .bold
} else if string == "*" || string == "_" {
return .Italic
return .italic
} else if string == "`" {
return .Code
return .code
} else if string == "[" {
return .Link
return .link
} else {
return .None
return .none
}
}
}
/// A class that takes a [Markdown](https://daringfireball.net/projects/markdown/) string or file and returns an NSAttributedString with the applied styles. Supports Dynamic Type.
public class SwiftyMarkdown {
open class SwiftyMarkdown {
/// The styles to apply to any H1 headers found in the Markdown
public var h1 = BasicStyles()
open var h1 = BasicStyles()
/// The styles to apply to any H2 headers found in the Markdown
public var h2 = BasicStyles()
open var h2 = BasicStyles()
/// The styles to apply to any H3 headers found in the Markdown
public var h3 = BasicStyles()
open var h3 = BasicStyles()
/// The styles to apply to any H4 headers found in the Markdown
public var h4 = BasicStyles()
open var h4 = BasicStyles()
/// The styles to apply to any H5 headers found in the Markdown
public var h5 = BasicStyles()
open var h5 = BasicStyles()
/// The styles to apply to any H6 headers found in the Markdown
public var h6 = BasicStyles()
open var h6 = BasicStyles()
/// The default body styles. These are the base styles and will be used for e.g. headers if no other styles override them.
public var body = BasicStyles()
open var body = BasicStyles()
/// The styles to apply to any links found in the Markdown
public var link = BasicStyles()
open var link = BasicStyles()
/// The styles to apply to any bold text found in the Markdown
public var bold = BasicStyles()
open var bold = BasicStyles()
/// The styles to apply to any italic text found in the Markdown
public var italic = BasicStyles()
open var italic = BasicStyles()
/// The styles to apply to any code blocks or inline code text found in the Markdown
public var code = BasicStyles()
open var code = BasicStyles()
var currentType : LineType = .Body
var currentType : LineType = .body
let string : String
let instructionSet = NSCharacterSet(charactersInString: "[\\*_`")
let instructionSet = CharacterSet(charactersIn: "[\\*_`")
/**
@@ -111,14 +111,13 @@ public class SwiftyMarkdown {
- returns: An initialized SwiftyMarkdown object, or nil if the string couldn't be read
*/
public init?(url : NSURL ) {
public init?(url : URL ) {
do {
self.string = try NSString(contentsOfURL: url, encoding: NSUTF8StringEncoding) as String
self.string = try NSString(contentsOf: url, encoding: String.Encoding.utf8.rawValue) as String
} catch {
self.string = ""
fatalError("Couldn't read string")
return nil
}
}
@@ -128,10 +127,10 @@ public class SwiftyMarkdown {
- returns: An NSAttributedString with the styles applied
*/
public func attributedString() -> NSAttributedString {
open func attributedString() -> NSAttributedString {
let attributedString = NSMutableAttributedString(string: "")
let lines = self.string.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
let lines = self.string.components(separatedBy: CharacterSet.newlines)
var lineCount = 0
@@ -139,23 +138,23 @@ public class SwiftyMarkdown {
var skipLine = false
for theLine in lines {
lineCount++
lineCount += 1
if skipLine {
skipLine = false
continue
}
var line = theLine
var line = theLine == "" ? " " : theLine
for heading in headings {
if let range = line.rangeOfString(heading) where range.startIndex == line.startIndex {
if let range = line.range(of: heading) , range.lowerBound == line.startIndex {
let startHeadingString = line.stringByReplacingCharactersInRange(range, withString: "")
let startHeadingString = line.replacingCharacters(in: range, with: "")
// Remove ending
let endHeadingString = heading.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
line = startHeadingString.stringByReplacingOccurrencesOfString(endHeadingString, withString: "").stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
let endHeadingString = heading.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
line = startHeadingString.replacingOccurrences(of: endHeadingString, with: "").trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
currentType = LineType(rawValue: headings.indexOf(heading)!)!
currentType = LineType(rawValue: headings.index(of: heading)!)!
// We found a heading so break out of the inner loop
break
@@ -166,16 +165,16 @@ public class SwiftyMarkdown {
if lineCount < lines.count {
let nextLine = lines[lineCount]
if let range = nextLine.rangeOfString("=") where range.startIndex == nextLine.startIndex {
if let range = nextLine.range(of: "=") , range.lowerBound == nextLine.startIndex {
// Make H1
currentType = .H1
currentType = .h1
// We need to skip the next line
skipLine = true
}
if let range = nextLine.rangeOfString("-") where range.startIndex == nextLine.startIndex {
if let range = nextLine.range(of: "-") , range.lowerBound == nextLine.startIndex {
// Make H2
currentType = .H2
currentType = .h2
// We need to skip the next line
skipLine = true
}
@@ -185,55 +184,57 @@ public class SwiftyMarkdown {
if line.characters.count > 0 {
// ...start scanning
let scanner = NSScanner(string: line)
let scanner = Scanner(string: line)
// We want to be aware of spaces
scanner.charactersToBeSkipped = nil
while !scanner.atEnd {
while !scanner.isAtEnd {
var string : NSString?
// Get all the characters up to the ones we are interested in
if scanner.scanUpToCharactersFromSet(instructionSet, intoString: &string) {
if scanner.scanUpToCharacters(from: instructionSet, into: &string) {
if let hasString = string as? String {
let bodyString = attributedStringFromString(hasString, withStyle: .None)
attributedString.appendAttributedString(bodyString)
let bodyString = attributedStringFromString(hasString, withStyle: .none)
attributedString.append(bodyString)
let location = scanner.scanLocation
let matchedCharacters = tagFromScanner(scanner).foundCharacters
// If the next string after the characters is a space, then add it to the final string and continue
let set = NSMutableCharacterSet.whitespaceCharacterSet()
set.formUnionWithCharacterSet(NSCharacterSet.punctuationCharacterSet())
if scanner.scanUpToCharactersFromSet(set, intoString: nil) {
let set = NSMutableCharacterSet.whitespace()
set.formUnion(with: CharacterSet.punctuationCharacters)
if scanner.scanUpToCharacters(from: set as CharacterSet, into: nil) {
scanner.scanLocation = location
attributedString.appendAttributedString(self.attributedStringFromScanner(scanner))
attributedString.append(self.attributedStringFromScanner(scanner))
} else if matchedCharacters == "[" {
scanner.scanLocation = location
attributedString.appendAttributedString(self.attributedStringFromScanner(scanner))
attributedString.append(self.attributedStringFromScanner(scanner))
} else {
let charAtts = attributedStringFromString(matchedCharacters, withStyle: .None)
attributedString.appendAttributedString(charAtts)
let charAtts = attributedStringFromString(matchedCharacters, withStyle: .none)
attributedString.append(charAtts)
}
}
} else {
attributedString.appendAttributedString(self.attributedStringFromScanner(scanner, atStartOfLine: true))
attributedString.append(self.attributedStringFromScanner(scanner, atStartOfLine: true))
}
}
}
// Append a new line character to the end of the processed line
attributedString.appendAttributedString(NSAttributedString(string: "\n"))
currentType = .Body
// if lineCount < lines.count {
attributedString.append(NSAttributedString(string: "\n"))
// }
currentType = .body
}
return attributedString
}
func attributedStringFromScanner( scanner : NSScanner, atStartOfLine start : Bool = false) -> NSAttributedString {
func attributedStringFromScanner( _ scanner : Scanner, atStartOfLine start : Bool = false) -> NSAttributedString {
var followingString : NSString?
let results = self.tagFromScanner(scanner)
@@ -241,132 +242,134 @@ public class SwiftyMarkdown {
var style = LineStyle.styleFromString(results.foundCharacters)
var attributes = [String : AnyObject]()
if style == .Link {
if style == .link {
var linkText : NSString?
var linkURL : NSString?
let linkCharacters = NSCharacterSet(charactersInString: "]()")
let linkCharacters = CharacterSet(charactersIn: "]()")
scanner.scanUpToCharactersFromSet(linkCharacters, intoString: &linkText)
scanner.scanCharactersFromSet(linkCharacters, intoString: nil)
scanner.scanUpToCharactersFromSet(linkCharacters, intoString: &linkURL)
scanner.scanCharactersFromSet(linkCharacters, intoString: nil)
scanner.scanUpToCharacters(from: linkCharacters, into: &linkText)
scanner.scanCharacters(from: linkCharacters, into: nil)
scanner.scanUpToCharacters(from: linkCharacters, into: &linkURL)
scanner.scanCharacters(from: linkCharacters, into: nil)
if let hasLink = linkText, hasURL = linkURL {
followingString = hasLink as String
attributes[NSLinkAttributeName] = hasURL as String
if let hasLink = linkText, let hasURL = linkURL {
followingString = hasLink
attributes[NSLinkAttributeName] = hasURL
} else {
style = .None
style = .none
}
} else {
scanner.scanUpToCharactersFromSet(instructionSet, intoString: &followingString)
scanner.scanUpToCharacters(from: instructionSet, into: &followingString)
}
let attributedString = attributedStringFromString(results.escapedCharacters, withStyle: style).mutableCopy() as! NSMutableAttributedString
if let hasString = followingString as? String {
let prefix = ( style == .Code && start ) ? "\t" : ""
let prefix = ( style == .code && start ) ? "\t" : ""
let attString = attributedStringFromString(prefix + hasString, withStyle: style, attributes: attributes)
attributedString.appendAttributedString(attString)
attributedString.append(attString)
}
let suffix = self.tagFromScanner(scanner)
attributedString.appendAttributedString(attributedStringFromString(suffix.escapedCharacters, withStyle: style))
attributedString.append(attributedStringFromString(suffix.escapedCharacters, withStyle: style))
return attributedString
}
func tagFromScanner( scanner : NSScanner ) -> (foundCharacters : String, escapedCharacters : String) {
func tagFromScanner( _ scanner : Scanner ) -> (foundCharacters : String, escapedCharacters : String) {
var matchedCharacters : String = ""
var tempCharacters : NSString?
// Scan the ones we are interested in
while scanner.scanCharactersFromSet(instructionSet, intoString: &tempCharacters) {
while scanner.scanCharacters(from: instructionSet, into: &tempCharacters) {
if let chars = tempCharacters as? String {
matchedCharacters = matchedCharacters + chars
}
}
var foundCharacters : String = ""
while matchedCharacters.containsString("\\") {
if let hasRange = matchedCharacters.rangeOfString("\\") {
while matchedCharacters.contains("\\") {
if let hasRange = matchedCharacters.range(of: "\\") {
let newRange = Range(start: hasRange.startIndex, end: hasRange.endIndex.advancedBy(1))
foundCharacters = foundCharacters + matchedCharacters.substringWithRange(newRange)
matchedCharacters.removeRange(newRange)
if matchedCharacters.characters.count > 1 {
let newRange = hasRange.lowerBound..<matchedCharacters.index(hasRange.upperBound, offsetBy: 1)
foundCharacters = foundCharacters + matchedCharacters.substring(with: newRange)
matchedCharacters.removeSubrange(newRange)
} else {
break
}
}
}
return (matchedCharacters, foundCharacters.stringByReplacingOccurrencesOfString("\\", withString: ""))
return (matchedCharacters, foundCharacters.replacingOccurrences(of: "\\", with: ""))
}
// Make H1
func attributedStringFromString(string : String, withStyle style : LineStyle, var attributes : [String : AnyObject] = [:] ) -> NSAttributedString {
let textStyle : String
func attributedStringFromString(_ string : String, withStyle style : LineStyle, attributes : [String : AnyObject] = [:] ) -> NSAttributedString {
let textStyle : UIFontTextStyle
var fontName : String?
var attributes = attributes
// What type are we and is there a font name set?
switch currentType {
case .H1:
case .h1:
fontName = h1.fontName
if #available(iOS 9, *) {
textStyle = UIFontTextStyleTitle1
textStyle = UIFontTextStyle.title1
} else {
textStyle = UIFontTextStyleHeadline
textStyle = UIFontTextStyle.headline
}
attributes[NSForegroundColorAttributeName] = h1.color
case .H2:
case .h2:
fontName = h2.fontName
if #available(iOS 9, *) {
textStyle = UIFontTextStyleTitle2
textStyle = UIFontTextStyle.title2
} else {
textStyle = UIFontTextStyleHeadline
textStyle = UIFontTextStyle.headline
}
attributes[NSForegroundColorAttributeName] = h2.color
case .H3:
case .h3:
fontName = h3.fontName
if #available(iOS 9, *) {
textStyle = UIFontTextStyleTitle2
textStyle = UIFontTextStyle.title2
} else {
textStyle = UIFontTextStyleSubheadline
textStyle = UIFontTextStyle.subheadline
}
attributes[NSForegroundColorAttributeName] = h3.color
case .H4:
case .h4:
fontName = h4.fontName
textStyle = UIFontTextStyleHeadline
textStyle = UIFontTextStyle.headline
attributes[NSForegroundColorAttributeName] = h4.color
case .H5:
case .h5:
fontName = h5.fontName
textStyle = UIFontTextStyleSubheadline
textStyle = UIFontTextStyle.subheadline
attributes[NSForegroundColorAttributeName] = h5.color
case .H6:
case .h6:
fontName = h6.fontName
textStyle = UIFontTextStyleFootnote
textStyle = UIFontTextStyle.footnote
attributes[NSForegroundColorAttributeName] = h6.color
default:
fontName = body.fontName
textStyle = UIFontTextStyleBody
textStyle = UIFontTextStyle.body
attributes[NSForegroundColorAttributeName] = body.color
break
}
// Check for code
if style == .Code {
if style == .code {
fontName = code.fontName
attributes[NSForegroundColorAttributeName] = code.color
}
if style == .Link {
if style == .link {
fontName = link.fontName
attributes[NSForegroundColorAttributeName] = link.color
}
@@ -378,25 +381,29 @@ public class SwiftyMarkdown {
fontName = body.fontName
}
let font = UIFont.preferredFontForTextStyle(textStyle)
let styleDescriptor = font.fontDescriptor()
let styleSize = styleDescriptor.fontAttributes()[UIFontDescriptorSizeAttribute] as? CGFloat ?? CGFloat(14)
let font = UIFont.preferredFont(forTextStyle: textStyle)
let styleDescriptor = font.fontDescriptor
let styleSize = styleDescriptor.fontAttributes[UIFontDescriptorSizeAttribute] as? CGFloat ?? CGFloat(14)
var finalFont : UIFont
if let finalFontName = fontName, font = UIFont(name: finalFontName, size: styleSize) {
if let finalFontName = fontName, let font = UIFont(name: finalFontName, size: styleSize) {
finalFont = font
} else {
finalFont = UIFont.preferredFontForTextStyle(textStyle)
finalFont = UIFont.preferredFont(forTextStyle: textStyle)
}
let finalFontDescriptor = finalFont.fontDescriptor()
if style == .Italic {
let italicDescriptor = finalFontDescriptor.fontDescriptorWithSymbolicTraits(.TraitItalic)
finalFont = UIFont(descriptor: italicDescriptor, size: styleSize)
let finalFontDescriptor = finalFont.fontDescriptor
if style == .italic {
if let italicDescriptor = finalFontDescriptor.withSymbolicTraits(.traitItalic) {
finalFont = UIFont(descriptor: italicDescriptor, size: styleSize)
}
}
if style == .Bold {
let boldDescriptor = finalFontDescriptor.fontDescriptorWithSymbolicTraits(.TraitBold)
finalFont = UIFont(descriptor: boldDescriptor, size: styleSize)
if style == .bold {
if let boldDescriptor = finalFontDescriptor.withSymbolicTraits(.traitBold) {
finalFont = UIFont(descriptor: boldDescriptor, size: styleSize)
}
}
@@ -233,18 +233,21 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "Voyage Travel Apps";
TargetAttributes = {
F4CE98A71C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 0800;
};
F4CE98BB1C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 0800;
TestTargetID = F4CE98A71C8AEF7D00D735C1;
};
F4CE98C61C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 0800;
TestTargetID = F4CE98A71C8AEF7D00D735C1;
};
};
@@ -394,8 +397,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";
@@ -439,8 +444,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";
@@ -459,6 +466,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@@ -472,6 +480,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -483,6 +492,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -494,6 +504,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftyMarkdownExample.app/SwiftyMarkdownExample";
};
name = Debug;
@@ -506,6 +517,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftyMarkdownExample.app/SwiftyMarkdownExample";
};
name = Release;
@@ -517,6 +529,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_TARGET_NAME = SwiftyMarkdownExample;
USES_XCTRUNNER = YES;
};
@@ -529,6 +542,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_TARGET_NAME = SwiftyMarkdownExample;
USES_XCTRUNNER = YES;
};
@@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
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) {
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) {
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) {
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) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@@ -17,10 +17,10 @@ class ViewController: UIViewController {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.textView.dataDetectorTypes = UIDataDetectorTypes.All
if let url = NSBundle.mainBundle().URLForResource("example", withExtension: "md"), md = SwiftyMarkdown(url: url) {
self.textView.dataDetectorTypes = UIDataDetectorTypes.all
if let url = Bundle.main.url(forResource: "example", withExtension: "md"), let md = SwiftyMarkdown(url: url) {
md.h2.fontName = "AvenirNextCondensed-Bold"
md.h2.color = UIColor.redColor()
md.h2.color = UIColor.red
md.code.fontName = "CourierNewPSMT"
self.textView.attributedText = md.attributedString()
@@ -35,7 +35,5 @@ class ViewController: UIViewController {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
@@ -28,7 +28,7 @@ class SwiftyMarkdownExampleTests: XCTestCase {
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
self.measure {
// Put the code you want to measure the time of here.
}
}
+2 -2
View File
@@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.2.1</string>
<string>0.3.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>12</string>
<string>14</string>
</dict>
</plist>
+4 -69
View File
@@ -16,73 +16,8 @@
# This is the minimum version number required.
# Update this, if you use features of a newer version
fastlane_version "1.36.1"
$scheme = "SwiftyMarkdown"
$spec = "SwiftyMarkdown.podspec"
$project = './SwiftyMarkdown.xcodeproj'
default_platform :ios
platform :ios do
spec = "SwiftyMarkdown.podspec"
before_all do
ensure_git_branch
ensure_git_status_clean
increment_build_number
commit_version_bump(xcodeproj: './SwiftyMarkdown.xcodeproj')
end
desc "Bumps the patch version, increments it, and pushes it to both the remote and spec repos"
lane :patch do
# snapshot
update(type: "patch")
end
desc "Bumps the minor version, increments it, and pushes it to both the remote and spec repos"
lane :minor do
# snapshot
update(type: "minor")
end
lane :initial do
version = version_get_podspec
bump(version: version)
end
private_lane :update do |options|
type = options[:type]
version = version_bump_podspec(path: spec, bump_type: type)
increment_version_number( bump_type: type, version_number: version )
git_commit(path: spec, message: "Updating podspec")
bump(version: version)
end
private_lane :bump do |options|
version = options[:version]
add_git_tag( tag: version)
push_to_git_remote
pod_push(path: spec)
end
# You can define as many lanes as you want
after_all do |lane|
# This block is called, only if the executed lane was successful
notification(subtitle: "SwiftyMarkdown fastlane finished", message: "Completed '#{lane}' successfully")
end
error do |lane, exception|
notification(subtitle: "Error: SwiftyMarkdown fastlane", message: "'#{exception.message}'")
end
end
# More information about multiple platforms in fastlane: https://github.com/KrauseFx/fastlane/blob/master/docs/Platforms.md
# All available actions: https://github.com/KrauseFx/fastlane/blob/master/docs/Actions.md
import "../../Fastlane/FastfilePods"
+28 -9
View File
@@ -10,20 +10,39 @@ sudo gem install fastlane
```
fastlane ios patch
```
Bumps the patch version, increments it, and pushes it to both the remote and spec repos
This does the following:
- Runs the unit tests
- Ensures Cocoapods compatibility
- Bumps the patch version
- Pushes it to the remote repository
- Updates the spec repository
### ios minor
```
fastlane ios minor
```
Bumps the minor version, increments it, and pushes it to both the remote and spec repos
### ios initial
```
fastlane ios initial
```
This does the following:
- Runs the unit tests
- Ensures Cocoapods compatibility
- Bumps the minor version
- Pushes it to the remote repository
- Updates the spec repository
----
This README.md is auto-generated and will be re-generated every time to run [fastlane](https://fastlane.tools).
More information about fastlane can be found on [https://fastlane.tools](https://fastlane.tools).
The documentation of fastlane can be found on [GitHub](https://github.com/fastlane/fastlane).
This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
More information about fastlane can be found on [https://fastlane.tools](https://fastlane.tools).
The documentation of fastlane can be found on [GitHub](https://github.com/fastlane/fastlane/tree/master/fastlane).