From 7a395f9cbe9797ea091d5928b6a9ecca801da33e Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 26 Sep 2022 00:30:02 +0800 Subject: [PATCH 1/7] Remove unnecessary optional check --- Sources/Markdown/Parser/BlockDirectiveParser.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Markdown/Parser/BlockDirectiveParser.swift b/Sources/Markdown/Parser/BlockDirectiveParser.swift index 3dd9100e..c9046bcf 100644 --- a/Sources/Markdown/Parser/BlockDirectiveParser.swift +++ b/Sources/Markdown/Parser/BlockDirectiveParser.swift @@ -318,7 +318,7 @@ struct TrimmedLine { guard let lineNumber = lineNumber else { return nil } - let startIndex = (self.lineNumber ?? 1) == 1 + let startIndex = lineNumber == 1 ? untrimmedText.startIndex : startParseIndex let alreadyParsedPrefix = untrimmedText[startIndex.. Date: Mon, 26 Sep 2022 00:35:15 +0800 Subject: [PATCH 2/7] Fix and add test case for single line block parse --- Sources/Markdown/Base/DirectiveArgument.swift | 3 ++- .../Parser/BlockDirectiveParser.swift | 4 ++-- .../Parsing/BlockDirectiveParserTests.swift | 24 +++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) 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 c9046bcf..1ab871e7 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 eb67ee40..fdceccc7 100644 --- a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift +++ b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift @@ -1042,6 +1042,30 @@ 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) + ) } // FIXME: swift-testing macro for specifying the relationship between a bug and a test From 2552a6ccd3ea8599d67a96a64cae010fdb7435cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20R=C3=B6nnqvist?= Date: Mon, 11 Dec 2023 14:49:14 +0100 Subject: [PATCH 3/7] Add test for various combinations of directive argument location --- .../Parsing/BlockDirectiveParserTests.swift | 172 ++++++++++++++++-- 1 file changed, 153 insertions(+), 19 deletions(-) diff --git a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift index fdceccc7..8aef37ef 100644 --- a/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift +++ b/Tests/MarkdownTests/Parsing/BlockDirectiveParserTests.swift @@ -1042,29 +1042,163 @@ class BlockDirectiveArgumentParserTests: XCTestCase { └─ Text "Line c This is a single-line comment" """ XCTAssertEqual(expected, documentation.debugDescription()) + } - func testDirectiveArgumentOnNonfirstLineParsing() throws { - let source = """ - - @Options(scope: page) - """ + func testParsingDirectiveArgumentsWithWhitespaceBeforeDirective() throws { + struct ExpectedArgumentInfo { + var line: Int + let name: String + var nameRange: Range + let value: String + var valueRange: Range + } + + func assertDirectiveArguments( + _ expectedArguments: ExpectedArgumentInfo..., + parsing content: String, + file: StaticString = #file, + line: UInt = #line + ) throws { + func substring(with range: SourceRange) -> String { + let line = content.split(omittingEmptySubsequences: false, whereSeparator: \.isNewline)[range.lowerBound.line - 1] + return String(line.prefix(range.upperBound.column - 1).dropFirst(range.lowerBound.column - 1)) + } + + let source = URL(fileURLWithPath: "/test-file-location") + let document = Document(parsing: content, source: source, options: .parseBlockDirectives) + let directive = try XCTUnwrap(document.child(at: 0) as? BlockDirective, file: file, line: line) + let arguments = directive.argumentText.parseNameValueArguments() + XCTAssertEqual(arguments.count, expectedArguments.count, file: file, line: line) + for expectedArgument in expectedArguments { + let argument = try XCTUnwrap(arguments[expectedArgument.name], file: file, line: line) + + XCTAssertEqual(expectedArgument.name, argument.name, file: file, line: line) + XCTAssertEqual( + argument.nameRange, + SourceLocation(line: expectedArgument.line, column: expectedArgument.nameRange.lowerBound, source: source) ..< SourceLocation(line: expectedArgument.line, column: expectedArgument.nameRange.upperBound, source: source), + file: file, + line: line + ) + XCTAssertEqual(expectedArgument.name, argument.nameRange.map(substring(with:)), file: file, line: line) + + XCTAssertEqual(expectedArgument.value, argument.value, file: file, line: line) + XCTAssertEqual( + argument.valueRange, + SourceLocation(line: expectedArgument.line, column: expectedArgument.valueRange.lowerBound, source: source) ..< SourceLocation(line: expectedArgument.line, column: expectedArgument.valueRange.upperBound, source: source), + file: file, + line: line + ) + XCTAssertEqual(expectedArgument.value, argument.valueRange.map(substring(with:)), file: file, line: line) + } + } + + // One argument + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 1, name: "firstArgument", nameRange: 16 ..< 29, value: "firstValue", valueRange: 31 ..< 41), + parsing: "@DirectiveName(firstArgument: firstValue)" + ) + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 2, name: "firstArgument", nameRange: 16 ..< 29, value: "firstValue", valueRange: 31 ..< 41), + parsing: """ + + @DirectiveName(firstArgument: firstValue) + """ + ) + + // Argument on single line + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 1, name: "firstArgument", nameRange: 17 ..< 30, value: "firstValue", valueRange: 31 ..< 41), + ExpectedArgumentInfo(line: 1, name: "secondArgument", nameRange: 44 ..< 58, value: "secondValue", valueRange: 62 ..< 73), + parsing: "@DirectiveName( firstArgument:firstValue ,\tsecondArgument: \t secondValue)" + ) + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 2, name: "firstArgument", nameRange: 17 ..< 30, value: "firstValue", valueRange: 31 ..< 41), + ExpectedArgumentInfo(line: 2, name: "secondArgument", nameRange: 44 ..< 58, value: "secondValue", valueRange: 62 ..< 73), + parsing: """ - 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) + @DirectiveName( firstArgument:firstValue ,\tsecondArgument: \t secondValue) + """ ) + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 2, name: "firstArgument", nameRange: 19 ..< 32, value: "firstValue", valueRange: 33 ..< 43), + ExpectedArgumentInfo(line: 2, name: "secondArgument", nameRange: 46 ..< 60, value: "secondValue", valueRange: 64 ..< 75), + parsing: """ - XCTAssertEqual("page", scopeArg.value) - XCTAssertEqual( - scopeArg.valueRange, - SourceLocation(line: line, column: 17, source: nil) ..< SourceLocation(line: line, column: 21, source: nil) + @DirectiveName( firstArgument:firstValue ,\tsecondArgument: \t secondValue) + """ + ) + + // Second argument on new line + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 1, name: "firstArgument", nameRange: 17 ..< 30, value: "firstValue", valueRange: 31 ..< 41), + ExpectedArgumentInfo(line: 2, name: "secondArgument", nameRange: 16 ..< 30, value: "secondValue", valueRange: 34 ..< 45), + parsing: """ + @DirectiveName( firstArgument:firstValue , + secondArgument: \t secondValue) + """ + ) + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 2, name: "firstArgument", nameRange: 17 ..< 30, value: "firstValue", valueRange: 31 ..< 41), + ExpectedArgumentInfo(line: 3, name: "secondArgument", nameRange: 16 ..< 30, value: "secondValue", valueRange: 34 ..< 45), + parsing: """ + + @DirectiveName( firstArgument:firstValue , + secondArgument: \t secondValue) + """ + ) + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 2, name: "firstArgument", nameRange: 19 ..< 32, value: "firstValue", valueRange: 33 ..< 43), + ExpectedArgumentInfo(line: 3, name: "secondArgument", nameRange: 18 ..< 32, value: "secondValue", valueRange: 36 ..< 47), + parsing: """ + + @DirectiveName( firstArgument:firstValue , + secondArgument: \t secondValue) + """ + ) + + // Arguments on separate lines + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 2, name: "firstArgument", nameRange: 3 ..< 16, value: "firstValue", valueRange: 17 ..< 27), + ExpectedArgumentInfo(line: 3, name: "secondArgument", nameRange: 2 ..< 16, value: "secondValue", valueRange: 20 ..< 31), + parsing: """ + @DirectiveName( + firstArgument:firstValue , + \tsecondArgument: \t secondValue + ) + """ + ) + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 3, name: "firstArgument", nameRange: 3 ..< 16, value: "firstValue", valueRange: 17 ..< 27), + ExpectedArgumentInfo(line: 4, name: "secondArgument", nameRange: 2 ..< 16, value: "secondValue", valueRange: 20 ..< 31), + parsing: """ + + @DirectiveName( + firstArgument:firstValue , + \tsecondArgument: \t secondValue + ) + """ + ) + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 3, name: "firstArgument", nameRange: 5 ..< 18, value: "firstValue", valueRange: 19 ..< 29), + ExpectedArgumentInfo(line: 4, name: "secondArgument", nameRange: 4 ..< 18, value: "secondValue", valueRange: 22 ..< 33), + parsing: """ + + @DirectiveName( + firstArgument:firstValue , + \tsecondArgument: \t secondValue + ) + """ ) } From 9b311bf34d9ef517ac056836f06b78c120f5d222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20R=C3=B6nnqvist?= Date: Mon, 11 Dec 2023 15:54:12 +0100 Subject: [PATCH 4/7] Initialize LineSegment with the text of only one line Also, update test to verify emoji ranges --- Sources/Markdown/Base/DirectiveArgument.swift | 4 +- .../Parser/BlockDirectiveParser.swift | 46 +++++++++++-------- .../Parsing/BlockDirectiveParserTests.swift | 18 +++++++- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/Sources/Markdown/Base/DirectiveArgument.swift b/Sources/Markdown/Base/DirectiveArgument.swift index 0d98426d..d4334f05 100644 --- a/Sources/Markdown/Base/DirectiveArgument.swift +++ b/Sources/Markdown/Base/DirectiveArgument.swift @@ -201,8 +201,8 @@ public struct DirectiveArgumentText: Equatable { var line = TrimmedLine(untrimmedText[...], source: range?.lowerBound.source, lineNumber: range?.lowerBound.line, - parseIndex: parseIndex, - startParseIndex: untrimmedText.index(parseIndex, offsetBy: 1 - (range?.lowerBound.column ?? 1))) + parseIndex: parseIndex + ) line.lexWhitespace() while !line.isEmptyOrAllWhitespace { let name: TrimmedLine.Lex? diff --git a/Sources/Markdown/Parser/BlockDirectiveParser.swift b/Sources/Markdown/Parser/BlockDirectiveParser.swift index 1ab871e7..ac59de7e 100644 --- a/Sources/Markdown/Parser/BlockDirectiveParser.swift +++ b/Sources/Markdown/Parser/BlockDirectiveParser.swift @@ -282,9 +282,6 @@ struct TrimmedLine { /// The original untrimmed text of the line. let untrimmedText: Substring - /// The starting parse index. - let startParseIndex: Substring.Index - /// The current index a parser is looking at on a line. var parseIndex: Substring.Index @@ -303,13 +300,16 @@ struct TrimmedLine { } } - /// - parameter untrimmedText: ``untrimmedText`` - init(_ untrimmedText: Substring, source: URL?, lineNumber: Int?, parseIndex: Substring.Index? = nil, startParseIndex: Substring.Index? = nil) { + /// - Parameters: + /// - untrimmedText: The original untrimmed text of the line. + /// - source: The source file or resource from which the line came, or `nil` if no such file or resource can be identified. + /// - lineNumber: The line number of this line in the source if known, starting with `0`. + /// - parseIndex: The current index a parser is looking at on a line, or `nil` if a parser is looking at the start of the untrimmed text. + init(_ untrimmedText: Substring, source: URL?, lineNumber: Int?, parseIndex: Substring.Index? = nil) { self.untrimmedText = untrimmedText self.source = source self.parseIndex = parseIndex ?? untrimmedText.startIndex self.lineNumber = lineNumber - self.startParseIndex = startParseIndex ?? self.parseIndex } /// Return the UTF-8 source location of the parse index if the line @@ -318,10 +318,7 @@ struct TrimmedLine { guard let lineNumber = lineNumber else { return nil } - let startIndex = lineNumber == 1 - ? untrimmedText.startIndex - : startParseIndex - let alreadyParsedPrefix = untrimmedText[startIndex.. String { let line = content.split(omittingEmptySubsequences: false, whereSeparator: \.isNewline)[range.lowerBound.line - 1] - return String(line.prefix(range.upperBound.column - 1).dropFirst(range.lowerBound.column - 1)) + let startIndex = line.utf8.index(line.utf8.startIndex, offsetBy: range.lowerBound.column - 1) + let endIndex = line.utf8.index(line.utf8.startIndex, offsetBy: range.upperBound.column - 1) + return String(line[startIndex ..< endIndex]) } let source = URL(fileURLWithPath: "/test-file-location") let document = Document(parsing: content, source: source, options: .parseBlockDirectives) - let directive = try XCTUnwrap(document.child(at: 0) as? BlockDirective, file: file, line: line) + let directive = try XCTUnwrap(document.children.compactMap({ $0 as? BlockDirective }).first, file: file, line: line) let arguments = directive.argumentText.parseNameValueArguments() XCTAssertEqual(arguments.count, expectedArguments.count, file: file, line: line) for expectedArgument in expectedArguments { @@ -1200,6 +1202,18 @@ class BlockDirectiveArgumentParserTests: XCTestCase { ) """ ) + + // Content and directives with emoji + + try assertDirectiveArguments( + ExpectedArgumentInfo(line: 3, name: "firstArgument", nameRange: 20 ..< 33, value: "first💻Value", valueRange: 35 ..< 49), + ExpectedArgumentInfo(line: 3, name: "secondArgument", nameRange: 51 ..< 65, value: "secondValue", valueRange: 67 ..< 78), + parsing: """ + Paragraph before with emoji: 💻 + + @Directive💻Name(firstArgument: first💻Value, secondArgument: secondValue) + """ + ) } // FIXME: swift-testing macro for specifying the relationship between a bug and a test From f6bf306175b5905a89a3507de9ddd5ae9f7c386c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20R=C3=B6nnqvist?= Date: Mon, 11 Dec 2023 18:19:44 +0100 Subject: [PATCH 5/7] Update documentation for `LineSegment.untrimmedText` to reflect its use Also deprecate `LineSegment.lineStartIndex` Also remove `lineStartIndex` parameter from internal `LineSegment` init --- Sources/Markdown/Base/DirectiveArgument.swift | 18 +++++++++--------- .../BlockDirective.swift | 1 - .../Markdown/Parser/BlockDirectiveParser.swift | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Sources/Markdown/Base/DirectiveArgument.swift b/Sources/Markdown/Base/DirectiveArgument.swift index d4334f05..71b4b21e 100644 --- a/Sources/Markdown/Base/DirectiveArgument.swift +++ b/Sources/Markdown/Base/DirectiveArgument.swift @@ -43,11 +43,14 @@ public struct DirectiveArgumentText: Equatable { /// A segment of a line of argument text. public struct LineSegment: Equatable { - /// The segment's untrimmed text from which arguments can be parsed. + /// The original untrimmed text of the line, from which arguments can be parsed. public var untrimmedText: String - /// The index in ``untrimmedText`` where the line started. - public var lineStartIndex: String.Index + @available(*, deprecated, renamed: "untrimmedText.startIndex") + public var lineStartIndex: String.Index { + get { untrimmedText.startIndex } + set { } + } /// The index from which parsing should start. public var parseIndex: String.Index @@ -64,13 +67,11 @@ public struct DirectiveArgumentText: Equatable { /// Create an argument line segment. /// - Parameters: /// - untrimmedText: the segment's untrimmed text from which arguments can be parsed. - /// - lineStartIndex: the index in ``text`` where the line started. - /// - parseIndex: index from which parsing should start. + /// - parseIndex: The index from which parsing should start. /// - range: The range from which a segment was extracted from a line /// of source, or `nil` if the argument text was provided by other means. - init(untrimmedText: String, lineStartIndex: String.Index, parseIndex: String.Index? = nil, range: SourceRange? = nil) { + init(untrimmedText: String, parseIndex: String.Index? = nil, range: SourceRange? = nil) { self.untrimmedText = untrimmedText - self.lineStartIndex = lineStartIndex self.parseIndex = parseIndex ?? untrimmedText.startIndex self.range = range } @@ -81,7 +82,6 @@ public struct DirectiveArgumentText: Equatable { /// - Returns: `true` if the two segments are equal. public static func ==(lhs: LineSegment, rhs: LineSegment) -> Bool { return lhs.untrimmedText == rhs.untrimmedText && - lhs.lineStartIndex == rhs.lineStartIndex && lhs.parseIndex == rhs.parseIndex && lhs.range == rhs.range } @@ -284,7 +284,7 @@ public struct DirectiveArgumentText: Equatable { /// from a string. public init(_ string: S) { let text = String(string) - self.segments = [LineSegment(untrimmedText: text, lineStartIndex: text.startIndex, range: nil)] + self.segments = [LineSegment(untrimmedText: text, range: nil)] } /// Create a body of argument text from a sequence of ``LineSegment`` elements. diff --git a/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.swift b/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.swift index 835bb5c7..7dba90d0 100644 --- a/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.swift +++ b/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.swift @@ -95,7 +95,6 @@ public extension BlockDirective { omittingEmptySubsequences: false).map { lineText -> DirectiveArgumentText.LineSegment in let untrimmedText = String(lineText) return DirectiveArgumentText.LineSegment(untrimmedText: untrimmedText, - lineStartIndex: untrimmedText.startIndex, range: nil) } ?? [] try! self.init(.blockDirective(name: name, diff --git a/Sources/Markdown/Parser/BlockDirectiveParser.swift b/Sources/Markdown/Parser/BlockDirectiveParser.swift index ac59de7e..8cb624ab 100644 --- a/Sources/Markdown/Parser/BlockDirectiveParser.swift +++ b/Sources/Markdown/Parser/BlockDirectiveParser.swift @@ -732,7 +732,7 @@ private enum ParseContainer: CustomStringConvertible { } let parseIndex = base.utf8.index($0.text.startIndex, offsetBy: -base.utf8.distance(from: base.startIndex, to: lineStartIndex)) let untrimmedLine = String(base[lineStartIndex..<$0.text.endIndex]) - return DirectiveArgumentText.LineSegment(untrimmedText: untrimmedLine, lineStartIndex: untrimmedLine.startIndex, parseIndex: parseIndex, range: $0.range) + return DirectiveArgumentText.LineSegment(untrimmedText: untrimmedLine, parseIndex: parseIndex, range: $0.range) }), parsedRange: pendingBlockDirective.atLocation.. Date: Mon, 11 Dec 2023 18:21:09 +0100 Subject: [PATCH 6/7] Remove custom `==(_:_:)` that's same as synthesized implementation --- Sources/Markdown/Base/DirectiveArgument.swift | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Sources/Markdown/Base/DirectiveArgument.swift b/Sources/Markdown/Base/DirectiveArgument.swift index 71b4b21e..8188d35e 100644 --- a/Sources/Markdown/Base/DirectiveArgument.swift +++ b/Sources/Markdown/Base/DirectiveArgument.swift @@ -76,16 +76,6 @@ public struct DirectiveArgumentText: Equatable { self.range = range } - /// Returns a Boolean value indicating whether two line segments are equal. - /// - Parameter lhs: a line segment to compare - /// - Parameter rhs: another line segment to compare - /// - Returns: `true` if the two segments are equal. - public static func ==(lhs: LineSegment, rhs: LineSegment) -> Bool { - return lhs.untrimmedText == rhs.untrimmedText && - lhs.parseIndex == rhs.parseIndex && - lhs.range == rhs.range - } - /// Parse a quoted literal. /// /// ``` From af30c0d574d49af1cd7c3186691861e03cb87362 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 13 Dec 2023 00:36:05 +0800 Subject: [PATCH 7/7] Update LICENSE year and code format --- Sources/Markdown/Base/DirectiveArgument.swift | 2 +- .../BlockDirective.swift | 2 +- .../Parser/BlockDirectiveParser.swift | 45 ++++++++++--------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Sources/Markdown/Base/DirectiveArgument.swift b/Sources/Markdown/Base/DirectiveArgument.swift index 8188d35e..503eb698 100644 --- a/Sources/Markdown/Base/DirectiveArgument.swift +++ b/Sources/Markdown/Base/DirectiveArgument.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 diff --git a/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.swift b/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.swift index 7dba90d0..50910b65 100644 --- a/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.swift +++ b/Sources/Markdown/Block Nodes/Block Container Blocks/BlockDirective.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 diff --git a/Sources/Markdown/Parser/BlockDirectiveParser.swift b/Sources/Markdown/Parser/BlockDirectiveParser.swift index 8cb624ab..40dd3ae5 100644 --- a/Sources/Markdown/Parser/BlockDirectiveParser.swift +++ b/Sources/Markdown/Parser/BlockDirectiveParser.swift @@ -715,27 +715,30 @@ private enum ParseContainer: CustomStringConvertible { let children = children.flatMap { $0.convertToRawMarkup(ranges: &ranges, parent: self, options: options) } - return [.blockDirective( - name: String(pendingBlockDirective.name), - nameLocation: pendingBlockDirective.atLocation, - argumentText: DirectiveArgumentText(segments: pendingBlockDirective.argumentsText.map { - let base = $0.text.base - let lineStartIndex: String.Index - if let argumentRange = $0.range { - // If the argument has a known source range, offset the column (number of UTF8 bytes) to find the start of the line. - lineStartIndex = base.utf8.index($0.text.startIndex, offsetBy: 1 - argumentRange.lowerBound.column) - } else if let newLineIndex = base[..<$0.text.startIndex].lastIndex(where: \.isNewline) { - // Iterate backwards from the argument start index to find the the start of the line. - lineStartIndex = base.utf8.index(after: newLineIndex) - } else { - lineStartIndex = base.startIndex - } - let parseIndex = base.utf8.index($0.text.startIndex, offsetBy: -base.utf8.distance(from: base.startIndex, to: lineStartIndex)) - let untrimmedLine = String(base[lineStartIndex..<$0.text.endIndex]) - return DirectiveArgumentText.LineSegment(untrimmedText: untrimmedLine, parseIndex: parseIndex, range: $0.range) - }), - parsedRange: pendingBlockDirective.atLocation..