package org.freeplane.features.text; import java.util.List; import org.freeplane.core.util.HtmlUtils; import org.freeplane.features.format.FormatController; import org.freeplane.features.format.PatternFormat; import org.freeplane.features.map.NodeModel; class FormatContentTransformer extends AbstractContentTransformer { final private TextController textController; public FormatContentTransformer(final TextController textController, final int priority) { super(priority); this.textController = textController; } public Object transformContent(TextController textController, Object obj, final NodeModel node, Object transformedExtension) { if (obj == null || node.getUserObject() != transformedExtension) return obj; final String format = textController.getNodeFormat(node); final boolean nodeNumbering = textController.getNodeNumbering(node); return expandFormat(obj, node, format, nodeNumbering); } private Object expandFormat(Object obj, final NodeModel node, final String format, boolean nodeNumbering) { final boolean hasFormat = format != null && format.length() != 0 && !PatternFormat.IDENTITY_PATTERN.equals(format); if (!hasFormat && !nodeNumbering){ return obj; } // - if html: strip html header // - if number or date format: Convertible.toObject(text) // - format/expand // - if error: use original text // - if nodeNumbering add // - if html: enclose in html tag final boolean isHtml = (obj instanceof String) && HtmlUtils.isHtmlNode((String)obj); if (isHtml) { obj = HtmlUtils.extractRawBody((String)obj); } if (hasFormat) obj = FormatController.format(obj, format); if (nodeNumbering && !node.isRoot()){ StringBuilder builder = new StringBuilder(node.getNodeLevel(true) * 2); getPathToRoot(builder, node); builder.append(' '); if (isHtml) { obj = insertPrefix(obj.toString(), builder.toString()); } else{ obj = builder.toString() + obj; } } if (isHtml) obj = "<html><head></head><body>" + obj + "</body></html>"; return obj.toString(); } private String insertPrefix(String html, String prefix) { StringBuilder sb = new StringBuilder(html.length() + prefix.length() + 1); int i = 0; int level = 0; WHILE: while(i < html.length()){ final char c = html.charAt(i); switch(c){ case '<': level++; break; case '>': level--; break; default: if(level == 0 && ! Character.isWhitespace(c)) break WHILE; } i++; } sb.append(html.subSequence(0, i)); sb.append(prefix); sb.append(html.subSequence(i, html.length())); return sb.toString(); } private void getPathToRoot(StringBuilder builder, NodeModel node) { final NodeModel parentNode = node.getParentNode(); if(parentNode == null) return; if( textController.getNodeNumbering(parentNode)){ getPathToRoot(builder, parentNode); if (builder.length() > 0) builder.append('.'); } final List<NodeModel> children = parentNode.getChildren(); int counter = 1; for (NodeModel child : children) { if(child.equals(node)) break; if(textController.getNodeNumbering(child)) counter++; } builder.append(counter); } }