// This file is part of PleoCommand: // Interactively control Pleo with psychobiological parameters // // Copyright (C) 2010 Oliver Hoffmann - Hoffmann_Oliver@gmx.de // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Boston, USA. package pleocmd; import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import pleocmd.pipe.data.Data; import pleocmd.pipe.val.Syntax; public final class StringManip { private StringManip() { // final class and only static methods } public static String safeHTML(final String s) { return s.replace("<", "<").replace(">", ">") .replace("\n", "<br>"); } public static String safeTex(final String s) { return safeTex(s, false); } public static String safeTex(final String s, final boolean onlyPart) { final StringBuilder sb = new StringBuilder(); char last = '\0'; for (final char c : s.toCharArray()) { switch (c) { case '{': sb.append("\\{"); break; case '}': sb.append("\\}"); break; case '[': sb.append("\\lbrack{}"); break; case ']': sb.append("\\rbrack{}"); break; case '\\': sb.append("\\textbackslash{}"); break; case '&': sb.append(onlyPart ? "&" : "\\&"); break; case '$': sb.append("\\$"); break; case '\n': sb.append("\\\\\n"); break; case '\"': sb.append("''"); break; case '.': sb.append("\"\"."); break; case '_': sb.append("\\_"); break; case ' ': sb.append(last == ' ' || last == '{' || // last == '>' ? "\\thinspace{}" : " "); break; default: sb.append(c); } last = c; } return sb.toString(); } public static String removePseudoHTML(final String text) { if (!text.startsWith("<html>")) return text; final StringBuilder sb = new StringBuilder(); for (int i = 0; i < text.length(); ++i) { final char c = text.charAt(i); switch (c) { case '<': { while (text.charAt(++i) != '>') { // ignore the whole tag } break; } case '&': { final StringBuilder sb2 = new StringBuilder(); char c2; while ((c2 = text.charAt(++i)) != ';') sb2.append(c2); final String id = sb2.toString(); if ("lt".equals(id)) sb.append('<'); else if ("gt".equals(id)) sb.append('>'); else if ("amp".equals(id)) sb.append('&'); else if ("quot".equals(id)) sb.append('"'); else Log.detail("Ignoring unknown &%s;", id); // CS_IGNORE break; } default: sb.append(c); } } return sb.toString(); } public static String convertPseudoToRealHTML(final String text) { if (!text.startsWith("<html>")) return safeHTML(text); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < text.length(); ++i) { final char c = text.charAt(i); switch (c) { case '<': { final StringBuilder sb2 = new StringBuilder(); char c2; while ((c2 = text.charAt(++i)) != '>') sb2.append(c2); final String tag = sb2.toString(); if ("html".equals(tag) || "/html".equals(tag)) { // just ignore them silently } else sb.append("<" + tag + ">"); break; } default: sb.append(c); } } return sb.toString(); } public static String convertPseudoHTMLToTex(final String s, final Set<String> colorNames) { if (!s.startsWith("<html>")) return safeTex(s); final String text = safeTex(s, true); final StringBuilder sb = new StringBuilder(); sb.append("{"); for (int i = 0; i < text.length(); ++i) { final char c = text.charAt(i); switch (c) { case '<': { final StringBuilder sb2 = new StringBuilder(); char c2; while ((c2 = text.charAt(++i)) != '>') sb2.append(c2); final String tag = sb2.toString(); if ("/font".equals(tag) || "/b".equals(tag) || "/i".equals(tag)) { // ignore } else if (tag.startsWith("b")) sb.append("}{\\bf "); else if (tag.startsWith("i")) sb.append("}{\\it "); else if (tag.startsWith("font color=#")) { final String clrName = "PleoCommandColor" + tag.substring(12, 18); sb.append("}\\textcolor{"); sb.append(clrName); colorNames.add(clrName); sb.append("}{"); } else if ("html".equals(tag) || "/html".equals(tag)) { // just ignore them silently } else Log.detail("Ignoring unknown tag '%s'", tag); break; } case '&': { final StringBuilder sb2 = new StringBuilder(); char c2; while ((c2 = text.charAt(++i)) != ';') sb2.append(c2); final String id = sb2.toString(); if ("lt".equals(id)) sb.append('<'); else if ("gt".equals(id)) sb.append('>'); else if ("amp".equals(id)) sb.append("\\&"); else if ("quot".equals(id)) sb.append("''"); else Log.detail("Ignoring unknown &%s;", id); // CS_IGNORE break; } default: sb.append(c); } } sb.append("}"); return sb.toString(); } public static Color hexToColor(final String hex) { try { return new Color(Integer.valueOf(hex.substring(0, 2), 16), Integer.valueOf(hex.substring(2, 4), 16), Integer.valueOf( hex.substring(4, 6), 16)); } catch (final NumberFormatException e) { return Color.RED; } } public static String printSyntaxHighlightedAscii(final Data data) throws IOException { final ByteArrayOutputStream out = new ByteArrayOutputStream(); final List<Syntax> syntaxList = new ArrayList<Syntax>(); data.writeToAscii(new DataOutputStream(out), false, syntaxList); // html like formatting, no real xml code here final StringBuilder sb = new StringBuilder(out.toString()); sb.insert(0, "<html>"); int o = 6; for (final Syntax sy : syntaxList) { final Color c = sy.getType().getColor(); sb.insert( sy.getPosition() + o, String.format("<font color=#%02X%02X%02X>", c.getRed(), c.getGreen(), c.getBlue())); o += 20; } return sb.toString(); } public static String printSyntaxHighlightedBinary(final Data data) throws IOException { final StringBuilder sb = new StringBuilder(); final List<Syntax> syntaxList = new ArrayList<Syntax>(); data.writeToBinary(sb, syntaxList); // html like formatting, no real xml code here sb.insert(0, "<html>"); int o = 6; for (final Syntax sy : syntaxList) { final Color c = sy.getType().getColor(); sb.insert( sy.getPosition() + o, String.format("<font color=#%02X%02X%02X>", c.getRed(), c.getGreen(), c.getBlue())); o += 20; } return sb.toString(); } }