Search in sources :

Example 1 with DelimiterProcessor

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);
}
Also used : DelimiterProcessor(com.vladsch.flexmark.parser.delimiter.DelimiterProcessor) AsteriskDelimiterProcessor(com.vladsch.flexmark.internal.inline.AsteriskDelimiterProcessor) UnderscoreDelimiterProcessor(com.vladsch.flexmark.internal.inline.UnderscoreDelimiterProcessor)

Example 2 with DelimiterProcessor

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);
    }
}
Also used : DelimiterProcessor(com.vladsch.flexmark.parser.delimiter.DelimiterProcessor) AsteriskDelimiterProcessor(com.vladsch.flexmark.internal.inline.AsteriskDelimiterProcessor) UnderscoreDelimiterProcessor(com.vladsch.flexmark.internal.inline.UnderscoreDelimiterProcessor) BasedSequence(com.vladsch.flexmark.util.sequence.BasedSequence)

Example 3 with DelimiterProcessor

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);
        }
    }
}
Also used : DelimiterProcessor(com.vladsch.flexmark.parser.delimiter.DelimiterProcessor) AsteriskDelimiterProcessor(com.vladsch.flexmark.internal.inline.AsteriskDelimiterProcessor) UnderscoreDelimiterProcessor(com.vladsch.flexmark.internal.inline.UnderscoreDelimiterProcessor)

Aggregations

AsteriskDelimiterProcessor (com.vladsch.flexmark.internal.inline.AsteriskDelimiterProcessor)3 UnderscoreDelimiterProcessor (com.vladsch.flexmark.internal.inline.UnderscoreDelimiterProcessor)3 DelimiterProcessor (com.vladsch.flexmark.parser.delimiter.DelimiterProcessor)3 BasedSequence (com.vladsch.flexmark.util.sequence.BasedSequence)1