private void printText(Node node) { boolean escape = true; String text = node.getNodeValue(); String source = getSource(node); if (source != null) { // Get the original source string. This will contain the actual entities // such as ">" instead of ">" which it gets turned into for the DOM nodes. // By operating on source we can preserve the user's entities rather than // having > for example always turned into >. text = source; escape = false; } // Most text nodes are just whitespace for formatting (which we're replacing) // so look for actual text content and extract that part out String trimmed = text.trim(); if (!trimmed.isEmpty()) { // TODO: Reformat the contents if it is too wide? // Note that we append the actual text content, NOT the trimmed content, // since the whitespace may be significant, e.g. // <string name="toast_sync_error">Sync error: <xliff:g id="error">%1$s</xliff:g>... // However, we should remove all blank lines in the prefix and suffix of the // text node, or we will end up inserting additional blank lines each time you're // formatting a text node within an outer element (which also adds spacing lines) int lastPrefixNewline = -1; for (int i = 0, n = text.length(); i < n; i++) { char c = text.charAt(i); if (c == '\n') { lastPrefixNewline = i; } else if (!Character.isWhitespace(c)) { break; } } int firstSuffixNewline = -1; for (int i = text.length() - 1; i >= 0; i--) { char c = text.charAt(i); if (c == '\n') { firstSuffixNewline = i; } else if (!Character.isWhitespace(c)) { break; } } if (lastPrefixNewline != -1 || firstSuffixNewline != -1) { boolean stripSuffix; if (firstSuffixNewline == -1) { firstSuffixNewline = text.length(); stripSuffix = false; } else { stripSuffix = true; } int stripFrom = lastPrefixNewline + 1; if (firstSuffixNewline >= stripFrom) { text = text.substring(stripFrom, firstSuffixNewline); // In markup strings we may need to preserve spacing on the left and/or // right if we're next to a markup string on the given side if (lastPrefixNewline != -1) { Node left = node.getPreviousSibling(); if (left != null && left.getNodeType() == Node.ELEMENT_NODE && isMarkupElement((Element) left)) { text = ' ' + text; } } if (stripSuffix) { Node right = node.getNextSibling(); if (right != null && right.getNodeType() == Node.ELEMENT_NODE && isMarkupElement((Element) right)) { text += ' '; } } } } if (escape) { XmlUtils.appendXmlTextValue(mOut, text); } else { // Text is already escaped mOut.append(text); } if (mStyle != XmlFormatStyle.RESOURCE) { mOut.append(mLineSeparator); } } else { // Ensure that if we're in the middle of a markup string, we preserve spacing. // In other words, "<b>first</b> <b>second</b>" - we don't want that middle // space to disappear, but we do want repeated spaces to collapse into one. Node left = node.getPreviousSibling(); Node right = node.getNextSibling(); if (left != null && right != null && left.getNodeType() == Node.ELEMENT_NODE && right.getNodeType() == Node.ELEMENT_NODE && isMarkupElement((Element) left)) { mOut.append(' '); } } }