diff --git a/Proton/Sources/Swift/Core/ListParser.swift b/Proton/Sources/Swift/Core/ListParser.swift index cdde9d57..8268f94e 100644 --- a/Proton/Sources/Swift/Core/ListParser.swift +++ b/Proton/Sources/Swift/Core/ListParser.swift @@ -114,7 +114,18 @@ public struct ListParser { } return items } - + + /// Parses NSAttributedString to list items + /// - Parameters: + /// - attributedString: NSAttributedString to convert to list items. + /// - indent: Indentation used in list representation in attributedString. This determines the level of list item. + /// - Returns: Array of list item nodes with hierarchical representation of list + /// - Note: If NSAttributedString passed into the function is non continuous i.e. contains multiple lists, the array will contain items from all the list with the range corresponding to range of text in original attributed string. + public static func parseListHierarchy(attributedString: NSAttributedString, indent: CGFloat = 25) -> [ListItemNode] { + let listItems = parse(attributedString: attributedString, indent: indent).map { $0.listItem } + return createListItemNodes(from: listItems) + } + /// Creates hierarchical representation of `ListItem` from the provided collection based on levels of each of the items /// - Parameter listItems: ListItems to convert /// - Returns: Collection of `ListItemNode` with each node having children nodes based on level of individual list items. @@ -130,7 +141,7 @@ public struct ListParser { stack.removeLast() } - if let last = stack.last { + if stack.last != nil { // If there's a parent, add this node to its children stack[stack.count - 1].node.children.append(newNode) } else { diff --git a/Proton/Tests/Core/ListParserTests.swift b/Proton/Tests/Core/ListParserTests.swift index df599f5f..1f0f616f 100644 --- a/Proton/Tests/Core/ListParserTests.swift +++ b/Proton/Tests/Core/ListParserTests.swift @@ -388,6 +388,24 @@ class ListParserTests: XCTestCase { XCTAssertEqual(list[1].range, NSRange(location: 80, length: 47)) } + func FIXME_testParsesNonContinuousListNodes() { + let paraStyle = NSMutableParagraphStyle.forListLevel(1) + let line1 = NSAttributedString(string: "This is line 1. This is line 1. This is line 1. This is line 1.", attributes: [.listItem: 1, .paragraphStyle: paraStyle]) + let line2 = NSAttributedString(string: "This is line 2.") + let line3 = NSAttributedString(string: "This is line 3. This is line 3. This is line 3.", attributes: [.listItem: 1, .paragraphStyle: paraStyle]) + + let text = NSMutableAttributedString(attributedString: line1) + text.append(NSAttributedString(string: "\n")) + text.append(line2) + text.append(NSAttributedString(string: "\n")) + text.append( line3) + + let list = ListParser.parse(attributedString: text) + let listNodes = ListParser.parseListHierarchy(attributedString: text) + XCTFail() + } + + func testFullCircleWithSameAttributeValue() { let listItems1 = [ ListItem(text: NSAttributedString(string: "One"), level: 1, attributeValue: 1),