Skip to content

Commit 69f31f8

Browse files
committed
Add single line block directive parsing logic
1 parent 395fbf2 commit 69f31f8

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

Sources/Markdown/Parser/BlockDirectiveParser.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ struct PendingBlockDirective {
6969
/// The location of the last character accepted into the block directive.
7070
var endLocation: SourceLocation
7171

72+
/// The pending line of the block directive
73+
var pendingLine: TrimmedLine?
74+
7275
/// `true` if the block directive container is expecting child content,
7376
/// i.e. it has parsed an opening curly brace `{`.
7477
var isAwaitingChildContent: Bool {
@@ -164,14 +167,35 @@ struct PendingBlockDirective {
164167

165168
/// Continue parsing from the `contentsEnd` state.
166169
@discardableResult
167-
mutating func parseContentsEnd(from line: TrimmedLine) -> Bool {
170+
mutating func parseContentsEnd(from line: TrimmedLine) -> Bool {
168171
precondition(isAwaitingChildContent)
169172
var line = line
170173
line.lexWhitespace()
171174
if line.lex("}") != nil {
172175
parseState = .done
173176
endLocation = line.location!
174177
} else {
178+
// If there is still some content on this line
179+
// Consider them to be lineRun
180+
// "@xx { yy": "yy" will be ignored
181+
// "@xx { yy }": "yy" will be parsed
182+
// "@xx { yy } zz }" "yy } zz" will be parsed
183+
184+
var reversedRemainingContent = TrimmedLine(Substring(line.text.reversed()), source: line.source, lineNumber: line.lineNumber)
185+
if !line.text.isEmpty,
186+
reversedRemainingContent.lex("}") != nil {
187+
let trailingWhiteSpaceCount = reversedRemainingContent.lexWhitespace()?.text.count ?? 0
188+
let textCount = line.text.count - trailingWhiteSpaceCount - 1
189+
let leadingSpacingCount = line.untrimmedText.count - textCount - trailingWhiteSpaceCount - 1
190+
innerIndentationColumnCount = leadingSpacingCount // Should we add a new property for this kind of usage?
191+
192+
let startIndex = line.untrimmedText.startIndex
193+
let endIndex = line.untrimmedText.index(startIndex, offsetBy: leadingSpacingCount)
194+
let newLine = line.untrimmedText.replacingCharacters(in: startIndex..<endIndex, with: String(repeating: " ", count: leadingSpacingCount)).dropLast(trailingWhiteSpaceCount + 1)
195+
pendingLine = TrimmedLine(newLine.dropFirst(0), source: line.source, lineNumber: line.lineNumber)
196+
parseState = .done
197+
endLocation = SourceLocation(line: line.lineNumber ?? 0, column: line.untrimmedText.count + 1, source: line.source)
198+
}
175199
return false
176200
}
177201
return true
@@ -815,6 +839,9 @@ struct ParseContainerStack {
815839
push(.blockDirective(newBlockDirective, []))
816840
}
817841
}
842+
if let pendingLine = newBlockDirective.pendingLine {
843+
push(.lineRun([pendingLine], isInCodeFence: false))
844+
}
818845
if case .done = newBlockDirective.parseState {
819846
closeTop()
820847
}

Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,4 +955,31 @@ class BlockDirectiveArgumentParserTests: XCTestCase {
955955
"""#
956956
XCTAssertEqual(document.debugDescription(options: .printSourceLocations), expectedDump)
957957
}
958+
959+
func testSingleLineDirective() {
960+
let source = """
961+
@xx { yy }
962+
@xx { yy } zz }
963+
@xx { yy
964+
z
965+
}
966+
Hello
967+
"""
968+
let document = Document(parsing: source, options: [.parseBlockDirectives])
969+
let expectedDump = #"""
970+
Document @1:1-6:6
971+
├─ BlockDirective @1:1-1:11 name: "xx"
972+
│ └─ Paragraph @1:7-1:9
973+
│ └─ Text @1:7-1:9 "yy"
974+
├─ BlockDirective @2:1-2:16 name: "xx"
975+
│ └─ Paragraph @2:7-2:14
976+
│ └─ Text @2:7-2:14 "yy } zz"
977+
├─ BlockDirective @3:1-5:2 name: "xx"
978+
│ └─ Paragraph @4:5-4:6
979+
│ └─ Text @4:5-4:6 "z"
980+
└─ Paragraph @6:1-6:6
981+
└─ Text @6:1-6:6 "Hello"
982+
"""#
983+
XCTAssertEqual(document.debugDescription(options: .printSourceLocations), expectedDump)
984+
}
958985
}

0 commit comments

Comments
 (0)