diff --git a/Modules/Sources/WordPressKitModels/NSString+Summary.swift b/Modules/Sources/WordPressKitModels/NSString+Summary.swift index 2a2696f56e2f..ab7cfd6a3690 100644 --- a/Modules/Sources/WordPressKitModels/NSString+Summary.swift +++ b/Modules/Sources/WordPressKitModels/NSString+Summary.swift @@ -5,76 +5,19 @@ import WordPressShared /// and convert HTML into plain text. /// extension NSString { - - static let PostDerivedSummaryLength = 150 - /// Create a summary for the post based on the post's content. /// /// - Returns: A summary for the post. /// @objc public func wpkit_summarized() -> String { - let characterSet = CharacterSet(charactersIn: "\n") - - return (self as String).strippingGutenbergContentForExcerpt() - .strippingShortcodes() - .makePlainText() - .trimmingCharacters(in: characterSet) - .wp_stringByEllipsizing(withMaxLength: NSString.PostDerivedSummaryLength, preserveWords: true) + GutenbergExcerptGenerator.firstParagraph(from: (self as String)) } -} -private extension String { - func makePlainText() -> String { - let characterSet = NSCharacterSet.whitespacesAndNewlines - - return self.strippingHTML() + @objc + public func wpkit_makePlainText() -> String { + self.strippingHTML() .stringByDecodingXMLCharacters() - .trimmingCharacters(in: characterSet) - } - - /// Creates a new string by stripping all shortcodes from this string. - /// - func strippingShortcodes() -> String { - let pattern = "\\[[^\\]]+\\]" - - return removingMatches(pattern: pattern, options: .caseInsensitive) - } - - /// This method is the main entry point to generate excerpts for Gutenberg content. - /// - func strippingGutenbergContentForExcerpt() -> String { - return strippingGutenbergGalleries().strippingGutenbergVideoPress() - } - - /// Strips Gutenberg galleries from strings. - /// - func strippingGutenbergGalleries() -> String { - let pattern = "(?s)" - - return removingMatches(pattern: pattern, options: .caseInsensitive) - } - - /// Strips VideoPress references from Gutenberg VideoPress and Video blocks. - /// - func strippingGutenbergVideoPress() -> String { - let pattern = "(?s)\n?" - - return removingMatches(pattern: pattern, options: .caseInsensitive) - } - - /// Creates a new string by removing all matches of the specified regex. - /// - func removingMatches(pattern: String, options: NSRegularExpression.Options = []) -> String { - let range = NSRange(location: 0, length: self.utf16.count) - let regex: NSRegularExpression - - do { - regex = try NSRegularExpression(pattern: pattern, options: options) - } catch { - return self - } - - return regex.stringByReplacingMatches(in: self, options: .reportCompletion, range: range, withTemplate: "") + .trimmingCharacters(in: .whitespacesAndNewlines) } } diff --git a/Modules/Sources/WordPressKitObjC/RemoteReaderPost.m b/Modules/Sources/WordPressKitObjC/RemoteReaderPost.m index 2f7b0557d1c6..8611bc202402 100644 --- a/Modules/Sources/WordPressKitObjC/RemoteReaderPost.m +++ b/Modules/Sources/WordPressKitObjC/RemoteReaderPost.m @@ -707,7 +707,7 @@ - (NSString *)createSummaryFromContent:(NSString *)string */ - (NSString *)makePlainText:(NSString *)string { - return [string wpkit_summarized]; + return [string wpkit_makePlainText]; } /** diff --git a/Modules/Sources/WordPressShared/Utility/GutenbergExcerptGenerator.swift b/Modules/Sources/WordPressShared/Utility/GutenbergExcerptGenerator.swift index b21be87dbf7a..cd3aa5db4d2f 100644 --- a/Modules/Sources/WordPressShared/Utility/GutenbergExcerptGenerator.swift +++ b/Modules/Sources/WordPressShared/Utility/GutenbergExcerptGenerator.swift @@ -14,10 +14,10 @@ public struct GutenbergExcerptGenerator { return "" } - // Extract content + // Extract content while convering
,
,
to newlines first let rawText = String(content[tagEnd.upperBound..", with: " ", options: .regularExpression) - // Remove HTML tags AND shortcodes in one pass let range = NSRange(rawText.startIndex..., in: rawText) let text = (regex?.stringByReplacingMatches(in: rawText, options: [], range: range, withTemplate: "") ?? rawText) .stringByDecodingXMLCharacters() diff --git a/Modules/Tests/WordPressSharedTests/GutenbergExcerptGeneratorTests.swift b/Modules/Tests/WordPressSharedTests/GutenbergExcerptGeneratorTests.swift index eff9361a7686..ebb0bc7c6741 100644 --- a/Modules/Tests/WordPressSharedTests/GutenbergExcerptGeneratorTests.swift +++ b/Modules/Tests/WordPressSharedTests/GutenbergExcerptGeneratorTests.swift @@ -14,14 +14,14 @@ struct GutenbergPostExcerptGeneratorTests { let content = "

Some Content

" let summary = GutenbergExcerptGenerator.firstParagraph(from: content, maxLength: 150) - #expect(summary == "Some Content") + #expect(summary == "Some Content…") } @Test func summaryForContentWithGallery2() { let content = "

Before

\n

After

" let summary = GutenbergExcerptGenerator.firstParagraph(from: content, maxLength: 150) - #expect(summary == "Before") + #expect(summary == "Before…") } @Test @@ -29,6 +29,14 @@ struct GutenbergPostExcerptGeneratorTests { let content = "

Before

\n\n
\nhttps://videopress.com/v/AbCDe?resizeToParent=true&cover=true&preloadContent=metadata&useAverageColor=true\n
\n\n

After

" let summary = GutenbergExcerptGenerator.firstParagraph(from: content, maxLength: 150) - #expect(summary == "Before") + #expect(summary == "Before…") + } + + @Test func testPostWithBRTags() { + let content = #"

Yes,
look behind
in remembrance and with gratitude.

Then,
stay present,
or miss memories in the making.

"# + + let summary = GutenbergExcerptGenerator.firstParagraph(from: content, maxLength: 150) + print(summary) + #expect(summary == "Yes, look behind in remembrance and with gratitude.") } }