From a32b9722012ab142c6f9948220954f5c18a1b6b9 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Tue, 16 Jan 2024 19:15:56 -0500 Subject: [PATCH] Add append action to element callbacks --- .../AttributedStringConverter.swift | 10 ++++--- .../HTMLConversionCallbacks.swift | 1 + Sources/HTMLStreamer/TextConverter.swift | 10 ++++--- .../AttributedStringConverterTests.swift | 26 ++++++++++++++----- .../TextConverterTests.swift | 17 ++++++++---- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/Sources/HTMLStreamer/AttributedStringConverter.swift b/Sources/HTMLStreamer/AttributedStringConverter.swift index f3b3b7d..a4d2436 100644 --- a/Sources/HTMLStreamer/AttributedStringConverter.swift +++ b/Sources/HTMLStreamer/AttributedStringConverter.swift @@ -242,16 +242,18 @@ public struct AttributedStringConverter { }() private mutating func finishRun() { - guard !currentRun.isEmpty else { - return - } - if actionStack.contains(.skip) { currentRun = "" return + } else if case .append(let s) = actionStack.last { + currentRun.append(s) } else if case .replace(let replacement) = actionStack.first(where: \.isReplace) { currentRun = replacement } + + guard !currentRun.isEmpty else { + return + } var attributes = [NSAttributedString.Key: Any]() var paragraphStyle = configuration.paragraphStyle diff --git a/Sources/HTMLStreamer/HTMLConversionCallbacks.swift b/Sources/HTMLStreamer/HTMLConversionCallbacks.swift index 44d40c1..a2db8ab 100644 --- a/Sources/HTMLStreamer/HTMLConversionCallbacks.swift +++ b/Sources/HTMLStreamer/HTMLConversionCallbacks.swift @@ -16,6 +16,7 @@ public enum ElementAction: Equatable { case `default` case skip case replace(String) + case append(String) var isReplace: Bool { if case .replace(_) = self { diff --git a/Sources/HTMLStreamer/TextConverter.swift b/Sources/HTMLStreamer/TextConverter.swift index 4b8428e..028024e 100644 --- a/Sources/HTMLStreamer/TextConverter.swift +++ b/Sources/HTMLStreamer/TextConverter.swift @@ -109,17 +109,19 @@ public struct TextConverter { } private mutating func finishRun() { - guard !currentRun.isEmpty else { - return - } - if actionStack.contains(.skip) { currentRun = "" return + } else if case .append(let s) = actionStack.last { + currentRun.append(s) } else if case .replace(let replacement) = actionStack.first(where: \.isReplace) { currentRun = replacement } + guard !currentRun.isEmpty else { + return + } + str.append(currentRun) currentRun = "" } diff --git a/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift b/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift index 041ae59..2c5147d 100644 --- a/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift +++ b/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift @@ -250,27 +250,41 @@ final class AttributedStringConverterTests: XCTestCase { struct Callbacks: HTMLConversionCallbacks { static func elementAction(name: String, attributes: [Attribute]) -> ElementAction { let clazz = attributes.attributeValue(for: "class") - if clazz == "invisible" { + if clazz == "skip" { return .skip - } else if clazz == "ellipsis" { + } else if clazz == "replace" { return .replace("…") + } else if clazz == "append" { + return .append("…") } else { return .default } } } - let skipped = convert("", callbacks: Callbacks.self) + let skipped = convert("test", callbacks: Callbacks.self) XCTAssertEqual(skipped, NSAttributedString()) - let skipNested = convert("", callbacks: Callbacks.self) + let skipNested = convert("test", callbacks: Callbacks.self) XCTAssertEqual(skipNested, NSAttributedString()) - let skipNestped2 = convert("", callbacks: Callbacks.self) + let skipNestped2 = convert("test", callbacks: Callbacks.self) XCTAssertEqual(skipNestped2, NSAttributedString()) - let replaced = convert("test", callbacks: Callbacks.self) + let replaced = convert("test", callbacks: Callbacks.self) XCTAssertEqual(replaced, NSAttributedString(string: "…", attributes: [ .font: font, .paragraphStyle: NSParagraphStyle.default, .foregroundColor: color, ])) + let appended = convert("test", callbacks: Callbacks.self) + XCTAssertEqual(appended, NSAttributedString(string: "test…", attributes: [ + .font: font, + .paragraphStyle: NSParagraphStyle.default, + .foregroundColor: color, + ])) + let appended2 = convert("test blah", callbacks: Callbacks.self) + XCTAssertEqual(appended2, NSAttributedString(string: "test blah…", attributes: [ + .font: font, + .paragraphStyle: NSParagraphStyle.default, + .foregroundColor: color, + ])) } func testOrderedList() { diff --git a/Tests/HTMLStreamerTests/TextConverterTests.swift b/Tests/HTMLStreamerTests/TextConverterTests.swift index 78faee4..482bd44 100644 --- a/Tests/HTMLStreamerTests/TextConverterTests.swift +++ b/Tests/HTMLStreamerTests/TextConverterTests.swift @@ -46,21 +46,28 @@ final class TextConverterTests: XCTestCase { struct Callbacks: HTMLConversionCallbacks { static func elementAction(name: String, attributes: [Attribute]) -> ElementAction { let clazz = attributes.attributeValue(for: "class") - if clazz == "invisible" { + if clazz == "skip" { return .skip - } else if clazz == "ellipsis" { + } else if clazz == "replace" { return .replace("…") + } else if clazz == "append" { + return .append("…") } else { return .default } } } - let skipped = convert("", callbacks: Callbacks.self) + let skipped = convert("test", callbacks: Callbacks.self) XCTAssertEqual(skipped, "") - let skipNested = convert("", callbacks: Callbacks.self) + let skipNested = convert("test", callbacks: Callbacks.self) XCTAssertEqual(skipNested, "") - let replaced = convert("test", callbacks: Callbacks.self) + let replaced = convert("test", callbacks: Callbacks.self) XCTAssertEqual(replaced, "…") + let appended = convert("test", callbacks: Callbacks.self) + XCTAssertEqual(appended, "test…") + let appended2 = convert("test blah", callbacks: Callbacks.self) + XCTAssertEqual(appended2, "test blah…") + } func testEmptyBlockElements() {