/* * Created on 2004-5-11 * */ package com.bitmechanic.spindle; /** TextHtml * * 23.10.2001 MAP Initial release * 24.01.2002 MAP Method "text2html()". * Check for the ordinal value of char before addressing * "symbolicCode" array. Non ISO8859-1 char. * 14.06.2005 Luogang add unicode converter from html. */ import java.util.Arrays; /** * This class convert a text in an HTML text format with symbolic code (&xxxx;), * it also convert a given HTML text format which contain symbolic code to text. * @version 1.1 * @author Philippe Martin */ public class TextHtml { /** * Method text2html: Convert a text to an HTML format. * * @param text: The original text string * @return The converted HTML text including symbolic codes string */ public static void main(String argv[]) throws Exception { //VisitedTaskList vt = new VisitedTaskList(); //System.out.println(TextHtml.html2text("<code>"Hello from ActivePerl!"</code> 逍遥   ")); System.out.println(TextHtml.text2html("&")); //System.out.println(TextHtml.html2text("网站导航")); //char a = ':'; //System.out.println(TextHtml.print(new String("将红帽认证培训计划引入中国".getBytes("GBK"), "iso8859_1"))); } public static String text2html(String text) { if (text == null) return text; StringBuffer t = new StringBuffer(text.length() + 10); // 10 is just a test value, could be anything, should affect performance for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); // Check for non ISO8859-1 characters if ((int)c < symbolicCode.length) { // Maybe slower than "(int)c & 0xFF != 0" but more evolutive //System.out.println("hi"); String sc = symbolicCode[(int)c]; if ("".equals(sc)) { t = t.append(c); } else { t = t.append(sc); } } else { t.append("&#x"); t.append(Integer.toHexString(c)); System.out.println("char:"+Integer.toHexString(c)); t.append(";"); } } return t.toString(); } public static String print(String text) { if (text == null) return text; StringBuffer t = new StringBuffer(text.length() + 10); // 10 is just a test value, could be anything, should affect performance for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); // Check for non ISO8859-1 characters //{ t.append("&#x"); t.append(Integer.toHexString(c)); System.out.println("char:"+Integer.toHexString(c)); t.append(";"); //} } return t.toString(); } /** * Method html2text: Convert an HTML text format to a normal text format. * * @param text: The original HTML text string * @return The converted text without symbolic codes string */ public static String html2text(String text) { if (text == null) return text; StringBuffer t = new StringBuffer(text.length()); boolean number=false; char tempchar; for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); if (c == '&') { String code = String.valueOf(c); number=false; do { if (++i >= text.length()) break; tempchar = text.charAt(i); if (tempchar == '&') { i--; break; } else if (tempchar == '#') number=true; code += tempchar; } while (text.charAt(i) != ';'); if (!code.equals(" ")) { if (number) { try { //System.out.println("will decode:"+"0"+code.substring(2,code.length() -1)); long tempL; if(code.length()<4) { t.append(code); continue; } if (code.substring(2,code.length() -1).startsWith("x")) tempL= (Long.decode("0"+code.substring(2,code.length() -1))).longValue(); else tempL= (Long.decode(code.substring(2,code.length() -1))).longValue(); //System.out.println("long value:"+tempL); byte[] b; String charset; //{ //System.out.println("into utf"); b= new byte[2]; b[1]=(byte)tempL; //System.out.println(b[1]); b[0]=(byte)(tempL>>>8); //System.out.println(b[0]); charset = "UTF-16BE";//"UTF-16LE";// //} try{ //System.out.println(new String(b, charset )); t.append(new String(b, charset )); }catch(Exception e) {} } catch(NumberFormatException e) { t.append(code); } } else { int index = Arrays.binarySearch(sortedSymbolicCode, new NumericSymbolicCode(code, 0)); // Does the extracting code correspond to something ? if (index >= 0) { t = t.append((char)sortedSymbolicCode[index].getNumericCode()); } else { t = t.append(code); } } } } else { t = t.append(c); //modify here //if(c == '<') intag = true; //if(! intag) t = t.append(c); //if(c == '>')intag = false; //end modify } } return t.toString(); } /** * Array of symbolic code order by numeric code ! <br> * The symbolic codes and their position correspond to the ISO 8859-1 set * of char. The empty definitions mean that there is no symbolic codes for * that character or this symbolic code is not used. */ private static final String[] symbolicCode = { // 0 "", "", "", "", "", "", "", "", "", "", // 10 "", "", "", "", "", "", "", "", "", "", // 20 "", "", "", "", "", "", // yen sign "", "", "", "", // 30 "", "", " ", "", """, // quotation mark "", "", "", "&", "", // unfortunately ' is not supported in HTML 4, only XHTML 1.0 // 40 "", "", "", "", "", "", "", "", "", "", // 50 "", "", "", "", "", "", "", "", "", "", // 60 //change here "<", "", ">", "", //end change luogang "@", // commercial at "", "", "", "", "", // 70 "", "", "", "", "", "", "", "", "", "", // 80 "", "", "", "", "", "", "", "", "", "", // 90 "", "", "", "", "", "", "`", // grave accent "", "", "", // 100 "", "", "", "", "", "", "", "", "", "", // 110-130 "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", // 140 "", "", "", "", "", "", "’", // other apostrophe "", "", "", // 150 "", "", "", "", "", "", "", "", "", "", // 160 "", // non breaking space (should be ) "¡", // invertedexclamation sign "¢", // cent sign "£", // pound sterling sign "¤", // general currency sign "¥", // yen sign "¦", // broken vertical bar "§", // section sign (legal) "¨", // umlaut (dieresis) "©", // copyright // 170 "ª", // feminine ordinal "«", // guillemot left "¬", // not sign "­", // soft hyphen "®", // registered trademark "¯", // macron accent "°", // degree sign "±", // plus or minus "²", // raised to square(superscript two) "³", // superscript three // 180 "´", // acute accent "µ", // micron sign "¶", // paragraph sign, Pi "·", // middle dot "¸", // cedilla mark "&supl;", // raised to one(superscript one) "º", // masculine ordinal "»", // guillemot right "¼", // one-forth fraction "½", // half fraction // 190 "¾", // three-forths fraction "¿", // inverted question mark "À", // A with grave accent "Á", // A with acute accent "Â", // A with circumflex accent "Ã", // A with tilde accent "Ä", // A with angstrom "Å", // A with umlaut mark "Æ", // AE dipthong (ligature) "Ç", // C with cedilla mark // 200 "È", // E with grave accent "É", // E with acute accent "Ê", // E with circumflex accent "Ë", // E with umlaut mark "Ì", // I with grave accent "Í", // I with acute accent "Î", // I with circumflex accent "Ï", // I with umlaut mark "Ð", // Icelandic Capital Eth "Ñ", // N with tilde accent // 210 "Ò", // O with grave accent "Ó", // O with acute accent "Ô", // O with circumflex accent "Õ", // O with tilde accent "Ö", // O with umlaut mark "×", // multiply sign "Ø", // O slash "Ù", // U with grave accent "Ú", // U with acute accent "Û", // U with circumflex accent // 220 "Ü", // U with umlaut mark "Ý", // Y with acute accent "Þ", // Icelandic Capital Thorn "ß", // small sharp s(sz ligature) "à", // a with grave accent "á", // a with acute accent "â", // a with circumflex accent "ã", // a with tilde accent "ä", // a with angstrom "å", // a with umlaut mark // 230 "æ", // ae dipthong (ligature) "ç", // c with cedilla mark "è", // e with grave accent "é", // e with acute accent "ê", // e with circumflex accent "ë", // e with umlaut mark "ì", // i with grave accent "í", // i with acute accent "î", // i with circumflex accent "ï", // i with umlaut mark // 240 "ð", // Icelandic small eth "ñ", // n with tilde accent "ò", // o with grave accent "ó", // o with acute accent "ô", // o with circumflex accent "õ", // o with tilde accent "ö", // o with umlaut mark "÷", // divide sign "ø", // o slash "ù", // u with grave accent // 250 "ú", // u with acute accent "û", // u with circumflex accent "ü", // u with umlaut mark "ý", // y with acute accent "þ", // Icelandic small thorn "ÿ", // y with umlaut mark }; /** * Array of symbolic code order symbolic code !<br> * This array is the reciprocal from the 'symbolicCode' array. */ private static NumericSymbolicCode[] sortedSymbolicCode = new NumericSymbolicCode[symbolicCode.length]; /** * This class is the structure used for the 'sortedSymbolicCode' array. * Each symbolic code string (sorted by alphabetical order) have its numerical * corresponding code.<br> * This class also implements the 'Comparable' interface to ease the sorting * process in the initialisation bloc. */ final private static class NumericSymbolicCode implements Comparable { public NumericSymbolicCode(String symbolicCode, int numericCode) { this.symbolicCode = symbolicCode; this.numericCode = numericCode; } public String getSymbolicCode() { return symbolicCode; } public int getNumericCode() { return numericCode; } public int compareTo(Object object) { NumericSymbolicCode nsc = (NumericSymbolicCode)object; return symbolicCode.compareTo(nsc.symbolicCode); } private String symbolicCode; private int numericCode; } /** * Initialization and sorting of the 'sortedSymbolicCode' */ static { for (int i = 0; i < symbolicCode.length; i++) { sortedSymbolicCode[i] = new NumericSymbolicCode(symbolicCode[i], i); } Arrays.sort(sortedSymbolicCode); } }