diff --git a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift index df4fd6fe1..34a237563 100644 --- a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift +++ b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift @@ -56,8 +56,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol { // that could happen with the default HTML renderer of NSAttributedString which is a // webview. func fromHTML(_ htmlString: String?) -> AttributedString? { - guard let htmlString, - let data = htmlString.data(using: .utf8) else { + guard let htmlString else { return nil } @@ -65,6 +64,13 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol { return cached } + // Trick DTCoreText into preserving newlines + let adjustedHTMLString = htmlString.replacingOccurrences(of: "\n", with: "
") + + guard let data = adjustedHTMLString.data(using: .utf8) else { + return nil + } + let defaultFont = UIFont.preferredFont(forTextStyle: .body) let parsingOptions: [String: Any] = [ diff --git a/UnitTests/Sources/AttributedStringBuilderTests.swift b/UnitTests/Sources/AttributedStringBuilderTests.swift index 0010eb6e4..5e1a91c89 100644 --- a/UnitTests/Sources/AttributedStringBuilderTests.swift +++ b/UnitTests/Sources/AttributedStringBuilderTests.swift @@ -396,6 +396,17 @@ class AttributedStringBuilderTests: XCTestCase { XCTAssertEqual(numberOfBlockquotes, 3, "Couldn't find all the blockquotes") } + func testNewLinesArePreserved() { + let htmlString = "Bob's\nyour\nuncle\nand\nFanny's\nyour\naunt" + + guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else { + XCTFail("Could not build the attributed string") + return + } + + XCTAssertEqual(String(attributedString.characters), htmlString.replacingOccurrences(of: "\n", with: "\u{2028}")) + } + // MARK: - Private private func checkLinkIn(attributedString: AttributedString?, expectedLink: String, expectedRuns: Int) {