Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.intellij.markdown.flavours.gfm.table

import org.intellij.markdown.MarkdownTokenTypes
import org.intellij.markdown.flavours.gfm.GFMElementTypes
import org.intellij.markdown.flavours.gfm.GFMTokenTypes
import org.intellij.markdown.parser.LookaheadText
Expand Down Expand Up @@ -34,6 +35,7 @@ class GitHubTableMarkerBlock(pos: LookaheadText.Position,
}
// That means it's table header separator line
if (currentLine == 1) {
addBlockQuoteMarkersProduction(pos, lineConstraints)
val separatorStart = pos.offset + 1 + lineConstraints.getCharsEaten(pos.currentLine)
productionHolder.addProduction(listOf(SequentialParser.Node(separatorStart..pos.nextLineOrEofOffset,
GFMTokenTypes.TABLE_SEPARATOR)))
Expand All @@ -48,6 +50,7 @@ class GitHubTableMarkerBlock(pos: LookaheadText.Position,
if (cellsAndSeps.isEmpty()) {
return MarkerBlock.ProcessingResult.DEFAULT
}
addBlockQuoteMarkersProduction(pos, lineConstraints)
productionHolder.addProduction(
listOf(SequentialParser.Node(cellsAndSeps.first().range.first..cellsAndSeps.last().range.last,
GFMElementTypes.ROW))
Expand All @@ -65,6 +68,35 @@ class GitHubTableMarkerBlock(pos: LookaheadText.Position,

override fun allowsSubBlocks() = false

/**
* Emits [MarkdownTokenTypes.BLOCK_QUOTE] tokens for the block quote markers eaten by the constraints
* of a table continuation line. Without these productions the `>` markers would become part of
* the whitespace between the table rows and could be lost on a whitespace-normalizing tree mutation.
*/
private fun addBlockQuoteMarkersProduction(pos: LookaheadText.Position, lineConstraints: MarkdownConstraints) {
Comment thread
p3rmiashkin marked this conversation as resolved.
val line = pos.currentLine
val prefixLength = lineConstraints.getCharsEaten(line)
val lineStartOffset = pos.offset + 1
val nodes = ArrayList<SequentialParser.Node>(0)
var index = 0
while (index < prefixLength) {
if (line[index] == '>') {
var end = index + 1
if (end < prefixLength && line[end] == ' ') {
end++
}
nodes.add(SequentialParser.Node(lineStartOffset + index..lineStartOffset + end,
MarkdownTokenTypes.BLOCK_QUOTE))
index = end
} else {
index++
}
}
if (nodes.isNotEmpty()) {
productionHolder.addProduction(nodes)
}
}

private fun fillCells(pos: LookaheadText.Position,
lineConstraints: MarkdownConstraints = constraints): List<SequentialParser.Node> {
val result = ArrayList<SequentialParser.Node>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,13 @@ Markdown:MARKDOWN_FILE
defaultTest(GFMFlavourDescriptor())
}

// IJPL-95908: block quote markers of table lines should be parsed as BLOCK_QUOTE tokens,
// not whitespace, so that they survive whitespace-normalizing tree mutations
@Test
fun testTableInsideBlockQuote() {
defaultTest(GFMFlavourDescriptor())
}

@Test
fun testTableInsideOrderedListItem() {
defaultTest(GFMFlavourDescriptor())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
>| one | two | three | four |
>|------|-----|-------|---------|
>| 1 | 2 | 3 | 4 |
>| odin | dva | tri | chetyre |

>>| nested | quote |
>>|--------|-------|
>>| a | b |
116 changes: 116 additions & 0 deletions src/fileBasedTest/resources/data/parser/tableInsideBlockQuote.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
Markdown:MARKDOWN_FILE
Markdown:BLOCK_QUOTE
Markdown:BLOCK_QUOTE('>')
Markdown:TABLE
Markdown:HEADER
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('one')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('two')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('three')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('four')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
Markdown:BLOCK_QUOTE('>')
Markdown:TABLE_SEPARATOR('|------|-----|-------|---------|')
Markdown:EOL('\n')
Markdown:BLOCK_QUOTE('>')
Markdown:ROW
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('1')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('2')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('3')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('4')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
Markdown:BLOCK_QUOTE('>')
Markdown:ROW
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('odin')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('dva')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('tri')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('chetyre')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
Markdown:EOL('\n')
Markdown:BLOCK_QUOTE
Markdown:BLOCK_QUOTE('>')
Markdown:BLOCK_QUOTE
Markdown:BLOCK_QUOTE('>')
Markdown:TABLE
Markdown:HEADER
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('nested')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('quote')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
Markdown:BLOCK_QUOTE('>')
Markdown:BLOCK_QUOTE('>')
Markdown:TABLE_SEPARATOR('|--------|-------|')
Markdown:EOL('\n')
Markdown:BLOCK_QUOTE('>')
Markdown:BLOCK_QUOTE('>')
Markdown:ROW
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('a')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
WHITE_SPACE(' ')
Markdown:TEXT('b')
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ Markdown:MARKDOWN_FILE
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
WHITE_SPACE(' > ')
WHITE_SPACE(' ')
Markdown:BLOCK_QUOTE('> ')
Markdown:TABLE_SEPARATOR('| --- |')
Markdown:EOL('\n')
WHITE_SPACE(' > ')
WHITE_SPACE(' ')
Markdown:BLOCK_QUOTE('> ')
Markdown:ROW
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Markdown:MARKDOWN_FILE
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
WHITE_SPACE('> ')
Markdown:BLOCK_QUOTE('> ')
Markdown:TABLE_SEPARATOR('| --- | ------ | ---- |')
Markdown:EOL('\n')
WHITE_SPACE('> ')
Markdown:BLOCK_QUOTE('> ')
Markdown:ROW
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
Expand All @@ -42,7 +42,7 @@ Markdown:MARKDOWN_FILE
WHITE_SPACE(' ')
Markdown:TABLE_SEPARATOR('|')
Markdown:EOL('\n')
WHITE_SPACE('> ')
Markdown:BLOCK_QUOTE('> ')
Markdown:ROW
Markdown:TABLE_SEPARATOR('|')
Markdown:CELL
Expand Down
Loading