org.commonmark.internal.IndentedCodeBlockParser Maven / Gradle / Ivy
package org.commonmark.internal;
import org.commonmark.internal.util.Parsing;
import org.commonmark.node.Block;
import org.commonmark.node.IndentedCodeBlock;
import org.commonmark.node.Paragraph;
import org.commonmark.parser.SourceLine;
import org.commonmark.parser.block.*;
import org.commonmark.text.Characters;
import java.util.ArrayList;
import java.util.List;
public class IndentedCodeBlockParser extends AbstractBlockParser {
private final IndentedCodeBlock block = new IndentedCodeBlock();
private final List lines = new ArrayList<>();
@Override
public Block getBlock() {
return block;
}
@Override
public BlockContinue tryContinue(ParserState state) {
if (state.getIndent() >= Parsing.CODE_BLOCK_INDENT) {
return BlockContinue.atColumn(state.getColumn() + Parsing.CODE_BLOCK_INDENT);
} else if (state.isBlank()) {
return BlockContinue.atIndex(state.getNextNonSpaceIndex());
} else {
return BlockContinue.none();
}
}
@Override
public void addLine(SourceLine line) {
lines.add(line.getContent());
}
@Override
public void closeBlock() {
int lastNonBlank = lines.size() - 1;
while (lastNonBlank >= 0) {
if (!Characters.isBlank(lines.get(lastNonBlank))) {
break;
}
lastNonBlank--;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lastNonBlank + 1; i++) {
sb.append(lines.get(i));
sb.append('\n');
}
String literal = sb.toString();
block.setLiteral(literal);
}
public static class Factory extends AbstractBlockParserFactory {
@Override
public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) {
// An indented code block cannot interrupt a paragraph.
if (state.getIndent() >= Parsing.CODE_BLOCK_INDENT && !state.isBlank() && !(state.getActiveBlockParser().getBlock() instanceof Paragraph)) {
return BlockStart.of(new IndentedCodeBlockParser()).atColumn(state.getColumn() + Parsing.CODE_BLOCK_INDENT);
} else {
return BlockStart.none();
}
}
}
}