Search in sources :

Example 1 with Heading

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

the class TitleExtract method findTitle.

private static String findTitle(Node root) {
    if (root instanceof Heading) {
        Heading h = (Heading) root;
        if (h.getLevel() == 1 && h.hasChildren()) {
            TextCollectingVisitor collectingVisitor = new TextCollectingVisitor();
            return collectingVisitor.collectAndGetText(h);
        }
    }
    if (root instanceof Block && root.hasChildren()) {
        Node child = root.getFirstChild();
        while (child != null) {
            String title = findTitle(child);
            if (title != null) {
                return title;
            }
            child = child.getNext();
        }
    }
    return null;
}
Also used : TextCollectingVisitor(com.vladsch.flexmark.ast.util.TextCollectingVisitor) Heading(com.vladsch.flexmark.ast.Heading) Node(com.vladsch.flexmark.ast.Node) Block(com.vladsch.flexmark.ast.Block)

Example 2 with Heading

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

the class TocUtils method htmlHeadingTexts.

public static Paired<List<Heading>, List<String>> htmlHeadingTexts(NodeRendererContext context, List<Heading> headings, TocOptions tocOptions) {
    final List<String> headingContents = new ArrayList<String>(headings.size());
    final boolean isReversed = tocOptions.listType == TocOptions.ListType.SORTED_REVERSED || tocOptions.listType == TocOptions.ListType.FLAT_REVERSED;
    final boolean isSorted = tocOptions.listType == TocOptions.ListType.SORTED || tocOptions.listType == TocOptions.ListType.SORTED_REVERSED;
    final boolean needText = isReversed || isSorted;
    final HashMap<String, Heading> headingNodes = !needText ? null : new HashMap<String, Heading>(headings.size());
    final HashMap<String, String> headingTexts = !needText || tocOptions.isTextOnly ? null : new HashMap<String, String>(headings.size());
    for (Heading heading : headings) {
        String headingContent;
        // need to skip anchor links but render emphasis
        if (tocOptions.isTextOnly) {
            headingContent = getHeadingText(heading).toString();
        } else {
            TextCollectingAppendable out = getHeadingContent(context, heading);
            headingContent = out.getHtml();
            if (needText) {
                headingTexts.put(headingContent, getHeadingText(heading).toString());
            }
        }
        if (needText) {
            headingNodes.put(headingContent, heading);
        }
        headingContents.add(headingContent);
    }
    if (isSorted || isReversed) {
        if (tocOptions.isTextOnly) {
            if (isSorted) {
                Collections.sort(headingContents, new Comparator<String>() {

                    @Override
                    public int compare(String heading1, String heading2) {
                        return isReversed ? heading2.compareTo(heading1) : heading1.compareTo(heading2);
                    }
                });
            } else {
                Collections.reverse(headingContents);
            }
        } else {
            if (isSorted) {
                Collections.sort(headingContents, new Comparator<String>() {

                    @Override
                    public int compare(String heading1, String heading2) {
                        final String headingText1 = headingTexts.get(heading1);
                        final String headingText2 = headingTexts.get(heading2);
                        return isReversed ? headingText2.compareTo(headingText1) : headingText1.compareTo(headingText2);
                    }
                });
            } else {
                Collections.reverse(headingContents);
            }
        }
        headings = new ArrayList<Heading>();
        for (String headingContent : headingContents) {
            headings.add(headingNodes.get(headingContent));
        }
    }
    return Pair.of(headings, headingContents);
}
Also used : Heading(com.vladsch.flexmark.ast.Heading) TextCollectingAppendable(com.vladsch.flexmark.html.renderer.TextCollectingAppendable)

Example 3 with Heading

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

the class TocUtils method markdownHeaderTexts.

public static List<String> markdownHeaderTexts(List<Heading> headings, TocOptions tocOptions) {
    ArrayList<String> headingTexts = new ArrayList<String>(headings.size());
    for (Heading header : headings) {
        String headerText;
        // need to skip anchor links but render emphasis
        if (tocOptions.isTextOnly) {
            headerText = new TextCollectingVisitor().collectAndGetText(header);
        } else {
            headerText = header.getChars().toString();
        }
        String headerId = header.getAnchorRefId();
        String headerLink;
        if (headerId == null || headerText.isEmpty()) {
            headerLink = headerText;
        } else {
            headerLink = "[" + headerText + "](#" + headerId + ")";
        }
        headingTexts.add(headerLink);
    }
    return headingTexts;
}
Also used : TextCollectingVisitor(com.vladsch.flexmark.ast.util.TextCollectingVisitor) Heading(com.vladsch.flexmark.ast.Heading)

Example 4 with Heading

use of com.vladsch.flexmark.ast.Heading 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 5 with Heading

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

the class AnchorLinkNodePostProcessor method process.

@Override
public void process(NodeTracker state, Node node) {
    if (node instanceof Heading) {
        if (node.isOrDescendantOfType(BlockQuote.class)) {
            int tmp = 0;
        }
        Heading heading = (Heading) node;
        if (heading.getText().isNotNull()) {
            Node anchor = new AnchorLink();
            if (!options.wrapText) {
                if (heading.getFirstChild() == null) {
                    anchor.setChars(heading.getText().subSequence(0, 0));
                    heading.appendChild(anchor);
                } else {
                    anchor.setChars(heading.getFirstChild().getChars().subSequence(0, 0));
                    heading.getFirstChild().insertBefore(anchor);
                }
            } else {
                anchor.takeChildren(heading);
                heading.appendChild(anchor);
            }
            anchor.setCharsFromContent();
            state.nodeAdded(anchor);
        }
    } else {
        int tmp = 0;
    }
}
Also used : AnchorLink(com.vladsch.flexmark.ext.anchorlink.AnchorLink) Heading(com.vladsch.flexmark.ast.Heading) Node(com.vladsch.flexmark.ast.Node)

Aggregations

Heading (com.vladsch.flexmark.ast.Heading)8 Node (com.vladsch.flexmark.ast.Node)2 HeadingCollectingVisitor (com.vladsch.flexmark.ast.util.HeadingCollectingVisitor)2 TextCollectingVisitor (com.vladsch.flexmark.ast.util.TextCollectingVisitor)2 Block (com.vladsch.flexmark.ast.Block)1 AnchorLink (com.vladsch.flexmark.ext.anchorlink.AnchorLink)1 TextCollectingAppendable (com.vladsch.flexmark.html.renderer.TextCollectingAppendable)1 Computable (com.vladsch.flexmark.util.Computable)1 ValueRunnable (com.vladsch.flexmark.util.ValueRunnable)1