diff --git a/src/main/kotlin/com/engine/protoc/util/comment/CommentParser.kt b/src/main/kotlin/com/engine/protoc/util/comment/CommentParser.kt index adfabfc..465b34e 100644 --- a/src/main/kotlin/com/engine/protoc/util/comment/CommentParser.kt +++ b/src/main/kotlin/com/engine/protoc/util/comment/CommentParser.kt @@ -65,6 +65,10 @@ public abstract class CommentParser { private val commentContentCharsPattern = Regex("""[a-zA-Z0-9]""") private val rightFrameEdgePattern = Regex(""".*?([^a-zA-Z0-9]+)$""") private val leftRawEdgePattern = Regex("""^([^a-zA-Z0-9]+).*$""") + + // A single content line can't reveal a non-whitespace frame edge — frames need multiple lines + // to corroborate. Trailing punctuation like "]." or "." on one line is content, not a frame. + private val rightSingleLineEdgePattern = Regex(""".*?(\s+)$""") public fun of(rawComment: String): ParseContext = ParseContext(rawComment) } @@ -133,7 +137,13 @@ public abstract class CommentParser { 1 -> { val l = leftRawEdgePattern.matchEntire(rawContentLines[0]) ?.let { it.groupValues[1] } ?: "" - val r = rightFrameEdgePattern.matchEntire(rawContentLines[0]) + // If there's frame chrome around this single content line (top/bottom borders or + // padding), use the aggressive pattern to capture the frame's right edge. Otherwise + // this is an isolated content line — fall back to whitespace-only so we don't + // misread trailing content punctuation (e.g. "[MissingAnchor].") as a frame edge. + val hasFrameChrome = rawCommentLines.count { it.isNotBlank() } > 1 + val rightPattern = if (hasFrameChrome) rightFrameEdgePattern else rightSingleLineEdgePattern + val r = rightPattern.matchEntire(rawContentLines[0]) ?.let { it.groupValues[1] } ?: "" l to r } diff --git a/src/test/kotlin/CommentTests.kt b/src/test/kotlin/CommentTests.kt index 90f882e..6bea162 100644 --- a/src/test/kotlin/CommentTests.kt +++ b/src/test/kotlin/CommentTests.kt @@ -269,6 +269,18 @@ class CommentTests : """.trimMargin(), expectedCleanedResult = "Framed Single Line", ), + TestCase( + description = "Reference link at end of line with period", + source = """ + |// The greeting will be randomly selected [MissingAnchor]. + | + """.trimMargin(), + protoc = """ + | The greeting will be randomly selected [MissingAnchor]. + | + """.trimMargin(), + expectedCleanedResult = "The greeting will be randomly selected [MissingAnchor].", + ), ) context("Comment parsing tests") {