Repository: apple/swift-markdown (swift)

Issue:
BlockDirective parsing for a new line ")" will give an incorrect output
### Description

```
@Image(
       source: "xx", 
       alt: "yy"
)
```

### Checklist

- [X] If possible, I've reproduced the issue using the `main` branch of this package.
- [X] This issue hasn't been addressed in an [existing GitHub issue](https://github.com/apple/swift-docc/issues).

### Expected Behavior

Show the image

### Actual behavior

Show the image with an extra ")"

### Steps To Reproduce

I highly suspect this is a swift-markdown issue

### Swift-DocC Version Information

_No response_

### Swift Compiler Version Information

_No response_

Pull request description:
Bug/issue #, if applicable: 

Close #152 

## Summary

Fix multiline directive without content parsing range issue

## Dependencies

None

## Testing

See `testDirectiveMultiLineWithoutContentParsing` in `BlockDirectiveParserTests.swift`

## Checklist

Make sure you check off the following items. If they cannot be completed, provide a reason.

- [x] Added tests
- [x] Ran the `./bin/test` script and it succeeded
- [x] Updated documentation if necessary

Patch:
diff --git a/Sources/Markdown/Parser/BlockDirectiveParser.swift b/Sources/Markdown/Parser/BlockDirectiveParser.swift
index 17d7f04c..3dd9100e 100644
--- a/Sources/Markdown/Parser/BlockDirectiveParser.swift
+++ b/Sources/Markdown/Parser/BlockDirectiveParser.swift
@@ -1,7 +1,7 @@
 /*
  This source file is part of the Swift.org open source project
 
- Copyright (c) 2021 Apple Inc. and the Swift project authors
+ Copyright (c) 2021-2023 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
@@ -127,7 +127,7 @@ struct PendingBlockDirective {
 
         if line.text.starts(with: ")") {
             parseState = .argumentsEnd
-            parseArgumentsEnd(from: line)
+            accepted = parseArgumentsEnd(from: line)
         }
 
         return accepted
@@ -143,10 +143,10 @@ struct PendingBlockDirective {
             parseState = .contentsStart
             endLocation = line.location!
             parseContentsStart(from: line)
+            return true
         } else {
             return false
         }
-        return true
     }
 
     /// Continue parsing from the `contentsStart` state.


Test patch:
diff --git a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift
index 1849419d..eb67ee40 100644
--- a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift
+++ b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift
@@ -1,7 +1,7 @@
 /*
  This source file is part of the Swift.org open source project
 
- Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
+ Copyright (c) 2021-2023 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
@@ -1043,4 +1043,27 @@ class BlockDirectiveArgumentParserTests: XCTestCase {
         """
         XCTAssertEqual(expected, documentation.debugDescription())
     }
+
+    // FIXME: swift-testing macro for specifying the relationship between a bug and a test
+    // Uncomment the following code when we integrate swift-testing
+    // @Test("Directive MultiLine WithoutContent Parsing", .bug("#152", relationship: .verifiesFix))
+    func testDirectiveMultiLineWithoutContentParsing() throws {
+        let source = """
+        @Image(
+          source: "example.png",
+          alt: "Example image"
+        )
+        """
+
+        let document = Document(parsing: source, options: .parseBlockDirectives)
+        _ = try XCTUnwrap(document.child(at: 0) as? BlockDirective)
+        let expected = #"""
+        Document @1:1-4:2
+        └─ BlockDirective @1:1-4:2 name: "Image"
+           ├─ Argument text segments:
+           |    @2:1-2:25: "  source: \"example.png\","
+           |    @3:1-3:23: "  alt: \"Example image\""
+        """#
+        XCTAssertEqual(expected, document.debugDescription(options: .printSourceLocations))
+    }
 }