Search in sources :

Example 1 with Computable

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

the class TocUtils method renderMarkdownToc.

public static void renderMarkdownToc(HtmlWriter html, List<Heading> headings, List<String> headingTexts, final TocOptions tocOptions) {
    int initLevel = -1;
    int lastLevel = -1;
    final int[] headingNumbers = new int[7];
    final boolean[] openedItems = new boolean[7];
    Computable<String, Integer> listOpen = new Computable<String, Integer>() {

        @Override
        public String compute(Integer level) {
            openedItems[level] = true;
            if (tocOptions.isNumbered) {
                int v = ++headingNumbers[level];
                return v + ". ";
            } else {
                return "- ";
            }
        }
    };
    ValueRunnable<Integer> listClose = new ValueRunnable<Integer>() {

        @Override
        public void run(Integer level) {
            if (tocOptions.isNumbered) {
                headingNumbers[level] = 0;
            }
        }
    };
    if (headings.size() > 0 && !tocOptions.title.isEmpty()) {
        html.raw("######".substring(0, tocOptions.titleLevel)).raw(" ").raw(tocOptions.title).line();
    }
    for (int i = 0; i < headings.size(); i++) {
        Heading header = headings.get(i);
        String headerText = headingTexts.get(i);
        int headerLevel = tocOptions.listType != TocOptions.ListType.HIERARCHY ? 1 : header.getLevel();
        if (initLevel == -1) {
            initLevel = headerLevel;
            lastLevel = headerLevel;
        }
        if (lastLevel < headerLevel) {
            for (int lv = lastLevel; lv <= headerLevel - 1; lv++) {
                openedItems[lv + 1] = false;
            }
            html.indent();
        } else if (lastLevel == headerLevel) {
            if (i != 0) {
                html.line();
            }
        } else {
            for (int lv = lastLevel; lv >= headerLevel + 1; lv++) {
                if (openedItems[lv]) {
                    html.unIndent();
                    listClose.run(lv);
                }
            }
            html.line();
        }
        html.line().raw(listOpen.compute(headerLevel));
        html.raw(headerText);
        lastLevel = headerLevel;
    }
    html.line();
}
Also used : Heading(com.vladsch.flexmark.ast.Heading) ValueRunnable(com.vladsch.flexmark.util.ValueRunnable) Computable(com.vladsch.flexmark.util.Computable)

Example 2 with Computable

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

the class TocLevelsOptionParser method parseOption.

@SuppressWarnings("unchecked")
@Override
public Pair<TocOptions, List<ParsedOption<TocOptions>>> parseOption(BasedSequence optionText, TocOptions options, MessageProvider provider) {
    // may have levels
    TocOptions result = options;
    BasedSequence[] levelsOptionValue = optionText.split(',');
    final ParserParams parserParams = new ParserParams();
    if (provider == null)
        provider = MessageProvider.DEFAULT;
    int newLevels = 0;
    int i = 0;
    final MessageProvider finalProvider = provider;
    Computable<Integer, BasedSequence> convertWithMessage = new Computable<Integer, BasedSequence>() {

        @Override
        public Integer compute(BasedSequence option) {
            try {
                return option.isEmpty() ? null : Integer.parseInt(option.toString());
            } catch (Exception ignored) {
                parserParams.add(new ParserMessage(option, ParsedOptionStatus.ERROR, finalProvider.message(KEY_OPTION_0_VALUE_1_NOT_INTEGER, OPTION_0_VALUE_1_NOT_INTEGER, myOptionName, option)));
                parserParams.skip = true;
                return null;
            }
        }
    };
    for (BasedSequence option : levelsOptionValue) {
        BasedSequence[] optionRange = option.split('-', 2, BasedSequence.SPLIT_TRIM_PARTS);
        Integer rangeStart;
        Integer rangeEnd;
        parserParams.skip = false;
        if (optionRange.length == 2) {
            rangeStart = convertWithMessage.compute(optionRange[0]);
            rangeEnd = convertWithMessage.compute(optionRange[1]);
            if (rangeStart == null)
                rangeStart = 1;
            if (rangeEnd == null)
                rangeEnd = 6;
        } else {
            rangeStart = convertWithMessage.compute(optionRange[0]);
            rangeEnd = rangeStart;
        }
        if (!parserParams.skip) {
            if (rangeStart == null) {
                parserParams.add(new ParserMessage(option, ParsedOptionStatus.IGNORED, finalProvider.message(KEY_OPTION_0_VALUE_1_TRUNCATED_TO_EMPTY_RANGE, OPTION_0_VALUE_1_TRUNCATED_TO_EMPTY_RANGE, myOptionName, option)));
            } else {
                if (rangeEnd < rangeStart) {
                    int tmp = rangeStart;
                    rangeStart = rangeEnd;
                    rangeEnd = tmp;
                }
                if (rangeEnd < 1 || rangeStart > 6) {
                    if (rangeStart == (int) rangeEnd) {
                        parserParams.add(new ParserMessage(option, ParsedOptionStatus.IGNORED, provider.message(KEY_OPTION_0_VALUE_1_NOT_IN_RANGE, OPTION_0_VALUE_1_NOT_IN_RANGE, myOptionName, option)));
                    } else {
                        parserParams.add(new ParserMessage(option, ParsedOptionStatus.WARNING, finalProvider.message(KEY_OPTION_0_VALUE_1_TRUNCATED_TO_EMPTY_RANGE, OPTION_0_VALUE_1_TRUNCATED_TO_EMPTY_RANGE, myOptionName, option)));
                    }
                } else {
                    int wasStart = rangeStart;
                    int wasEnd = rangeEnd;
                    rangeStart = Utils.minLimit(rangeStart, 1);
                    rangeEnd = Utils.maxLimit(rangeEnd, 6);
                    if (wasStart != rangeStart || wasEnd != rangeEnd) {
                        parserParams.add(new ParserMessage(option, ParsedOptionStatus.WEAK_WARNING, finalProvider.message(KEY_OPTION_0_VALUE_1_TRUNCATED_TO_RANGE_2, OPTION_0_VALUE_1_TRUNCATED_TO_RANGE_2, myOptionName, option, rangeStart + ", " + rangeEnd)));
                    }
                    for (int b = rangeStart; b <= rangeEnd; b++) newLevels = newLevels | (1 << b);
                }
            }
        }
        i++;
    }
    if (newLevels != 0)
        result = result.withLevels(newLevels);
    return new Pair<TocOptions, List<ParsedOption<TocOptions>>>(result, (List<ParsedOption<TocOptions>>) Collections.<ParsedOption<TocOptions>>singletonList(new ParsedOption(optionText, this, parserParams.status, parserParams.messages)));
}
Also used : BasedSequence(com.vladsch.flexmark.util.sequence.BasedSequence) Computable(com.vladsch.flexmark.util.Computable) Pair(com.vladsch.flexmark.util.Pair)

Aggregations

Computable (com.vladsch.flexmark.util.Computable)2 Heading (com.vladsch.flexmark.ast.Heading)1 Pair (com.vladsch.flexmark.util.Pair)1 ValueRunnable (com.vladsch.flexmark.util.ValueRunnable)1 BasedSequence (com.vladsch.flexmark.util.sequence.BasedSequence)1