diff --git a/Sources/Markdown/Base/RawMarkup.swift b/Sources/Markdown/Base/RawMarkup.swift index b001a318..3391265e 100644 --- a/Sources/Markdown/Base/RawMarkup.swift +++ b/Sources/Markdown/Base/RawMarkup.swift @@ -35,7 +35,7 @@ enum RawMarkupData: Equatable { case image(source: String?, title: String?) case inlineHTML(String) case lineBreak - case link(destination: String?, title: String?) + case link(destination: String?) case softBreak case strong case text(String) @@ -274,8 +274,8 @@ final class RawMarkup: ManagedBuffer { return .create(data: .lineBreak, parsedRange: parsedRange, children: []) } - static func link(destination: String?, title: String? = nil,parsedRange: SourceRange?, _ children: [RawMarkup]) -> RawMarkup { - return .create(data: .link(destination: destination, title: title), parsedRange: parsedRange, children: children) + static func link(destination: String?, parsedRange: SourceRange?, _ children: [RawMarkup]) -> RawMarkup { + return .create(data: .link(destination: destination), parsedRange: parsedRange, children: children) } static func softBreak(parsedRange: SourceRange?) -> RawMarkup { diff --git a/Sources/Markdown/Inline Nodes/Inline Containers/Link.swift b/Sources/Markdown/Inline Nodes/Inline Containers/Link.swift index e1143626..1dc70db1 100644 --- a/Sources/Markdown/Inline Nodes/Inline Containers/Link.swift +++ b/Sources/Markdown/Inline Nodes/Inline Containers/Link.swift @@ -29,7 +29,7 @@ public struct Link: InlineMarkup, InlineContainer { public extension Link { /// Create a link with a destination and zero or more child inline elements. - init(destination: String? = nil, title: String? = nil, _ children: Children) where Children.Element == RecurringInlineMarkup { + init(destination: String? = nil, _ children: Children) where Children.Element == RecurringInlineMarkup { let destinationToUse: String? if let d = destination, d.isEmpty { @@ -37,14 +37,8 @@ public extension Link { } else { destinationToUse = destination } - let titleToUse: String? - if let t = title, t.isEmpty { - titleToUse = nil - } else { - titleToUse = title - } - try! self.init(.link(destination: destinationToUse, title: titleToUse, parsedRange: nil, children.map { $0.raw.markup })) + try! self.init(.link(destination: destinationToUse, parsedRange: nil, children.map { $0.raw.markup })) } /// Create a link with a destination and zero or more child inline elements. @@ -55,33 +49,16 @@ public extension Link { /// The link's destination. var destination: String? { get { - guard case let .link(destination, _) = _data.raw.markup.data else { + guard case let .link(destination) = _data.raw.markup.data else { fatalError("\(self) markup wrapped unexpected \(_data.raw)") } return destination } set { if let d = newValue, d.isEmpty { - _data = _data.replacingSelf(.link(destination: nil, title: title, parsedRange: nil, _data.raw.markup.copyChildren())) - } else { - _data = _data.replacingSelf(.link(destination: newValue, title: title, parsedRange: nil, _data.raw.markup.copyChildren())) - } - } - } - - /// The link's title. - var title: String? { - get { - guard case let .link(_, title) = _data.raw.markup.data else { - fatalError("\(self) markup wrapped unexpected \(_data.raw)") - } - return title - } - set { - if let t = newValue, t.isEmpty { - _data = _data.replacingSelf(.link(destination: destination, title: nil, parsedRange: nil, _data.raw.markup.copyChildren())) + _data = _data.replacingSelf(.link(destination: nil, parsedRange: nil, _data.raw.markup.copyChildren())) } else { - _data = _data.replacingSelf(.link(destination: destination, title: newValue, parsedRange: nil, _data.raw.markup.copyChildren())) + _data = _data.replacingSelf(.link(destination: newValue, parsedRange: nil, _data.raw.markup.copyChildren())) } } } diff --git a/Sources/Markdown/Parser/CommonMarkConverter.swift b/Sources/Markdown/Parser/CommonMarkConverter.swift index 47a5d604..f2a62da3 100644 --- a/Sources/Markdown/Parser/CommonMarkConverter.swift +++ b/Sources/Markdown/Parser/CommonMarkConverter.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2021-2023 Apple Inc. and the Swift project authors + Copyright (c) 2021 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -452,18 +452,9 @@ struct MarkupParser { let parsedRange = state.range(state.node) let childConversion = convertChildren(state) let destination = String(cString: cmark_node_get_url(state.node)) - let title = String(cString: cmark_node_get_title(state.node)) precondition(childConversion.state.node == state.node) precondition(childConversion.state.event == CMARK_EVENT_EXIT) - return MarkupConversion( - state: childConversion.state.next(), - result: .link( - destination: destination.isEmpty ? nil : destination, - title: title.isEmpty ? nil : title, - parsedRange: parsedRange, - childConversion.result - ) - ) + return MarkupConversion(state: childConversion.state.next(), result: .link(destination: destination, parsedRange: parsedRange, childConversion.result)) } private static func convertImage(_ state: MarkupConverterState) -> MarkupConversion { @@ -471,18 +462,11 @@ struct MarkupParser { precondition(state.nodeType == .image) let parsedRange = state.range(state.node) let childConversion = convertChildren(state) - let source = String(cString: cmark_node_get_url(state.node)) + let destination = String(cString: cmark_node_get_url(state.node)) let title = String(cString: cmark_node_get_title(state.node)) precondition(childConversion.state.node == state.node) precondition(childConversion.state.event == CMARK_EVENT_EXIT) - return MarkupConversion( - state: childConversion.state.next(), - result: .image( - source: source.isEmpty ? nil : source, - title: title.isEmpty ? nil : title, - parsedRange: parsedRange, childConversion.result - ) - ) + return MarkupConversion(state: childConversion.state.next(), result: .image(source: destination, title: title, parsedRange: parsedRange, childConversion.result)) } private static func convertStrikethrough(_ state: MarkupConverterState) -> MarkupConversion { diff --git a/Tests/MarkdownTests/Inline Nodes/LinkTests.swift b/Tests/MarkdownTests/Inline Nodes/LinkTests.swift index 123b4d83..aeeca9be 100644 --- a/Tests/MarkdownTests/Inline Nodes/LinkTests.swift +++ b/Tests/MarkdownTests/Inline Nodes/LinkTests.swift @@ -48,35 +48,4 @@ class LinkTests: XCTestCase { link.destination = "test.example.com" XCTAssertFalse(link.isAutolink) } - - func testTitleLink() throws { - let markdown = #""" - [Example](example.com "The example title") - [Example2](example2.com) - [Example3]() - """# - - let document = Document(parsing: markdown) - XCTAssertEqual(document.childCount, 1) - let paragraph = try XCTUnwrap(document.child(at: 0) as? Paragraph) - XCTAssertEqual(paragraph.childCount, 5) - - XCTAssertTrue(paragraph.child(at: 1) is SoftBreak) - XCTAssertTrue(paragraph.child(at: 3) is SoftBreak) - let linkWithTitle = try XCTUnwrap(paragraph.child(at: 0) as? Link) - let linkWithoutTitle = try XCTUnwrap(paragraph.child(at: 2) as? Link) - let linkWithoutDestination = try XCTUnwrap(paragraph.child(at: 4) as? Link) - - XCTAssertEqual(try XCTUnwrap(linkWithTitle.child(at: 0) as? Text).string, "Example") - XCTAssertEqual(linkWithTitle.destination, "example.com") - XCTAssertEqual(linkWithTitle.title, "The example title") - - XCTAssertEqual(try XCTUnwrap(linkWithoutTitle.child(at: 0) as? Text).string, "Example2") - XCTAssertEqual(linkWithoutTitle.destination, "example2.com") - XCTAssertEqual(linkWithoutTitle.title, nil) - - XCTAssertEqual(try XCTUnwrap(linkWithoutDestination.child(at: 0) as? Text).string, "Example3") - XCTAssertEqual(linkWithoutDestination.destination, nil) - XCTAssertEqual(linkWithoutDestination.title, nil) - } } diff --git a/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift b/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift index e88cfd82..44116421 100644 --- a/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift +++ b/Tests/MarkdownTests/Visitors/MarkupFormatterTests.swift @@ -711,7 +711,7 @@ class MarkupFormatterSimpleRoundTripTests: XCTestCase { func testRoundTripHardBreakWithImage() { let source = """ This is some text.\(" ") - ![This is an image.](image.png) + ![This is an image.](image.png "") """ checkRoundTrip(for: source) checkCharacterEquivalence(for: source) @@ -720,7 +720,7 @@ class MarkupFormatterSimpleRoundTripTests: XCTestCase { func testRoundTripSoftBreakWithImage() { let source = """ This is some text. - ![This is an image.](image.png) + ![This is an image.](image.png "") """ checkRoundTrip(for: source) checkCharacterEquivalence(for: source) @@ -1394,6 +1394,7 @@ class MarkupFormatterTableTests: XCTestCase { """ let document = Document(parsing: source) + let expectedDump = """ Document └─ Table alignments: |l|c|r| @@ -1413,7 +1414,7 @@ class MarkupFormatterTableTests: XCTestCase { │ │ └─ Link destination: "https://apple.com" │ │ └─ Text "Apple" │ ├─ Cell - │ │ └─ Image source: "image.png" + │ │ └─ Image source: "image.png" title: "" │ │ └─ Text "image" │ └─ Cell │ └─ Link destination: "https://swift.org" @@ -1428,14 +1429,17 @@ class MarkupFormatterTableTests: XCTestCase { let formatted = document.format() let expected = """ - |*A* |**B** |~C~ | - |:-------------------------|:-----------------:|------------------:| - |[Apple](https://apple.com)|![image](image.png)|| - |
|| | + |*A* |**B** |~C~ | + |:-------------------------|:--------------------:|------------------:| + |[Apple](https://apple.com)|![image](image.png "")|| + |
|| | """ + XCTAssertEqual(expected, formatted) + print(formatted) let reparsed = Document(parsing: formatted) + print(reparsed.debugDescription()) XCTAssertTrue(document.hasSameStructure(as: reparsed)) } diff --git a/Tests/MarkdownTests/Visitors/MarkupTreeDumperTests.swift b/Tests/MarkdownTests/Visitors/MarkupTreeDumperTests.swift index 16ae6161..54de038d 100644 --- a/Tests/MarkdownTests/Visitors/MarkupTreeDumperTests.swift +++ b/Tests/MarkdownTests/Visitors/MarkupTreeDumperTests.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2021-2023 Apple Inc. and the Swift project authors + Copyright (c) 2021 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See https://swift.org/LICENSE.txt for license information @@ -29,7 +29,7 @@ final class MarkupTreeDumperTests: XCTestCase { │ ├─ Link @3:39-3:50 #12 destination: "foo" │ │ └─ Text @3:40-3:44 #13 "link" │ ├─ Text @3:50-3:51 #14 " " - │ ├─ Image @3:51-3:64 #15 source: "foo" + │ ├─ Image @3:51-3:64 #15 source: "foo" title: "" │ │ └─ Text @3:53-3:58 #16 "image" │ └─ Text @3:64-3:65 #17 "." ├─ UnorderedList @5:1-9:1 #18