Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix using @ symbol inside code block #2418

Merged
merged 3 commits into from Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 42 additions & 1 deletion plugins/base/src/main/kotlin/parsers/Parser.kt
@@ -1,6 +1,8 @@
package org.jetbrains.dokka.base.parsers

import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.model.doc.Deprecated
import org.jetbrains.dokka.model.doc.Suppress

abstract class Parser {

Expand Down Expand Up @@ -49,10 +51,49 @@ abstract class Parser {

private fun jkdocToListOfPairs(javadoc: String): List<Pair<String, String>> =
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
"description $javadoc"
.split("\n@")
.splitIgnoredInsideBackticks("\n@")
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
.map { content ->
val contentWithEscapedAts = content.replace("\\@", "@")
val (tag, body) = contentWithEscapedAts.split(" ", limit = 2)
tag to body
}

private fun CharSequence.splitIgnoredInsideBackticks(delimiter: String): List<String> {
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
var countOfBackticks = 0
var countOfBackticksInOpeningFence = 0

var isInCode = false
val result = mutableListOf<String>()
val buf = StringBuilder()
var currentOffset = 0
while (currentOffset < length) {

if (get(currentOffset) == '`') {
countOfBackticks++
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
} else {
if (isInCode) {
// The closing code fence must be at least as long as the opening fence
isInCode = countOfBackticks < countOfBackticksInOpeningFence
} else {
if (countOfBackticks > 0) {
isInCode = true
countOfBackticksInOpeningFence = countOfBackticks
}
}
countOfBackticks = 0
}
if (!isInCode && startsWith(delimiter, currentOffset)) {
result.add(buf.toString())
buf.clear()
currentOffset += delimiter.length
continue
}

buf.append(get(currentOffset))
++currentOffset
}
result.add(buf.toString())
return result
}

}
2 changes: 2 additions & 0 deletions plugins/base/src/test/kotlin/markdown/ParserTest.kt
Expand Up @@ -951,6 +951,7 @@ class ParserTest : KDocTest() {
fun `Multilined Code Block`() {
val kdoc = """
| ```kotlin
| @Suppress("UNUSED_VARIABLE")
| val x: Int = 0
| val y: String = "Text"
|
Expand All @@ -968,6 +969,7 @@ class ParserTest : KDocTest() {
listOf(
CodeBlock(
listOf(
Text("@Suppress(\"UNUSED_VARIABLE\")"), Br,
Text("val x: Int = 0"), Br,
Text("val y: String = \"Text\""), Br, Br,
Text(" val z: Boolean = true"), Br,
Expand Down
@@ -1,12 +1,11 @@
package parsers

import org.jetbrains.dokka.base.parsers.moduleAndPackage.IllegalModuleAndPackageDocumentation
import org.intellij.markdown.MarkdownElementTypes
import org.jetbrains.dokka.base.parsers.moduleAndPackage.*
import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.Classifier.Module
import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentation.Classifier.Package
import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationFile
import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationFragment
import org.jetbrains.dokka.base.parsers.moduleAndPackage.ModuleAndPackageDocumentationSource
import org.jetbrains.dokka.base.parsers.moduleAndPackage.parseModuleAndPackageDocumentationFragments
import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.utilities.DokkaLogger
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -216,6 +215,64 @@ class ParseModuleAndPackageDocumentationFragmentsTest {
)
}

@Test
fun `at in code block is supported`() {
val fragment = parseModuleAndPackageDocumentationFragments(
source(
"""
# Module My Module
```
@Smth
```
@author Smb
""".trimIndent()
)
)

assertEquals(
"```\n" +
"@Smth\n" +
"```\n" +
"@author Smb", fragment.single().documentation,
"Expected documentation being available"
)

val parsingContext = ModuleAndPackageDocumentationParsingContext(object : DokkaLogger {
override var warningsCount: Int = 0
override var errorsCount: Int = 0
override fun debug(message: String) {}
override fun info(message: String) {}
override fun progress(message: String) {}
override fun warn(message: String) {}
override fun error(message: String) {}
})
val parsedFragment = parseModuleAndPackageDocumentation(parsingContext, fragment.single())
val expectedDocumentationNode = DocumentationNode(
listOf(
Description(
CustomDocTag(
listOf(
CodeBlock(
listOf(
Text("@Smth")
)
)
), name = MarkdownElementTypes.MARKDOWN_FILE.name
)
),
Author(
CustomDocTag(
listOf(
P(listOf(Text("Smb")))
), name = MarkdownElementTypes.MARKDOWN_FILE.name
)
)
)
)
assertEquals(
expectedDocumentationNode, parsedFragment.documentation
)
}

private fun source(documentation: String): ModuleAndPackageDocumentationSource =
object : ModuleAndPackageDocumentationSource() {
Expand Down