From 5fbf806e7328dd07f0928c2009e100809d3533cd Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Wed, 22 May 2024 17:48:29 -0400 Subject: [PATCH] Handle break tags at the beginning of paragraphs --- BlockState.dot | 3 ++- Sources/HTMLStreamer/BlockState.swift | 13 +++++++++++-- .../AttributedStringConverterTests.swift | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/BlockState.dot b/BlockState.dot index 245bdc1..72283f1 100644 --- a/BlockState.dot +++ b/BlockState.dot @@ -35,7 +35,8 @@ digraph blockstate { nonEmptyBlock -> beginListItem [label = "
  • "]; nonEmptyBlock -> endListItem [label = "
  • "]; emptyBlock -> nonEmptyBlock [label = "non-whitespace (block break)"]; - emptyBlock -> emptyBlock [label = "whitespace (skip)\n
    \n\nstart/end block"]; + emptyBlock -> emptyBlock [label = "whitespace (skip)\n\nstart/end block"]; + emptyBlock -> lineBreakTag [label = "
    (append to tmp, block break)"]; emptyBlock -> afterPreStartTag [label = "
     (depth = 1)"];
     	emptyBlock -> beginListItem [label = "
  • "]; emptyBlock -> endListItem [label = "
  • "]; diff --git a/Sources/HTMLStreamer/BlockState.swift b/Sources/HTMLStreamer/BlockState.swift index 3c5a46c..39491e6 100644 --- a/Sources/HTMLStreamer/BlockState.swift +++ b/Sources/HTMLStreamer/BlockState.swift @@ -19,7 +19,11 @@ import Foundation */ struct BlockStateMachine { - var blockState: BlockState = .start + var blockState: BlockState = .start { + didSet { + print("new state: \(blockState)") + } + } let blockBreak: String let lineBreak: String let listIndentForContentOutsideItem: String @@ -30,6 +34,7 @@ struct BlockStateMachine { extension BlockStateMachine { mutating func startOrEndBlock() { + print("start/end block") switch blockState { case .start: break @@ -78,6 +83,7 @@ extension BlockStateMachine { } mutating func continueBlock(char: UnicodeScalar) -> Bool { + print("continue block: \(char.debugDescription)") let isNewline = char == "\n" let isWhitespace = isNewline || isWhitespace(char) switch blockState { @@ -292,11 +298,14 @@ extension BlockStateMachine { } mutating func breakTag() { + print("break tag") switch blockState { case .start: break case .emptyBlock: - append(lineBreak) + blockState = .lineBreakTag + append(blockBreak) + temporaryBuffer.append(lineBreak) case .nonEmptyBlock: blockState = .lineBreakTag temporaryBuffer.append(lineBreak) diff --git a/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift b/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift index f1e2829..b413996 100644 --- a/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift +++ b/Tests/HTMLStreamerTests/AttributedStringConverterTests.swift @@ -662,4 +662,21 @@ final class AttributedStringConverterTests: XCTestCase { XCTAssertEqual(convert(html, callbacks: Replace.self), result) } + func testLineBreakAtBeginningOfBlockElement() { + let result = NSAttributedString(string: "a\n\n\n\nb", attributes: [ + .font: font, + .paragraphStyle: NSParagraphStyle.default, + .foregroundColor: color, + ]) + XCTAssertEqual(convert("

    a


    b

    "), result) + + let result2 = NSAttributedString(string: "a\n\n\nb\n\nc", attributes: [ + .font: font, + .paragraphStyle: NSParagraphStyle.default, + .foregroundColor: color, + ]) + XCTAssertEqual(convert("

    a


    b

    c

    "), result2) + } + + }