diff --git a/Notepad/Storage.swift b/Notepad/Storage.swift index cc41cf1..bfc83ba 100644 --- a/Notepad/Storage.swift +++ b/Notepad/Storage.swift @@ -126,7 +126,18 @@ public class Storage: NSTextStorage { for (style) in theme.styles { style.regex.enumerateMatches(in: backingString, options: .withoutAnchoringBounds, range: range, using: { (match, flags, stop) in guard let match = match else { return } + backingStore.addAttributes(style.attributes, range: match.range(at: 0)) + if #available(iOS 11.0, *) { + if let groups = style.groups { + for group in groups { + if let groupStyle = theme.style(withName: group) { + let range = match.range(withName: group) + backingStore.addAttributes(groupStyle.attributes, range: range) + } + } + } + } }) } } diff --git a/Notepad/Style.swift b/Notepad/Style.swift index 5288d5a..7780069 100644 --- a/Notepad/Style.swift +++ b/Notepad/Style.swift @@ -9,17 +9,23 @@ import Foundation public struct Style { + public var name: String? var regex: NSRegularExpression! public var attributes: [NSAttributedString.Key: Any] = [:] + var groups: [String]? - public init(element: Element, attributes: [NSAttributedString.Key: Any]) { + public init(element: Element, attributes: [NSAttributedString.Key: Any], groups: [String]? = nil, name: String? = nil) { + self.name = name self.regex = element.toRegex() self.attributes = attributes + self.groups = groups } - public init(regex: NSRegularExpression, attributes: [NSAttributedString.Key: Any]) { + public init(regex: NSRegularExpression, attributes: [NSAttributedString.Key: Any], groups: [String]? = nil, name: String? = nil) { + self.name = name self.regex = regex self.attributes = attributes + self.groups = groups } public init() { diff --git a/Notepad/Theme.swift b/Notepad/Theme.swift index 08b69b5..bafdc80 100644 --- a/Notepad/Theme.swift +++ b/Notepad/Theme.swift @@ -41,6 +41,9 @@ public struct Theme { /// All of the other styles for the Notepad editor. public var styles: [Style] = [] + public func style(withName name: String) -> Style? { + styles.first(where: { $0.name == name }) + } /// Build a theme from a JSON theme file. /// @@ -120,12 +123,13 @@ public struct Theme { allStyles.removeValue(forKey: "body") for (element, attributes) in allStyles { if let parsedStyles = parse(attributes as! [String : AnyObject]) { + let groups = attributes["groups"] as? [String] + if let regexString = attributes["regex"] as? String { let regex = regexString.toRegex() - styles.append(Style(regex: regex, attributes: parsedStyles)) - } - else { - styles.append(Style(element: Element.unknown.from(string: element), attributes: parsedStyles)) + styles.append(Style(regex: regex, attributes: parsedStyles, groups: groups, name: element)) + } else { + styles.append(Style(element: Element.unknown.from(string: element), attributes: parsedStyles, groups: groups, name: element)) } } } diff --git a/Notepad/themes/one-dark-custom.json b/Notepad/themes/one-dark-custom.json index 0ad20d2..85883e7 100644 --- a/Notepad/themes/one-dark-custom.json +++ b/Notepad/themes/one-dark-custom.json @@ -25,10 +25,15 @@ "size": 25 }, "h3": { + "regex": "^((?\\#{3})(.*))$", "font": "Courier-Bold", - "color": "#D36770", + "groups": ["hash"], + "color": "#FFFFFF", "size": 22 }, + "hash": { + "color": "#D36770" + }, "body": { "font": "Courier", "size": 17,