mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
IDEA-342771 Rename QuickDocCodeHighlightingHelper to QuickDocHighlightingHelper, improve API and add JavaDoc
GitOrigin-RevId: 412d6ec56fc0f08a4383f03357f9b93fa0ef2698
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fa7bfe0a4b
commit
6140fd9910
@@ -83,7 +83,7 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.intellij.codeInsight.javadoc.SnippetMarkup.*;
|
||||
import static com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.*;
|
||||
import static com.intellij.lang.documentation.QuickDocHighlightingHelper.*;
|
||||
|
||||
|
||||
public class JavaDocInfoGenerator {
|
||||
|
||||
@@ -61,7 +61,7 @@ import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.appendStyledSignatureFragment;
|
||||
import static com.intellij.lang.documentation.QuickDocHighlightingHelper.appendStyledSignatureFragment;
|
||||
import static com.intellij.util.ObjectUtils.notNull;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight.documentation;
|
||||
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper;
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
@@ -92,7 +92,7 @@ public final class DocumentationHtmlUtil {
|
||||
|
||||
// Styled code
|
||||
EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
result.addAll(QuickDocCodeHighlightingHelper.getDefaultDocCodeStyles(globalScheme, background));
|
||||
result.addAll(QuickDocHighlightingHelper.getDefaultDocCodeStyles(globalScheme, background));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.intellij.codeInsight.documentation.DocumentationActionProvider;
|
||||
import com.intellij.codeInsight.documentation.DocumentationComponent;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper;
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -385,7 +385,7 @@ public final class DocRenderer implements CustomFoldRegionRenderer {
|
||||
".section {padding-right: 5; white-space: nowrap}" +
|
||||
".content {padding: 2 0 2 0}" +
|
||||
(useTipsKit ? createAdditionalStylesForTips(editor) : "") +
|
||||
StringUtil.join(QuickDocCodeHighlightingHelper.getDefaultDocCodeStyles(
|
||||
StringUtil.join(QuickDocHighlightingHelper.getDefaultDocCodeStyles(
|
||||
colorsScheme, colorsScheme.getDefaultBackground()), "\n");
|
||||
StyleSheet result = StyleSheetUtil.loadStyleSheet(input);
|
||||
if (!useTipsKit) {
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.lang.documentation
|
||||
|
||||
import com.intellij.ide.ui.html.StyleSheetRulesProviderForCodeHighlighting
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.documentation.DocumentationSettings.InlineCodeHighlightingMode
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.project.DefaultProjectFactory
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.xml.util.XmlStringUtil
|
||||
import java.awt.Color
|
||||
|
||||
object QuickDocCodeHighlightingHelper {
|
||||
|
||||
const val CODE_BLOCK_PREFIX = StyleSheetRulesProviderForCodeHighlighting.CODE_BLOCK_PREFIX
|
||||
const val CODE_BLOCK_SUFFIX = StyleSheetRulesProviderForCodeHighlighting.CODE_BLOCK_SUFFIX
|
||||
|
||||
const val INLINE_CODE_PREFIX = StyleSheetRulesProviderForCodeHighlighting.INLINE_CODE_PREFIX
|
||||
const val INLINE_CODE_SUFFIX = StyleSheetRulesProviderForCodeHighlighting.INLINE_CODE_SUFFIX
|
||||
|
||||
@JvmStatic
|
||||
fun getStyledCodeBlock(code: @NlsSafe CharSequence, language: Language?, project: Project? = null): @NlsSafe String =
|
||||
StringBuilder().apply { appendStyledCodeBlock(code, language, project) }.toString()
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledCodeBlock(code: @NlsSafe CharSequence,
|
||||
language: Language?,
|
||||
project: Project? = null): @NlsSafe StringBuilder =
|
||||
append(CODE_BLOCK_PREFIX)
|
||||
.appendHighlightedCode(DocumentationSettings.isHighlightingOfCodeBlocksEnabled(), code, language, project, true)
|
||||
.append(CODE_BLOCK_SUFFIX)
|
||||
|
||||
@JvmStatic
|
||||
fun removeSurroundingStyledCodeBlock(string: String): String =
|
||||
string.trim().removeSurrounding(CODE_BLOCK_PREFIX, CODE_BLOCK_SUFFIX)
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun getStyledInlineCode(@NlsSafe code: String, language: Language? = null, project: Project? = null): @NlsSafe String =
|
||||
StringBuilder().apply { appendStyledInlineCode(code, language, project) }.toString()
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun StringBuilder.appendStyledInlineCode(@NlsSafe code: String, language: Language? = null, project: Project? = null): StringBuilder =
|
||||
append(INLINE_CODE_PREFIX)
|
||||
.appendHighlightedCode(
|
||||
DocumentationSettings.getInlineCodeHighlightingMode() == InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING, code, language, project,
|
||||
true)
|
||||
.append(INLINE_CODE_SUFFIX)
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun getStyledInlineCodeFragment(code: String, language: Language? = null, project: Project? = null): String =
|
||||
StringBuilder().apply { appendStyledInlineCodeFragment(code, language, project) }.toString()
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun StringBuilder.appendStyledInlineCodeFragment(code: String, language: Language? = null, project: Project? = null): StringBuilder =
|
||||
appendHighlightedCode(true, code, language, project, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledLinkFragment(contents: String, textAttributes: TextAttributes): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), textAttributes,
|
||||
contents, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledLinkFragment(contents: String, textAttributesKey: TextAttributesKey): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), textAttributesKey,
|
||||
contents, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledSignatureFragment(contents: String, textAttributes: TextAttributes): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(), textAttributes,
|
||||
contents, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledSignatureFragment(contents: String, textAttributesKey: TextAttributesKey): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(), textAttributesKey,
|
||||
contents, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledFragment(contents: String, textAttributes: TextAttributes): StringBuilder =
|
||||
appendStyledSpan(true, textAttributes, contents, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledFragment(contents: String, textAttributesKey: TextAttributesKey): StringBuilder =
|
||||
appendStyledSpan(true, textAttributesKey, contents, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendWrappedWithInlineCodeTag(@NlsSafe contents: CharSequence): @NlsSafe StringBuilder =
|
||||
if (!contents.isBlank())
|
||||
append(INLINE_CODE_PREFIX, contents, INLINE_CODE_SUFFIX)
|
||||
else
|
||||
this
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.wrapWithInlineCodeTag(): @NlsSafe StringBuilder =
|
||||
if (!isBlank())
|
||||
insert(0, INLINE_CODE_PREFIX)
|
||||
.append(INLINE_CODE_SUFFIX)
|
||||
else
|
||||
this
|
||||
|
||||
@JvmStatic
|
||||
fun wrapWithInlineCodeTag(string: String): @NlsSafe String =
|
||||
if (!string.isBlank())
|
||||
INLINE_CODE_PREFIX + string + INLINE_CODE_SUFFIX
|
||||
else
|
||||
string
|
||||
|
||||
@JvmStatic
|
||||
fun guessLanguage(language: String?): Language? =
|
||||
if (language == null)
|
||||
null
|
||||
else
|
||||
Language
|
||||
.findInstancesByMimeType(language)
|
||||
.asSequence()
|
||||
.plus(Language.findInstancesByMimeType("text/$language"))
|
||||
.plus(
|
||||
Language.getRegisteredLanguages()
|
||||
.asSequence()
|
||||
.filter { languageMatches(language, it) }
|
||||
)
|
||||
.firstOrNull()
|
||||
|
||||
@JvmStatic
|
||||
fun getDefaultDocCodeStyles(
|
||||
colorScheme: EditorColorsScheme,
|
||||
editorPaneBackgroundColor: Color,
|
||||
): List<String> = StyleSheetRulesProviderForCodeHighlighting.getRules(
|
||||
colorScheme, editorPaneBackgroundColor,
|
||||
listOf(".content", ".content-separated", ".content-only div:not(.bottom)", ".sections"),
|
||||
listOf(".definition code", ".definition pre", ".definition-only code", ".definition-only"),
|
||||
DocumentationSettings.isCodeBackgroundEnabled()
|
||||
&& DocumentationSettings.getInlineCodeHighlightingMode() !== InlineCodeHighlightingMode.NO_HIGHLIGHTING,
|
||||
DocumentationSettings.isCodeBackgroundEnabled()
|
||||
&& DocumentationSettings.isHighlightingOfCodeBlocksEnabled(),
|
||||
)
|
||||
|
||||
private fun StringBuilder.appendHighlightedCode(doHighlighting: Boolean, code: CharSequence, language: Language?, project: Project?,
|
||||
isForRenderedDoc: Boolean): StringBuilder {
|
||||
val trimmedCode = code.toString().trim('\n', '\r').trimIndent().replace(' ', ' ')
|
||||
if (language != null && doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(
|
||||
this, project ?: DefaultProjectFactory.getInstance().defaultProject, language, trimmedCode,
|
||||
DocumentationSettings.getHighlightingSaturation(isForRenderedDoc))
|
||||
}
|
||||
else {
|
||||
append(XmlStringUtil.escapeString(trimmedCode))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendStyledSpan(doHighlighting: Boolean, attributesKey: TextAttributesKey,
|
||||
value: String?, isForRenderedDoc: Boolean): StringBuilder {
|
||||
if (doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendStyledSpan(this, attributesKey, value, DocumentationSettings.getHighlightingSaturation(isForRenderedDoc))
|
||||
}
|
||||
else {
|
||||
append(XmlStringUtil.escapeString(value))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendStyledSpan(doHighlighting: Boolean, attributes: TextAttributes,
|
||||
value: String?, isForRenderedDoc: Boolean): StringBuilder {
|
||||
if (doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendStyledSpan(this, attributes, value, DocumentationSettings.getHighlightingSaturation(isForRenderedDoc))
|
||||
}
|
||||
else {
|
||||
append(XmlStringUtil.escapeString(value))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun languageMatches(langType: String, language: Language): Boolean =
|
||||
langType.equals(language.id, ignoreCase = true)
|
||||
|| FileTypeManager.getInstance().getFileTypeByExtension(langType) === language.associatedFileType
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.lang.documentation
|
||||
|
||||
import com.intellij.ide.ui.html.StyleSheetRulesProviderForCodeHighlighting
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.documentation.DocumentationSettings.InlineCodeHighlightingMode
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.concurrency.annotations.RequiresReadLock
|
||||
import com.intellij.xml.util.XmlStringUtil
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.awt.Color
|
||||
|
||||
/**
|
||||
* This class facilitates generation of highlighted text and code for Quick Documentation.
|
||||
* It honors [DocumentationSettings], when highlighting code and links.
|
||||
*/
|
||||
object QuickDocHighlightingHelper {
|
||||
|
||||
const val CODE_BLOCK_PREFIX = StyleSheetRulesProviderForCodeHighlighting.CODE_BLOCK_PREFIX
|
||||
const val CODE_BLOCK_SUFFIX = StyleSheetRulesProviderForCodeHighlighting.CODE_BLOCK_SUFFIX
|
||||
|
||||
const val INLINE_CODE_PREFIX = StyleSheetRulesProviderForCodeHighlighting.INLINE_CODE_PREFIX
|
||||
const val INLINE_CODE_SUFFIX = StyleSheetRulesProviderForCodeHighlighting.INLINE_CODE_SUFFIX
|
||||
|
||||
/**
|
||||
* The returned code block HTML (prefixed with [CODE_BLOCK_PREFIX] and suffixed with [CODE_BLOCK_SUFFIX])
|
||||
* has syntax highlighted, if there is language provided and
|
||||
* [DocumentationSettings.isHighlightingOfCodeBlocksEnabled] is `true`. The code block will
|
||||
* be rendered with a special background if [DocumentationSettings.isCodeBackgroundEnabled] is `true`.
|
||||
*/
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
fun getStyledCodeBlock(project: Project, language: Language?, code: @NlsSafe CharSequence): @NlsSafe String =
|
||||
StringBuilder().apply { appendStyledCodeBlock(project, language, code) }.toString()
|
||||
|
||||
/**
|
||||
* Appends code block HTML (prefixed with [CODE_BLOCK_PREFIX] and suffixed with [CODE_BLOCK_SUFFIX]),
|
||||
* which has syntax highlighted, if there is language provided and
|
||||
* [DocumentationSettings.isHighlightingOfCodeBlocksEnabled] is `true`. The code block will
|
||||
* be rendered with a special background if [DocumentationSettings.isCodeBackgroundEnabled] is `true`.
|
||||
*/
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
fun StringBuilder.appendStyledCodeBlock(project: Project, language: Language?, code: @NlsSafe CharSequence): @NlsSafe StringBuilder =
|
||||
append(CODE_BLOCK_PREFIX)
|
||||
.appendHighlightedCode(project, language, DocumentationSettings.isHighlightingOfCodeBlocksEnabled(), code, true)
|
||||
.append(CODE_BLOCK_SUFFIX)
|
||||
|
||||
@JvmStatic
|
||||
fun removeSurroundingStyledCodeBlock(string: String): String =
|
||||
string.trim().removeSurrounding(CODE_BLOCK_PREFIX, CODE_BLOCK_SUFFIX)
|
||||
|
||||
/**
|
||||
* The returned inline code HTML (prefixed with [INLINE_CODE_PREFIX] and suffixed with [INLINE_CODE_SUFFIX])
|
||||
* has syntax highlighted, if there is language provided and
|
||||
* [DocumentationSettings.getInlineCodeHighlightingMode] is [DocumentationSettings.InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING].
|
||||
* The code block will be rendered with a special background if [DocumentationSettings.isCodeBackgroundEnabled] is `true` and
|
||||
* [DocumentationSettings.getInlineCodeHighlightingMode] is not [DocumentationSettings.InlineCodeHighlightingMode.NO_HIGHLIGHTING].
|
||||
*/
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
fun getStyledInlineCode(project: Project, language: Language?, @NlsSafe code: String): @NlsSafe String =
|
||||
StringBuilder().apply { appendStyledInlineCode(project, language, code) }.toString()
|
||||
|
||||
/**
|
||||
* Appends inline code HTML (prefixed with [INLINE_CODE_PREFIX] and suffixed with [INLINE_CODE_SUFFIX]),
|
||||
* which has syntax highlighted, if there is language provided and
|
||||
* [DocumentationSettings.getInlineCodeHighlightingMode] is [DocumentationSettings.InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING].
|
||||
* The code block will be rendered with a special background if [DocumentationSettings.isCodeBackgroundEnabled] is `true` and
|
||||
* [DocumentationSettings.getInlineCodeHighlightingMode] is not [DocumentationSettings.InlineCodeHighlightingMode.NO_HIGHLIGHTING].
|
||||
*/
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
fun StringBuilder.appendStyledInlineCode(project: Project, language: Language?, @NlsSafe code: String): StringBuilder =
|
||||
append(INLINE_CODE_PREFIX)
|
||||
.appendHighlightedCode(
|
||||
project, language, DocumentationSettings.getInlineCodeHighlightingMode() == InlineCodeHighlightingMode.SEMANTIC_HIGHLIGHTING, code,
|
||||
true)
|
||||
.append(INLINE_CODE_SUFFIX)
|
||||
|
||||
/**
|
||||
* Returns an HTML fragment containing [code] highlighted with [language].
|
||||
*
|
||||
* Should not be used when generating Quick Doc signature or [PsiElement] links.
|
||||
*/
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
fun getStyledInlineCodeFragment(project: Project, language: Language, @NlsSafe code: String): @NlsSafe String =
|
||||
StringBuilder().apply { appendStyledInlineCodeFragment(project, language, code) }.toString()
|
||||
|
||||
/**
|
||||
* Appends an HTML fragment containing [code] highlighted with [language].
|
||||
*
|
||||
* Should not be used when generating Quick Doc signature or [PsiElement] links.
|
||||
*/
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
fun StringBuilder.appendStyledInlineCodeFragment(project: Project, language: Language, @NlsSafe code: String): StringBuilder =
|
||||
appendHighlightedCode(project, language, true, code, false)
|
||||
|
||||
/**
|
||||
* This method should be used when generating links to PsiElements.
|
||||
*
|
||||
* Appends an HTML fragment containing [contents] colored according to [textAttributes]
|
||||
* if [DocumentationSettings.isSemanticHighlightingOfLinksEnabled] is `true`.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledLinkFragment(contents: String, textAttributes: TextAttributes): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), textAttributes,
|
||||
contents, false)
|
||||
|
||||
/**
|
||||
* This method should be used when generating links to PsiElements.
|
||||
*
|
||||
* Appends an HTML fragment containing [contents] colored according to [textAttributesKey]
|
||||
* if [DocumentationSettings.isSemanticHighlightingOfLinksEnabled] is `true`.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledLinkFragment(contents: String, textAttributesKey: TextAttributesKey): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isSemanticHighlightingOfLinksEnabled(), textAttributesKey,
|
||||
contents, false)
|
||||
|
||||
/**
|
||||
* This method should be used when generating Quick Doc element signatures.
|
||||
*
|
||||
* Appends an HTML fragment containing [contents] colored according to [textAttributes]
|
||||
* if [DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled] is `true`.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledSignatureFragment(contents: String, textAttributes: TextAttributes): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(), textAttributes,
|
||||
contents, false)
|
||||
|
||||
/**
|
||||
* This method should be used when generating Quick Doc element signatures.
|
||||
*
|
||||
* Appends an HTML fragment containing [contents] colored according to [textAttributesKey]
|
||||
* if [DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled] is `true`.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledSignatureFragment(contents: String, textAttributesKey: TextAttributesKey): StringBuilder =
|
||||
appendStyledSpan(DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(), textAttributesKey,
|
||||
contents, false)
|
||||
|
||||
/**
|
||||
* This method should be used when generating Quick Doc element signatures.
|
||||
*
|
||||
* Appends an HTML fragment containing containing [code] highlighted with [language]
|
||||
* if [DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled] is `true`.
|
||||
*/
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
fun StringBuilder.appendStyledSignatureFragment(project: Project, language: Language, code: String): StringBuilder =
|
||||
appendHighlightedCode(project, language, DocumentationSettings.isHighlightingOfQuickDocSignaturesEnabled(), code, false)
|
||||
|
||||
/**
|
||||
* Returns an HTML fragment containing [contents] colored according to [textAttributes].
|
||||
*
|
||||
* Should not be used when generating Quick Doc signature or [PsiElement] links.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getStyledFragment(contents: String, textAttributes: TextAttributes): String =
|
||||
StringBuilder().apply { appendStyledFragment(contents, textAttributes) }.toString()
|
||||
|
||||
/**
|
||||
* Returns an HTML fragment containing [contents] colored according to [textAttributesKey].
|
||||
*
|
||||
* Should not be used when generating Quick Doc signature or [PsiElement] links.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getStyledFragment(contents: String, textAttributesKey: TextAttributesKey): String =
|
||||
StringBuilder().apply { appendStyledFragment(contents, textAttributesKey) }.toString()
|
||||
|
||||
/**
|
||||
* Appends an HTML fragment containing [contents] colored according to [textAttributes].
|
||||
*
|
||||
* Should not be used when generating Quick Doc signature or [PsiElement] links.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledFragment(contents: String, textAttributes: TextAttributes): StringBuilder =
|
||||
appendStyledSpan(true, textAttributes, contents, false)
|
||||
|
||||
/**
|
||||
* Appends an HTML fragment containing [contents] colored according to [textAttributesKey].
|
||||
*
|
||||
* Should not be used when generating Quick Doc signature or [PsiElement] links.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendStyledFragment(contents: String, textAttributesKey: TextAttributesKey): StringBuilder =
|
||||
appendStyledSpan(true, textAttributesKey, contents, false)
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.appendWrappedWithInlineCodeTag(@NlsSafe contents: CharSequence): @NlsSafe StringBuilder =
|
||||
if (!contents.isBlank())
|
||||
append(INLINE_CODE_PREFIX, contents, INLINE_CODE_SUFFIX)
|
||||
else
|
||||
this
|
||||
|
||||
@JvmStatic
|
||||
fun StringBuilder.wrapWithInlineCodeTag(): @NlsSafe StringBuilder =
|
||||
if (!isBlank())
|
||||
insert(0, INLINE_CODE_PREFIX)
|
||||
.append(INLINE_CODE_SUFFIX)
|
||||
else
|
||||
this
|
||||
|
||||
@JvmStatic
|
||||
fun wrapWithInlineCodeTag(string: String): @NlsSafe String =
|
||||
if (!string.isBlank())
|
||||
INLINE_CODE_PREFIX + string + INLINE_CODE_SUFFIX
|
||||
else
|
||||
string
|
||||
|
||||
/**
|
||||
* Tries to guess a registered IDE language based. Useful e.g. for Markdown support
|
||||
* to figure out a language to render a code block.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun guessLanguage(language: String?): Language? =
|
||||
if (language == null)
|
||||
null
|
||||
else
|
||||
Language
|
||||
.findInstancesByMimeType(language)
|
||||
.asSequence()
|
||||
.plus(Language.findInstancesByMimeType("text/$language"))
|
||||
.plus(
|
||||
Language.getRegisteredLanguages()
|
||||
.asSequence()
|
||||
.filter { languageMatches(language, it) }
|
||||
)
|
||||
.firstOrNull()
|
||||
|
||||
@Internal
|
||||
@JvmStatic
|
||||
fun getDefaultDocCodeStyles(
|
||||
colorScheme: EditorColorsScheme,
|
||||
editorPaneBackgroundColor: Color,
|
||||
): List<String> = StyleSheetRulesProviderForCodeHighlighting.getRules(
|
||||
colorScheme, editorPaneBackgroundColor,
|
||||
listOf(".content", ".content-separated", ".content-only div:not(.bottom)", ".sections"),
|
||||
listOf(".definition code", ".definition pre", ".definition-only code", ".definition-only"),
|
||||
DocumentationSettings.isCodeBackgroundEnabled()
|
||||
&& DocumentationSettings.getInlineCodeHighlightingMode() !== InlineCodeHighlightingMode.NO_HIGHLIGHTING,
|
||||
DocumentationSettings.isCodeBackgroundEnabled()
|
||||
&& DocumentationSettings.isHighlightingOfCodeBlocksEnabled(),
|
||||
)
|
||||
|
||||
private fun StringBuilder.appendHighlightedCode(project: Project, language: Language?, doHighlighting: Boolean,
|
||||
code: CharSequence, isForRenderedDoc: Boolean): StringBuilder {
|
||||
val trimmedCode = code.toString().trim('\n', '\r').trimIndent().replace(' ', ' ')
|
||||
if (language != null && doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(
|
||||
this, project, language, trimmedCode,
|
||||
DocumentationSettings.getHighlightingSaturation(isForRenderedDoc))
|
||||
}
|
||||
else {
|
||||
append(XmlStringUtil.escapeString(trimmedCode))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendStyledSpan(doHighlighting: Boolean, attributesKey: TextAttributesKey,
|
||||
value: String?, isForRenderedDoc: Boolean): StringBuilder {
|
||||
if (doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendStyledSpan(this, attributesKey, value, DocumentationSettings.getHighlightingSaturation(isForRenderedDoc))
|
||||
}
|
||||
else {
|
||||
append(XmlStringUtil.escapeString(value))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendStyledSpan(doHighlighting: Boolean, attributes: TextAttributes,
|
||||
value: String?, isForRenderedDoc: Boolean): StringBuilder {
|
||||
if (doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendStyledSpan(this, attributes, value, DocumentationSettings.getHighlightingSaturation(isForRenderedDoc))
|
||||
}
|
||||
else {
|
||||
append(XmlStringUtil.escapeString(value))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun languageMatches(langType: String, language: Language): Boolean =
|
||||
langType.equals(language.id, ignoreCase = true)
|
||||
|| FileTypeManager.getInstance().getFileTypeByExtension(langType) === language.associatedFileType
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package com.intellij.openapi.editor.richcopy;
|
||||
|
||||
import com.intellij.ide.highlighter.HighlighterFactory;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper;
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.ColorKey;
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.util.concurrency.annotations.RequiresReadLock;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -35,20 +36,24 @@ public final class HtmlSyntaxInfoUtil {
|
||||
|
||||
private HtmlSyntaxInfoUtil() { }
|
||||
|
||||
public static @NotNull String getStyledSpan(@Nullable String value, String @NotNull ... properties) {
|
||||
return appendStyledSpan(new StringBuilder(), value, properties).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link QuickDocHighlightingHelper} for adding highlighted HTML to documentation
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static @NotNull String getStyledSpan(@NotNull TextAttributesKey attributesKey, @Nullable String value, float saturationFactor) {
|
||||
return appendStyledSpan(new StringBuilder(), attributesKey, value, saturationFactor).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link QuickDocHighlightingHelper} for adding highlighted HTML to documentation
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static @NotNull String getStyledSpan(@NotNull TextAttributes attributes, @Nullable String value, float saturationFactor) {
|
||||
return appendStyledSpan(new StringBuilder(), attributes, value, saturationFactor).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link QuickDocCodeHighlightingHelper} for adding code fragments to documentation
|
||||
* @deprecated Use {@link QuickDocHighlightingHelper} for adding code fragments to documentation
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static @NotNull String getHighlightedByLexerAndEncodedAsHtmlCodeSnippet(
|
||||
@@ -108,6 +113,7 @@ public final class HtmlSyntaxInfoUtil {
|
||||
return appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(buffer, project, language, codeSnippet, true, saturationFactor);
|
||||
}
|
||||
|
||||
@RequiresReadLock
|
||||
public static @NotNull StringBuilder appendHighlightedByLexerAndEncodedAsHtmlCodeSnippet(
|
||||
@NotNull StringBuilder buffer,
|
||||
@NotNull Project project,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.markdown.utils.doc
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.documentation.DocumentationSettings
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper
|
||||
import com.intellij.markdown.utils.doc.impl.DocFlavourDescriptor
|
||||
import com.intellij.markdown.utils.doc.impl.DocTagRenderer
|
||||
import com.intellij.openapi.diagnostic.ControlFlowException
|
||||
@@ -9,7 +12,9 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.ui.ColorUtil
|
||||
import com.intellij.util.concurrency.annotations.RequiresReadLock
|
||||
import com.intellij.util.containers.CollectionFactory
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.ui.UIUtil
|
||||
@@ -20,9 +25,12 @@ import org.jetbrains.annotations.Contract
|
||||
import org.jetbrains.annotations.Nls
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* [DocMarkdownToHtmlConverter] handles conversion of Markdown text to HTML, which is intended
|
||||
* to be displayed in Quick Doc popup, or inline in an editor.
|
||||
*/
|
||||
object DocMarkdownToHtmlConverter {
|
||||
private val LOG = Logger.getInstance(DocMarkdownToHtmlConverter::class.java)
|
||||
|
||||
private val TAG_START_OR_CLOSE_PATTERN: Pattern = Pattern.compile("(<)/?(\\w+)[> ]")
|
||||
internal val TAG_PATTERN: Pattern = Pattern.compile("^</?([a-z][a-z-_0-9]*)[^>]*>$", Pattern.CASE_INSENSITIVE)
|
||||
private val SPLIT_BY_LINE_PATTERN: Pattern = Pattern.compile("\n|\r|\r\n")
|
||||
@@ -65,10 +73,18 @@ object DocMarkdownToHtmlConverter {
|
||||
))
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts provided Markdown text to HTML. The results are intended to be used for Quick Documentation.
|
||||
* If [defaultLanguage] is provided, it will be used for syntax coloring of inline code and code blocks, if language specifier is missing.
|
||||
* Block and inline code syntax coloring is being done by [QuickDocHighlightingHelper], which honors [DocumentationSettings].
|
||||
* Conversion must be run within a Read Action as it might require to create intermediate [PsiFile] to highlight block of code,
|
||||
* or an inline code.
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
@JvmStatic
|
||||
@RequiresReadLock
|
||||
@JvmOverloads
|
||||
fun convert(markdownText: String, project: Project? = null): String {
|
||||
fun convert(project: Project, markdownText: String, defaultLanguage: Language? = null): String {
|
||||
val lines = SPLIT_BY_LINE_PATTERN.split(markdownText)
|
||||
val processedLines = ArrayList<String>(lines.size)
|
||||
var isInCode = false
|
||||
@@ -125,7 +141,7 @@ object DocMarkdownToHtmlConverter {
|
||||
if (!ContainerUtil.isEmpty(tableFormats)) {
|
||||
val parts = splitTableCols(processedLine)
|
||||
if (isTableHeaderSeparator(parts)) continue
|
||||
processedLine = getProcessedRow(isInTable, parts, tableFormats, project)
|
||||
processedLine = getProcessedRow(project, defaultLanguage, isInTable, parts, tableFormats)
|
||||
if (!isInTable) processedLine = "<table style=\"border: 0px;\" cellspacing=\"0\">$processedLine"
|
||||
isInTable = true
|
||||
}
|
||||
@@ -142,7 +158,7 @@ object DocMarkdownToHtmlConverter {
|
||||
var normalizedMarkdown = StringUtil.join(processedLines, "\n")
|
||||
if (isInTable) normalizedMarkdown += "</table>" //NON-NLS
|
||||
|
||||
var html = performConversion(normalizedMarkdown, project)
|
||||
var html = performConversion(project, defaultLanguage, normalizedMarkdown)
|
||||
if (html == null) {
|
||||
html = replaceProhibitedTags(convertNewLinePlaceholdersToTags(markdownText), ContainerUtil.emptyList())
|
||||
}
|
||||
@@ -181,10 +197,11 @@ object DocMarkdownToHtmlConverter {
|
||||
return parts
|
||||
}
|
||||
|
||||
private fun getProcessedRow(isInTable: Boolean,
|
||||
private fun getProcessedRow(project: Project,
|
||||
defaultLanguage: Language?,
|
||||
isInTable: Boolean,
|
||||
parts: List<String>,
|
||||
tableFormats: List<String>?,
|
||||
project: Project?): String {
|
||||
tableFormats: List<String>?): String {
|
||||
val openingTagStart = if (isInTable)
|
||||
"<td style=\"$border\" "
|
||||
else
|
||||
@@ -196,7 +213,7 @@ object DocMarkdownToHtmlConverter {
|
||||
if (i > 0) {
|
||||
resultBuilder.append(closingTag).append(openingTagStart).append("align=\"").append(getAlign(i, tableFormats)).append("\">")
|
||||
}
|
||||
resultBuilder.append(performConversion(parts[i].trim { it <= ' ' }, project))
|
||||
resultBuilder.append(performConversion(project, defaultLanguage, parts[i].trim { it <= ' ' }))
|
||||
}
|
||||
resultBuilder.append(closingTag).append("</tr>")
|
||||
return resultBuilder.toString()
|
||||
@@ -215,9 +232,9 @@ object DocMarkdownToHtmlConverter {
|
||||
|
||||
private val embeddedHtmlType = IElementType("ROOT")
|
||||
|
||||
private fun performConversion(text: @Nls String, project: Project?): @NlsSafe String? {
|
||||
private fun performConversion(project: Project, defaultLanguage: Language?, text: @Nls String): @NlsSafe String? {
|
||||
try {
|
||||
val flavour = DocFlavourDescriptor(project)
|
||||
val flavour = DocFlavourDescriptor(project, defaultLanguage)
|
||||
val parsedTree = MarkdownParser(flavour).parse(embeddedHtmlType, text, true)
|
||||
return HtmlGenerator(text, parsedTree, flavour, false)
|
||||
.generateHtml(DocTagRenderer(text))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.markdown.utils.doc.impl
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.intellij.markdown.IElementType
|
||||
import org.intellij.markdown.MarkdownElementTypes
|
||||
@@ -18,7 +19,7 @@ import org.intellij.markdown.parser.markerblocks.MarkerBlockProvider
|
||||
import org.intellij.markdown.parser.markerblocks.providers.HtmlBlockProvider
|
||||
import java.net.URI
|
||||
|
||||
internal class DocFlavourDescriptor(private val project: Project?) : GFMFlavourDescriptor() {
|
||||
internal class DocFlavourDescriptor(private val project: Project, private val defaultLanguage: Language?) : GFMFlavourDescriptor() {
|
||||
override val markerProcessorFactory: MarkerProcessorFactory
|
||||
get() = object : MarkerProcessorFactory {
|
||||
override fun createMarkerProcessor(productionHolder: ProductionHolder): MarkerProcessor<*> =
|
||||
@@ -28,8 +29,8 @@ internal class DocFlavourDescriptor(private val project: Project?) : GFMFlavourD
|
||||
override fun createHtmlGeneratingProviders(linkMap: LinkMap, baseURI: URI?): Map<IElementType, GeneratingProvider> {
|
||||
val result = HashMap(super.createHtmlGeneratingProviders(linkMap, baseURI))
|
||||
result[MarkdownTokenTypes.HTML_TAG] = DocSanitizingTagGeneratingProvider()
|
||||
result[MarkdownElementTypes.CODE_FENCE] = DocCodeFenceGeneratingProvider(project)
|
||||
result[MarkdownElementTypes.CODE_SPAN] = DocCodeSpanGeneratingProvider()
|
||||
result[MarkdownElementTypes.CODE_FENCE] = DocCodeFenceGeneratingProvider(project, defaultLanguage)
|
||||
result[MarkdownElementTypes.CODE_SPAN] = DocCodeSpanGeneratingProvider(project, defaultLanguage)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.markdown.utils.doc.impl
|
||||
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.guessLanguage
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper.guessLanguage
|
||||
import com.intellij.markdown.utils.doc.DocMarkdownToHtmlConverter
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
@@ -33,7 +34,7 @@ internal class DocSanitizingTagGeneratingProvider : GeneratingProvider {
|
||||
}
|
||||
}
|
||||
|
||||
internal class DocCodeFenceGeneratingProvider(private val project: Project?) : GeneratingProvider {
|
||||
internal class DocCodeFenceGeneratingProvider(private val project: Project, private val defaultLanguage: Language?) : GeneratingProvider {
|
||||
override fun processNode(visitor: HtmlGenerator.HtmlGeneratingVisitor, text: String, node: ASTNode) {
|
||||
val contents = StringBuilder()
|
||||
var language: String? = null
|
||||
@@ -45,17 +46,18 @@ internal class DocCodeFenceGeneratingProvider(private val project: Project?) : G
|
||||
language = HtmlGenerator.leafText(text, child).toString().trim().split(' ')[0]
|
||||
}
|
||||
}
|
||||
visitor.consumeHtml(QuickDocCodeHighlightingHelper.getStyledCodeBlock(contents.toString(), guessLanguage(language), project))
|
||||
visitor.consumeHtml(QuickDocHighlightingHelper.getStyledCodeBlock(
|
||||
project, guessLanguage(language) ?: defaultLanguage, contents.toString()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class DocCodeSpanGeneratingProvider : GeneratingProvider {
|
||||
internal class DocCodeSpanGeneratingProvider(private val project: Project, private val defaultLanguage: Language?) : GeneratingProvider {
|
||||
override fun processNode(visitor: HtmlGenerator.HtmlGeneratingVisitor, text: String, node: ASTNode) {
|
||||
val nodes = node.children.subList(1, node.children.size - 1)
|
||||
val output = nodes
|
||||
.filter { it.type != MarkdownTokenTypes.BLOCK_QUOTE }
|
||||
.joinToString(separator = "") { it.getTextInNode(text) }.trim()
|
||||
visitor.consumeHtml(QuickDocCodeHighlightingHelper.getStyledInlineCode(output))
|
||||
visitor.consumeHtml(QuickDocHighlightingHelper.getStyledInlineCode(project, defaultLanguage, output))
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,14 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme
|
||||
import com.intellij.openapi.editor.impl.EditorCssFontResolver
|
||||
import com.intellij.ui.ColorUtil
|
||||
import com.intellij.util.containers.addAllIfNotNull
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.awt.Color
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Provides list of CSS rules for rendering code tags
|
||||
*/
|
||||
@Internal
|
||||
object StyleSheetRulesProviderForCodeHighlighting {
|
||||
|
||||
const val CODE_BLOCK_PREFIX = "<div class='styled-code'><pre style=\"padding: 0px; margin: 0px\">"
|
||||
|
||||
@@ -64,7 +64,7 @@ abstract class CustomElementsManifestScopeBase :
|
||||
|
||||
protected class CustomElementsManifestJsonOriginImpl(
|
||||
override val library: String,
|
||||
private val project: Project?,
|
||||
private val project: Project,
|
||||
override val version: String? = null,
|
||||
override val typeSupport: WebSymbolTypeSupport? = null,
|
||||
private val sourceSymbolResolver: (source: SourceReference, cacheHolder: UserDataHolderEx) -> PsiElement? = { _, _ -> null },
|
||||
@@ -76,7 +76,7 @@ abstract class CustomElementsManifestScopeBase :
|
||||
sourceSymbolResolver(source, cacheHolder)
|
||||
|
||||
override fun renderDescription(description: String): String =
|
||||
DocMarkdownToHtmlConverter.convert(description, project)
|
||||
DocMarkdownToHtmlConverter.convert(project, description)
|
||||
|
||||
override fun toString(): String {
|
||||
return "$library@$version"
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
package com.intellij.webSymbols.utils;
|
||||
|
||||
import com.intellij.markdown.utils.doc.DocMarkdownToHtmlConverter;
|
||||
import com.intellij.openapi.project.DefaultProjectFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link DocMarkdownToHtmlConverter} directly
|
||||
* @deprecated Use {@link DocMarkdownToHtmlConverter#convert(Project, String)} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final class HtmlMarkdownUtils {
|
||||
@@ -16,13 +18,13 @@ public final class HtmlMarkdownUtils {
|
||||
|
||||
@Contract(pure = true)
|
||||
public static @NotNull String toHtml(@NotNull String markdownText) {
|
||||
return DocMarkdownToHtmlConverter.convert(markdownText);
|
||||
return DocMarkdownToHtmlConverter.convert(DefaultProjectFactory.getInstance().getDefaultProject(), markdownText);
|
||||
}
|
||||
|
||||
|
||||
@Contract(pure = true)
|
||||
public static @NotNull String toHtml(@NotNull String markdownText, boolean convertTagCodeBlocks) {
|
||||
return DocMarkdownToHtmlConverter.convert(markdownText);
|
||||
return DocMarkdownToHtmlConverter.convert(DefaultProjectFactory.getInstance().getDefaultProject(), markdownText);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ abstract class WebTypesScopeBase :
|
||||
protected class WebTypesJsonOriginImpl(
|
||||
webTypes: WebTypes,
|
||||
override val typeSupport: WebSymbolTypeSupport,
|
||||
private val project: Project?,
|
||||
private val project: Project,
|
||||
private val symbolLocationResolver: (source: SourceBase) -> WebTypesSymbol.Location? = { null },
|
||||
private val sourceSymbolResolver: (location: WebTypesSymbol.Location, cacheHolder: UserDataHolderEx) -> PsiElement? = { _, _ -> null },
|
||||
private val iconLoader: (path: String) -> Icon? = { null },
|
||||
@@ -198,7 +198,7 @@ abstract class WebTypesScopeBase :
|
||||
private val descriptionRenderer: (String) -> String =
|
||||
when (webTypes.descriptionMarkupWithLegacy) {
|
||||
WebTypes.DescriptionMarkup.HTML -> { doc -> doc }
|
||||
WebTypes.DescriptionMarkup.MARKDOWN -> { doc -> DocMarkdownToHtmlConverter.convert(doc, project) }
|
||||
WebTypes.DescriptionMarkup.MARKDOWN -> { doc -> DocMarkdownToHtmlConverter.convert(project, doc) }
|
||||
else -> { doc -> "<p>" + StringUtil.escapeXmlEntities(doc).replace(EOL_PATTERN, "<br>") }
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ import com.intellij.testFramework.UsefulTestCase
|
||||
import com.intellij.webSymbols.context.WebSymbolsContext.Companion.KIND_FRAMEWORK
|
||||
import com.intellij.webSymbols.context.impl.WebSymbolsContextProviderExtensionPoint
|
||||
import com.intellij.webSymbols.query.impl.CustomElementsManifestMockScopeImpl
|
||||
import com.intellij.webSymbols.webTypes.filters.WebSymbolsMatchPrefixFilter
|
||||
import com.intellij.webSymbols.webTypes.impl.WebSymbolsFilterEP
|
||||
import com.intellij.webSymbols.query.impl.WebSymbolsMockQueryExecutorFactory
|
||||
import com.intellij.webSymbols.query.impl.WebTypesMockScopeImpl
|
||||
import com.intellij.webSymbols.webTypes.filters.WebSymbolsMatchPrefixFilter
|
||||
import com.intellij.webSymbols.webTypes.impl.WebSymbolsFilterEP
|
||||
import java.io.File
|
||||
|
||||
abstract class WebSymbolsMockQueryExecutorTestBase : UsefulTestCase() {
|
||||
@@ -63,7 +63,7 @@ abstract class WebSymbolsMockQueryExecutorTestBase : UsefulTestCase() {
|
||||
fun registerFiles(framework: String?, webTypes: List<String>, customElementManifests: List<String>) {
|
||||
framework?.let { (webSymbolsQueryExecutorFactory as WebSymbolsMockQueryExecutorFactory).context[KIND_FRAMEWORK] = it }
|
||||
if (webTypes.isNotEmpty()) {
|
||||
webSymbolsQueryExecutorFactory.addScope(WebTypesMockScopeImpl().also { scope ->
|
||||
webSymbolsQueryExecutorFactory.addScope(WebTypesMockScopeImpl(testRootDisposable).also { scope ->
|
||||
webTypes.forEach { file ->
|
||||
scope.registerFile(File(testPath, "../$file.web-types.json").takeIf { it.exists() }
|
||||
?: File(testPath, "../../common/$file.web-types.json"))
|
||||
@@ -71,7 +71,7 @@ abstract class WebSymbolsMockQueryExecutorTestBase : UsefulTestCase() {
|
||||
}, null, testRootDisposable)
|
||||
}
|
||||
if (customElementManifests.isNotEmpty()) {
|
||||
webSymbolsQueryExecutorFactory.addScope(CustomElementsManifestMockScopeImpl().also {scope ->
|
||||
webSymbolsQueryExecutorFactory.addScope(CustomElementsManifestMockScopeImpl(testRootDisposable).also { scope ->
|
||||
customElementManifests.forEach { file ->
|
||||
scope.registerFile(File(testPath, "../$file.custom-elements-manifest.json").takeIf { it.exists() }
|
||||
?: File(testPath, "../../common/$file.custom-elements-manifest.json"))
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.webSymbols.query.impl
|
||||
|
||||
import com.intellij.mock.MockProjectEx
|
||||
import com.intellij.model.Pointer
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.webSymbols.customElements.CustomElementsManifestScopeBase
|
||||
import com.intellij.webSymbols.customElements.readCustomElementsManifest
|
||||
import java.io.File
|
||||
|
||||
internal class CustomElementsManifestMockScopeImpl : CustomElementsManifestScopeBase() {
|
||||
internal class CustomElementsManifestMockScopeImpl(private val disposable: Disposable) : CustomElementsManifestScopeBase() {
|
||||
|
||||
fun registerFile(file: File) {
|
||||
val manifest = readCustomElementsManifest(file.toString())
|
||||
val context = CustomElementsManifestJsonOriginImpl(
|
||||
file.name.takeWhile { it != '.' },
|
||||
project = null,
|
||||
project = MockProjectEx(disposable),
|
||||
typeSupport = WebSymbolsMockTypeSupport
|
||||
)
|
||||
addCustomElementsManifest(manifest, context)
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.webSymbols.query.impl
|
||||
|
||||
import com.intellij.mock.MockProjectEx
|
||||
import com.intellij.model.Pointer
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.webSymbols.webTypes.WebTypesJsonFilesCache
|
||||
import com.intellij.webSymbols.webTypes.WebTypesScopeBase
|
||||
import java.io.File
|
||||
|
||||
internal class WebTypesMockScopeImpl : WebTypesScopeBase() {
|
||||
internal class WebTypesMockScopeImpl(private val disposable: Disposable) : WebTypesScopeBase() {
|
||||
|
||||
fun registerFile(file: File) {
|
||||
val webTypes = WebTypesJsonFilesCache.fromUrlNoCache(file.toURI().toString())
|
||||
val context = WebTypesJsonOriginImpl(
|
||||
webTypes,
|
||||
typeSupport = WebSymbolsMockTypeSupport,
|
||||
project = null
|
||||
project = MockProjectEx(disposable),
|
||||
)
|
||||
addWebTypes(webTypes, context)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,8 @@ package org.jetbrains.plugins.groovy.lang.documentation;
|
||||
|
||||
import com.intellij.codeInsight.javadoc.JavaDocInfoGeneratorFactory;
|
||||
import com.intellij.ide.highlighter.JavaHighlightingColors;
|
||||
import com.intellij.lang.documentation.DocumentationSettings;
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -137,7 +136,7 @@ public final class GroovyPresentationUtil {
|
||||
@Nullable String value
|
||||
) {
|
||||
if (doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendStyledSpan(buffer, attributesKey, value, DocumentationSettings.getHighlightingSaturation(false));
|
||||
QuickDocHighlightingHelper.appendStyledFragment(buffer, value, attributesKey);
|
||||
}
|
||||
else {
|
||||
buffer.append(value);
|
||||
|
||||
@@ -61,7 +61,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.appendStyledSignatureFragment;
|
||||
import static com.intellij.lang.documentation.QuickDocHighlightingHelper.appendStyledSignatureFragment;
|
||||
|
||||
|
||||
public class GroovyDocumentationProvider implements CodeDocumentationProvider, ExternalDocumentationProvider {
|
||||
|
||||
@@ -6,11 +6,12 @@ import com.intellij.codeInsight.documentation.DocumentationManagerUtil
|
||||
import com.intellij.codeInsight.javadoc.JavaDocInfoGeneratorFactory
|
||||
import com.intellij.lang.documentation.DocumentationMarkup.*
|
||||
import com.intellij.lang.documentation.DocumentationSettings
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.appendStyledCodeBlock
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.appendStyledInlineCode
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.appendStyledInlineCodeFragment
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper.appendStyledLinkFragment
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper.appendStyledCodeBlock
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper.appendStyledFragment
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper.appendStyledInlineCode
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper.appendStyledInlineCodeFragment
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper.appendStyledLinkFragment
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
|
||||
import com.intellij.openapi.editor.HighlighterColors
|
||||
@@ -18,7 +19,6 @@ import com.intellij.openapi.editor.colors.CodeInsightColors
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -200,14 +200,14 @@ object KDocRenderer {
|
||||
append("<p>")
|
||||
this@appendSamplesList.appendHyperlink(subjectLink)
|
||||
this@appendSamplesList.appendStyledCodeBlock(
|
||||
subjectLink.project,
|
||||
KotlinLanguage.INSTANCE,
|
||||
if (DumbService.isDumb(subjectLink.project))
|
||||
"// " + KotlinBundle.message("kdoc.comment.unresolved")
|
||||
else when (val target = subjectLink.getTargetElement()) {
|
||||
null -> "// " + KotlinBundle.message("kdoc.comment.unresolved")
|
||||
else -> trimCommonIndent(target.extractExampleText()).htmlEscape()
|
||||
},
|
||||
KotlinLanguage.INSTANCE,
|
||||
subjectLink.project
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -388,7 +388,7 @@ object KDocRenderer {
|
||||
val startDelimiter = node.child(MarkdownTokenTypes.BACKTICK)?.text
|
||||
if (startDelimiter != null) {
|
||||
val text = node.text.substring(startDelimiter.length).removeSuffix(startDelimiter)
|
||||
sb.appendStyledInlineCode(text, KotlinLanguage.INSTANCE, comment.project)
|
||||
sb.appendStyledInlineCode(comment.project, KotlinLanguage.INSTANCE, text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,7 +406,11 @@ object KDocRenderer {
|
||||
language = child.text.trim().split(' ')[0]
|
||||
}
|
||||
}
|
||||
sb.appendStyledCodeBlock(contents, QuickDocCodeHighlightingHelper.guessLanguage(language) ?: KotlinLanguage.INSTANCE)
|
||||
sb.appendStyledCodeBlock(
|
||||
project = comment.project,
|
||||
language = QuickDocHighlightingHelper.guessLanguage(language) ?: KotlinLanguage.INSTANCE,
|
||||
code = contents
|
||||
)
|
||||
}
|
||||
|
||||
MarkdownTokenTypes.FENCE_LANG, MarkdownTokenTypes.CODE_LINE, MarkdownTokenTypes.CODE_FENCE_CONTENT -> {
|
||||
@@ -438,7 +442,7 @@ object KDocRenderer {
|
||||
true
|
||||
)
|
||||
}
|
||||
?: sb.appendStyledSpan(true, KotlinHighlightingColors.RESOLVED_TO_ERROR, label)
|
||||
?: sb.appendStyledFragment(label, KotlinHighlightingColors.RESOLVED_TO_ERROR)
|
||||
}
|
||||
} else {
|
||||
sb.append(node.text)
|
||||
@@ -566,15 +570,6 @@ object KDocRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendStyledSpan(doHighlighting: Boolean, attributesKey: TextAttributesKey, value: String?): StringBuilder {
|
||||
if (doHighlighting) {
|
||||
HtmlSyntaxInfoUtil.appendStyledSpan(this, attributesKey, value, DocumentationSettings.getHighlightingSaturation(true))
|
||||
} else {
|
||||
append(value)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* If highlighted links has the same color as highlighted inline code blocks they will be indistinguishable.
|
||||
* In this case we should change link color to standard hyperlink color which we believe is apriori different.
|
||||
@@ -633,16 +628,11 @@ object KDocRenderer {
|
||||
value: String,
|
||||
attributes: TextAttributesAdapter
|
||||
) {
|
||||
HtmlSyntaxInfoUtil.appendStyledSpan(
|
||||
this,
|
||||
attributes.attributes,
|
||||
value,
|
||||
DocumentationSettings.getHighlightingSaturation(false)
|
||||
)
|
||||
appendStyledFragment(value, attributes.attributes)
|
||||
}
|
||||
|
||||
override fun StringBuilder.appendCodeSnippetHighlightedByLexer(codeSnippet: String) {
|
||||
appendStyledInlineCodeFragment(codeSnippet, KotlinLanguage.INSTANCE, project)
|
||||
appendStyledInlineCodeFragment(project, KotlinLanguage.INSTANCE, codeSnippet)
|
||||
}
|
||||
|
||||
private fun resolveKey(key: TextAttributesKey): TextAttributesAdapter {
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python
|
||||
|
||||
import com.intellij.lang.documentation.DocumentationSettings
|
||||
import com.intellij.lang.documentation.QuickDocCodeHighlightingHelper
|
||||
import com.intellij.lang.documentation.QuickDocHighlightingHelper
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.editor.richcopy.HtmlSyntaxInfoUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
class PythonDocumentationHighlightingServiceImpl : PythonDocumentationHighlightingService() {
|
||||
override fun highlightedCodeSnippet(project: Project, codeSnippet: String): String {
|
||||
return QuickDocCodeHighlightingHelper.getStyledInlineCodeFragment(codeSnippet, PythonLanguage.INSTANCE, project)
|
||||
return QuickDocHighlightingHelper.getStyledInlineCodeFragment(project, PythonLanguage.INSTANCE, codeSnippet)
|
||||
}
|
||||
|
||||
override fun styledSpan(textAttributeKey: TextAttributesKey, text: String): String {
|
||||
return HtmlSyntaxInfoUtil.getStyledSpan(textAttributeKey, text, DocumentationSettings.getHighlightingSaturation(false))
|
||||
return QuickDocHighlightingHelper.getStyledFragment(text, textAttributeKey)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||
import com.intellij.lang.documentation.DocumentationMarkup
|
||||
import com.intellij.markdown.utils.doc.DocMarkdownToHtmlConverter
|
||||
import com.intellij.openapi.project.DefaultProjectFactory
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
import com.intellij.openapi.util.text.StringUtil.capitalize
|
||||
import com.intellij.openapi.util.text.StringUtil.toLowerCase
|
||||
@@ -209,7 +210,12 @@ class MdnSymbolDocumentationAdapter(override val name: String,
|
||||
|
||||
override val description: String
|
||||
get() = capitalize(
|
||||
doc.doc?.let { if (it.contains("```")) DocMarkdownToHtmlConverter.convert(it) else it } ?: ""
|
||||
doc.doc?.let {
|
||||
if (it.contains("```"))
|
||||
DocMarkdownToHtmlConverter.convert(DefaultProjectFactory.getInstance().defaultProject, it)
|
||||
else
|
||||
it
|
||||
} ?: ""
|
||||
).fixUrls()
|
||||
|
||||
override val sections: Map<String, String>
|
||||
|
||||
Reference in New Issue
Block a user