Updates readme
This commit is contained in:
parent
4e2f5c234e
commit
79467395b5
53
README.md
53
README.md
|
@ -92,6 +92,12 @@ label.attributedText = md.attributedString()
|
|||
[Links](http://voyagetravelapps.com/)
|
||||

|
||||
|
||||
[Referenced Links][1]
|
||||
![Referenced Images][2]
|
||||
|
||||
[1]: http://voyagetravelapps.com/
|
||||
[2]: <Name of asset in bundle>
|
||||
|
||||
> Blockquotes
|
||||
|
||||
- Bulleted
|
||||
|
@ -292,13 +298,46 @@ enum CharacterStyle : CharacterStyling {
|
|||
}
|
||||
|
||||
static public var characterRules = [
|
||||
CharacterRule(openTag: "[", intermediateTag: "](", closingTag: ")", escapeCharacter: "\\", styles: [1 : [CharacterStyle.link]], maxTags: 1),
|
||||
CharacterRule(openTag: "`", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.code]], maxTags: 1),
|
||||
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(primaryTag: CharacterRuleTag(tag: "[", type: .open), otherTags: [
|
||||
CharacterRuleTag(tag: "]", type: .close),
|
||||
CharacterRuleTag(tag: "[", type: .metadataOpen),
|
||||
CharacterRuleTag(tag: "]", type: .metadataClose)
|
||||
], styles: [1 : CharacterStyle.link], metadataLookup: true, definesBoundary: true),
|
||||
CharacterRule(primaryTag: CharacterRuleTag(tag: "`", type: .repeating), otherTags: [], styles: [1 : CharacterStyle.code], shouldCancelRemainingTags: true, balancedTags: true),
|
||||
CharacterRule(primaryTag: CharacterRuleTag(tag: "*", type: .repeating), otherTags: [], styles: [1 : CharacterStyle.italic, 2 : CharacterStyle.bold], minTags:1 , maxTags:2),
|
||||
CharacterRule(primaryTag: CharacterRuleTag(tag: "_", type: .repeating), otherTags: [], styles: [1 : CharacterStyle.italic, 2 : CharacterStyle.bold], minTags:1 , maxTags:2)
|
||||
]
|
||||
```
|
||||
|
||||
These Character Rules are defined by SwiftyMarkdown:
|
||||
|
||||
public struct CharacterRule : CustomStringConvertible {
|
||||
|
||||
public let primaryTag : CharacterRuleTag
|
||||
public let tags : [CharacterRuleTag]
|
||||
public let escapeCharacters : [Character]
|
||||
public let styles : [Int : CharacterStyling]
|
||||
public let minTags : Int
|
||||
public let maxTags : Int
|
||||
public var metadataLookup : Bool = false
|
||||
public var definesBoundary = false
|
||||
public var shouldCancelRemainingRules = false
|
||||
public var balancedTags = false
|
||||
}
|
||||
|
||||
1. `primaryTag`: Each rule must have at least one tag and it can be one of `repeating`, `open`, `close`, `metadataOpen`, or `metadataClose`. `repeating` tags are tags that have identical open and close characters (and often have more than 1 style depending on how many are in a group). For example, the `*` tag used in Markdown.
|
||||
2. `tags`: An array of other tags that the rule can look for. This is where you would put the `close` tag for a custom rule, for example.
|
||||
3. `escapeCharacters`: The characters that appear prior to any of the tag characters that tell the scanner to ignore the tag.
|
||||
4. `styles`: The styles that should be applied to every character between the opening and closing tags.
|
||||
5. `minTags`: The minimum number of repeating characters to be considered a successful match. For example, setting the `primaryTag` to `*` and the `minTag` to 2 would mean that `**foo**` would be a successful match wheras `*bar*` would not.
|
||||
6. `maxTags`: The maximum number of repeating characters to be considered a successful match.
|
||||
7. `metadataLookup`: Used for Markdown reference links. Tells the scanner to try to look up the metadata from this dictionary, rather than from the inline result.
|
||||
8. `definesBoundary`: In order for open and close tags to be successful, the `boundaryCount` for a given location in the string needs to be the same. Setting this property to `true` means that this rule will increase the `boundaryCount` for every character between its opening and closing tags. For example, the `[` rule defines a boundary. After it is applied, the string `*foo[bar*]` becomes `*foobar*` with a boundaryCount `00001111`. Applying the `*` rule results in the output `*foobar*` because the opening `*` tag and the closing `*` tag now have different `boundaryCount` values. It's basically a way to fix the `**[should not be bold**](url)` problem in Markdown.
|
||||
9. `shouldCancelRemainingTags`: A successful match will mark every character between the opening and closing tags as complete, thereby preventing any further rules from being applied to those characters.
|
||||
10. `balancedTags`: This flag requires that the opening and closing tags be of exactly equal length. E.g. If this is set to true, `**foo*` would result in `**foo*`. If it was false, the output would be `*foo`.
|
||||
|
||||
|
||||
|
||||
#### Rule Subsets
|
||||
|
||||
If you want to only support a small subset of Markdown, it's now easy to do.
|
||||
|
@ -308,8 +347,8 @@ This example would only process strings with `*` and `_` characters, ignoring li
|
|||
SwiftyMarkdown.lineRules = []
|
||||
|
||||
SwiftyMarkdown.characterRules = [
|
||||
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(primaryTag: CharacterRuleTag(tag: "*", type: .repeating), otherTags: [], styles: [1 : CharacterStyle.italic, 2 : CharacterStyle.bold], minTags:1 , maxTags:2),
|
||||
CharacterRule(primaryTag: CharacterRuleTag(tag: "_", type: .repeating), otherTags: [], styles: [1 : CharacterStyle.italic, 2 : CharacterStyle.bold], minTags:1 , maxTags:2)
|
||||
]
|
||||
```
|
||||
|
||||
|
@ -330,7 +369,7 @@ enum Characters : CharacterStyling {
|
|||
}
|
||||
|
||||
let characterRules = [
|
||||
CharacterRule(openTag: "%", intermediateTag: nil, closingTag: nil, escapeCharacter: "\\", styles: [1 : [CharacterStyle.elf]], maxTags: 1)
|
||||
CharacterRule(primaryTag: CharacterRuleTag(tag: "%", type: .repeating), otherTags: [], styles: [1 : CharacterStyle.elf])
|
||||
]
|
||||
|
||||
let processor = SwiftyTokeniser( with : characterRules )
|
||||
|
|
|
@ -53,27 +53,25 @@ public struct CharacterRule : CustomStringConvertible {
|
|||
return self.primaryTag.type == .repeating
|
||||
}
|
||||
public var definesBoundary = false
|
||||
public var shouldCancelRemainingTags = false
|
||||
public var shouldCancelRemainingRules = false
|
||||
public var balancedTags = false
|
||||
|
||||
public var description: String {
|
||||
return "Character Rule with Open tag: \(self.primaryTag.tag) and current styles : \(self.styles) "
|
||||
}
|
||||
|
||||
|
||||
|
||||
public func tag( for type : CharacterRuleTagType ) -> CharacterRuleTag? {
|
||||
return self.tags.filter({ $0.type == type }).first ?? nil
|
||||
}
|
||||
|
||||
public init(primaryTag: CharacterRuleTag, otherTags: [CharacterRuleTag], escapeCharacters : [Character] = ["\\"], styles: [Int : CharacterStyling] = [:], minTags : Int = 1, maxTags : Int = 1, metadataLookup : Bool = false, definesBoundary : Bool = false, shouldCancelRemainingTags : Bool = false, balancedTags : Bool = false) {
|
||||
public init(primaryTag: CharacterRuleTag, otherTags: [CharacterRuleTag], escapeCharacters : [Character] = ["\\"], styles: [Int : CharacterStyling] = [:], minTags : Int = 1, maxTags : Int = 1, metadataLookup : Bool = false, definesBoundary : Bool = false, shouldCancelRemainingRules : Bool = false, balancedTags : Bool = false) {
|
||||
self.primaryTag = primaryTag
|
||||
self.tags = otherTags
|
||||
self.escapeCharacters = escapeCharacters
|
||||
self.styles = styles
|
||||
self.metadataLookup = metadataLookup
|
||||
self.definesBoundary = definesBoundary
|
||||
self.shouldCancelRemainingTags = shouldCancelRemainingTags
|
||||
self.shouldCancelRemainingRules = shouldCancelRemainingRules
|
||||
self.minTags = maxTags < minTags ? maxTags : minTags
|
||||
self.maxTags = minTags > maxTags ? minTags : maxTags
|
||||
self.balancedTags = balancedTags
|
||||
|
|
|
@ -168,6 +168,11 @@ If that is not set, then the system default will be used.
|
|||
]
|
||||
|
||||
static public var characterRules = [
|
||||
CharacterRule(primaryTag: CharacterRuleTag(tag: "![", type: .open), otherTags: [
|
||||
CharacterRuleTag(tag: "]", type: .close),
|
||||
CharacterRuleTag(tag: "[", type: .metadataOpen),
|
||||
CharacterRuleTag(tag: "]", type: .metadataClose)
|
||||
], styles: [1 : CharacterStyle.image], metadataLookup: true, definesBoundary: true),
|
||||
CharacterRule(primaryTag: CharacterRuleTag(tag: "![", type: .open), otherTags: [
|
||||
CharacterRuleTag(tag: "]", type: .close),
|
||||
CharacterRuleTag(tag: "(", type: .metadataOpen),
|
||||
|
|
|
@ -42,15 +42,19 @@ class SwiftyScannerNonRepeating {
|
|||
let metadata : [String : String]
|
||||
var pointer : Int = 0
|
||||
|
||||
var spaceAndNewLine = CharacterSet.whitespacesAndNewlines
|
||||
var tagGroups : [TagGroup] = []
|
||||
|
||||
var isMetadataOpen = false
|
||||
|
||||
|
||||
var enableLog = (ProcessInfo.processInfo.environment["SwiftyScannerScanner"] != nil)
|
||||
|
||||
let currentPerfomanceLog = PerformanceLog(with: "SwiftyScannerScannerPerformanceLogging", identifier: "Scanner", log: OSLog.swiftyScannerPerformance)
|
||||
let log = PerformanceLog(with: "SwiftyScannerScanner", identifier: "Scanner", log: OSLog.swiftyScannerScanner)
|
||||
|
||||
|
||||
|
||||
enum Position {
|
||||
case forward(Int)
|
||||
case backward(Int)
|
||||
|
@ -278,7 +282,7 @@ class SwiftyScannerNonRepeating {
|
|||
if self.rule.definesBoundary {
|
||||
self.elements[idx].boundaryCount += 1
|
||||
}
|
||||
if self.rule.shouldCancelRemainingTags {
|
||||
if self.rule.shouldCancelRemainingRules {
|
||||
self.elements[idx].boundaryCount = 1000
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +307,7 @@ class SwiftyScannerNonRepeating {
|
|||
if shouldRemove {
|
||||
self.tagGroups.removeAll(where: { $0.groupID == id })
|
||||
}
|
||||
self.isMetadataOpen = false
|
||||
}
|
||||
|
||||
func emptyRanges( _ ranges : inout [ClosedRange<Int>] ) {
|
||||
|
@ -423,11 +428,6 @@ class SwiftyScannerNonRepeating {
|
|||
}
|
||||
}
|
||||
|
||||
var spaceAndNewLine = CharacterSet.whitespacesAndNewlines
|
||||
|
||||
|
||||
|
||||
|
||||
func scanRepeatingTags() {
|
||||
|
||||
var groupID = ""
|
||||
|
@ -485,9 +485,6 @@ class SwiftyScannerNonRepeating {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if !validTagGroup {
|
||||
if self.enableLog {
|
||||
os_log("Tag has whitespace on both sides", log: .swiftyScannerScanner, type: .info)
|
||||
|
@ -497,7 +494,6 @@ class SwiftyScannerNonRepeating {
|
|||
}
|
||||
|
||||
if let idx = tagGroups.firstIndex(where: { $0.groupID == groupID }) {
|
||||
|
||||
if tagType == .either {
|
||||
if tagGroups[idx].count == count {
|
||||
self.tagGroups[idx].tagRanges.append(openRange)
|
||||
|
@ -518,9 +514,6 @@ class SwiftyScannerNonRepeating {
|
|||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
var tagGroup = TagGroup(tagRanges: [openRange])
|
||||
groupID = tagGroup.groupID
|
||||
|
@ -528,7 +521,7 @@ class SwiftyScannerNonRepeating {
|
|||
tagGroup.count = count
|
||||
|
||||
if self.enableLog {
|
||||
os_log("New open tag found. Starting new Group with ID %@", log: OSLog.swiftyScannerScanner, type:.info , groupID)
|
||||
os_log("New open tag found with characters %@. Starting new Group with ID %@", log: OSLog.swiftyScannerScanner, type:.info, self.elements[openRange].map( { String($0.character) }).joined(), groupID)
|
||||
}
|
||||
|
||||
self.tagGroups.append(tagGroup)
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
<EnvironmentVariable
|
||||
key = "SwiftyScannerScanner"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
isEnabled = "NO">
|
||||
</EnvironmentVariable>
|
||||
<EnvironmentVariable
|
||||
key = "SwiftyScannerScannerPerformanceLogging"
|
||||
|
|
|
@ -11,12 +11,14 @@ import XCTest
|
|||
|
||||
class SwiftyMarkdownStylingTests: SwiftyMarkdownCharacterTests {
|
||||
|
||||
func testIsolatedCase() {
|
||||
|
||||
challenge = TokenTest(input: "a ```b`", output: "a ```b`", tokens : [
|
||||
Token(type: .string, inputString: "a ```b`", characterStyles: [])
|
||||
func off_testIsolatedCase() {
|
||||
|
||||
challenge = TokenTest(input: "*\\***\\****b*\\***\\****\\", output: "***b***\\", tokens : [
|
||||
Token(type: .string, inputString: "*", characterStyles: [CharacterStyle.italic]),
|
||||
Token(type: .string, inputString: "*b**", characterStyles: [CharacterStyle.bold, CharacterStyle.italic]),
|
||||
Token(type: .string, inputString: "\\", characterStyles: [])
|
||||
])
|
||||
results = self.attempt(challenge, rules: [.backticks])
|
||||
results = self.attempt(challenge)
|
||||
if results.stringTokens.count == challenge.tokens.count {
|
||||
for (idx, token) in results.stringTokens.enumerated() {
|
||||
XCTAssertEqual(token.inputString, challenge.tokens[idx].inputString)
|
||||
|
@ -508,12 +510,10 @@ class SwiftyMarkdownStylingTests: SwiftyMarkdownCharacterTests {
|
|||
}
|
||||
|
||||
func testForExtremeEscapeCombinations() {
|
||||
challenge = TokenTest(input: "Before *\\***\\****A bold string*\\***\\****\\ After", output: "Before ***A bold string***\\ After", tokens : [
|
||||
Token(type: .string, inputString: "Before ", characterStyles: []),
|
||||
Token(type: .string, inputString: "*", characterStyles: [CharacterStyle.italic]),
|
||||
Token(type: .string, inputString: "**", characterStyles: [CharacterStyle.bold]),
|
||||
Token(type: .string, inputString: "A bold string**", characterStyles: [CharacterStyle.bold, CharacterStyle.italic]),
|
||||
Token(type: .string, inputString: "\\ After", characterStyles: [])
|
||||
|
||||
challenge = TokenTest(input: "\\****b\\****", output: "*b*", tokens : [
|
||||
Token(type: .string, inputString: "*", characterStyles: []),
|
||||
Token(type: .string, inputString: "b*", characterStyles: [CharacterStyle.bold, CharacterStyle.italic])
|
||||
])
|
||||
results = self.attempt(challenge)
|
||||
if results.stringTokens.count == challenge.tokens.count {
|
||||
|
@ -526,6 +526,42 @@ class SwiftyMarkdownStylingTests: SwiftyMarkdownCharacterTests {
|
|||
}
|
||||
XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
XCTAssertEqual(results.attributedString.string, challenge.output)
|
||||
|
||||
challenge = TokenTest(input: "**\\**b*\\***", output: "*b*", tokens : [
|
||||
Token(type: .string, inputString: "*", characterStyles: [CharacterStyle.bold]),
|
||||
Token(type: .string, inputString: "b", characterStyles: [CharacterStyle.italic, CharacterStyle.bold]),
|
||||
Token(type: .string, inputString: "*", characterStyles: [CharacterStyle.bold]),
|
||||
])
|
||||
results = self.attempt(challenge)
|
||||
if results.stringTokens.count == challenge.tokens.count {
|
||||
for (idx, token) in results.stringTokens.enumerated() {
|
||||
XCTAssertEqual(token.inputString, challenge.tokens[idx].inputString)
|
||||
XCTAssertEqual(token.characterStyles as? [CharacterStyle], challenge.tokens[idx].characterStyles as? [CharacterStyle])
|
||||
}
|
||||
} else {
|
||||
XCTAssertEqual(results.stringTokens.count, challenge.tokens.count)
|
||||
}
|
||||
XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
XCTAssertEqual(results.attributedString.string, challenge.output)
|
||||
|
||||
// challenge = TokenTest(input: "Before *\\***\\****A bold string*\\***\\****\\ After", output: "Before ***A bold string***\\ After", tokens : [
|
||||
// Token(type: .string, inputString: "Before ", characterStyles: []),
|
||||
// Token(type: .string, inputString: "*", characterStyles: [CharacterStyle.italic]),
|
||||
// Token(type: .string, inputString: "**", characterStyles: [CharacterStyle.bold]),
|
||||
// Token(type: .string, inputString: "A bold string**", characterStyles: [CharacterStyle.bold, CharacterStyle.italic]),
|
||||
// Token(type: .string, inputString: "\\ After", characterStyles: [])
|
||||
// ])
|
||||
// results = self.attempt(challenge)
|
||||
// if results.stringTokens.count == challenge.tokens.count {
|
||||
// for (idx, token) in results.stringTokens.enumerated() {
|
||||
// XCTAssertEqual(token.inputString, challenge.tokens[idx].inputString)
|
||||
// XCTAssertEqual(token.characterStyles as? [CharacterStyle], challenge.tokens[idx].characterStyles as? [CharacterStyle])
|
||||
// }
|
||||
// } else {
|
||||
// XCTAssertEqual(results.stringTokens.count, challenge.tokens.count)
|
||||
// }
|
||||
// XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
// XCTAssertEqual(results.attributedString.string, challenge.output)
|
||||
}
|
||||
|
||||
func testThatExtraCharactersAreHandles() {
|
||||
|
|
|
@ -585,11 +585,10 @@ class SwiftyMarkdownLinkTests: SwiftyMarkdownCharacterTests {
|
|||
}
|
||||
XCTAssertEqual(results.attributedString.string, challenge.output)
|
||||
XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
var links = results.tokens.filter({ $0.type == .string && (($0.characterStyles as? [CharacterStyle])?.contains(.image) ?? false) })
|
||||
if links.count == 1 {
|
||||
XCTAssertEqual(links[0].metadataStrings.first, "imageName")
|
||||
if results.images.count == 1 {
|
||||
XCTAssertEqual(results.images[0].metadataStrings.first, "imageName")
|
||||
} else {
|
||||
XCTFail("Incorrect link count. Expecting 1, found \(links.count)")
|
||||
XCTFail("Incorrect link count. Expecting 1, found \(results.images.count)")
|
||||
}
|
||||
|
||||
challenge = TokenTest(input: "An [](https://www.neverendingvoyage.com/)", output: "An ", tokens: [
|
||||
|
@ -607,17 +606,37 @@ class SwiftyMarkdownLinkTests: SwiftyMarkdownCharacterTests {
|
|||
}
|
||||
XCTAssertEqual(results.attributedString.string, challenge.output)
|
||||
XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
links = results.tokens.filter({ $0.type == .string && (($0.characterStyles as? [CharacterStyle])?.contains(.image) ?? false) })
|
||||
if links.count == 1 {
|
||||
XCTAssertEqual(links[0].metadataStrings.first, "imageName")
|
||||
if results.images.count == 1 {
|
||||
XCTAssertEqual(results.images[0].metadataStrings.first, "imageName")
|
||||
} else {
|
||||
XCTFail("Incorrect link count. Expecting 1, found \(links.count)")
|
||||
XCTFail("Incorrect link count. Expecting 1, found \(results.images.count)")
|
||||
}
|
||||
links = results.tokens.filter({ $0.type == .string && (($0.characterStyles as? [CharacterStyle])?.contains(.link) ?? false) })
|
||||
if links.count == 1 {
|
||||
XCTAssertEqual(links[0].metadataStrings.last, "https://www.neverendingvoyage.com/")
|
||||
if results.links.count == 1 {
|
||||
XCTAssertEqual(results.links[0].metadataStrings.last, "https://www.neverendingvoyage.com/")
|
||||
} else {
|
||||
XCTFail("Incorrect link count. Expecting 1, found \(links.count)")
|
||||
XCTFail("Incorrect link count. Expecting 1, found \(results.links.count)")
|
||||
}
|
||||
}
|
||||
|
||||
func testForReferencedImages() {
|
||||
challenge = TokenTest(input: "A ![referenced image][image]\n[image]: imageName", output: "A ", tokens: [
|
||||
Token(type: .string, inputString: "A ", characterStyles: []),
|
||||
Token(type: .string, inputString: "referenced image", characterStyles: [CharacterStyle.image])
|
||||
])
|
||||
results = self.attempt(challenge)
|
||||
if results.stringTokens.count == challenge.tokens.count {
|
||||
for (idx, token) in results.stringTokens.enumerated() {
|
||||
XCTAssertEqual(token.inputString, challenge.tokens[idx].inputString)
|
||||
XCTAssertEqual(token.characterStyles as? [CharacterStyle], challenge.tokens[idx].characterStyles as? [CharacterStyle])
|
||||
}
|
||||
} else {
|
||||
XCTAssertEqual(results.stringTokens.count, challenge.tokens.count)
|
||||
}
|
||||
XCTAssertEqual(results.foundStyles, results.expectedStyles)
|
||||
if results.images.count == 1 {
|
||||
XCTAssertEqual(results.images[0].metadataStrings.first, "imageName")
|
||||
} else {
|
||||
XCTFail("Incorrect link count. Expecting 1, found \(results.links.count)")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ struct ChallengeReturn {
|
|||
let tokens : [Token]
|
||||
let stringTokens : [Token]
|
||||
let links : [Token]
|
||||
let images : [Token]
|
||||
let attributedString : NSAttributedString
|
||||
let foundStyles : [[CharacterStyle]]
|
||||
let expectedStyles : [[CharacterStyle]]
|
||||
|
@ -26,7 +27,8 @@ enum Rule {
|
|||
case images
|
||||
case links
|
||||
case referencedLinks
|
||||
case strikethroughs
|
||||
case referencedImages
|
||||
case tildes
|
||||
|
||||
func asCharacterRule() -> CharacterRule {
|
||||
switch self {
|
||||
|
@ -36,14 +38,16 @@ enum Rule {
|
|||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "[" && !$0.metadataLookup }).first!
|
||||
case .backticks:
|
||||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "`" }).first!
|
||||
case .strikethroughs:
|
||||
case .tildes:
|
||||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "~" }).first!
|
||||
case .asterisks:
|
||||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "*" }).first!
|
||||
case .underscores:
|
||||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "_" }).first!
|
||||
case .referencedLinks:
|
||||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "[" && $0.metadataLookup }).first!
|
||||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "[" && $0.metadataLookup }).first!
|
||||
case .referencedImages:
|
||||
return SwiftyMarkdown.characterRules.filter({ $0.primaryTag.tag == "![" && $0.metadataLookup }).first!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,8 +75,9 @@ class SwiftyMarkdownCharacterTests : XCTestCase {
|
|||
let expectedStyles = challenge.tokens.compactMap({ $0.characterStyles as? [CharacterStyle] })
|
||||
|
||||
let linkTokens = tokens.filter({ $0.type == .string && (($0.characterStyles as? [CharacterStyle])?.contains(.link) ?? false) })
|
||||
let imageTokens = tokens.filter({ $0.type == .string && (($0.characterStyles as? [CharacterStyle])?.contains(.image) ?? false) })
|
||||
|
||||
return ChallengeReturn(tokens: tokens, stringTokens: stringTokens, links : linkTokens, attributedString: attributedString, foundStyles: existentTokenStyles, expectedStyles : expectedStyles)
|
||||
return ChallengeReturn(tokens: tokens, stringTokens: stringTokens, links : linkTokens, images: imageTokens, attributedString: attributedString, foundStyles: existentTokenStyles, expectedStyles : expectedStyles)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue