package org.zwobble.mammoth.html; import java.util.Map; import static org.zwobble.mammoth.util.MammothLists.orderedBy; public class HtmlWriter { public static void write(HtmlNode node, StringBuilder builder) { node.visit(new HtmlNode.Visitor() { @Override public void visit(HtmlElement element) { builder.append("<").append(element.getTagName()); HtmlWriter.generateAttributes(element.getAttributes(), builder); builder.append(">"); element.getChildren().forEach(node -> write(node, builder)); builder .append(""); } @Override public void visit(HtmlSelfClosingElement element) { builder.append("<").append(element.getTagName()); HtmlWriter.generateAttributes(element.getAttributes(), builder); builder.append(" />"); } @Override public void visit(HtmlTextNode node) { builder.append(HtmlWriter.escapeText(node.getValue())); } @Override public void visit(HtmlForceWrite forceWrite) { } }); } private static void generateAttributes(Map attributes, StringBuilder builder) { for (Map.Entry attribute : orderedBy(attributes.entrySet(), Map.Entry::getKey)) { builder .append(" ") .append(attribute.getKey()) .append("=\"") .append(HtmlWriter.escapeAttributeValue(attribute.getValue())) .append("\""); } } private static String escapeText(String text) { return text.replace("&", "&").replace("<", "<").replace(">", ">"); } private static String escapeAttributeValue(String value) { return escapeText(value).replace("\"", """); } }