Search in sources :

Example 1 with Parsing

use of com.vladsch.flexmark.ast.util.Parsing in project flexmark-java by vsch.

the class ListBlockParser method parseListMarker.

/**
 * Parse a list marker and return data on the marker or null.
 */
static ListData parseListMarker(ListOptions options, int newItemCodeIndent, ParserState state) {
    Parsing parsing = state.getParsing();
    BasedSequence line = state.getLine();
    int markerIndex = state.getNextNonSpaceIndex();
    int markerColumn = state.getColumn() + state.getIndent();
    int markerIndent = state.getIndent();
    BasedSequence rest = line.subSequence(markerIndex, line.length());
    Matcher matcher = parsing.LIST_ITEM_MARKER.matcher(rest);
    if (!matcher.find()) {
        return null;
    }
    ListBlock listBlock = createListBlock(matcher);
    int markerLength = matcher.end() - matcher.start();
    boolean isNumberedList = !"+-*".contains(matcher.group());
    int indexAfterMarker = markerIndex + markerLength;
    // marker doesn't include tabs, so counting them as columns directly is ok
    int columnAfterMarker = markerColumn + markerLength;
    // the column within the line where the content starts
    int contentOffset = 0;
    // See at which column the content starts if there is content
    boolean hasContent = false;
    int contentIndex = indexAfterMarker;
    for (int i = indexAfterMarker; i < line.length(); i++) {
        char c = line.charAt(i);
        if (c == '\t') {
            contentOffset += Parsing.columnsToNextTabStop(columnAfterMarker + contentOffset);
            contentIndex++;
        } else if (c == ' ') {
            contentOffset++;
            contentIndex++;
        } else {
            hasContent = true;
            break;
        }
    }
    BasedSequence markerSuffix = BasedSequence.NULL;
    int markerSuffixOffset = contentOffset;
    if (!hasContent || contentOffset > newItemCodeIndent) {
        // If this line is blank or has a code block, default to 1 space after marker
        markerSuffixOffset = contentOffset = 1;
    } else if (!isNumberedList || options.isNumberedItemMarkerSuffixed()) {
        // see if we have optional suffix strings on the marker
        String[] markerSuffixes = options.getItemMarkerSuffixes();
        for (String suffix : markerSuffixes) {
            int suffixLength = suffix.length();
            if (suffixLength > 0 && line.matchChars(suffix, contentIndex)) {
                if (options.isItemMarkerSpace()) {
                    final char c = line.midCharAt(contentIndex + suffixLength);
                    if (c != ' ' && c != '\t') {
                        // no space after, no match
                        continue;
                    }
                }
                markerSuffix = line.subSequence(contentIndex, contentIndex + suffixLength);
                contentOffset += suffixLength;
                contentIndex += suffixLength;
                columnAfterMarker += suffixLength;
                hasContent = false;
                int suffixContentOffset = contentOffset;
                for (int i = contentIndex; i < line.length(); i++) {
                    char c = line.charAt(i);
                    if (c == '\t') {
                        contentOffset += Parsing.columnsToNextTabStop(columnAfterMarker + contentOffset);
                    } else if (c == ' ') {
                        contentOffset++;
                    } else {
                        hasContent = true;
                        break;
                    }
                }
                if (!hasContent || contentOffset - suffixContentOffset > newItemCodeIndent) {
                    // If this line is blank or has a code block, default to 1 space after marker suffix
                    contentOffset = suffixContentOffset + 1;
                }
                break;
            }
        }
    }
    return new ListData(listBlock, !hasContent, markerIndex, markerColumn, markerIndent, contentOffset, rest.subSequence(matcher.start(), matcher.end()), isNumberedList, markerSuffix, markerSuffixOffset);
}
Also used : Parsing(com.vladsch.flexmark.ast.util.Parsing) Matcher(java.util.regex.Matcher) BasedSequence(com.vladsch.flexmark.util.sequence.BasedSequence)

Aggregations

Parsing (com.vladsch.flexmark.ast.util.Parsing)1 BasedSequence (com.vladsch.flexmark.util.sequence.BasedSequence)1 Matcher (java.util.regex.Matcher)1