mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
fix(jdoc): inline mk structs break detection
GitOrigin-RevId: 0cb1adbd59262523ce59767fee5f33e78234bd9f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3b13ef3ec1
commit
0cdf89293d
@@ -388,7 +388,7 @@ public final class BasicJavaDocParser {
|
||||
while (!builder.eof()) {
|
||||
builder.advanceLexer();
|
||||
previousToken = token;
|
||||
token = getTokenType(builder);
|
||||
token = getTokenType(builder, false);
|
||||
if (token == needle) {
|
||||
return token;
|
||||
}
|
||||
@@ -398,7 +398,7 @@ public final class BasicJavaDocParser {
|
||||
}
|
||||
|
||||
// Markdown specific, check for EOL
|
||||
if (token == JavaDocTokenType.DOC_SPACE && previousToken == JavaDocTokenType.DOC_SPACE) {
|
||||
if (token == TokenType.WHITE_SPACE && previousToken == TokenType.WHITE_SPACE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -605,10 +605,15 @@ public final class BasicJavaDocParser {
|
||||
|
||||
@Nullable
|
||||
private static IElementType getTokenType(PsiBuilder builder) {
|
||||
return getTokenType(builder, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static IElementType getTokenType(PsiBuilder builder, boolean skipWhitespace) {
|
||||
IElementType tokenType;
|
||||
while ((tokenType = builder.getTokenType()) == JavaDocTokenType.DOC_SPACE) {
|
||||
builder.remapCurrentToken(TokenType.WHITE_SPACE);
|
||||
builder.advanceLexer();
|
||||
if (skipWhitespace) builder.advanceLexer();
|
||||
}
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// 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.codeInsight.javadoc.markdown;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import kotlin.ranges.IntRange;
|
||||
import org.intellij.markdown.MarkdownTokenTypes;
|
||||
import org.intellij.markdown.parser.sequentialparsers.RangesListBuilder;
|
||||
import org.intellij.markdown.parser.sequentialparsers.SequentialParser;
|
||||
import org.intellij.markdown.parser.sequentialparsers.TokensCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/// Inline parser dedicated to finding `<code>` tags.
|
||||
///
|
||||
/// Only purpose is to exclude the range from further markdown processing
|
||||
public class CodeTagParser implements SequentialParser {
|
||||
@Override
|
||||
public @NotNull ParsingResult parse(@NotNull TokensCache tokens, @NotNull List<IntRange> rangesToGlue) {
|
||||
var result = new SequentialParser.ParsingResultBuilder();
|
||||
var delegateIndices = new RangesListBuilder();
|
||||
TokensCache.Iterator iterator = tokens.new RangesListIterator(rangesToGlue);
|
||||
|
||||
while (iterator.getType() != null) {
|
||||
if (iterator.getType() == MarkdownTokenTypes.HTML_TAG && hasOpeningTag(getText(tokens, iterator), "code")) {
|
||||
int startIndex = iterator.getIndex();
|
||||
var endIterator = findEnd(tokens, iterator.advance());
|
||||
|
||||
if (endIterator != null) {
|
||||
result.withNode(new SequentialParser.Node(new IntRange(startIndex, endIterator.getIndex() + 1), JavaDocMarkdownFlavourDescriptor.RAW_TYPE));
|
||||
iterator = endIterator.advance();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
delegateIndices.put(iterator.getIndex());
|
||||
iterator = iterator.advance();
|
||||
}
|
||||
|
||||
return result.withFurtherProcessing(delegateIndices.get());
|
||||
}
|
||||
|
||||
/// @return The iterator located at the end tag, or `null` if the end isn't found
|
||||
private static TokensCache.Iterator findEnd(@NotNull TokensCache tokens, TokensCache.Iterator iterator) {
|
||||
while (iterator.getType() != null) {
|
||||
if (iterator.getType() == MarkdownTokenTypes.HTML_TAG) {
|
||||
if (hasClosingTag(getText(tokens, iterator), "code")) {
|
||||
return iterator;
|
||||
}
|
||||
}
|
||||
|
||||
iterator = iterator.advance();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getText(@NotNull TokensCache tokens, TokensCache.Iterator iterator) {
|
||||
return tokens.getOriginalText().subSequence(iterator.getStart(), iterator.getEnd()).toString();
|
||||
}
|
||||
|
||||
private static boolean hasOpeningTag(String tag, String tagName) {
|
||||
return StringUtil.trimEnd(StringUtil.trimStart(tag, "<"), ">").equals(tagName);
|
||||
}
|
||||
|
||||
private static boolean hasClosingTag(String tag, String tagName) {
|
||||
return StringUtil.trimEnd(StringUtil.trimStart(tag, "</"), ">").equals(tagName);
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,18 @@ import org.intellij.markdown.MarkdownElementTypes;
|
||||
import org.intellij.markdown.MarkdownTokenTypes;
|
||||
import org.intellij.markdown.ast.ASTNode;
|
||||
import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor;
|
||||
import org.intellij.markdown.flavours.gfm.GFMTokenTypes;
|
||||
import org.intellij.markdown.flavours.gfm.StrikeThroughDelimiterParser;
|
||||
import org.intellij.markdown.html.GeneratingProvider;
|
||||
import org.intellij.markdown.html.HtmlGenerator;
|
||||
import org.intellij.markdown.html.TransparentInlineHolderProvider;
|
||||
import org.intellij.markdown.html.TrimmingInlineHolderProvider;
|
||||
import org.intellij.markdown.parser.LinkMap;
|
||||
import org.intellij.markdown.parser.MarkerProcessorFactory;
|
||||
import org.intellij.markdown.parser.sequentialparsers.EmphasisLikeParser;
|
||||
import org.intellij.markdown.parser.sequentialparsers.SequentialParser;
|
||||
import org.intellij.markdown.parser.sequentialparsers.SequentialParserManager;
|
||||
import org.intellij.markdown.parser.sequentialparsers.impl.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -23,10 +30,31 @@ import java.util.Map;
|
||||
* Flavour descriptor which describes how to generate html text from markdown documentation
|
||||
*/
|
||||
public class JavaDocMarkdownFlavourDescriptor extends GFMFlavourDescriptor {
|
||||
public static final IElementType RAW_TYPE = new IElementType("RAW_TYPE");
|
||||
|
||||
public JavaDocMarkdownFlavourDescriptor() {
|
||||
super(true, false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull SequentialParserManager getSequentialParserManager() {
|
||||
return new SequentialParserManager() {
|
||||
@Override
|
||||
public @NotNull List<SequentialParser> getParserSequence() {
|
||||
return List.of(
|
||||
new AutolinkParser(List.of(MarkdownTokenTypes.AUTOLINK, GFMTokenTypes.GFM_AUTOLINK)),
|
||||
new BacktickParser(),
|
||||
new CodeTagParser(), // Custom parser excluding <code> blocks content to be processed as markdown
|
||||
new MathParser(),
|
||||
new ImageParser(),
|
||||
new InlineLinkParser(),
|
||||
new ReferenceLinkParser(),
|
||||
new EmphasisLikeParser(new EmphStrongDelimiterParser(), new StrikeThroughDelimiterParser())
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<IElementType, GeneratingProvider> createHtmlGeneratingProviders(@NotNull LinkMap linkMap, @Nullable URI baseURI) {
|
||||
@@ -38,6 +66,9 @@ public class JavaDocMarkdownFlavourDescriptor extends GFMFlavourDescriptor {
|
||||
// Paragraphs may need to be inlined
|
||||
result.put(MarkdownElementTypes.PARAGRAPH, new JavaDocParagraphProvider());
|
||||
|
||||
// Custom type, no processing
|
||||
result.put(RAW_TYPE, new TransparentInlineHolderProvider());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<html><head><base href="placeholder"></head><body><div class='definition'><pre><span style="color:#000080;font-weight:bold;">class</span> <span style="color:#000000;">MarkdownCodeBlock</span></pre></div><div class='content'><p>Single liner code block:
|
||||
<code><span style="">Hello world</span></code></p><p>No tags are interpreted inside them
|
||||
<code><span style="">{@link java.lang.String niceLink}</span></code></p></div><table class='sections'><p></table>
|
||||
<code><span style="">{@link java.lang.String niceLink}</span></code></p><p>No markdown markup is interpreted inside them
|
||||
<code><span style="">_Hello_ <code></span></code></p><p>This is a broken inline link
|
||||
`Start of broken link</p>end of broken link`</div><table class='sections'><p></table>
|
||||
@@ -4,4 +4,12 @@
|
||||
///
|
||||
/// No tags are interpreted inside them
|
||||
/// `{@link java.lang.String niceLink}`
|
||||
///
|
||||
/// No markdown markup is interpreted inside them
|
||||
/// `_Hello_ <code>`
|
||||
///
|
||||
/// This is a broken inline link
|
||||
/// `Start of broken link
|
||||
///
|
||||
/// end of broken link`
|
||||
class MarkdownCodeBlock {}
|
||||
@@ -3,4 +3,5 @@
|
||||
Some text with inline <code><span style="">code</span></code>
|
||||
</pre>
|
||||
<pre><code><span style="">String fullLine = </span><span style="color:#008000;font-weight:bold;">""</span><span style="">;</span></code></pre> </pre>
|
||||
<pre><code><span style="">String secondFullLine = </span><span style="color:#008000;font-weight:bold;">""</span><span style="">;</span></code></pre>
|
||||
</div><table class='sections'><p></table>
|
||||
@@ -7,6 +7,7 @@
|
||||
* String fullLine = "";
|
||||
* }
|
||||
* </pre>
|
||||
* <pre> {@code String secondFullLine = ""; }</pre>
|
||||
*/
|
||||
class Test {
|
||||
public String field = null;
|
||||
|
||||
Reference in New Issue
Block a user