diff --git a/Lambdas/GHHooks/Extensions/String+Document.swift b/Lambdas/GHHooks/Extensions/String+Document.swift index 76319014..dee87128 100644 --- a/Lambdas/GHHooks/Extensions/String+Document.swift +++ b/Lambdas/GHHooks/Extensions/String+Document.swift @@ -27,7 +27,26 @@ extension String { /(?\d+) /# let withModifiedLinks = self.replacing(regex) { match in - "[\(match.output.org)/\(match.output.repo)#\(match.output.number)](\(self[match.range]))" + let current = self[match.range] + /// `match.output` is a `Range` which means it's `..<`. + /// So the character at `index == upperBound` is not part of the match. + if match.range.upperBound < self.endIndex, + /// `offsetBy: 2` is guaranteed to exist because the string must contain + /// `https` based on the regex above, so it has more length than 3. + match.range.lowerBound > self.index(self.startIndex, offsetBy: 2) { + /// All 3 indexes below are guaranteed to exist based on the range check above. + let before = self.index(before: match.range.lowerBound) + let beforeBefore = self.index(before: before) + /// Is surrounded like `STR` in `](STR)` or not + let isSurroundedInSomePuncs = self[beforeBefore] == "]" && + self[before] == "(" && + self[match.range.upperBound] == ")" + /// If it's surrounded in the punctuations above, it + /// might already be a link, so don't manipulate it. + if isSurroundedInSomePuncs { return current } + } + let output = match.output + return "[\(output.org)/\(output.repo)#\(output.number)](\(current))" } /// Remove all HTML elements and all links lacking a destination; they don't look good in Discord. diff --git a/Tests/PennyTests/Tests/GHHooksTests.swift b/Tests/PennyTests/Tests/GHHooksTests.swift index 88d6b6c6..d7611c37 100644 --- a/Tests/PennyTests/Tests/GHHooksTests.swift +++ b/Tests/PennyTests/Tests/GHHooksTests.swift @@ -506,9 +506,9 @@ class GHHooksTests: XCTestCase { /// Test modifying GitHub links do { let text = """ - Final stage of Vapor’s `Sendable` journey as `Request` is now `Sendable` at https://github.com/swift-server/swiftly/pull/9. + https://github.com/swift-server/swiftly/pull/9Final stage of Vapor’s `Sendable` journey as `Request` is now [#40](https://github.com/swift-server/swiftly/pull/9) `Sendable` at https://github.com/swift-server/swiftly/pull/9. - There should https://github.com/vapor-bad-link/issues/44 be no more `Sendable` warnings in Vaporhttps://github.com/vapor/penny-bot/issues/98, even with complete concurrency checking turned on. + There should https://github.com/vapor-bad-link/issues/44 be no more `Sendable` warnings in Vapor https://github.com/vapor/penny-bot/issues/98, even with complete concurrency checking turned on.](https://github.com/vapor/penny-bot/issues/98 """ let formatted = text.formatMarkdown( @@ -518,9 +518,9 @@ class GHHooksTests: XCTestCase { ) XCTAssertMultilineStringsEqual(formatted, """ - Final stage of Vapor’s `Sendable` journey as `Request` is now `Sendable` at [swift-server/swiftly#9](https://github.com/swift-server/swiftly/pull/9). + [swift-server/swiftly#9](https://github.com/swift-server/swiftly/pull/9)Final stage of Vapor’s `Sendable` journey as `Request` is now [#40](https://github.com/swift-server/swiftly/pull/9) `Sendable` at [swift-server/swiftly#9](https://github.com/swift-server/swiftly/pull/9). - There should https://github.com/vapor-bad-link/issues/44 be no more `Sendable` warnings in Vapor[vapor/penny-bot#98](https://github.com/vapor/penny-bot/issues/98), even with complete concurrency checking turned on. + There should https://github.com/vapor-bad-link/issues/44 be no more `Sendable` warnings in Vapor [vapor/penny-bot#98](https://github.com/vapor/penny-bot/issues/98), even with complete concurrency checking turned on.]([vapor/penny-bot#98](https://github.com/vapor/penny-bot/issues/98) """) } }