From 0297955bd67e8f61cf10122a42bed80a402e74f2 Mon Sep 17 00:00:00 2001 From: "Dmitry.Krasilschikov" Date: Tue, 21 May 2019 18:35:05 +0300 Subject: [PATCH] IDEA-213112 introduce HTML in markdown GitOrigin-RevId: 3a3bc07feda3b94de0312167b331ffcfb5ceeba2 --- plugins/markdown/resource/META-INF/plugin.xml | 1 + .../markdown/lang/MarkdownElementTypes.java | 7 +++ .../markdown/lang/MarkdownFileViewProvider.kt | 56 +++++++++++++++++++ .../markdown/lang/psi/MarkdownPsiFactory.java | 3 - .../markdown/test/data/html/embedded/html1.md | 1 + .../test/data/html/embedded/html1.txt | 11 ++++ .../markdown/test/data/html/embedded/html2.md | 4 ++ .../test/data/html/embedded/html2.txt | 12 ++++ .../markdown/test/data/html/embedded/html3.md | 9 +++ .../test/data/html/embedded/html3.txt | 14 +++++ .../markdown/html/MarkdownEmbeddedHtmlTest.kt | 30 ++++++++++ 11 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownFileViewProvider.kt create mode 100644 plugins/markdown/test/data/html/embedded/html1.md create mode 100644 plugins/markdown/test/data/html/embedded/html1.txt create mode 100644 plugins/markdown/test/data/html/embedded/html2.md create mode 100644 plugins/markdown/test/data/html/embedded/html2.txt create mode 100644 plugins/markdown/test/data/html/embedded/html3.md create mode 100644 plugins/markdown/test/data/html/embedded/html3.txt create mode 100644 plugins/markdown/test/src/org/intellij/plugins/markdown/html/MarkdownEmbeddedHtmlTest.kt diff --git a/plugins/markdown/resource/META-INF/plugin.xml b/plugins/markdown/resource/META-INF/plugin.xml index 37f706c29e42..3422e583854b 100644 --- a/plugins/markdown/resource/META-INF/plugin.xml +++ b/plugins/markdown/resource/META-INF/plugin.xml @@ -31,6 +31,7 @@ Includes the following features:

+ diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownElementTypes.java b/plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownElementTypes.java index 142ea3a3f736..ba1f51949d78 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownElementTypes.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownElementTypes.java @@ -15,6 +15,7 @@ */ package org.intellij.plugins.markdown.lang; +import com.intellij.psi.templateLanguages.TemplateDataElementType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; @@ -22,6 +23,7 @@ import org.intellij.markdown.flavours.gfm.GFMElementTypes; import org.intellij.markdown.flavours.gfm.GFMTokenTypes; import static org.intellij.plugins.markdown.lang.MarkdownElementType.platformType; +import static org.intellij.plugins.markdown.lang.MarkdownTokenTypes.HTML_BLOCK_CONTENT; public interface MarkdownElementTypes { IFileElementType MARKDOWN_FILE_ELEMENT_TYPE = new IStubFileElementType("Markdown file", MarkdownLanguage.INSTANCE); @@ -62,6 +64,11 @@ public interface MarkdownElementTypes { IElementType HTML_BLOCK = platformType(org.intellij.markdown.MarkdownElementTypes.HTML_BLOCK); + IElementType MARKDOWN_OUTER_BLOCK = new IElementType("MARKDOWN_OUTER_BLOCK", MarkdownLanguage.INSTANCE); + + TemplateDataElementType MARKDOWN_TEMPLATE_DATA = + new TemplateDataElementType("MARKDOWN_TEMPLATE_DATA", MarkdownLanguage.INSTANCE, HTML_BLOCK_CONTENT, MARKDOWN_OUTER_BLOCK); + IElementType AUTOLINK = platformType(org.intellij.markdown.MarkdownElementTypes.AUTOLINK); IElementType TABLE = platformType(GFMElementTypes.TABLE); diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownFileViewProvider.kt b/plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownFileViewProvider.kt new file mode 100644 index 000000000000..87b9b3e13771 --- /dev/null +++ b/plugins/markdown/src/org/intellij/plugins/markdown/lang/MarkdownFileViewProvider.kt @@ -0,0 +1,56 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.intellij.plugins.markdown.lang + +import com.intellij.lang.Language +import com.intellij.lang.LanguageParserDefinitions +import com.intellij.lang.StdLanguages +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.* +import com.intellij.psi.impl.source.PsiFileImpl +import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider +import gnu.trove.THashSet +import org.intellij.plugins.markdown.lang.MarkdownElementTypes.MARKDOWN_TEMPLATE_DATA +import org.intellij.plugins.markdown.lang.psi.impl.MarkdownFile + +class MarkdownFileViewProvider(manager: PsiManager, virtualFile: VirtualFile, eventSystemEnabled: Boolean) + : MultiplePsiFilesPerDocumentFileViewProvider(manager, virtualFile, eventSystemEnabled), TemplateLanguageFileViewProvider { + + private val myRelevantLanguages = THashSet() + + init { + myRelevantLanguages.add(baseLanguage) + myRelevantLanguages.add(templateDataLanguage) + } + + override fun createFile(lang: Language): PsiFile? { + if (lang === MarkdownLanguage.INSTANCE) { + return MarkdownFile(this) + } + + val parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang) ?: return null + + val psiFile = parserDefinition.createFile(this) + if (lang === templateDataLanguage && psiFile is PsiFileImpl) { + psiFile.contentElementType = MARKDOWN_TEMPLATE_DATA + } + + return psiFile + } + + override fun getBaseLanguage(): Language = MarkdownLanguage.INSTANCE + + override fun getLanguages(): Set = myRelevantLanguages + + override fun getTemplateDataLanguage(): Language = StdLanguages.HTML + + override fun cloneInner(fileCopy: VirtualFile): MultiplePsiFilesPerDocumentFileViewProvider = + MarkdownFileViewProvider(manager, fileCopy, false) +} + +class MarkdownFileViewProviderFactory : FileViewProviderFactory { + override fun createFileViewProvider(file: VirtualFile, + language: Language, + manager: PsiManager, + eventSystemEnabled: Boolean): FileViewProvider = + MarkdownFileViewProvider(manager, file, eventSystemEnabled) +} \ No newline at end of file diff --git a/plugins/markdown/src/org/intellij/plugins/markdown/lang/psi/MarkdownPsiFactory.java b/plugins/markdown/src/org/intellij/plugins/markdown/lang/psi/MarkdownPsiFactory.java index 76c529a6079f..45210209aed2 100644 --- a/plugins/markdown/src/org/intellij/plugins/markdown/lang/psi/MarkdownPsiFactory.java +++ b/plugins/markdown/src/org/intellij/plugins/markdown/lang/psi/MarkdownPsiFactory.java @@ -42,9 +42,6 @@ public enum MarkdownPsiFactory { if (elementType == MarkdownElementTypes.CODE_BLOCK) { return new MarkdownCodeBlockImpl(node); } - if (elementType == MarkdownElementTypes.HTML_BLOCK) { - return new MarkdownHtmlBlockImpl(node); - } if (elementType == MarkdownElementTypes.TABLE) { return new MarkdownTableImpl(node); } diff --git a/plugins/markdown/test/data/html/embedded/html1.md b/plugins/markdown/test/data/html/embedded/html1.md new file mode 100644 index 000000000000..d41397a357c7 --- /dev/null +++ b/plugins/markdown/test/data/html/embedded/html1.md @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/plugins/markdown/test/data/html/embedded/html1.txt b/plugins/markdown/test/data/html/embedded/html1.txt new file mode 100644 index 000000000000..cd3f0ee45897 --- /dev/null +++ b/plugins/markdown/test/data/html/embedded/html1.txt @@ -0,0 +1,11 @@ +HtmlFile:html1.md + PsiElement(HTML_DOCUMENT) + PsiElement(XML_PROLOG) + + HtmlTag:table + XmlToken:XML_START_TAG_START('<') + XmlToken:XML_NAME('table') + XmlToken:XML_TAG_END('>') + XmlToken:XML_END_TAG_START('') diff --git a/plugins/markdown/test/data/html/embedded/html2.md b/plugins/markdown/test/data/html/embedded/html2.md new file mode 100644 index 000000000000..f2bb2bb02df5 --- /dev/null +++ b/plugins/markdown/test/data/html/embedded/html2.md @@ -0,0 +1,4 @@ + + +**bold** +
\ No newline at end of file diff --git a/plugins/markdown/test/data/html/embedded/html2.txt b/plugins/markdown/test/data/html/embedded/html2.txt new file mode 100644 index 000000000000..65767f6c7a2b --- /dev/null +++ b/plugins/markdown/test/data/html/embedded/html2.txt @@ -0,0 +1,12 @@ +HtmlFile:html2.md + PsiElement(HTML_DOCUMENT) + PsiElement(XML_PROLOG) + + HtmlTag:table + XmlToken:XML_START_TAG_START('<') + XmlToken:XML_NAME('table') + XmlToken:XML_TAG_END('>') + PsiElement(MARKDOWN_OUTER_BLOCK)('\n\n**bold**\n') + XmlToken:XML_END_TAG_START('') diff --git a/plugins/markdown/test/data/html/embedded/html3.md b/plugins/markdown/test/data/html/embedded/html3.md new file mode 100644 index 000000000000..ff564ac93725 --- /dev/null +++ b/plugins/markdown/test/data/html/embedded/html3.md @@ -0,0 +1,9 @@ +#header + + + +#header + +
+ +#header \ No newline at end of file diff --git a/plugins/markdown/test/data/html/embedded/html3.txt b/plugins/markdown/test/data/html/embedded/html3.txt new file mode 100644 index 000000000000..321f668271ed --- /dev/null +++ b/plugins/markdown/test/data/html/embedded/html3.txt @@ -0,0 +1,14 @@ +HtmlFile:html3.md + PsiElement(HTML_DOCUMENT) + PsiElement(XML_PROLOG) + + PsiElement(MARKDOWN_OUTER_BLOCK)('#header\n\n') + HtmlTag:table + XmlToken:XML_START_TAG_START('<') + XmlToken:XML_NAME('table') + XmlToken:XML_TAG_END('>') + PsiElement(MARKDOWN_OUTER_BLOCK)('\n\n#header\n\n') + XmlToken:XML_END_TAG_START('') + PsiElement(MARKDOWN_OUTER_BLOCK)('\n\n#header') diff --git a/plugins/markdown/test/src/org/intellij/plugins/markdown/html/MarkdownEmbeddedHtmlTest.kt b/plugins/markdown/test/src/org/intellij/plugins/markdown/html/MarkdownEmbeddedHtmlTest.kt new file mode 100644 index 000000000000..d79bee4d4d5c --- /dev/null +++ b/plugins/markdown/test/src/org/intellij/plugins/markdown/html/MarkdownEmbeddedHtmlTest.kt @@ -0,0 +1,30 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.intellij.plugins.markdown.html + +import com.intellij.lang.html.HTMLLanguage +import com.intellij.psi.impl.DebugUtil +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase +import junit.framework.TestCase +import org.intellij.plugins.markdown.MarkdownTestingUtil + +class MarkdownEmbeddedHtmlTest : LightPlatformCodeInsightFixtureTestCase() { + override fun getTestDataPath(): String { + return MarkdownTestingUtil.TEST_DATA_PATH + "/html/embedded/" + } + + fun testHtml1() = doTest() + + fun testHtml2() = doTest() + + fun testHtml3() = doTest() + + fun doTest() { + val name = getTestName(true) + val file = myFixture.configureByFile("$name.md") + + val psi = DebugUtil.psiToString(file.viewProvider.getPsi(HTMLLanguage.INSTANCE), false, false) + val tree = myFixture.configureByFile("$name.txt").text + + TestCase.assertEquals(psi, tree) + } +} \ No newline at end of file