Add append action to element callbacks

This commit is contained in:
Shadowfacts 2024-01-16 19:15:56 -05:00
parent 64b68a6cec
commit a32b972201
5 changed files with 45 additions and 19 deletions

View File

@ -242,17 +242,19 @@ public struct AttributedStringConverter<Callbacks: HTMLConversionCallbacks> {
}()
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
var currentFontTraits: FontTrait = []

View File

@ -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 {

View File

@ -109,17 +109,19 @@ public struct TextConverter<Callbacks: HTMLConversionCallbacks> {
}
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 = ""
}

View File

@ -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("<span class='invisible'>test</span>", callbacks: Callbacks.self)
let skipped = convert("<span class='skip'>test</span>", callbacks: Callbacks.self)
XCTAssertEqual(skipped, NSAttributedString())
let skipNested = convert("<span class='invisible'><b>test</b></span>", callbacks: Callbacks.self)
let skipNested = convert("<span class='skip'><b>test</b></span>", callbacks: Callbacks.self)
XCTAssertEqual(skipNested, NSAttributedString())
let skipNestped2 = convert("<b><span class='invisible'>test</span></b>", callbacks: Callbacks.self)
let skipNestped2 = convert("<b><span class='skip'>test</span></b>", callbacks: Callbacks.self)
XCTAssertEqual(skipNestped2, NSAttributedString())
let replaced = convert("<span class='ellipsis'>test</span>", callbacks: Callbacks.self)
let replaced = convert("<span class='replace'>test</span>", callbacks: Callbacks.self)
XCTAssertEqual(replaced, NSAttributedString(string: "", attributes: [
.font: font,
.paragraphStyle: NSParagraphStyle.default,
.foregroundColor: color,
]))
let appended = convert("<span class='append'>test</span>", callbacks: Callbacks.self)
XCTAssertEqual(appended, NSAttributedString(string: "test…", attributes: [
.font: font,
.paragraphStyle: NSParagraphStyle.default,
.foregroundColor: color,
]))
let appended2 = convert("<span class='append'>test <span>blah</span></span>", callbacks: Callbacks.self)
XCTAssertEqual(appended2, NSAttributedString(string: "test blah…", attributes: [
.font: font,
.paragraphStyle: NSParagraphStyle.default,
.foregroundColor: color,
]))
}
func testOrderedList() {

View File

@ -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("<span class='invisible'>test</span>", callbacks: Callbacks.self)
let skipped = convert("<span class='skip'>test</span>", callbacks: Callbacks.self)
XCTAssertEqual(skipped, "")
let skipNested = convert("<span class='invisible'><b>test</b></span>", callbacks: Callbacks.self)
let skipNested = convert("<span class='skip'><b>test</b></span>", callbacks: Callbacks.self)
XCTAssertEqual(skipNested, "")
let replaced = convert("<span class='ellipsis'>test</span>", callbacks: Callbacks.self)
let replaced = convert("<span class='replace'>test</span>", callbacks: Callbacks.self)
XCTAssertEqual(replaced, "")
let appended = convert("<span class='append'>test</span>", callbacks: Callbacks.self)
XCTAssertEqual(appended, "test…")
let appended2 = convert("<span class='append'>test <span>blah</span></span>", callbacks: Callbacks.self)
XCTAssertEqual(appended2, "test blah…")
}
func testEmptyBlockElements() {