diff --git a/Sources/Markdown/Base/DirectiveArgument.swift b/Sources/Markdown/Base/DirectiveArgument.swift index 4b742ea9..0d98426d 100644 --- a/Sources/Markdown/Base/DirectiveArgument.swift +++ b/Sources/Markdown/Base/DirectiveArgument.swift @@ -201,7 +201,8 @@ public struct DirectiveArgumentText: Equatable { var line = TrimmedLine(untrimmedText[...], source: range?.lowerBound.source, lineNumber: range?.lowerBound.line, - parseIndex: parseIndex) + parseIndex: parseIndex, + startParseIndex: untrimmedText.index(parseIndex, offsetBy: 1 - (range?.lowerBound.column ?? 1))) line.lexWhitespace() while !line.isEmptyOrAllWhitespace { let name: TrimmedLine.Lex? diff --git a/Sources/Markdown/Parser/BlockDirectiveParser.swift b/Sources/Markdown/Parser/BlockDirectiveParser.swift index cc9a02a4..5c27729f 100644 --- a/Sources/Markdown/Parser/BlockDirectiveParser.swift +++ b/Sources/Markdown/Parser/BlockDirectiveParser.swift @@ -304,12 +304,12 @@ struct TrimmedLine { } /// - parameter untrimmedText: ``untrimmedText`` - init(_ untrimmedText: Substring, source: URL?, lineNumber: Int?, parseIndex: Substring.Index? = nil) { + init(_ untrimmedText: Substring, source: URL?, lineNumber: Int?, parseIndex: Substring.Index? = nil, startParseIndex: Substring.Index? = nil) { self.untrimmedText = untrimmedText self.source = source self.parseIndex = parseIndex ?? untrimmedText.startIndex self.lineNumber = lineNumber - self.startParseIndex = self.parseIndex + self.startParseIndex = startParseIndex ?? self.parseIndex } /// Return the UTF-8 source location of the parse index if the line diff --git a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift index 1849419d..04c4d324 100644 --- a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift +++ b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift @@ -1042,5 +1042,29 @@ class BlockDirectiveArgumentParserTests: XCTestCase { └─ Text "Line c This is a single-line comment" """ XCTAssertEqual(expected, documentation.debugDescription()) + + func testDirectiveArgumentOnNonfirstLineParsing() throws { + let source = """ + + @Options(scope: page) + """ + + let line = 2 + let document = Document(parsing: source, options: .parseBlockDirectives) + let directive = try XCTUnwrap(document.child(at: 0) as? BlockDirective) + let arguments = directive.argumentText.parseNameValueArguments() + let scopeArg = try XCTUnwrap(arguments["scope"]) + + XCTAssertEqual("scope", scopeArg.name) + XCTAssertEqual( + scopeArg.nameRange, + SourceLocation(line: line, column: 10, source: nil) ..< SourceLocation(line: line, column: 15, source: nil) + ) + + XCTAssertEqual("page", scopeArg.value) + XCTAssertEqual( + scopeArg.valueRange, + SourceLocation(line: line, column: 17, source: nil) ..< SourceLocation(line: line, column: 21, source: nil) + ) } }