use of com.vladsch.flexmark.parser.delimiter.DelimiterProcessor in project flexmark-java by vsch.
the class InlineParserImpl method removeDelimiterKeepNode.
/**
* Remove the delimiter but keep the corresponding node as text. For unused delimiters such as `_` in `foo_bar`.
*
* @param delim delimiter being processed
*/
@Override
public void removeDelimiterKeepNode(Delimiter delim) {
Node node;
DelimiterProcessor delimiterProcessor = delimiterProcessors.get(delim.delimiterChar);
node = delimiterProcessor != null ? delimiterProcessor.unmatchedDelimiterNode(this, delim) : null;
if (node != null) {
if (node != delim.node) {
// replace node
delim.node.insertAfter(node);
delim.node.unlink();
}
} else {
node = delim.node;
}
Text previousText = delim.getPreviousNonDelimiterTextNode();
Text nextText = delim.getNextNonDelimiterTextNode();
if (node instanceof Text && (previousText != null || nextText != null)) {
// Merge adjacent text nodes into one
if (nextText != null && previousText != null) {
node.setChars(input.baseSubSequence(previousText.getStartOffset(), nextText.getEndOffset()));
previousText.unlink();
nextText.unlink();
} else if (previousText != null) {
node.setChars(input.baseSubSequence(previousText.getStartOffset(), node.getEndOffset()));
previousText.unlink();
} else {
node.setChars(input.baseSubSequence(node.getStartOffset(), nextText.getEndOffset()));
nextText.unlink();
}
}
removeDelimiter(delim);
}
use of com.vladsch.flexmark.parser.delimiter.DelimiterProcessor in project flexmark-java by vsch.
the class InlineParserImpl method processDelimiters.
@Override
public void processDelimiters(Delimiter stackBottom) {
Map<Character, Delimiter> openersBottom = new HashMap<Character, Delimiter>();
// find first closer above stackBottom:
Delimiter closer = lastDelimiter;
while (closer != null && closer.previous != stackBottom) {
closer = closer.previous;
}
// move forward, looking for closers, and handling each
while (closer != null) {
char delimiterChar = closer.delimiterChar;
DelimiterProcessor delimiterProcessor = delimiterProcessors.get(delimiterChar);
if (!closer.canClose || delimiterProcessor == null) {
closer = closer.next;
continue;
}
char openingDelimiterChar = delimiterProcessor.getOpeningCharacter();
// found delimiter closer. now look back for first matching opener:
int useDelims = 0;
boolean openerFound = false;
boolean potentialOpenerFound = false;
Delimiter opener = closer.previous;
while (opener != null && opener != stackBottom && opener != openersBottom.get(delimiterChar)) {
if (opener.canOpen && opener.delimiterChar == openingDelimiterChar) {
potentialOpenerFound = true;
useDelims = delimiterProcessor.getDelimiterUse(opener, closer);
if (useDelims > 0) {
openerFound = true;
break;
}
}
opener = opener.previous;
}
if (!openerFound) {
if (!potentialOpenerFound) {
// Set lower bound for future searches for openers.
// Only do this when we didn't even have a potential
// opener (one that matches the character and can open).
// If an opener was rejected because of the number of
// delimiters (e.g. because of the "multiple of 3" rule),
// we want to consider it next time because the number
// of delimiters can change as we continue processing.
openersBottom.put(delimiterChar, closer.previous);
if (!closer.canOpen) {
// We can remove a closer that can't be an opener,
// once we've seen there's no matching opener:
removeDelimiterKeepNode(closer);
}
}
closer = closer.next;
continue;
}
// Remove number of used delimiters from stack and inline nodes.
opener.numDelims -= useDelims;
closer.numDelims -= useDelims;
removeDelimitersBetween(opener, closer);
// // The delimiter processor can re-parent the nodes between opener and closer,
// // so make sure they're contiguous already.
// mergeTextNodes(openerNode.getNext(), closerNode.getPrevious());
opener.numDelims += useDelims;
closer.numDelims += useDelims;
delimiterProcessor.process(opener, closer, useDelims);
opener.numDelims -= useDelims;
closer.numDelims -= useDelims;
// No delimiter characters left to process, so we can remove delimiter and the now empty node.
if (opener.numDelims == 0) {
removeDelimiterAndNode(opener);
} else {
// adjust number of characters in the node by keeping outer of numDelims
opener.node.setChars(opener.node.getChars().subSequence(0, opener.numDelims));
}
if (closer.numDelims == 0) {
Delimiter next = closer.next;
removeDelimiterAndNode(closer);
closer = next;
} else {
// adjust number of characters in the node by keeping outer of numDelims
BasedSequence chars = closer.node.getChars();
int length = chars.length();
closer.node.setChars(chars.subSequence(length - closer.numDelims, length));
closer.setIndex(closer.getIndex() + useDelims);
}
}
// removeIndex all delimiters
while (lastDelimiter != null && lastDelimiter != stackBottom) {
removeDelimiterKeepNode(lastDelimiter);
}
}
use of com.vladsch.flexmark.parser.delimiter.DelimiterProcessor in project flexmark-java by vsch.
the class InlineParserImpl method addDelimiterProcessors.
private static void addDelimiterProcessors(List<? extends DelimiterProcessor> delimiterProcessors, Map<Character, DelimiterProcessor> map) {
for (DelimiterProcessor delimiterProcessor : delimiterProcessors) {
char opening = delimiterProcessor.getOpeningCharacter();
addDelimiterProcessorForChar(opening, delimiterProcessor, map);
char closing = delimiterProcessor.getClosingCharacter();
if (opening != closing) {
addDelimiterProcessorForChar(closing, delimiterProcessor, map);
}
}
}
Aggregations