Repository: apple/swift-markdown (swift)

Issue:
Including a @Comment in silently breaks symbol's doc rendering
### Description

Let's say I have a symbol `Example`.

In my `Sources/ExampleThing/ExampleThing.docc/Example.md` i have

```md
# ``Example``

@Comment { Don't forget X }

## More things here

Lorem ipsum...
```

This silently breaks the rendering of the entire page's rendering -- it appears completely empty and no warnings are emitted either.

I'm guessing `@Comment` can only be used in a tutorial -- which is a bit meh... the syntax should be the same in al types of files.

### Checklist

- [ ] 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

The @Comment should work as expected -- just not be rendered.

### Actual behavior

The rendering of the entire documentation page for the symbol is empty / broken by the presence of a `@Comment`

### Steps To Reproduce

- document any symbol
- add `@Comment { hello }`
- observe the comment prevented content, other than the sub-title from being rendered

### Swift-DocC Version Information

5.7

### Swift Compiler Version Information

```shell
-> % swift --version
swift-driver version: 1.62.1 Apple Swift version 5.7 (swiftlang-5.7.0.123.6 clang-1400.0.29.50)
```

Pull request:
Bug/issue #, if applicable: 

- [ ] Close #64
- [x] Close #65

## Summary

Before this PR, the block directive parser will just ignore the content after "{" in the same line.

After the PR, the behavior becomes the following:
```
@xx { yy           // "yy" will be ignored
@xx { yy }         // "yy" will be parsed
@xx { yy } zz }    // "yy } zz" will be parsed. It can be "yy } zz" or "yy". My implementation choose it to the former.
```
## 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 73eb2308..8792c96c 100644
--- a/Sources/Markdown/Parser/BlockDirectiveParser.swift
+++ b/Sources/Markdown/Parser/BlockDirectiveParser.swift
@@ -69,6 +69,9 @@ struct PendingBlockDirective {
     /// The location of the last character accepted into the block directive.
     var endLocation: SourceLocation
 
+    /// The pending line of the block directive
+    var pendingLine: TrimmedLine?
+
     /// `true` if the block directive container is expecting child content,
     /// i.e. it has parsed an opening curly brace `{`.
     var isAwaitingChildContent: Bool {
@@ -164,7 +167,7 @@ struct PendingBlockDirective {
 
     /// Continue parsing from the `contentsEnd` state.
     @discardableResult
-    mutating func parseContentsEnd(from line: TrimmedLine) -> Bool  {
+    mutating func parseContentsEnd(from line: TrimmedLine) -> Bool {
         precondition(isAwaitingChildContent)
         var line = line
         line.lexWhitespace()
@@ -172,6 +175,27 @@ struct PendingBlockDirective {
             parseState = .done
             endLocation = line.location!
         } else {
+            // If there is still some content on this line
+            // Consider them to be lineRun
+            // "@xx { yy": "yy" will be ignored
+            // "@xx { yy }": "yy" will be parsed
+            // "@xx { yy } zz }" "yy } zz" will be parsed
+
+            var reversedRemainingContent = TrimmedLine(Substring(line.text.reversed()), source: line.source, lineNumber: line.lineNumber)
+            if !line.text.isEmpty,
+               reversedRemainingContent.lex("}") != nil {
+                let trailingWhiteSpaceCount = reversedRemainingContent.lexWhitespace()?.text.count ?? 0
+                let textCount = line.text.count - trailingWhiteSpaceCount - 1
+                let leadingSpacingCount = line.untrimmedText.count - textCount - trailingWhiteSpaceCount - 1
+                innerIndentationColumnCount = leadingSpacingCount // Should we add a new property for this kind of usage?
+                
+                let startIndex = line.untrimmedText.startIndex
+                let endIndex = line.untrimmedText.index(startIndex, offsetBy: leadingSpacingCount)
+                let newLine = line.untrimmedText.replacingCharacters(in: startIndex..<endIndex, with: String(repeating: " ", count: leadingSpacingCount)).dropLast(trailingWhiteSpaceCount + 1)
+                pendingLine = TrimmedLine(newLine.dropFirst(0), source: line.source, lineNumber: line.lineNumber)
+                parseState = .done
+                endLocation = SourceLocation(line: line.lineNumber ?? 0, column: line.untrimmedText.count + 1, source: line.source)
+            }
             return false
         }
         return true
@@ -815,6 +839,9 @@ struct ParseContainerStack {
                     push(.blockDirective(newBlockDirective, []))
                 }
             }
+            if let pendingLine = newBlockDirective.pendingLine {
+                push(.lineRun([pendingLine], isInCodeFence: false))
+            }
             if case .done = newBlockDirective.parseState {
                 closeTop()
             }


Test patch:
diff --git a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift
index 07bbebba..6d4338bd 100644
--- a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift
+++ b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift
@@ -955,4 +955,31 @@ class BlockDirectiveArgumentParserTests: XCTestCase {
         """#
         XCTAssertEqual(document.debugDescription(options: .printSourceLocations), expectedDump)
     }
+    
+    func testSingleLineDirective() {
+        let source = """
+        @xx { yy }
+        @xx { yy } zz }
+        @xx { yy
+            z
+        }
+        Hello
+        """
+        let document = Document(parsing: source, options: [.parseBlockDirectives])
+        let expectedDump = #"""
+        Document @1:1-6:6
+        ├─ BlockDirective @1:1-1:11 name: "xx"
+        │  └─ Paragraph @1:7-1:9
+        │     └─ Text @1:7-1:9 "yy"
+        ├─ BlockDirective @2:1-2:16 name: "xx"
+        │  └─ Paragraph @2:7-2:14
+        │     └─ Text @2:7-2:14 "yy } zz"
+        ├─ BlockDirective @3:1-5:2 name: "xx"
+        │  └─ Paragraph @4:5-4:6
+        │     └─ Text @4:5-4:6 "z"
+        └─ Paragraph @6:1-6:6
+           └─ Text @6:1-6:6 "Hello"
+        """#
+        XCTAssertEqual(document.debugDescription(options: .printSourceLocations), expectedDump)
+    }
 }