Fixes #69
This commit is contained in:
parent
a209277d97
commit
19c473e81d
50
Gemfile.lock
50
Gemfile.lock
|
@ -63,8 +63,8 @@ GEM
|
|||
dotenv (2.7.5)
|
||||
emoji_regex (1.0.1)
|
||||
escape (0.0.4)
|
||||
excon (0.71.1)
|
||||
faraday (0.17.1)
|
||||
excon (0.72.0)
|
||||
faraday (0.17.3)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday-cookie_jar (0.0.6)
|
||||
faraday (>= 0.7.4)
|
||||
|
@ -72,7 +72,7 @@ GEM
|
|||
faraday_middleware (0.13.1)
|
||||
faraday (>= 0.7.4, < 1.0)
|
||||
fastimage (2.1.7)
|
||||
fastlane (2.138.0)
|
||||
fastlane (2.140.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
babosa (>= 1.0.2, < 2.0.0)
|
||||
|
@ -87,7 +87,7 @@ GEM
|
|||
faraday_middleware (~> 0.13.1)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-api-client (>= 0.21.2, < 0.24.0)
|
||||
google-api-client (>= 0.29.2, < 0.37.0)
|
||||
google-cloud-storage (>= 1.15.0, < 2.0.0)
|
||||
highline (>= 1.7.2, < 2.0.0)
|
||||
json (< 3.0.0)
|
||||
|
@ -112,30 +112,34 @@ GEM
|
|||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
google-api-client (0.23.9)
|
||||
google-api-client (0.36.4)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.5, < 0.7.0)
|
||||
googleauth (~> 0.9)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
mime-types (~> 3.0)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.9)
|
||||
google-cloud-core (1.4.1)
|
||||
signet (~> 0.12)
|
||||
google-cloud-core (1.5.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.3.0)
|
||||
faraday (~> 0.11)
|
||||
google-cloud-storage (1.16.0)
|
||||
google-cloud-errors (1.0.0)
|
||||
google-cloud-storage (1.25.1)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
google-api-client (~> 0.23)
|
||||
google-api-client (~> 0.33)
|
||||
google-cloud-core (~> 1.2)
|
||||
googleauth (>= 0.6.2, < 0.10.0)
|
||||
googleauth (0.6.7)
|
||||
googleauth (~> 0.9)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.10.0)
|
||||
faraday (~> 0.12)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.7)
|
||||
signet (~> 0.12)
|
||||
highline (1.7.10)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
|
@ -145,11 +149,9 @@ GEM
|
|||
json (2.3.0)
|
||||
jwt (2.1.0)
|
||||
memoist (0.16.2)
|
||||
mime-types (3.3)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2019.1009)
|
||||
mini_magick (4.9.5)
|
||||
minitest (5.13.0)
|
||||
mini_magick (4.10.1)
|
||||
mini_mime (1.0.2)
|
||||
minitest (5.14.0)
|
||||
molinillo (0.6.6)
|
||||
multi_json (1.14.1)
|
||||
multi_xml (0.6.0)
|
||||
|
@ -183,17 +185,17 @@ GEM
|
|||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
tty-cursor (0.7.0)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.7.0)
|
||||
tty-spinner (0.9.2)
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
tzinfo (1.2.5)
|
||||
tzinfo (1.2.6)
|
||||
thread_safe (~> 0.1)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.6)
|
||||
unicode-display_width (1.6.0)
|
||||
unicode-display_width (1.6.1)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.14.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
|
@ -214,4 +216,4 @@ DEPENDENCIES
|
|||
fastlane
|
||||
|
||||
BUNDLED WITH
|
||||
2.0.2
|
||||
2.1.4
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
F4CE98E61C8AF01300D735C1 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
|
||||
F4CE98E71C8AF01300D735C1 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
F4CE98E81C8AF01300D735C1 /* SwiftyMarkdown.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SwiftyMarkdown.podspec; sourceTree = "<group>"; };
|
||||
F4FEF07423E13365007219EF /* metadataTest.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = metadataTest.md; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -117,6 +118,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
F4A48ABA23A8518900713437 /* test.md */,
|
||||
F4FEF07423E13365007219EF /* metadataTest.md */,
|
||||
F4CE98901C8A921300D735C1 /* SwiftyMarkdownLineTests.swift */,
|
||||
F40D3A7E23A807F60085CF6E /* SwiftyMarkdownCharacterTests.swift */,
|
||||
F4CE98921C8A921300D735C1 /* Info.plist */,
|
||||
|
|
|
@ -38,6 +38,7 @@ public enum Remove {
|
|||
public enum ChangeApplication {
|
||||
case current
|
||||
case previous
|
||||
case untilClose
|
||||
}
|
||||
|
||||
public struct LineRule {
|
||||
|
@ -58,6 +59,7 @@ public struct LineRule {
|
|||
|
||||
public class SwiftyLineProcessor {
|
||||
|
||||
var closeToken : String? = nil
|
||||
let defaultType : LineStyling
|
||||
public var processEmptyStrings : LineStyling?
|
||||
let lineRules : [LineRule]
|
||||
|
@ -87,18 +89,12 @@ public class SwiftyLineProcessor {
|
|||
return output
|
||||
}
|
||||
|
||||
func processLineLevelAttributes( _ text : String ) -> SwiftyLine {
|
||||
func processLineLevelAttributes( _ text : String ) -> SwiftyLine? {
|
||||
if text.isEmpty, let style = processEmptyStrings {
|
||||
return SwiftyLine(line: "", lineStyle: style)
|
||||
}
|
||||
let previousLines = lineRules.filter({ $0.changeAppliesTo == .previous })
|
||||
for element in previousLines {
|
||||
let output = (element.shouldTrim) ? text.trimmingCharacters(in: .whitespaces) : text
|
||||
let charSet = CharacterSet(charactersIn: element.token )
|
||||
if output.unicodeScalars.allSatisfy({ charSet.contains($0) }) {
|
||||
return SwiftyLine(line: "", lineStyle: element.type)
|
||||
}
|
||||
}
|
||||
|
||||
for element in lineRules {
|
||||
guard element.token.count > 0 else {
|
||||
continue
|
||||
|
@ -106,6 +102,10 @@ public class SwiftyLineProcessor {
|
|||
var output : String = (element.shouldTrim) ? text.trimmingCharacters(in: .whitespaces) : text
|
||||
let unprocessed = output
|
||||
|
||||
if let hasToken = self.closeToken, unprocessed != hasToken {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch element.removeFrom {
|
||||
case .leading:
|
||||
output = findLeadingLineElement(element, in: output)
|
||||
|
@ -114,6 +114,8 @@ public class SwiftyLineProcessor {
|
|||
case .both:
|
||||
output = findLeadingLineElement(element, in: output)
|
||||
output = findTrailingLineElement(element, in: output)
|
||||
case .entireLine:
|
||||
output = findLeadingLineElement(element, in: output)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -121,11 +123,26 @@ public class SwiftyLineProcessor {
|
|||
guard unprocessed != output else {
|
||||
continue
|
||||
}
|
||||
if element.changeAppliesTo == .untilClose {
|
||||
self.closeToken = (self.closeToken == nil) ? element.token : nil
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
output = (element.shouldTrim) ? output.trimmingCharacters(in: .whitespaces) : output
|
||||
return SwiftyLine(line: output, lineStyle: element.type)
|
||||
|
||||
}
|
||||
|
||||
for element in previousLines {
|
||||
let output = (element.shouldTrim) ? text.trimmingCharacters(in: .whitespaces) : text
|
||||
let charSet = CharacterSet(charactersIn: element.token )
|
||||
if output.unicodeScalars.allSatisfy({ charSet.contains($0) }) {
|
||||
return SwiftyLine(line: "", lineStyle: element.type)
|
||||
}
|
||||
}
|
||||
|
||||
return SwiftyLine(line: text.trimmingCharacters(in: .whitespaces), lineStyle: defaultType)
|
||||
}
|
||||
|
||||
|
@ -137,8 +154,9 @@ public class SwiftyLineProcessor {
|
|||
continue
|
||||
}
|
||||
|
||||
let input : SwiftyLine
|
||||
input = processLineLevelAttributes(String(heading))
|
||||
guard let input = processLineLevelAttributes(String(heading)) else {
|
||||
continue
|
||||
}
|
||||
|
||||
if let existentPrevious = input.lineStyle.styleIfFoundStyleAffectsPreviousLine(), foundAttributes.count > 0 {
|
||||
if let idx = foundAttributes.firstIndex(of: foundAttributes.last!) {
|
||||
|
|
|
@ -140,6 +140,8 @@ extension SwiftyMarkdown {
|
|||
func color( for line : SwiftyLine ) -> UIColor {
|
||||
// What type are we and is there a font name set?
|
||||
switch line.lineStyle as! MarkdownLineStyle {
|
||||
case .yaml:
|
||||
return body.color
|
||||
case .h1, .previousH1:
|
||||
return h1.color
|
||||
case .h2, .previousH2:
|
||||
|
|
|
@ -38,7 +38,7 @@ enum MarkdownLineStyle : LineStyling {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
case yaml
|
||||
case h1
|
||||
case h2
|
||||
case h3
|
||||
|
@ -125,6 +125,7 @@ If that is not set, then the system default will be used.
|
|||
/// 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.
|
||||
@objc open class SwiftyMarkdown: NSObject {
|
||||
static public var lineRules = [
|
||||
|
||||
LineRule(token: "=", type: MarkdownLineStyle.previousH1, removeFrom: .entireLine, changeAppliesTo: .previous),
|
||||
LineRule(token: "-", type: MarkdownLineStyle.previousH2, removeFrom: .entireLine, changeAppliesTo: .previous),
|
||||
LineRule(token: " ", type: MarkdownLineStyle.codeblock, removeFrom: .leading, shouldTrim: false),
|
||||
|
@ -140,11 +141,11 @@ If that is not set, then the system default will be used.
|
|||
]
|
||||
|
||||
static public var characterRules = [
|
||||
CharacterRule(openTag: "", escapeCharacter: "\\", styles: [1 : [CharacterStyle.image]], maxTags: 1),
|
||||
// CharacterRule(openTag: "", escapeCharacter: "\\", styles: [1 : [CharacterStyle.image]], maxTags: 1),
|
||||
CharacterRule(openTag: "[", intermediateTag: "](", closingTag: ")", escapeCharacter: "\\", styles: [1 : [CharacterStyle.link]], maxTags: 1),
|
||||
CharacterRule(openTag: "`", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.code]], maxTags: 1, cancels: .allRemaining),
|
||||
// CharacterRule(openTag: "`", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.code]], maxTags: 1, cancels: .allRemaining),
|
||||
CharacterRule(openTag: "*", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3),
|
||||
CharacterRule(openTag: "_", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3)
|
||||
// CharacterRule(openTag: "_", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.italic], 2 : [CharacterStyle.bold], 3 : [CharacterStyle.bold, CharacterStyle.italic]], maxTags: 3)
|
||||
]
|
||||
|
||||
let lineProcessor = SwiftyLineProcessor(rules: SwiftyMarkdown.lineRules, defaultRule: MarkdownLineStyle.body)
|
||||
|
|
|
@ -193,6 +193,7 @@ public class SwiftyTokeniser {
|
|||
continue
|
||||
}
|
||||
if let hasReplacement = self.replacements[token.inputString] {
|
||||
os_log("Found replacement for %@", log: .tokenising, type: .info, token.inputString)
|
||||
for var repToken in hasReplacement {
|
||||
guard repToken.type == .string else {
|
||||
finalTokens.append(repToken)
|
||||
|
@ -248,10 +249,13 @@ public class SwiftyTokeniser {
|
|||
var outputTokens : [Token] = []
|
||||
let scanner = Scanner(string: stringToken.outputString)
|
||||
scanner.charactersToBeSkipped = nil
|
||||
var repTokens = replacements
|
||||
|
||||
// Remove any replacements that don't appear in the incoming string
|
||||
var repTokens = replacements.filter({ stringToken.outputString.contains($0.inputString) })
|
||||
|
||||
var testString = "\n"
|
||||
while !scanner.isAtEnd {
|
||||
var outputString : String = ""
|
||||
var testString = "\n"
|
||||
if repTokens.count > 0 {
|
||||
testString = repTokens.removeFirst().inputString
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ SwiftyMarkdown is a Swift-based *Markdown* parser that converts *Markdown* files
|
|||
|
||||
Show Images From Your App Bundle!
|
||||
---
|
||||

|
||||
 There may be a problem with [Links](https://www.neverendingvoyage.com/).
|
||||
|
||||
Customise fonts and colors easily in a Swift-like way:
|
||||
|
||||
|
|
|
@ -13,9 +13,11 @@ import XCTest
|
|||
class SwiftyMarkdownCharacterTests: XCTestCase {
|
||||
|
||||
func testIsolatedCase() {
|
||||
let challenge = TokenTest(input: "[Link1](http://voyagetravelapps.com/) test, testing another link [Link2](http://voyagetravelapps.com/)", output: "Link1 test, testing another link Link2", tokens: [
|
||||
let challenge = TokenTest(input: "[Link1](http://voyagetravelapps.com/) **bold** [Link2](http://voyagetravelapps.com/)", output: "Link1 bold Link2", tokens: [
|
||||
Token(type: .string, inputString: "Link1", characterStyles: [CharacterStyle.link]),
|
||||
Token(type: .string, inputString: " test, testing another link ", characterStyles: []),
|
||||
Token(type: .string, inputString: " ", characterStyles: []),
|
||||
Token(type: .string, inputString: "bold", characterStyles: [CharacterStyle.bold]),
|
||||
Token(type: .string, inputString: " ", characterStyles: []),
|
||||
Token(type: .string, inputString: "Link2", characterStyles: [CharacterStyle.link])
|
||||
])
|
||||
let results = self.attempt(challenge)
|
||||
|
@ -490,6 +492,19 @@ class SwiftyMarkdownCharacterTests: XCTestCase {
|
|||
XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
XCTAssertEqual(results.attributedString.string, challenge.output)
|
||||
|
||||
challenge = TokenTest(input: "[Link1](http://voyagetravelapps.com/) **bold** [Link2](http://voyagetravelapps.com/)", output: "Link1 bold Link2", tokens: [
|
||||
Token(type: .string, inputString: "Link1", characterStyles: [CharacterStyle.link]),
|
||||
Token(type: .string, inputString: " ", characterStyles: []),
|
||||
Token(type: .string, inputString: "bold", characterStyles: [CharacterStyle.bold]),
|
||||
Token(type: .string, inputString: " ", characterStyles: []),
|
||||
Token(type: .string, inputString: "Link2", characterStyles: [CharacterStyle.link])
|
||||
])
|
||||
results = self.attempt(challenge)
|
||||
XCTAssertEqual(challenge.tokens.count, results.stringTokens.count)
|
||||
XCTAssertEqual(results.tokens.map({ $0.outputString }).joined(), challenge.output)
|
||||
XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
XCTAssertEqual(results.attributedString.string, challenge.output)
|
||||
|
||||
}
|
||||
|
||||
func testLinksWithOtherStyles() {
|
||||
|
|
|
@ -139,4 +139,10 @@ class SwiftyMarkdownTests: XCTestCase {
|
|||
XCTAssertEqual(output, expected)
|
||||
}
|
||||
|
||||
func testThatYAMLMetadataIsRemoved() {
|
||||
let yaml = StringTest(input: "---\nlayout: page\ntitle: \"Trail Wallet FAQ\"\ndate: 2015-04-22 10:59\ncomments: true\nsharing: true\nliking: false\nfooter: true\nsidebar: false\n---\n# Finally some Markdown!", expectedOutput: "Finally some Markdown!")
|
||||
let md = SwiftyMarkdown(string: yaml.input)
|
||||
XCTAssertEqual(md.attributedString().string, yaml.expectedOutput)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Trail Wallet FAQ"
|
||||
date: 2015-04-22 10:59
|
||||
comments: true
|
||||
sharing: true
|
||||
liking: false
|
||||
footer: true
|
||||
sidebar: false
|
||||
---
|
||||
|
||||
# Good Day To You, Walleteer!
|
||||
|
||||
We are Erin and Simon from [Never Ending Voyage][1] and we want to thank you for trying out our app. We have been travelling non-stop for seven years and part of how we support ourselves is through Trail Wallet.
|
Loading…
Reference in New Issue