Compare commits

...

23 Commits

Author SHA1 Message Date
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
17 changed files with 860 additions and 470 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'
+281
View File
@@ -0,0 +1,281 @@
GEM
remote: https://rubygems.org/
specs:
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.4.0)
babosa (1.0.2)
cert (1.4.2)
fastlane_core (>= 0.50.3, < 1.0.0)
spaceship (>= 0.32.0, < 1.0.0)
claide (1.0.0)
cocoapods (1.1.0.rc.2)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.0, < 2.0)
cocoapods-core (= 1.1.0.rc.2)
cocoapods-deintegrate (>= 1.0.1, < 2.0)
cocoapods-downloader (>= 1.1.1, < 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.0.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored (~> 1.2)
escape (~> 0.0.4)
fourflusher (~> 1.0.1)
gh_inspector (~> 1.0)
molinillo (~> 0.5.1)
nap (~> 1.0)
xcodeproj (>= 1.3.1, < 2.0)
cocoapods-core (1.1.0.rc.2)
activesupport (>= 4.0.2, < 5)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.1)
cocoapods-downloader (1.1.1)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.0.0)
nap (>= 0.8, < 2.0)
netrc (= 0.7.8)
cocoapods-try (1.1.0)
colored (1.2)
commander (4.4.0)
highline (~> 1.7.2)
credentials_manager (0.16.1)
colored
commander (>= 4.3.5)
highline (>= 1.7.1)
security
deliver (1.14.0)
credentials_manager (>= 0.16.0, < 1.0.0)
fastimage (~> 1.6)
fastlane_core (>= 0.52.0, < 1.0.0)
plist (~> 3.1.0)
spaceship (>= 0.34.1, < 1.0.0)
domain_name (0.5.20160826)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.1.1)
escape (0.0.4)
excon (0.45.4)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.10.0)
faraday (>= 0.7.4, < 0.10)
fastimage (1.6.8)
addressable (~> 2.3, >= 2.3.5)
fastlane (1.104.0)
activesupport (< 5)
addressable (~> 2.3)
bundler (~> 1.12)
cert (>= 1.4.1, < 2.0.0)
credentials_manager (>= 0.16.0, < 1.0.0)
deliver (>= 1.13.3, < 2.0.0)
fastlane_core (>= 0.52.0, < 1.0.0)
frameit (>= 2.7.0, < 3.0.0)
gym (>= 1.9.0, < 2.0.0)
krausefx-shenzhen (>= 0.14.10)
match (>= 0.8.0, < 1.0.0)
multipart-post (~> 2.0.0)
pem (>= 1.3.2, < 2.0.0)
pilot (>= 1.10.0, < 2.0.0)
plist (~> 3.1.0)
produce (>= 1.2.0, < 2.0.0)
scan (>= 0.13.0, < 2.0.0)
screengrab (>= 0.5.2, < 1.0.0)
sigh (>= 1.11.1, < 2.0.0)
slack-notifier (~> 1.3)
snapshot (>= 1.16.0, < 2.0.0)
spaceship (>= 0.33.0, < 1.0.0)
supply (>= 0.7.1, < 1.0.0)
terminal-notifier (~> 1.6.2)
terminal-table (~> 1.4.5)
word_wrap (~> 1.0.0)
xcode-install (~> 2.0.0)
xcodeproj (>= 0.20, < 2.0.0)
xcpretty (>= 0.2.1)
fastlane_core (0.52.0)
babosa
colored
commander (>= 4.4.0, <= 5.0.0)
credentials_manager (>= 0.16.0, < 1.0.0)
excon (~> 0.45.0)
gh_inspector (>= 1.0.1, < 2.0.0)
highline (>= 1.7.2)
json
multi_json
plist (~> 3.1)
rubyzip (~> 1.1.6)
terminal-table (~> 1.4.5)
fourflusher (1.0.1)
frameit (2.7.0)
deliver (> 0.3)
fastimage (~> 1.6.3)
fastlane_core (>= 0.36.1, < 1.0.0)
mini_magick (~> 4.5.1)
fuzzy_match (2.0.4)
gh_inspector (1.0.2)
google-api-client (0.9.15)
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)
gym (1.10.0)
fastlane_core (>= 0.52.0, < 1.0.0)
plist
rubyzip (>= 1.1.7)
terminal-table
xcpretty (>= 0.2.1)
highline (1.7.8)
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.2.4)
hurley (0.2)
i18n (0.7.0)
json (1.8.3)
jwt (1.5.6)
krausefx-shenzhen (0.14.10)
commander (>= 4.3, < 5.0)
dotenv (>= 0.7)
faraday (~> 0.9)
faraday_middleware (~> 0.9)
highline (>= 1.7.2)
json (~> 1.8)
net-sftp (~> 2.1.2)
plist (~> 3.1.0)
rubyzip (~> 1.1)
security (~> 0.1.3)
terminal-table (~> 1.4.5)
little-plugger (1.1.4)
logging (2.1.0)
little-plugger (~> 1.1)
multi_json (~> 1.10)
match (0.8.0)
cert (>= 1.4.2, < 2.0.0)
credentials_manager (>= 0.16.0, < 1.0.0)
fastlane_core (>= 0.52.0, < 1.0.0)
security
sigh (>= 1.11.0, < 2.0.0)
spaceship (>= 0.33.0, < 1.0.0)
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.9.1)
molinillo (0.5.1)
multi_json (1.12.1)
multi_xml (0.5.5)
multipart-post (2.0.0)
nap (1.1.0)
net-sftp (2.1.2)
net-ssh (>= 2.6.5)
net-ssh (3.2.0)
netrc (0.7.8)
os (0.9.6)
pem (1.3.2)
fastlane_core (>= 0.43.1, < 1.0.0)
spaceship (>= 0.26.2, < 1.0.0)
pilot (1.10.0)
credentials_manager (>= 0.3.0)
fastlane_core (>= 0.46.2, < 1.0.0)
spaceship (>= 0.29.0, < 1.0.0)
terminal-table (~> 1.4.5)
plist (3.1.0)
produce (1.2.0)
fastlane_core (>= 0.30.0, < 1.0.0)
spaceship (>= 0.31.1, < 1.0.0)
representable (2.3.0)
uber (~> 0.0.7)
retriable (2.1.0)
rouge (1.11.1)
rubyzip (1.1.7)
scan (0.13.0)
fastlane_core (>= 0.52.0, < 1.0.0)
slack-notifier (~> 1.3)
terminal-table
xcpretty (>= 0.2.1)
xcpretty-travis-formatter (>= 0.0.3)
screengrab (0.5.4)
fastlane_core (>= 0.52.0, < 1.0.0)
security (0.1.3)
sigh (1.11.1)
fastlane_core (>= 0.52.0, < 1.0.0)
plist (~> 3.1)
spaceship (>= 0.33.0, < 1.0.0)
signet (0.7.3)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (~> 1.5)
multi_json (~> 1.10)
slack-notifier (1.5.1)
snapshot (1.16.1)
fastimage (~> 1.6.3)
fastlane_core (>= 0.52.0, < 1.0.0)
plist (~> 3.1.0)
xcpretty (>= 0.2.3)
spaceship (0.34.1)
colored
credentials_manager (>= 0.16.0)
faraday (~> 0.9)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
fastimage (~> 1.6)
multi_xml (~> 0.5)
plist (~> 3.1)
supply (0.7.1)
credentials_manager (>= 0.15.0)
fastlane_core (>= 0.43.4)
google-api-client (~> 0.9.1)
terminal-notifier (1.6.3)
terminal-table (1.4.5)
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)
word_wrap (1.0.0)
xcode-install (2.0.7)
claide (>= 0.9.1, < 1.1.0)
spaceship (>= 0.25.1, < 1.0.0)
xcodeproj (1.3.1)
activesupport (>= 3)
claide (>= 1.0.0, < 2.0)
colored (~> 1.2)
xcpretty (0.2.3)
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.12.5
+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.0"
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/'
+17 -5
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";
@@ -323,9 +329,10 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
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";
@@ -335,6 +342,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -342,9 +350,10 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
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";
@@ -353,6 +362,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdown;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -363,6 +373,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 +384,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;
};
+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.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>12</string>
<string>14</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
+115 -115
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,10 +111,10 @@ 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 = ""
@@ -128,10 +128,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,7 +139,7 @@ public class SwiftyMarkdown {
var skipLine = false
for theLine in lines {
lineCount++
lineCount += 1
if skipLine {
skipLine = false
continue
@@ -147,15 +147,15 @@ public class SwiftyMarkdown {
var line = 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 +166,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 +185,55 @@ 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
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 +241,132 @@ 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)
// FIXME: Possible error in range
let newRange = hasRange.lowerBound..<matchedCharacters.index(hasRange.upperBound, offsetBy: 1)
foundCharacters = foundCharacters + matchedCharacters.substring(with: newRange)
matchedCharacters.removeSubrange(newRange)
}
}
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 +378,25 @@ 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 {
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 {
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.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>12</string>
<string>14</string>
</dict>
</plist>
+53 -14
View File
@@ -20,17 +20,19 @@ fastlane_version "1.36.1"
default_platform :ios
platform :ios do
spec = "SwiftyMarkdown.podspec"
project = './SwiftyMarkdown.xcodeproj'
before_all do
ensure_git_branch
ensure_git_status_clean
increment_build_number
commit_version_bump(xcodeproj: './SwiftyMarkdown.xcodeproj')
before_all do |lane, options|
ENV["SLACK_URL"] = "https://hooks.slack.com/services/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"
if options[:skip_checks]
UI.message "Skipping checks"
else
ensure_git_branch
ensure_git_status_clean
end
end
desc "Bumps the patch version, increments it, and pushes it to both the remote and spec repos"
@@ -50,17 +52,52 @@ platform :ios do
version = version_get_podspec
bump(version: version)
end
private_lane :update do |options|
increment_build_number
pod_lib_lint(
allow_warnings: true
)
type = options[:type]
if type == "none"
UI.message("No type found")
else
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")
commit_version_bump(xcodeproj: project)
add_git_tag( tag: version)
push_to_git_remote
pod_push(path: spec)
post_to_slack(scheme:"SwiftyMarkdown", version: version)
end
end
private_lane :update do |options|
# 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")
# 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)
# bump(version: version)
end
# end
private_lane :post_to_slack do |options|
scheme = options[:scheme]
version = options[:version]
environment = scheme.upcase
slack(
message: "New `#{environment}` version: *#{version}* released :rocket:",
)
end
private_lane :bump do |options|
version = options[:version]
@@ -79,6 +116,8 @@ platform :ios do
error do |lane, exception|
notification(subtitle: "Error: SwiftyMarkdown fastlane", message: "'#{exception.message}'")
version = get_version_number(xcodeproj: project, target: "SwiftyMarkdown")
post_to_slack(scheme:"SwiftyMarkdown", version: version)
end
end
+3 -3
View File
@@ -24,6 +24,6 @@ fastlane ios initial
----
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).