/** * Helper * @param element * @return Closing tag of the given element as a String. */ public String endTag(E element) { return "</" + view.getTagName(element) + ">"; }
@Override public String getTagName(E element) { return inner.getTagName(element); }
/** * TODO(user): generalise this. * @param element * @return true if the element may self-close */ private boolean isSelfClosing(E element) { return view.getTagName(element).equals("br"); }
/** * @return true if the node is an element with the given tag name */ public static <N, E extends N> boolean isMatchingElement( final ReadableDocument<N, E, ?> doc, N node, String tagName) { E el = doc.asElement(node); return el != null && doc.getTagName(el).equals(tagName); }
/** * Appends element's tag name * * @param doc * @param element */ private <E extends N, T extends N> void appendTagName( ReadableDocument<N, E, T> doc, E element) { append(doc.getTagName(element).toLowerCase()); }
/** * Helper * @param element * @param selfClosing Whether this tag is self-closing * @return Opening tag of the given element as a String. */ public String startTag(E element, boolean selfClosing) { return "<" + view.getTagName(element) + getAttributesString(element) + (selfClosing ? "/>" : ">"); }
/** * @param doc * @param node * @return true if node prefers to be output inline */ private <E extends N, T extends N> boolean isInline( ReadableDocument<N, E, T> doc, N node) { E element = doc.asElement(node); T text = doc.asText(node); return text != null || "|b|u|i|".contains("|" + doc.getTagName(element).toLowerCase() + "|"); }
@Override public Object next(ReadableDocument<Object, Object, Object> doc, Object current, Object stopAt) { Object next = super.next(doc, current, stopAt); while (next != null && !doc.getTagName(doc.asElement(next)).equals(tagName)) { next = super.next(doc, next, stopAt); } return next; } }
/** * @param doc * @param node * @return true if the node is a line container element * * NOTE(danilatos): In the future, the match may involve more than * just a tag name check. Other element types, such as table cells, * might be line containers. */ public static <N, E extends N> boolean isLineContainer( final ReadableDocument<N, E, ?> doc, N node) { E el = doc.asElement(node); if (el != null) { return isLineContainerTagname(doc.getTagName(el)); } else { return false; } }
/** * Returns the last element in a subtree with the given tag name. The subtree * root will never match. * * @param doc document to look in * @param tagName tag name to find * @return the last element in the subtree with tagName, or null if none exist */ public static <N, E extends N> E getLastElementWithTagName(ReadableDocument<N, E, ?> doc, String tagName, E subtreeRoot) { N node = DocHelper.getPrevNodeDepthFirst(doc, subtreeRoot, subtreeRoot, true); while (node != null) { E element = doc.asElement(node); if (element != null) { if (doc.getTagName(element).equals(tagName)) { return element; } } node = DocHelper.getPrevNodeDepthFirst(doc, node, subtreeRoot, true); } return null; }
/** * Returns the first element in a subtree with the given tag name. The subtree * root will never match. * * @param doc document to look in * @param tagName tag name to find * @param subtreeRoot of the subtree to search (exclusive) * @return the first element in the subtree with tagName, or null if none * exist */ public static <N, E extends N> E getElementWithTagName(ReadableDocument<N, E, ?> doc, String tagName, E subtreeRoot) { N node = DocHelper.getNextNodeDepthFirst(doc, subtreeRoot, subtreeRoot, true); while (node != null) { E element = doc.asElement(node); if (element != null) { if (doc.getTagName(element).equals(tagName)) { return element; } } node = DocHelper.getNextNodeDepthFirst(doc, node, subtreeRoot, true); } return null; }
/** * Checks whether the current walk is the correct type of element. * @throws IllegalStateException if the element does not match the expected state. * @return the checked element. */ public E checkElement(String tagName, Map<String, String> attributes) { Preconditions.checkState(nodeWalker.hasNext(), "Tree Walker: no more nodes to walk, element expected"); progress(); E element = document.asElement(currentNode); Preconditions.checkState(element != null, "Tree Walker: At text node, element expected"); Preconditions.checkState(document.getTagName(element).equals(tagName), "Tree Walker: Incorrect tag name"); Preconditions.checkState(ValueUtils.equal(document.getAttributes(element), attributes), "Tree Walker: Incorrect attributes"); return element; }
/** Performs a walk against an iterable collection of nodes, returns true if all checks pass. */ public boolean checkWalk(ReadableDocument<N, E, T> doc, Iterable<N> nodes) { try { for (N node : nodes) { E elt = doc.asElement(node); if (elt != null) { checkElement(doc.getTagName(elt), doc.getAttributes(elt)); } else { checkTextNode(doc.getData(doc.asText(node))); } } return checkComplete(); } catch (IllegalStateException e) { return false; // assertion failed. } }
/** * Writes an element's information out to an initialization cursor, optionally recursing * to do likewise for its children. * * @param doc Document the node resides within. * @param element Element containing information to be written. * @param cursor Cursor to write results out to. * @param recurse Whether or not to write children to the operation. */ public static <N, E extends N, T extends N> void buildDomInitializationFromElement( ReadableDocument<N, E, T> doc, E element, DocInitializationCursor cursor, boolean recurse) { cursor.elementStart(doc.getTagName(element), new AttributesImpl(doc.getAttributes(element))); if (recurse) { for (N child = doc.getFirstChild(element); child != null; child = doc.getNextSibling(child)) { buildDomInitializationFromSubtree(doc, child, cursor); } } cursor.elementEnd(); } }