From 3510e7d8f39b7fd266b852a440aaf1d91bb49b3e Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 30 Nov 2021 12:07:54 +0100 Subject: [PATCH 1/3] Add Mark formatter --- Aztec.xcodeproj/project.pbxproj | 4 ++ .../NSAttributedStringKey+Aztec.swift | 4 ++ .../Implementations/MarkFormatter.swift | 37 +++++++++++++++++++ .../GUI/FormatBar/FormattingIdentifier.swift | 1 + Aztec/Classes/TextKit/TextView.swift | 13 ++++++- 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 Aztec/Classes/Formatters/Implementations/MarkFormatter.swift diff --git a/Aztec.xcodeproj/project.pbxproj b/Aztec.xcodeproj/project.pbxproj index fe24c3ca5..fe4bc7aa0 100644 --- a/Aztec.xcodeproj/project.pbxproj +++ b/Aztec.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 40A2986D1FD61B0C00AEDF3B /* ElementConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40A2986C1FD61B0C00AEDF3B /* ElementConverter.swift */; }; 40A298711FD61B6F00AEDF3B /* ImageElementConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40A298701FD61B6F00AEDF3B /* ImageElementConverter.swift */; }; 40A298731FD61E1900AEDF3B /* VideoElementConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40A298721FD61E1900AEDF3B /* VideoElementConverter.swift */; }; + 568FF25827552BFF0057B2E3 /* MarkFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568FF25727552BFF0057B2E3 /* MarkFormatter.swift */; }; 594C9D6F1D8BE61F00D74542 /* Aztec.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5951CB8E1D8BC93600E1866F /* Aztec.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 594C9D731D8BE6C300D74542 /* InAttributeConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59FEA06B1D8BDFA700D138DF /* InAttributeConverterTests.swift */; }; 594C9D741D8BE6C700D74542 /* InNodeConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59FEA06D1D8BDFA700D138DF /* InNodeConverterTests.swift */; }; @@ -287,6 +288,7 @@ 40A298701FD61B6F00AEDF3B /* ImageElementConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageElementConverter.swift; sourceTree = ""; }; 40A298721FD61E1900AEDF3B /* VideoElementConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoElementConverter.swift; sourceTree = ""; }; 50A1CC6E250FEA93001D5517 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; + 568FF25727552BFF0057B2E3 /* MarkFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkFormatter.swift; sourceTree = ""; }; 5951CB8E1D8BC93600E1866F /* Aztec.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Aztec.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5951CB921D8BC93600E1866F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5951CB971D8BC93600E1866F /* AztecTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AztecTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1013,6 +1015,7 @@ FF949363245744560085ABB3 /* SubscriptFormatter.swift */, FF61909D202481F4004BCD0A /* CodeFormatter.swift */, FFB5D29620BEB21A0038DCFB /* CiteFormatter.swift */, + 568FF25727552BFF0057B2E3 /* MarkFormatter.swift */, ); path = Implementations; sourceTree = ""; @@ -1696,6 +1699,7 @@ F1079D67208F80FE009717FA /* EditorView.swift in Sources */, F15A8B6520BED08900C57ED2 /* ParagraphPropertyConverter.swift in Sources */, F1D7F525221CE2D20065555D /* HTMLStyleToggler.swift in Sources */, + 568FF25827552BFF0057B2E3 /* MarkFormatter.swift in Sources */, F1FA0E811E6EF514009D98EE /* Attribute.swift in Sources */, F16A2ADD20CC503F00BF3A0A /* VideoAttachmentToElementConverter.swift in Sources */, ); diff --git a/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift b/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift index d426bc5e2..9427faa61 100644 --- a/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift +++ b/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift @@ -61,4 +61,8 @@ public extension NSAttributedString.Key { /// Key used to store Sub Tag Metadata, by our SupFormatter. /// static let subHtmlRepresentation = NSAttributedString.Key("Sub.htmlRepresentation") + + /// Key used to store Mark Tag Metadata, by our MarkFormatter. + /// + static let markHtmlRepresentation = NSAttributedString.Key("Mark.htmlRepresentation") } diff --git a/Aztec/Classes/Formatters/Implementations/MarkFormatter.swift b/Aztec/Classes/Formatters/Implementations/MarkFormatter.swift new file mode 100644 index 000000000..b6e411b17 --- /dev/null +++ b/Aztec/Classes/Formatters/Implementations/MarkFormatter.swift @@ -0,0 +1,37 @@ +import Foundation +import UIKit + +class MarkFormatter: AttributeFormatter { + + var placeholderAttributes: [NSAttributedString.Key: Any]? + + func applicationRange(for range: NSRange, in text: NSAttributedString) -> NSRange { + return range + } + + func apply(to attributes: [NSAttributedString.Key: Any], andStore representation: HTMLRepresentation?) -> [NSAttributedString.Key: Any] { + var resultingAttributes = attributes + + var representationToUse = HTMLRepresentation(for: .element(HTMLElementRepresentation.init(name: "mark", attributes: []))) + if let requestedRepresentation = representation { + representationToUse = requestedRepresentation + } + resultingAttributes[.markHtmlRepresentation] = representationToUse + + return resultingAttributes + } + + func remove(from attributes: [NSAttributedString.Key: Any]) -> [NSAttributedString.Key: Any] { + var resultingAttributes = attributes + + resultingAttributes.removeValue(forKey: .markHtmlRepresentation) + + return resultingAttributes + } + + func present(in attributes: [NSAttributedString.Key: Any]) -> Bool { + return attributes[NSAttributedString.Key.markHtmlRepresentation] != nil + } +} + + diff --git a/Aztec/Classes/GUI/FormatBar/FormattingIdentifier.swift b/Aztec/Classes/GUI/FormatBar/FormattingIdentifier.swift index a662c9fc6..8856c0ae4 100644 --- a/Aztec/Classes/GUI/FormatBar/FormattingIdentifier.swift +++ b/Aztec/Classes/GUI/FormatBar/FormattingIdentifier.swift @@ -36,4 +36,5 @@ extension FormattingIdentifier { public static let strikethrough = FormattingIdentifier("strikethrough") public static let underline = FormattingIdentifier("underline") public static let unorderedlist = FormattingIdentifier("unorderedlist") + public static let mark = FormattingIdentifier("mark") } diff --git a/Aztec/Classes/TextKit/TextView.swift b/Aztec/Classes/TextKit/TextView.swift index 377f0e9c5..0f5fdf41a 100644 --- a/Aztec/Classes/TextKit/TextView.swift +++ b/Aztec/Classes/TextKit/TextView.swift @@ -853,7 +853,8 @@ open class TextView: UITextView { .header5: HeaderFormatter(headerLevel: .h5), .header6: HeaderFormatter(headerLevel: .h6), .p: HTMLParagraphFormatter(), - .code: CodeFormatter() + .code: CodeFormatter(), + .mark: MarkFormatter() ] /// Get a list of format identifiers spanning the specified range as a String array. @@ -1136,6 +1137,16 @@ open class TextView: UITextView { toggle(formatter: formatter, atRange: range) forceRedrawCursorAfterDelay() } + + /// Adds or removes a mark style from the specified range. + /// + /// - Parameter range: The NSRange to edit. + /// + open func toggleMark(range: NSRange) { + let formatter = MarkFormatter() + formatter.placeholderAttributes = self.defaultAttributes + toggle(formatter: formatter, atRange: range) + } /// Replaces with an horizontal ruler on the specified range /// From 0e292aee193ca7a1cc029b126019a0513c82dae5 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 30 Nov 2021 12:20:03 +0100 Subject: [PATCH 2/3] Fix lint whitespace issues --- Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift | 2 +- Aztec/Classes/Formatters/Implementations/MarkFormatter.swift | 2 -- Aztec/Classes/TextKit/TextView.swift | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift b/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift index 9427faa61..54d1a6763 100644 --- a/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift +++ b/Aztec/Classes/Extensions/NSAttributedStringKey+Aztec.swift @@ -61,7 +61,7 @@ public extension NSAttributedString.Key { /// Key used to store Sub Tag Metadata, by our SupFormatter. /// static let subHtmlRepresentation = NSAttributedString.Key("Sub.htmlRepresentation") - + /// Key used to store Mark Tag Metadata, by our MarkFormatter. /// static let markHtmlRepresentation = NSAttributedString.Key("Mark.htmlRepresentation") diff --git a/Aztec/Classes/Formatters/Implementations/MarkFormatter.swift b/Aztec/Classes/Formatters/Implementations/MarkFormatter.swift index b6e411b17..61da0a621 100644 --- a/Aztec/Classes/Formatters/Implementations/MarkFormatter.swift +++ b/Aztec/Classes/Formatters/Implementations/MarkFormatter.swift @@ -33,5 +33,3 @@ class MarkFormatter: AttributeFormatter { return attributes[NSAttributedString.Key.markHtmlRepresentation] != nil } } - - diff --git a/Aztec/Classes/TextKit/TextView.swift b/Aztec/Classes/TextKit/TextView.swift index 0f5fdf41a..7d94b6156 100644 --- a/Aztec/Classes/TextKit/TextView.swift +++ b/Aztec/Classes/TextKit/TextView.swift @@ -1137,7 +1137,7 @@ open class TextView: UITextView { toggle(formatter: formatter, atRange: range) forceRedrawCursorAfterDelay() } - + /// Adds or removes a mark style from the specified range. /// /// - Parameter range: The NSRange to edit. @@ -1971,7 +1971,7 @@ private extension TextView { /// Removes all paragraph formatting from the typingAttributes and from the selected range. /// private func removeParagraphFormatting() { - for formatter in paragraphFormatters { + for formatter in paragraphFormatters { typingAttributes = formatter.remove(from: typingAttributes) formatter.removeAttributes(from: storage, at: selectedRange) } From 60cbbd879bd3572c1ad008c366dd2590a9444f58 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Tue, 30 Nov 2021 12:21:55 +0100 Subject: [PATCH 3/3] Fix lint issue --- Aztec/Classes/TextKit/TextView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aztec/Classes/TextKit/TextView.swift b/Aztec/Classes/TextKit/TextView.swift index 7d94b6156..186429c92 100644 --- a/Aztec/Classes/TextKit/TextView.swift +++ b/Aztec/Classes/TextKit/TextView.swift @@ -1971,7 +1971,7 @@ private extension TextView { /// Removes all paragraph formatting from the typingAttributes and from the selected range. /// private func removeParagraphFormatting() { - for formatter in paragraphFormatters { + for formatter in paragraphFormatters { typingAttributes = formatter.remove(from: typingAttributes) formatter.removeAttributes(from: storage, at: selectedRange) }