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();
}
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)));
}
Aggregations