[Markdown][IDEA-305524] Add support for MS Azure mermaid code fences

GitOrigin-RevId: e2ec0fa87fba5abd147187bf14163fe382a764a9
This commit is contained in:
Ivan Posti
2023-02-10 16:06:59 +01:00
committed by intellij-monorepo-bot
parent f682aeb3a4
commit 9d384da8d7
3 changed files with 77 additions and 1 deletions

View File

@@ -15,6 +15,7 @@ import org.intellij.markdown.parser.constraints.getCharsEaten
import org.intellij.markdown.parser.markerblocks.MarkerBlockProvider
import org.intellij.markdown.parser.markerblocks.providers.*
import org.intellij.markdown.parser.sequentialparsers.SequentialParser
import org.intellij.plugins.markdown.lang.parser.blocks.CodeFenceMarkerProvider
import org.intellij.plugins.markdown.lang.parser.blocks.CommentAwareLinkReferenceDefinitionProvider
import org.intellij.plugins.markdown.lang.parser.blocks.DefinitionListMarkerProvider
import org.intellij.plugins.markdown.lang.parser.blocks.frontmatter.FrontMatterHeaderMarkerProvider
@@ -62,7 +63,7 @@ open class MarkdownDefaultMarkerProcessor(
override fun getMarkerBlockProviders(): List<MarkerBlockProvider<StateInfo>> {
return buildList {
add(CodeBlockProvider())
add(CodeFenceProvider())
add(CodeFenceMarkerProvider())
add(SetextHeaderProvider())
add(BlockQuoteProvider())
add(ListMarkerProvider())

View File

@@ -0,0 +1,39 @@
package org.intellij.plugins.markdown.lang.parser.blocks
import org.intellij.markdown.parser.LookaheadText
import org.intellij.markdown.parser.constraints.MarkdownConstraints
import org.intellij.markdown.parser.markerblocks.MarkerBlockProvider
import org.intellij.markdown.parser.markerblocks.providers.CodeFenceProvider
import org.jetbrains.annotations.ApiStatus
/**
* Extends default [CodeFenceProvider] to support additional MS Azure code fence syntax
* for Mermaid.js fences.
*
* ```markdown
* ::: mermaid
* <mermaid diagram syntax>
* :::
* ```
*/
@ApiStatus.Experimental
open class CodeFenceMarkerProvider: CodeFenceProvider() {
override fun obtainFenceOpeningInfo(pos: LookaheadText.Position, constraints: MarkdownConstraints): OpeningInfo? {
if (!MarkerBlockProvider.isStartOfLineWithConstraints(pos, constraints)) {
return null
}
val matchResult = openingRegex.find(pos.currentLineFromPosition) ?: return null
val delimiter = matchResult.groups[1]?.value
checkNotNull(delimiter) { "Failed to obtain delimiter group value from match result" }
val info = matchResult.groups[2]?.value
checkNotNull(info) { "Failed to obtain info string group value form match result" }
if (delimiter.startsWith(":::") && info.trim().lowercase() != "mermaid") {
return null
}
return OpeningInfo(delimiter, info)
}
companion object {
private val openingRegex = Regex("^ {0,3}(~~~+|```+|:::+)([^`]*)\$")
}
}

View File

@@ -0,0 +1,36 @@
package org.intellij.plugins.markdown.parser
import com.intellij.psi.SyntaxTraverser
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
import junit.framework.TestCase
import org.intellij.plugins.markdown.lang.psi.impl.MarkdownCodeFence
class MarkdownCodeFenceFlavourParserTest: LightPlatformCodeInsightTestCase() {
fun `test valid mermaid fence`() {
val content = """
::: mermaid
:::
""".trimIndent()
configureFromFileText("some.md", content)
val fence = findFence()
TestCase.assertNotNull("Failed to find a fence", fence)
checkNotNull(fence)
val language = fence.fenceLanguage?.trim()
TestCase.assertEquals("mermaid", language)
}
fun `test delimiter syntax with non mermaid info string`() {
val content = """
::: java
:::
""".trimIndent()
configureFromFileText("some.md", content)
val fence = findFence()
TestCase.assertNull("This fragment should not be parsed as a fence", fence)
}
private fun findFence(): MarkdownCodeFence? {
val elements = SyntaxTraverser.psiTraverser(file).asSequence()
return elements.filterIsInstance<MarkdownCodeFence>().firstOrNull()
}
}