Search in sources :

Example 1 with AttributesNode

use of com.vladsch.flexmark.ext.attributes.AttributesNode in project flexmark-java by vsch.

the class AttributesInlineParserExtension method parse.

@Override
public boolean parse(final InlineParser inlineParser) {
    if (inlineParser.peek(1) != '{') {
        int index = inlineParser.getIndex();
        BasedSequence input = inlineParser.getInput();
        Matcher matcher = inlineParser.matcher(parsing.ATTRIBUTES_TAG);
        if (matcher != null) {
            BasedSequence attributesOpen = input.subSequence(matcher.start(), matcher.end());
            // see what we have
            // open, see if open/close
            BasedSequence attributesText = input.subSequence(matcher.start(1), matcher.end(1));
            AttributesNode attributes = new AttributesNode(attributesOpen.subSequence(0, 1), attributesText, attributesOpen.endSequence(1));
            attributes.setCharsFromContent();
            int leadingSpaces = attributesText.countLeading(" \t");
            // give it to the text node
            if (leadingSpaces > 0) {
                inlineParser.appendText(attributesText, 0, leadingSpaces);
                attributesText = attributesText.subSequence(leadingSpaces);
            }
            inlineParser.flushTextNode();
            inlineParser.getBlock().appendChild(attributes);
            BasedSequence attributeText = attributesText.trim();
            if (!attributeText.isEmpty()) {
                // have some attribute text
                // parse attributes
                Matcher attributeMatcher = parsing.ATTRIBUTE.matcher(attributeText);
                while (attributeMatcher.find()) {
                    BasedSequence attributeName = attributeText.subSequence(attributeMatcher.start(1), attributeMatcher.end(1));
                    BasedSequence attributeSeparator = attributeMatcher.groupCount() == 1 || attributeMatcher.start(2) == -1 ? BasedSequence.NULL : attributeText.subSequence(attributeMatcher.end(1), attributeMatcher.start(2)).trim();
                    BasedSequence attributeValue = attributeMatcher.groupCount() == 1 || attributeMatcher.start(2) == -1 ? BasedSequence.NULL : attributeText.subSequence(attributeMatcher.start(2), attributeMatcher.end(2));
                    boolean isQuoted = attributeValue.length() >= 2 && (attributeValue.charAt(0) == '"' && attributeValue.endCharAt(1) == '"' || attributeValue.charAt(0) == '\'' && attributeValue.endCharAt(1) == '\'');
                    BasedSequence attributeOpen = !isQuoted ? BasedSequence.NULL : attributeValue.subSequence(0, 1);
                    BasedSequence attributeClose = !isQuoted ? BasedSequence.NULL : attributeValue.endSequence(1, 0);
                    if (isQuoted) {
                        attributeValue = attributeValue.midSequence(1, -1);
                    }
                    AttributeNode attribute;
                    if (attributeSeparator.isNull() && attributeSeparator.isNull() && attributeValue.isNull() && AttributeNode.isImplicitName(attributeName)) {
                        attribute = new AttributeNode(attributeName.subSequence(0, 1), attributeSeparator, attributeOpen, attributeName.subSequence(1), attributeClose);
                    } else {
                        attribute = new AttributeNode(attributeName, attributeSeparator, attributeOpen, attributeValue, attributeClose);
                    }
                    attributes.appendChild(attribute);
                }
                return true;
            }
            // did not process, reset to where we started
            inlineParser.setIndex(index);
        }
    }
    return false;
}
Also used : AttributeNode(com.vladsch.flexmark.ext.attributes.AttributeNode) Matcher(java.util.regex.Matcher) BasedSequence(com.vladsch.flexmark.util.sequence.BasedSequence) AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode)

Example 2 with AttributesNode

use of com.vladsch.flexmark.ext.attributes.AttributesNode in project flexmark-java by vsch.

the class AttributesNodePostProcessor method process.

@Override
public void process(NodeTracker state, Node node) {
    if (node instanceof AttributesNode) {
        AttributesNode attributesNode = (AttributesNode) node;
        // apply to sibling unless the sibling is a Text node then apply it to the parent
        Node previous = attributesNode.getPrevious();
        Node next = attributesNode.getNext();
        // and to trim start of next sibling if we are first
        if (previous == null) {
            // we are first, trim start of next sibling
            if (next != null && !(next instanceof AttributesNode)) {
                if (next.getChars().isBlank()) {
                    // remove this node it is all blank
                    Node tmp = next;
                    next = next.getNext();
                    tmp.unlink();
                    state.nodeRemoved(tmp);
                } else {
                    next.setChars(next.getChars().trimStart());
                }
            }
        }
        if (next == null) {
            // we are last, trim end of prev sibling
            if (previous != null && !(previous instanceof AttributesNode)) {
                if (previous.getChars().isBlank()) {
                    // remove this node it is all blank
                    Node tmp = previous;
                    previous = previous.getPrevious();
                    tmp.unlink();
                    state.nodeRemoved(tmp);
                } else {
                    previous.setChars(previous.getChars().trimEnd());
                }
            }
        }
        Node attributeOwner = getAttributeOwner(state, attributesNode);
        nodeAttributeRepository.put(attributeOwner, attributesNode);
        // set the heading id for this node so the correct id will be used
        if (attributeOwner instanceof AnchorRefTarget) {
            for (Node attributeNode : attributesNode.getReversedChildren()) {
                if (attributeNode instanceof AttributeNode) {
                    if (((AttributeNode) attributeNode).isId()) {
                        ((AnchorRefTarget) attributeOwner).setAnchorRefId(((AttributeNode) attributeNode).getValue().toString());
                        break;
                    }
                }
            }
        }
    }
}
Also used : AttributeNode(com.vladsch.flexmark.ext.attributes.AttributeNode) AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode) AttributeNode(com.vladsch.flexmark.ext.attributes.AttributeNode) AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode)

Example 3 with AttributesNode

use of com.vladsch.flexmark.ext.attributes.AttributesNode in project flexmark-java by vsch.

the class AttributesNodePostProcessor method getAttributeOwner.

public Node getAttributeOwner(NodeTracker state, AttributesNode attributesNode) {
    Node previous = attributesNode.getPrevious();
    Node next = attributesNode.getNext();
    Node attributeOwner;
    Node parent = attributesNode.getParent();
    if (previous == null) {
        // 7. attributes go to the parent
        if (parent instanceof Paragraph) {
            if (parent.getParent() instanceof ParagraphItemContainer) {
                if (parent.getPrevious() == null) {
                    // 1. attributes go to the paragraph parent's parent
                    attributeOwner = parent.getParent().getParent();
                } else {
                    if (attributesNode.getNextAnyNot(AttributesNode.class) == null) {
                        // 2. attributes go to paragraph's previous sibling,
                        attributeOwner = parent.getPrevious();
                    } else {
                        // 3. attributes go to the paragraph
                        attributeOwner = parent;
                    }
                }
            } else {
                if (attributesNode.getNextAnyNot(AttributesNode.class) == null) {
                    if (parent.getPrevious() == null) {
                        // 4. attributes go to paragraph's parent
                        attributeOwner = parent.getParent();
                    } else {
                        // 5. attributes go to paragraph's previous sibling,
                        attributeOwner = parent.getPrevious();
                    }
                } else {
                    // 6. attributes go to the paragraph
                    attributeOwner = parent;
                }
            }
        } else {
            // 7. attributes go to the parent
            attributeOwner = parent;
        }
    } else {
        if ((!myOptions.assignTextAttributes && (previous instanceof Text || previous instanceof TextBase)) || previous.getChars().getEndOffset() < attributesNode.getStartOffset()) {
            // then attributes go to parent
            if (parent instanceof Paragraph && parent.getParent() instanceof ParagraphItemContainer) {
                attributeOwner = parent.getParent();
            } else {
                attributeOwner = parent;
            }
        } else {
            // attached, attributes go to previous node
            if (previous instanceof Text) {
                // insert text base where text was
                TextBase textBase = new TextBase(previous.getChars());
                previous.insertBefore(textBase);
                previous.unlink();
                state.nodeRemoved(previous);
                textBase.appendChild(previous);
                state.nodeAddedWithChildren(textBase);
                attributeOwner = textBase;
            } else {
                if (previous instanceof AttributesNode) {
                    // we are spliced right up against previous attributes, give our attributes to the owner of previous attributes
                    attributeOwner = getAttributeOwner(state, (AttributesNode) previous);
                } else {
                    attributeOwner = previous;
                }
            }
        }
    }
    return attributeOwner;
}
Also used : AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode) AttributeNode(com.vladsch.flexmark.ext.attributes.AttributeNode) AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode)

Example 4 with AttributesNode

use of com.vladsch.flexmark.ext.attributes.AttributesNode in project flexmark-java by vsch.

the class AttributesNodeRenderer method getNodeRenderingHandlers.

// only registered if assignTextAttributes is enabled
@Override
public Set<NodeRenderingHandler<?>> getNodeRenderingHandlers() {
    HashSet<NodeRenderingHandler<?>> set = new HashSet<NodeRenderingHandler<?>>();
    set.add(new NodeRenderingHandler<AttributesNode>(AttributesNode.class, new CustomNodeRenderer<AttributesNode>() {

        @Override
        public void render(AttributesNode node, NodeRendererContext context, HtmlWriter html) {
            int tmp = 0;
        }
    }));
    set.add(new NodeRenderingHandler<TextBase>(TextBase.class, new CustomNodeRenderer<TextBase>() {

        @Override
        public void render(TextBase node, NodeRendererContext context, HtmlWriter html) {
            if (myOptions.assignTextAttributes) {
                final Attributes nodeAttributes = context.extendRenderingNodeAttributes(AttributablePart.NODE, null);
                if (!nodeAttributes.isEmpty()) {
                    // has attributes then we wrap it in a span
                    html.setAttributes(nodeAttributes).withAttr().tag("span");
                    context.delegateRender();
                    html.closeTag("span");
                    return;
                }
            }
            context.delegateRender();
        }
    }));
    return set;
}
Also used : TextBase(com.vladsch.flexmark.ast.TextBase) HtmlWriter(com.vladsch.flexmark.html.HtmlWriter) Attributes(com.vladsch.flexmark.util.html.Attributes) CustomNodeRenderer(com.vladsch.flexmark.html.CustomNodeRenderer) AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode) HashSet(java.util.HashSet)

Example 5 with AttributesNode

use of com.vladsch.flexmark.ext.attributes.AttributesNode in project flexmark-java by vsch.

the class EnumeratedReferenceNodePostProcessor method process.

@Override
public void process(NodeTracker state, Node node) {
    if (node instanceof AttributesNode) {
        AttributesNode attributesNode = (AttributesNode) node;
        for (Node attributeNode : attributesNode.getChildren()) {
            if (attributeNode instanceof AttributeNode) {
                if (((AttributeNode) attributeNode).isId()) {
                    final String text = ((AttributeNode) attributeNode).getValue().toString();
                    enumeratedReferences.add(text);
                }
            }
        }
    }
}
Also used : AttributeNode(com.vladsch.flexmark.ext.attributes.AttributeNode) Node(com.vladsch.flexmark.ast.Node) AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode) AttributeNode(com.vladsch.flexmark.ext.attributes.AttributeNode) AttributesNode(com.vladsch.flexmark.ext.attributes.AttributesNode)

Aggregations

AttributesNode (com.vladsch.flexmark.ext.attributes.AttributesNode)5 AttributeNode (com.vladsch.flexmark.ext.attributes.AttributeNode)4 Node (com.vladsch.flexmark.ast.Node)1 TextBase (com.vladsch.flexmark.ast.TextBase)1 CustomNodeRenderer (com.vladsch.flexmark.html.CustomNodeRenderer)1 HtmlWriter (com.vladsch.flexmark.html.HtmlWriter)1 Attributes (com.vladsch.flexmark.util.html.Attributes)1 BasedSequence (com.vladsch.flexmark.util.sequence.BasedSequence)1 HashSet (java.util.HashSet)1 Matcher (java.util.regex.Matcher)1