Compare commits

...

95 Commits

Author SHA1 Message Date
Simon Fairbairn db1c0f7902 Merge branch 'release/0.6.0' 2018-10-11 12:32:52 +01:00
Simon Fairbairn 9a2cd21b15 Fixing rubyzip vulnerability 2018-10-11 12:32:41 +01:00
Simon Fairbairn fdbfbcda54 Version Bump 2018-10-11 12:31:12 +01:00
Simon Fairbairn 04b2f41c00 Updating podspec 2018-10-11 12:31:09 +01:00
Simon Fairbairn 957ec2b442 Updating fastlane 2018-10-11 12:29:58 +01:00
Simon Fairbairn 3848d54e45 Updating to Swift 4.2 2018-10-11 12:29:03 +01:00
Simon Fairbairn 85b1a0b944 Merge branch 'release/0.5.1' into develop 2017-12-04 14:08:41 +04:00
Simon Fairbairn 289925e34d Merge branch 'release/0.5.1' 2017-12-04 14:08:35 +04:00
Simon Fairbairn f8567bd974 Version Bump 2017-12-04 14:08:16 +04:00
Simon Fairbairn 10ed2abd88 Updating podspec 2017-12-04 14:08:13 +04:00
Simon Fairbairn 0e7ede23c3 Updating readme 2017-12-04 14:07:18 +04:00
Simon Fairbairn d316d83848 Merge branch 'master' into release/0.5.1 2017-12-04 13:56:58 +04:00
Simon Fairbairn 3c149a65e7 Updating readme 2017-12-04 13:56:40 +04:00
Simon Fairbairn 7a00026c2d Merge pull request #47 from xzoky/master
Fix String.characters warning
2017-12-04 16:52:16 +07:00
Simon Fairbairn 5f8a6ba7dd Updating Gemfile 2017-12-04 13:48:31 +04:00
Camille Kander 6797288c0e Fix String.characters warning 2017-12-03 23:48:07 -05:00
Simon Fairbairn 96e6ac313c Version Bump 2017-09-24 09:15:40 +08:00
Simon Fairbairn 76f76d8178 Updating podspec 2017-09-24 09:15:36 +08:00
Simon Fairbairn ea0717903e Using new subscript syntax 2017-09-24 09:14:05 +08:00
Simon Fairbairn 845985236a Updating .swift-version to indacte that podspec should use Swift 4 2017-09-24 09:08:39 +08:00
Simon Fairbairn e3e89715f8 Version Bump to 19 2017-09-15 13:55:58 +08:00
Simon Fairbairn b077d32f52 Updating podspec 2017-09-15 13:55:56 +08:00
Simon Fairbairn fc9d8b2646 Updating tests and example 2017-09-15 13:54:38 +08:00
Simon Fairbairn 43f94723c8 Removing line breaks at the end of extra lines. 2017-09-15 13:50:22 +08:00
Simon Fairbairn ea306673e8 Reverting some changes in #43 2017-09-15 13:30:55 +08:00
Simon Fairbairn 15f2a353be Version Bump to 18 2017-09-03 09:16:18 +08:00
Simon Fairbairn e9fed1ced9 Updating podspec 2017-09-03 09:16:16 +08:00
Simon Fairbairn 67297197e8 Merge pull request #44 from enhorn/fix/handle-international-characters
Fixes an erroneous identification of `Alt-H2` headers.
2017-09-03 09:14:23 +08:00
Robin Enhorn 6ee2001d43 Fixes an erroneous identification of Alt-H2 headers. 2017-08-30 17:04:17 +02:00
Simon Fairbairn 4bd6bf498f Version Bump to 17 2017-08-27 09:05:28 +08:00
Simon Fairbairn 1f5a6d4e50 Updating podspec 2017-08-27 09:05:26 +08:00
Simon Fairbairn 04de344a43 Updating project to support latest settings 2017-08-27 09:03:44 +08:00
Simon Fairbairn f386286a7e Adding example.md 2017-08-27 09:01:08 +08:00
Simon Fairbairn 7c07c37f10 Merge pull request #43 from lucasromanomr/master
Add fixed font size for type and support Objc
2017-08-27 08:59:06 +08:00
Lucas Romano 07e9cf69a4 Set font name and font color for all styles 2017-08-24 15:06:05 -03:00
Lucas Romano c86ae343f1 Set font size for all styles 2017-08-24 14:54:21 -03:00
Lucas Romano 170e4b6fa2 add options on asicStyles for objective c 2017-08-24 14:42:35 -03:00
Lucas Romano d62bf1dee9 Ajustes Objc 2017-08-24 13:57:50 -03:00
Lucas Romano c8e6bc6b44 Ajust class to Objc 2017-08-24 13:55:06 -03:00
Lucas Romano 18a1f2922a Transform struct to style in BasicStyle 2017-08-24 13:54:28 -03:00
Lucas Romano 6d1ec33196 Ajusts for public attributes 2017-08-24 13:47:47 -03:00
Lucas Romano 63f489eebe add suport for objc 2017-08-23 17:31:37 -03:00
Lucas Romano 01d153b3ca add fixed font size
add fixed font size for all text
2017-08-23 17:22:55 -03:00
Simon Fairbairn 5148e8ad77 Merge pull request #40 from Nonchalant/feature/fix_markdown
Fix markdown for swift3. Thanks to @Nonchalant
2017-05-04 15:58:43 +08:00
Nonchalant 994af3ad6d fix markdown for swift3 2017-04-24 12:32:13 +09:00
Simon Fairbairn 2b7bfc81d7 Version Bump to 16 2017-04-01 11:48:31 +02:00
Simon Fairbairn aaf8f3618a Updating podspec 2017-04-01 11:48:29 +02:00
Simon Fairbairn a030f210b3 Tidying up 2017-04-01 11:47:39 +02:00
Simon Fairbairn be2eaf522c Fixes issue #14. Fixes issue #33 2017-04-01 11:41:36 +02:00
Simon Fairbairn d48d6b1f90 Version Bump to 15 2017-04-01 10:26:52 +02:00
Simon Fairbairn 100bb3df20 Updating podspec 2017-04-01 10:26:50 +02:00
Simon Fairbairn 29da129a24 Updating gems 2017-04-01 10:24:59 +02:00
Simon Fairbairn 9fcdddf484 Fixing warnings in Xcode 8.3 2017-04-01 10:15:58 +02:00
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
24 changed files with 1174 additions and 636 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 @@
4.0
+7
View File
@@ -0,0 +1,7 @@
# frozen_string_literal: true
# A sample Gemfile
source "https://rubygems.org"
# gem "rails"
gem "cocoapods"
gem 'fastlane'
+190
View File
@@ -0,0 +1,190 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.5)
activesupport (4.2.9)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
babosa (1.0.2)
claide (1.0.2)
cocoapods (1.3.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.3.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.2.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (~> 2.0.1)
gh_inspector (~> 1.0)
molinillo (~> 0.5.7)
nap (~> 1.0)
ruby-macho (~> 1.1)
xcodeproj (>= 1.5.1, < 2.0)
cocoapods-core (1.3.1)
activesupport (>= 4.0.2, < 6)
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.2.0)
nap (>= 0.8, < 2.0)
netrc (= 0.7.8)
cocoapods-try (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.5)
highline (~> 1.7.2)
declarative (0.0.10)
declarative-option (0.1.0)
domain_name (0.5.20170404)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.2.1)
escape (0.0.4)
excon (0.59.0)
faraday (0.13.1)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.12.2)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.0)
fastlane (2.58.0)
CFPropertyList (>= 2.3, < 3.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 2.0.0)
colored
commander-fastlane (>= 4.4.5, < 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 (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.0.1, < 2.0.0)
google-api-client (>= 0.13.1, < 0.14.0)
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)
public_suffix (~> 2.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)
tty-screen (~> 0.5.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.5.0, < 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.13.6)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.5)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
googleauth (0.5.3)
faraday (~> 0.12)
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)
i18n (0.8.6)
json (2.1.0)
jwt (1.5.6)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
memoist (0.16.0)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_magick (4.5.1)
minitest (5.10.3)
molinillo (0.5.7)
multi_json (1.12.2)
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.3.0)
public_suffix (2.0.5)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.1.1)
rouge (2.0.7)
ruby-macho (1.1.0)
rubyzip (1.2.2)
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.8.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tty-screen (0.5.0)
tzinfo (1.2.3)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.4)
unicode-display_width (1.3.0)
word_wrap (1.0.0)
xcodeproj (1.5.1)
CFPropertyList (~> 2.3.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.3)
xcpretty (0.2.8)
rouge (~> 2.0.7)
xcpretty-travis-formatter (0.0.4)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
DEPENDENCIES
cocoapods
fastlane
BUNDLED WITH
1.14.5
+38 -12
View File
@@ -2,28 +2,54 @@
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 = Bundle.main.url(forResource: "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.h1.fontSize = 16
```
md.italic.color = UIColor.blueColor()
## Screenshot
![Screenshot](http://f.cl.ly/items/12332k3f2s0s0C281h2u/swiftymarkdown.png)
![Screenshot](http://f.cl.ly/items/12332k3f2s0s0C281h2u/swiftymarkdown.png)
+312 -303
View File
@@ -1,313 +1,322 @@
//: Playground - noun: a place where people can play
import UIKit
import XCPlayground
import PlaygroundSupport
let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 400.0, height: 600))
XCPlaygroundPage.currentPage.liveView = containerView
PlaygroundPage.current.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[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()
//}
//
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<playground version='5.0' target-platform='ios' last-migration='0900'>
<timeline fileName='timeline.xctimeline'/>
</playground>
+4 -3
View File
@@ -1,14 +1,15 @@
Pod::Spec.new do |s|
s.name = "SwiftyMarkdown"
s.version = "0.2.2"
s.version = "0.6.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/'
+48 -5
View File
@@ -154,14 +154,17 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Voyage Travel Apps";
TargetAttributes = {
F4CE98801C8A921300D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 1000;
};
F4CE988A1C8A921300D735C1 = {
CreatedOnToolsVersion = 7.2.1;
DevelopmentTeam = 52T262DA8V;
LastSwiftMigration = 1000;
};
};
};
@@ -238,18 +241,28 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
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 = 19;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -286,18 +299,28 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
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 = 19;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -312,6 +335,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,57 +346,76 @@
F4CE98961C8A921300D735C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BITCODE_GENERATION_MODE = bitcode;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 12;
DYLIB_CURRENT_VERSION = 19;
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_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
};
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*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 12;
DYLIB_CURRENT_VERSION = 19;
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_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
};
name = Release;
};
F4CE98991C8A921300D735C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEVELOPMENT_TEAM = 52T262DA8V;
INFOPLIST_FILE = SwiftyMarkdownTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
F4CE989A1C8A921300D735C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEVELOPMENT_TEAM = 52T262DA8V;
INFOPLIST_FILE = SwiftyMarkdownTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
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>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+2 -2
View File
@@ -15,11 +15,11 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.2.1</string>
<string>0.6.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>12</string>
<string>19</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
+223 -148
View File
@@ -9,9 +9,10 @@
import UIKit
public protocol FontProperties {
@objc public protocol FontProperties {
var fontName : String? { get set }
var color : UIColor { get set }
var fontSize : CGFloat { get set }
}
@@ -20,79 +21,81 @@ 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()
@objc open class BasicStyles : NSObject, FontProperties {
public var fontName : String? = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body).fontName
public var color = UIColor.black
public var fontSize : CGFloat = 0.0
}
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 {
@objc open class SwiftyMarkdown: NSObject {
/// 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,27 +114,70 @@ 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
}
}
/**
Set font size for all styles
- parameter size: size of font
*/
open func setFontSizeForAllStyles(with size: CGFloat) {
h1.fontSize = size
h2.fontSize = size
h3.fontSize = size
h4.fontSize = size
h5.fontSize = size
h6.fontSize = size
body.fontSize = size
italic.fontSize = size
code.fontSize = size
link.fontSize = size
}
open func setFontColorForAllStyles(with color: UIColor) {
h1.color = color
h2.color = color
h3.color = color
h4.color = color
h5.color = color
h6.color = color
body.color = color
italic.color = color
code.color = color
link.color = color
}
open func setFontNameForAllStyles(with name: String) {
h1.fontName = name
h2.fontName = name
h3.fontName = name
h4.fontName = name
h5.fontName = name
h6.fontName = name
body.fontName = name
italic.fontName = name
code.fontName = name
link.fontName = name
}
/**
Generates an NSAttributedString from the string or URL passed at initialisation. Custom fonts or styles are applied to the appropriate elements when this method is called.
- 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,24 +185,24 @@ 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.replacingCharacters(in: range, with: "")
let startHeadingString = line.stringByReplacingCharactersInRange(range, withString: "")
// 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.index(of: heading)!)!
currentType = LineType(rawValue: headings.indexOf(heading)!)!
// We found a heading so break out of the inner loop
break
}
@@ -166,209 +212,233 @@ public class SwiftyMarkdown {
if lineCount < lines.count {
let nextLine = lines[lineCount]
if let range = nextLine.rangeOfString("=") where range.startIndex == nextLine.startIndex {
let hasNonWhiteSpaceCharacters = (line.rangeOfCharacter(from: CharacterSet.whitespacesAndNewlines.inverted) != nil)
if hasNonWhiteSpaceCharacters, 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 {
// Make H2
currentType = .H2
// We need to skip the next line
skipLine = true
if hasNonWhiteSpaceCharacters, let nextRange = nextLine.range(of: "-") , nextRange.lowerBound == nextLine.startIndex {
if let range = line.range(of: "-"), range.lowerBound == line.startIndex {
// This is a bullet list, not an `Alt-H2`, don't skip
} else {
// Make H2
currentType = .h2
// We need to skip the next line
skipLine = true
}
}
}
// If this is not an empty line...
if line.characters.count > 0 {
if line.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)
if let hasString = string as String? {
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)
var style = LineStyle.styleFromString(results.foundCharacters)
var attributes = [String : AnyObject]()
if style == .Link {
var attributes = [NSAttributedString.Key : AnyObject]()
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[NSAttributedString.Key.link] = 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 {
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) {
if let chars = tempCharacters as? String {
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.count > 1 {
let newRange = hasRange.lowerBound..<matchedCharacters.index(hasRange.upperBound, offsetBy: 1)
foundCharacters = foundCharacters + matchedCharacters[newRange].replacingOccurrences(of: "\\", with: "")
matchedCharacters.removeSubrange(newRange)
} else {
foundCharacters = matchedCharacters
break
}
}
}
return (matchedCharacters, foundCharacters.stringByReplacingOccurrencesOfString("\\", withString: ""))
return (matchedCharacters, foundCharacters)
}
// 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 : [NSAttributedString.Key : AnyObject] = [:] ) -> NSAttributedString {
let textStyle : UIFont.TextStyle
var fontName : String?
var attributes = attributes
var fontSize : CGFloat?
// What type are we and is there a font name set?
switch currentType {
case .H1:
case .h1:
fontName = h1.fontName
fontSize = h1.fontSize
if #available(iOS 9, *) {
textStyle = UIFontTextStyleTitle1
textStyle = UIFont.TextStyle.title1
} else {
textStyle = UIFontTextStyleHeadline
textStyle = UIFont.TextStyle.headline
}
attributes[NSForegroundColorAttributeName] = h1.color
case .H2:
attributes[NSAttributedString.Key.foregroundColor] = h1.color
case .h2:
fontName = h2.fontName
fontSize = h2.fontSize
if #available(iOS 9, *) {
textStyle = UIFontTextStyleTitle2
textStyle = UIFont.TextStyle.title2
} else {
textStyle = UIFontTextStyleHeadline
textStyle = UIFont.TextStyle.headline
}
attributes[NSForegroundColorAttributeName] = h2.color
case .H3:
attributes[NSAttributedString.Key.foregroundColor] = h2.color
case .h3:
fontName = h3.fontName
fontSize = h3.fontSize
if #available(iOS 9, *) {
textStyle = UIFontTextStyleTitle2
textStyle = UIFont.TextStyle.title2
} else {
textStyle = UIFontTextStyleSubheadline
textStyle = UIFont.TextStyle.subheadline
}
attributes[NSForegroundColorAttributeName] = h3.color
case .H4:
attributes[NSAttributedString.Key.foregroundColor] = h3.color
case .h4:
fontName = h4.fontName
textStyle = UIFontTextStyleHeadline
attributes[NSForegroundColorAttributeName] = h4.color
case .H5:
fontSize = h4.fontSize
textStyle = UIFont.TextStyle.headline
attributes[NSAttributedString.Key.foregroundColor] = h4.color
case .h5:
fontName = h5.fontName
textStyle = UIFontTextStyleSubheadline
attributes[NSForegroundColorAttributeName] = h5.color
case .H6:
fontSize = h5.fontSize
textStyle = UIFont.TextStyle.subheadline
attributes[NSAttributedString.Key.foregroundColor] = h5.color
case .h6:
fontName = h6.fontName
textStyle = UIFontTextStyleFootnote
attributes[NSForegroundColorAttributeName] = h6.color
fontSize = h6.fontSize
textStyle = UIFont.TextStyle.footnote
attributes[NSAttributedString.Key.foregroundColor] = h6.color
default:
fontName = body.fontName
textStyle = UIFontTextStyleBody
attributes[NSForegroundColorAttributeName] = body.color
fontSize = body.fontSize
textStyle = UIFont.TextStyle.body
attributes[NSAttributedString.Key.foregroundColor] = body.color
break
}
// Check for code
if style == .Code {
if style == .code {
fontName = code.fontName
attributes[NSForegroundColorAttributeName] = code.color
fontSize = code.fontSize
attributes[NSAttributedString.Key.foregroundColor] = code.color
}
if style == .Link {
if style == .link {
fontName = link.fontName
attributes[NSForegroundColorAttributeName] = link.color
fontSize = link.fontSize
attributes[NSAttributedString.Key.foregroundColor] = link.color
}
// Fallback to body
@@ -378,29 +448,34 @@ public class SwiftyMarkdown {
fontName = body.fontName
}
let font = UIFont.preferredFontForTextStyle(textStyle)
let styleDescriptor = font.fontDescriptor()
let styleSize = styleDescriptor.fontAttributes()[UIFontDescriptorSizeAttribute] as? CGFloat ?? CGFloat(14)
fontSize = fontSize == 0.0 ? nil : fontSize
let font = UIFont.preferredFont(forTextStyle: textStyle)
let styleDescriptor = font.fontDescriptor
let styleSize = fontSize ?? styleDescriptor.fontAttributes[UIFontDescriptor.AttributeName.size] 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)
}
}
attributes[NSFontAttributeName] = finalFont
attributes[NSAttributedString.Key.font] = finalFont
return NSAttributedString(string: string, attributes: attributes)
}
@@ -233,18 +233,21 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Voyage Travel Apps";
TargetAttributes = {
F4CE98A71C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 0900;
};
F4CE98BB1C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 0900;
TestTargetID = F4CE98A71C8AEF7D00D735C1;
};
F4CE98C61C8AEF7D00D735C1 = {
CreatedOnToolsVersion = 7.2.1;
LastSwiftMigration = 0900;
TestTargetID = F4CE98A71C8AEF7D00D735C1;
};
};
@@ -389,13 +392,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -434,13 +447,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
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 +482,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 +496,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@@ -483,6 +509,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
};
name = Release;
};
@@ -494,6 +522,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftyMarkdownExample.app/SwiftyMarkdownExample";
};
name = Debug;
@@ -506,6 +536,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftyMarkdownExample.app/SwiftyMarkdownExample";
};
name = Release;
@@ -517,6 +549,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = SwiftyMarkdownExample;
USES_XCTRUNNER = YES;
};
@@ -529,6 +563,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.voyagetravelapps.SwiftyMarkdownExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.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:.
}
@@ -1,9 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12118" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
@@ -15,22 +19,31 @@
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" usesAttributedText="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qZP-CU-74n">
<rect key="frame" x="20" y="20" width="560" height="580"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<rect key="frame" x="16" y="20" width="343" height="601"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<attributedString key="attributedText"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JK2-Lo-xRa">
<rect key="frame" x="164" y="629" width="47" height="30"/>
<state key="normal" title="Reload"/>
<connections>
<action selector="reloadText:" destination="BYZ-38-t0r" eventType="touchUpInside" id="fGe-1g-NTo"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="qZP-CU-74n" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" id="1yU-8N-26a"/>
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="qZP-CU-74n" secondAttribute="bottom" id="7lJ-OQ-4eh"/>
<constraint firstItem="JK2-Lo-xRa" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="3Zx-lw-7hH"/>
<constraint firstAttribute="trailingMargin" secondItem="qZP-CU-74n" secondAttribute="trailing" id="F5p-iG-zTB"/>
<constraint firstItem="JK2-Lo-xRa" firstAttribute="top" secondItem="qZP-CU-74n" secondAttribute="bottom" constant="8" id="Rod-d1-6Yb"/>
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="JK2-Lo-xRa" secondAttribute="bottom" constant="8" id="Yc0-Xe-YPV"/>
<constraint firstItem="qZP-CU-74n" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="srf-u0-j0n"/>
</constraints>
</view>
@@ -40,6 +53,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="24.800000000000001" y="34.632683658170919"/>
</scene>
</scenes>
</document>
@@ -15,27 +15,31 @@ class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// This is to help debugging.
reloadText(nil)
}
@IBAction func reloadText( _ sender : UIButton? ) {
self.textView.dataDetectorTypes = UIDataDetectorTypes.all
self.textView.dataDetectorTypes = UIDataDetectorTypes.All
if let url = NSBundle.mainBundle().URLForResource("example", withExtension: "md"), md = SwiftyMarkdown(url: url) {
if self.textView.text != "" {
self.textView.attributedText = SwiftyMarkdown(string: "Yo I'm a *single* line **string**. How do I look?").attributedString()
return
}
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()
} else {
fatalError("Error loading file")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
@@ -15,3 +15,8 @@ Customise fonts and colours easily in a Swift-like way:
It ignores random * and correctly handles escaped \*asterisks\* and \_underlines\_ and has error handling for mismatched tags (\*\*bold\* == **bold*). It also supports inline Markdown [Links](http://voyagetravelapps.com/)
Supports Alternative Headings
===
@@ -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.6.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>12</string>
<string>19</string>
</dict>
</plist>
+71 -54
View File
@@ -28,13 +28,13 @@ class SwiftyMarkdownTests: XCTestCase {
let headerStringWithItalic = "## Header 2 _With Italics_"
var md = SwiftyMarkdown(string: headerString)
XCTAssertEqual(md.attributedString().string, "Header 1\nHeader 2\nHeader 3\nHeader 4\nHeader 5\nHeader 6\n")
XCTAssertEqual(md.attributedString().string, "Header 1\nHeader 2\nHeader 3\nHeader 4\nHeader 5\nHeader 6")
md = SwiftyMarkdown(string: headerStringWithBold)
XCTAssertEqual(md.attributedString().string, "Bold Header 1\n")
XCTAssertEqual(md.attributedString().string, "Bold Header 1")
md = SwiftyMarkdown(string: headerStringWithItalic)
XCTAssertEqual(md.attributedString().string, "Header 2 With Italics\n")
XCTAssertEqual(md.attributedString().string, "Header 2 With Italics")
}
@@ -47,19 +47,19 @@ class SwiftyMarkdownTests: XCTestCase {
let h2StringWithCode = "Header 2 `With Code`\n---\nSome following text"
var md = SwiftyMarkdown(string: h1String)
XCTAssertEqual(md.attributedString().string, "Header 1\nSome following text\n")
XCTAssertEqual(md.attributedString().string, "Header 1\nSome following text")
md = SwiftyMarkdown(string: h2String)
XCTAssertEqual(md.attributedString().string, "Header 2\nSome following text\n")
XCTAssertEqual(md.attributedString().string, "Header 2\nSome following text")
md = SwiftyMarkdown(string: h1StringWithBold)
XCTAssertEqual(md.attributedString().string, "Header 1 With Bold\nSome following text\n")
XCTAssertEqual(md.attributedString().string, "Header 1 With Bold\nSome following text")
md = SwiftyMarkdown(string: h2StringWithItalic)
XCTAssertEqual(md.attributedString().string, "Header 2 With Italic\nSome following text\n")
XCTAssertEqual(md.attributedString().string, "Header 2 With Italic\nSome following text")
md = SwiftyMarkdown(string: h2StringWithCode)
XCTAssertEqual(md.attributedString().string, "Header 2 With Code\nSome following text\n")
XCTAssertEqual(md.attributedString().string, "Header 2 With Code\nSome following text")
}
func testThatRegularTraitsAreParsedCorrectly() {
@@ -78,34 +78,34 @@ class SwiftyMarkdownTests: XCTestCase {
var md = SwiftyMarkdown(string: boldAtStartOfString)
XCTAssertEqual(md.attributedString().string, "A bold string\n")
XCTAssertEqual(md.attributedString().string, "A bold string")
md = SwiftyMarkdown(string: boldWithinString)
XCTAssertEqual(md.attributedString().string, "A string with a bold word\n")
XCTAssertEqual(md.attributedString().string, "A string with a bold word")
md = SwiftyMarkdown(string: codeAtStartOfString)
XCTAssertEqual(md.attributedString().string, "\tCode (should be indented)\n")
XCTAssertEqual(md.attributedString().string, "\tCode (should be indented)")
md = SwiftyMarkdown(string: codeWithinString)
XCTAssertEqual(md.attributedString().string, "A string with code (should not be indented)\n")
XCTAssertEqual(md.attributedString().string, "A string with code (should not be indented)")
md = SwiftyMarkdown(string: italicAtStartOfString)
XCTAssertEqual(md.attributedString().string, "An italicised string\n")
XCTAssertEqual(md.attributedString().string, "An italicised string")
md = SwiftyMarkdown(string: italicWithinString)
XCTAssertEqual(md.attributedString().string, "A string with italicised text\n")
XCTAssertEqual(md.attributedString().string, "A string with italicised text")
md = SwiftyMarkdown(string: multipleBoldWords)
XCTAssertEqual(md.attributedString().string, "A bold string with a mix of bold styles\n")
XCTAssertEqual(md.attributedString().string, "A bold string with a mix of bold styles")
md = SwiftyMarkdown(string: multipleCodeWords)
XCTAssertEqual(md.attributedString().string, "\tA code string with multiple code instances\n")
XCTAssertEqual(md.attributedString().string, "\tA code string with multiple code instances")
md = SwiftyMarkdown(string: multipleItalicWords)
XCTAssertEqual(md.attributedString().string, "An italic string with a mix of italic styles\n")
XCTAssertEqual(md.attributedString().string, "An italic string with a mix of italic styles")
md = SwiftyMarkdown(string: longMixedString)
XCTAssertEqual(md.attributedString().string, "An italic string, follwed by a bold one, with some code, **and some** _escaped_ `characters`, ending with more variety.\n")
XCTAssertEqual(md.attributedString().string, "An italic string, follwed by a bold one, with some code, **and some** _escaped_ `characters`, ending with more variety.")
}
@@ -114,10 +114,10 @@ class SwiftyMarkdownTests: XCTestCase {
let mismatchedBoldCharactersWithin = "A string *that should be italic**"
var md = SwiftyMarkdown(string: mismatchedBoldCharactersAtStart)
XCTAssertEqual(md.attributedString().string, "This should be bold\n")
XCTAssertEqual(md.attributedString().string, "This should be bold")
md = SwiftyMarkdown(string: mismatchedBoldCharactersWithin)
XCTAssertEqual(md.attributedString().string, "A string that should be italic\n")
XCTAssertEqual(md.attributedString().string, "A string that should be italic")
}
@@ -138,39 +138,42 @@ class SwiftyMarkdownTests: XCTestCase {
let oneEscapedAsteriskTwoNormalWithin = "A string with *\\**escaped**\\* asterisks"
var md = SwiftyMarkdown(string: escapedBoldAtStart)
XCTAssertEqual(md.attributedString().string, "**A normal string**\n")
XCTAssertEqual(md.attributedString().string, "**A normal string**")
md = SwiftyMarkdown(string: escapedBoldWithin)
XCTAssertEqual(md.attributedString().string, "A string with **escaped** asterisks\n")
XCTAssertEqual(md.attributedString().string, "A string with **escaped** asterisks")
md = SwiftyMarkdown(string: escapedItalicAtStart)
XCTAssertEqual(md.attributedString().string, "_A normal string_\n")
XCTAssertEqual(md.attributedString().string, "_A normal string_")
md = SwiftyMarkdown(string: escapedItalicWithin)
XCTAssertEqual(md.attributedString().string, "A string with _escaped_ underscores\n")
XCTAssertEqual(md.attributedString().string, "A string with _escaped_ underscores")
md = SwiftyMarkdown(string: escapedBackticksAtStart)
XCTAssertEqual(md.attributedString().string, "`A normal string`\n")
XCTAssertEqual(md.attributedString().string, "`A normal string`")
md = SwiftyMarkdown(string: escapedBacktickWithin)
XCTAssertEqual(md.attributedString().string, "A string with `escaped` backticks\n")
XCTAssertEqual(md.attributedString().string, "A string with `escaped` backticks")
md = SwiftyMarkdown(string: oneEscapedAsteriskOneNormalAtStart)
XCTAssertEqual(md.attributedString().string, "*A normal string*\n")
XCTAssertEqual(md.attributedString().string, "*A normal string*")
md = SwiftyMarkdown(string: oneEscapedAsteriskOneNormalWithin)
XCTAssertEqual(md.attributedString().string, "A string with *escaped* asterisks\n")
XCTAssertEqual(md.attributedString().string, "A string with *escaped* asterisks")
md = SwiftyMarkdown(string: oneEscapedAsteriskTwoNormalAtStart)
XCTAssertEqual(md.attributedString().string, "*A normal string*\n")
XCTAssertEqual(md.attributedString().string, "*A normal string*")
md = SwiftyMarkdown(string: oneEscapedAsteriskTwoNormalWithin)
XCTAssertEqual(md.attributedString().string, "A string with *escaped* asterisks\n")
XCTAssertEqual(md.attributedString().string, "A string with *escaped* asterisks")
}
func testThatAsterisksAndUnderscoresNotAttachedToWordsAreNotRemoved() {
let asteriskSpace = "An asterisk followed by a space: * "
let asteriskSpace = """
An asterisk followed by a space: *
Line break
"""
let backtickSpace = "A backtick followed by a space: ` "
let underscoreSpace = "An underscore followed by a space: _ "
@@ -187,43 +190,43 @@ class SwiftyMarkdownTests: XCTestCase {
let underscoreWithItalic = "An _italic_ word followed by an underscore _ "
var md = SwiftyMarkdown(string: asteriskSpace)
XCTAssertEqual(md.attributedString().string, asteriskSpace + "\n")
XCTAssertEqual(md.attributedString().string, asteriskSpace)
md = SwiftyMarkdown(string: backtickSpace)
XCTAssertEqual(md.attributedString().string, backtickSpace + "\n")
XCTAssertEqual(md.attributedString().string, backtickSpace)
md = SwiftyMarkdown(string: underscoreSpace)
XCTAssertEqual(md.attributedString().string, underscoreSpace + "\n")
XCTAssertEqual(md.attributedString().string, underscoreSpace)
md = SwiftyMarkdown(string: asteriskFullStop)
XCTAssertEqual(md.attributedString().string, asteriskFullStop + "\n")
XCTAssertEqual(md.attributedString().string, asteriskFullStop)
md = SwiftyMarkdown(string: backtickFullStop)
XCTAssertEqual(md.attributedString().string, backtickFullStop + "\n")
XCTAssertEqual(md.attributedString().string, backtickFullStop)
md = SwiftyMarkdown(string: underscoreFullStop)
XCTAssertEqual(md.attributedString().string, underscoreFullStop + "\n")
XCTAssertEqual(md.attributedString().string, underscoreFullStop)
md = SwiftyMarkdown(string: asteriskComma)
XCTAssertEqual(md.attributedString().string, asteriskComma + "\n")
XCTAssertEqual(md.attributedString().string, asteriskComma)
md = SwiftyMarkdown(string: backtickComma)
XCTAssertEqual(md.attributedString().string, backtickComma + "\n")
XCTAssertEqual(md.attributedString().string, backtickComma)
md = SwiftyMarkdown(string: underscoreComma)
XCTAssertEqual(md.attributedString().string, underscoreComma + "\n")
XCTAssertEqual(md.attributedString().string, underscoreComma)
md = SwiftyMarkdown(string: asteriskWithBold)
XCTAssertEqual(md.attributedString().string, "A bold word followed by an asterisk * \n")
XCTAssertEqual(md.attributedString().string, "A bold word followed by an asterisk * ")
md = SwiftyMarkdown(string: backtickWithCode)
XCTAssertEqual(md.attributedString().string, "A code word followed by a backtick ` \n")
XCTAssertEqual(md.attributedString().string, "A code word followed by a backtick ` ")
md = SwiftyMarkdown(string: underscoreWithItalic)
XCTAssertEqual(md.attributedString().string, "An italic word followed by an underscore _ \n")
XCTAssertEqual(md.attributedString().string, "An italic word followed by an underscore _ ")
}
func testForLinks() {
@@ -242,39 +245,53 @@ class SwiftyMarkdownTests: XCTestCase {
let syntaxErrorParenthesisWithin = "A [Link](http://voyagetravelapps.com/"
var md = SwiftyMarkdown(string: linkAtStart)
XCTAssertEqual(md.attributedString().string, "Link at start\n")
XCTAssertEqual(md.attributedString().string, "Link at start")
md = SwiftyMarkdown(string: linkWithin)
XCTAssertEqual(md.attributedString().string, "A Link\n")
XCTAssertEqual(md.attributedString().string, "A Link")
md = SwiftyMarkdown(string: headerLink)
XCTAssertEqual(md.attributedString().string, "Header link\n")
XCTAssertEqual(md.attributedString().string, "Header link")
md = SwiftyMarkdown(string: multipleLinks)
XCTAssertEqual(md.attributedString().string, "Link 1, Link 2\n")
XCTAssertEqual(md.attributedString().string, "Link 1, Link 2")
md = SwiftyMarkdown(string: syntaxErrorSquareBracketAtStart)
XCTAssertEqual(md.attributedString().string, "Link with missing square\n")
XCTAssertEqual(md.attributedString().string, "Link with missing square")
md = SwiftyMarkdown(string: syntaxErrorSquareBracketWithin)
XCTAssertEqual(md.attributedString().string, "A Link\n")
XCTAssertEqual(md.attributedString().string, "A Link")
md = SwiftyMarkdown(string: syntaxErrorParenthesisAtStart)
XCTAssertEqual(md.attributedString().string, "Link with missing parenthesis\n")
XCTAssertEqual(md.attributedString().string, "Link with missing parenthesis")
md = SwiftyMarkdown(string: syntaxErrorParenthesisWithin)
XCTAssertEqual(md.attributedString().string, "A Link\n")
XCTAssertEqual(md.attributedString().string, "A Link")
md = SwiftyMarkdown(string: mailtoAndTwitterLinks)
XCTAssertEqual(md.attributedString().string, "Email us at simon@voyagetravelapps.com Twitter @VoyageTravelApp\n")
XCTAssertEqual(md.attributedString().string, "Email us at simon@voyagetravelapps.com Twitter @VoyageTravelApp")
// let mailtoAndTwitterLinks = "Twitter [@VoyageTravelApp](twitter://user?screen_name=VoyageTravelApp)"
// let md = SwiftyMarkdown(string: mailtoAndTwitterLinks)
// XCTAssertEqual(md.attributedString().string, "Twitter @VoyageTravelApp\n")
// XCTAssertEqual(md.attributedString().string, "Twitter @VoyageTravelApp")
}
/*
The reason for this test is because the list of items dropped every other item in bullet lists marked with "-"
The faulty result was: "A cool title\n \n- Här har vi svenska ÅÄÖåäö tecken\n \nA Link"
As you can see, "- Point number one" and "- Point number two" are mysteriously missing.
It incorrectly identified rows as `Alt-H2`
*/
func testInternationalCharactersInList() {
let extected = "A cool title\n \n- Point number one\n- Här har vi svenska ÅÄÖåäö tecken\n- Point number two\n \nA Link"
let input = "# A cool title\n\n- Point number one\n- Här har vi svenska ÅÄÖåäö tecken\n- Point number two\n\n[A Link](http://dooer.com)"
let output = SwiftyMarkdown(string: input).attributedString().string
XCTAssertEqual(output, extected)
}
}
+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"
+66 -8
View File
@@ -1,29 +1,87 @@
fastlane documentation
================
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```
sudo gem install fastlane
xcode-select --install
```
## Choose your installation method:
<table width="100%" >
<tr>
<th width="33%"><a href="http://brew.sh">Homebrew</a></td>
<th width="33%">Installer Script</td>
<th width="33%">Rubygems</td>
</tr>
<tr>
<td width="33%" align="center">macOS</td>
<td width="33%" align="center">macOS</td>
<td width="33%" align="center">macOS or Linux with Ruby 2.0.0 or above</td>
</tr>
<tr>
<td width="33%"><code>brew cask install fastlane</code></td>
<td width="33%"><a href="https://download.fastlane.tools">Download the zip file</a>. Then double click on the <code>install</code> script (or run it in a terminal window).</td>
<td width="33%"><code>sudo gem install fastlane -NV</code></td>
</tr>
</table>
# Available Actions
## iOS
### ios patch
```
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
### ios minor
```
fastlane ios minor
```
Bumps the minor version, increments it, and pushes it to both the remote and spec repos
### ios initial
This does the following:
- Runs the unit tests
- Ensures Cocoapods compatibility
- Bumps the minor version
### ios major
```
fastlane ios initial
fastlane ios major
```
This does the following:
- Runs the unit tests
- Ensures Cocoapods compatibility
- Bumps the major version
### ios test
```
fastlane ios test
```
### ios submit_pod
```
fastlane ios submit_pod
```
Push the repo to remote and submits the Pod to the given spec repository. Do this after running update to run tests, bump versions, and commit changes.
----
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 [fastlane.tools](https://fastlane.tools).
The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).