Ticket #1958: html.patch
File html.patch, 13.6 KB (added by diana, 15 years ago) |
---|
-
src/main/java/org/sophie2/extra/func/html/HtmlTextImportManager.java
### Eclipse Workspace Patch 1.0 #P org.sophie2.extra.func.html
1 1 package org.sophie2.extra.func.html; 2 2 3 import java.io.ByteArrayInputStream; 3 4 import java.io.File; 4 import java.io.FileReader; 5 import java.io.FileInputStream; 6 import java.io.FileNotFoundException; 5 7 import java.io.IOException; 6 import java.io.Reader; 8 import java.io.InputStream; 9 import java.util.regex.Matcher; 10 import java.util.regex.Pattern; 7 11 8 12 import javax.swing.JTextPane; 9 13 import javax.swing.filechooser.FileFilter; … … 28 32 /** 29 33 * The file filter of the html resources. 30 34 */ 31 public static final FileFilter FILE_FILTER = 32 new FileExtensionFilter("HTML (*.html, *.htm)", "html", "htm");33 35 public static final FileFilter FILE_FILTER = new FileExtensionFilter( 36 "HTML (*.html, *.htm)", "html", "htm"); 37 34 38 /** 35 39 * The import role of the <code>HtmlTextImportManager</code>. 36 40 */ 37 41 public static final String IMPORT_ROLE = "import html text"; 38 42 39 43 @Override 40 44 public String getImportRole() { 41 45 return IMPORT_ROLE; 42 46 } 43 44 @Override 47 private static final String splitBadTagStr = "<meta\\s*http-equiv" + 48 "=\\s*\"Content-Type\"\\s*content=\"text/html;"; 49 private static final String splitEndTagStr = ">"; 50 @Override 45 51 public ImmHotText getResourceData(File resFile, ResourceH parentResource, 46 52 Object additionalData) { 47 if (resFile == null || !(resFile.getName().endsWith("html") 48 || resFile.getName().endsWith("htm"))) { 53 FileInputStream infile = null; 54 if (resFile == null 55 || !(resFile.getName().endsWith("html") || resFile.getName() 56 .endsWith("htm"))) { 49 57 return null; 50 58 } 51 59 60 StringBuilder fileContent = new StringBuilder(); 61 try { 62 infile = new FileInputStream(resFile); 63 byte[] bFileContent = new byte[infile.available()]; 64 int sizeRead = 0; 65 while (sizeRead != -1) { 66 try { 67 sizeRead = infile.read(bFileContent); 68 for (int i = 0; i < sizeRead; ++i) { 69 fileContent.append((char) bFileContent[i]); 70 } 71 } catch (IOException e) { 72 throw new RuntimeException("Could not import HTML file", e); 73 } 74 } 75 76 } catch (FileNotFoundException e) { 77 throw new RuntimeException("Could not import HTML file", e); 78 } catch (IOException e) { 79 throw new RuntimeException("Could not import HTML file", e); 80 } 81 Pattern badTagPattern = Pattern.compile(splitBadTagStr,Pattern.CASE_INSENSITIVE); 82 Pattern endTagPattern = Pattern.compile(splitEndTagStr); 83 Matcher badTagMatcher = badTagPattern.matcher(fileContent); 84 Matcher endTagMatcher = endTagPattern.matcher(fileContent); 85 if(badTagMatcher.find()) { 86 int start = badTagMatcher.start(); 87 int end = badTagMatcher.end(); 88 if(endTagMatcher.find(end)) { 89 end = endTagMatcher.end(); 90 } 91 fileContent.replace(start, end, ""); 92 } 93 52 94 HTMLEditorKit kit = new HTMLEditorKit(); 53 95 HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(); 54 55 96 JTextPane pane = new JTextPane(); 56 97 pane.setEditorKit(kit); 57 98 pane.setDocument(doc); 58 99 View view = pane.getUI().getRootView(pane); 59 60 Reader reader = null;61 String htmlPlain;62 100 try { 63 reader = new FileReader(resFile);64 kit.read( reader, doc, 0);65 reader.close();101 InputStream is = new ByteArrayInputStream(fileContent.toString().getBytes()); 102 kit.read(is, doc, 0); 103 is.close(); 66 104 67 htmlPlain = doc.getText(0, doc.getLength());68 105 } catch (BadLocationException e) { 69 106 throw new RuntimeException("Could not import HTML file", e); 70 107 } catch (IOException e) { 71 108 throw new RuntimeException("Could not import HTML file", e); 72 109 } 73 110 74 ImmHotText text = ImmHotText.createPlain(htmlPlain); 75 76 ApplyHtmlStylesUtility.applyStyles(text, view); 111 ImmHotText text = null; 77 112 113 try { 114 ApplyHtmlStylesUtility utility = new ApplyHtmlStylesUtility(); 115 text = utility.createStyled(view); 116 } catch (BadLocationException e) { 117 throw new RuntimeException(e); 118 } 119 78 120 return text; 121 79 122 } 80 123 81 124 } -
src/main/java/org/sophie2/extra/func/html/util/ApplyHtmlStylesUtility.java
1 1 package org.sophie2.extra.func.html.util; 2 2 3 import java.util.ArrayList; 3 4 import java.util.Enumeration; 4 5 import java.util.HashMap; 6 import java.util.List; 5 7 import java.util.Map; 6 8 7 9 import javax.swing.text.AttributeSet; 8 10 import javax.swing.text.BadLocationException; 9 11 import javax.swing.text.View; 10 12 13 import org.sophie2.base.commons.structures.ImmDosTree; 14 import org.sophie2.base.commons.structures.ImmTreeMap; 15 import org.sophie2.base.commons.util.ImmColor; 16 import org.sophie2.base.commons.util.ImmMap; 17 import org.sophie2.base.commons.util.ImmMap.ImmEntry; 11 18 import org.sophie2.base.model.text.HotAttr; 12 19 import org.sophie2.base.model.text.smart.HotPos; 13 20 import org.sophie2.base.model.text.smart.ImmHotText; 14 21 import org.sophie2.base.model.text.smart.elements.CommonAttr; 15 22 import org.sophie2.base.model.text.smart.position.HotInterval; 16 23 import org.sophie2.base.model.text.smart.style.HotStyleDef; 24 import org.sophie2.main.app.commons.element.ElementEntry; 17 25 import org.sophie2.main.app.commons.util.AttributedPair; 18 import org.sophie2.main.app.commons.util.TextManipulationUtility;19 26 20 27 /** 21 28 * Helps adding the styles of the html document to the resulting HotText. … … 23 30 * @author diana 24 31 */ 25 32 public class ApplyHtmlStylesUtility { 26 33 private ImmMap<String, HotAttr<?>> htmlMap; 34 private ImmMap<String,Integer> hexMap; 27 35 /** 36 * The default constructor; 37 */ 38 public ApplyHtmlStylesUtility() { 39 this.htmlMap = new ImmTreeMap<String, HotAttr<?>>( 40 new ImmDosTree<ImmEntry<String, HotAttr<?>>>()); 41 this.htmlMap = this.htmlMap.put("font-size", CommonAttr.FONT_SIZE); 42 this.htmlMap = this.htmlMap.put("margin-left", CommonAttr.PARA_LEFT_INDENT); 43 this.htmlMap = this.htmlMap.put("margin-right", CommonAttr.PARA_RIGHT_INDENT); 44 this.htmlMap = this.htmlMap.put("margin-bottom", CommonAttr.PARA_SPACE_BELOW); 45 this.htmlMap = this.htmlMap.put("margin-top", CommonAttr.PARA_SPACE_ABOVE); 46 this.htmlMap = this.htmlMap.put("color", CommonAttr.FOREGROUND_COLOR); 47 //--------------- 48 this.htmlMap = this.htmlMap.put("font-weight", CommonAttr.BOLD); 49 this.htmlMap = this.htmlMap.put("font-family", CommonAttr.FONT_FAMILY); 50 //-------------- 51 this.hexMap = new ImmTreeMap<String,Integer>( 52 new ImmDosTree<ImmEntry<String, Integer>>()); 53 for(int i = 0;i<10;++i) { 54 this.hexMap = this.hexMap.put(""+i, i); 55 } 56 this.hexMap = this.hexMap.put("A", 10); 57 this.hexMap = this.hexMap.put("B", 11); 58 this.hexMap = this.hexMap.put("C", 12); 59 this.hexMap = this.hexMap.put("D", 13); 60 this.hexMap = this.hexMap.put("E", 14); 61 this.hexMap = this.hexMap.put("F", 15); 62 } 63 64 /** 28 65 * Apply the styles for the html document. 29 66 * 30 * @param text31 * The HotText32 67 * @param view 33 * The view with the html text. 68 * The element with the html text. 69 * @return 70 * The created styled text. 71 * 72 * @throws BadLocationException 34 73 */ 35 public static void applyStyles(ImmHotText text, View view) { 74 public ImmHotText createStyled(View view) throws BadLocationException { 75 76 List<ElementEntry> entries = new ArrayList<ElementEntry>(); 77 StringBuilder builder = new StringBuilder(); 78 79 applyStyles(view, builder, entries); 80 81 ImmHotText newText = ImmHotText.createPlain(builder.toString()); 82 HotPos curPos = newText.getBegin(); 83 84 for (ElementEntry entry : entries) { 85 int length = entry.getLength(); 86 HotInterval interval = new HotInterval(curPos, newText.advance(curPos, length)); 87 HotStyleDef def = HotStyleDef.getEmpty().derive(entry.getAttributes()); 88 newText = newText.applyStyle(interval, def); 89 curPos = newText.advance(curPos, length); 90 } 91 92 return newText; 93 } 94 95 96 private void applyStyles( View view,StringBuilder builder,List<ElementEntry> entries) 97 throws BadLocationException { 36 98 if (view.getViewCount() == 0) { 99 view.getDocument().getText(0, view.getDocument().getLength()); 37 100 int begin = view.getElement().getStartOffset(); 38 101 int end = view.getElement().getEndOffset(); 39 StringBuffer buffer = new StringBuffer(); 40 String stringToAppend = null; 41 42 try { 43 stringToAppend = view.getDocument().getText(begin, end - begin); 44 } catch (BadLocationException e) { 45 throw new RuntimeException(e); 46 } 47 48 if (stringToAppend != null) { 49 buffer.append(stringToAppend); 50 AttributeSet as = view.getAttributes(); 51 52 if (as != null) { 53 Enumeration<?> names = as.getAttributeNames(); 54 Map<HotAttr<?>, Object> styleValues = new HashMap<HotAttr<?>, Object>(); 55 while (names.hasMoreElements()) { 56 Object nm = names.nextElement(); 57 AttributedPair<Object, Object> attr = 58 new AttributedPair<Object, Object>(nm, 59 as.getAttribute(nm)); 60 61 styleValues.put(CommonAttr.BOLD, true); 62 addCorrespondingValue(styleValues, attr); 63 } 64 HotStyleDef style = HotStyleDef.getEmpty().derive(styleValues); 65 66 TextManipulationUtility.addToEnd(text, buffer.toString()); 67 HotPos textEnd = text.getEnd(); 68 HotInterval interval = new HotInterval(text.advance( 69 textEnd, - buffer.length()), textEnd); 70 text.applyStyle(interval, style); 71 buffer.replace(0, buffer.length(), ""); 102 String text = view.getDocument().getText(begin, end - begin); 103 Map<HotAttr<?>, Object> styleValues = new HashMap<HotAttr<?>, Object>(); 104 AttributeSet set; 105 106 for (set = view.getAttributes(); set != null; set = set.getResolveParent()) { 107 Enumeration<?> names = set.getAttributeNames(); 108 while (names.hasMoreElements()) { 109 Object next = names.nextElement(); 110 AttributedPair<Object, Object> attr = 111 new AttributedPair<Object, Object>(next, set.getAttribute(next)); 112 addCorrespondingValue(styleValues, attr); 113 72 114 } 73 115 } 116 entries.add(new ElementEntry(text.length(), styleValues)); 117 builder.append(text); 74 118 } 75 119 for (int i = 0; i < view.getViewCount(); ++i) { 76 120 View child = view.getView(i); 77 applyStyles(text, child);121 applyStyles(child,builder,entries); 78 122 } 79 123 } 80 124 … … 85 129 * @param attr 86 130 * The attribute we are searching corresponding value for. 87 131 */ 88 public staticvoid addCorrespondingValue(Map<HotAttr<?>, Object> styleValues,132 public void addCorrespondingValue(Map<HotAttr<?>, Object> styleValues, 89 133 AttributedPair<Object, Object> attr) { 90 134 String key = attr.getKey().toString(); 91 135 Object value = attr.getValue(); 92 93 if (key.equals("font-size")) { 136 Object res = null; 137 if ( "margin-left".equals(key) || 138 "margin-right".equals(key) || "margin-bottom".equals(key) || 139 "margin-top".equals(key)) { 140 94 141 try { 95 int size = Integer.parseInt(value.toString()); 96 styleValues.put(CommonAttr.FONT_SIZE, 0f + size); 142 res = Float.parseFloat(value.toString()); 97 143 } catch (NumberFormatException e) { 98 144 // Do nothing 99 145 } 100 } else if (key.equals("margin-left")) { 146 147 } else if("font-size".equals(key)) { 101 148 try { 102 float size = Float.parseFloat(value.toString());103 styleValues.put(CommonAttr.PARA_LEFT_INDENT, size);149 String val = value.toString(); 150 res = Float.parseFloat(val.substring(0,val.length()-2)); 104 151 } catch (NumberFormatException e) { 105 152 // Do nothing 153 106 154 } 107 } else if (key.equals("margin-right")) { 108 try { 109 float size = Float.parseFloat(value.toString()); 110 styleValues.put(CommonAttr.PARA_RIGHT_INDENT, size); 111 } catch (NumberFormatException e) { 112 // Do nothing 113 } 114 } else if (key.equals("margin-bottom")) { 115 try { 116 float size = Float.parseFloat(value.toString()); 117 styleValues.put(CommonAttr.PARA_SPACE_BELOW, size); 118 } catch (NumberFormatException e) { 119 // Do nothing 120 } 121 } else if (key.equals("margin-top")) { 122 try { 123 float size = Float.parseFloat(value.toString()); 124 styleValues.put(CommonAttr.PARA_SPACE_ABOVE, size); 125 } catch (NumberFormatException e) { 126 // Do nothing 127 } 128 } else if (key.equals("color")) { 129 // styleValues.put(CommonAttr.FOREGROUND_COLOR, (String) value); 155 } 156 else if (key.equals("color")) { 157 res = getColor(value.toString()); 130 158 } else if (key.equals("font-weight")) { 131 159 if (value.toString().equals("bold")) { 132 styleValues.put(CommonAttr.BOLD, true);160 res = true; 133 161 } 134 } else if (key.equals("font-family")) { 135 String family = value.toString(); 136 styleValues.put(CommonAttr.FONT_FAMILY, family); 137 } else if (key.equals("name")) { 138 // TODO: add functionality 162 } else if ("font-family".equals(key)) { 163 res = value.toString(); 164 } 165 166 if (this.htmlMap.contains(key)) { 167 if(res != null){ 168 styleValues.put(this.htmlMap.get(key), res); 169 } 170 139 171 } 140 172 } 173 174 175 private ImmColor getColor(String value) { 176 String r = value.substring(1,3); 177 String g = value.substring(3,5); 178 String b = value.substring(5,7); 179 return new ImmColor((float)(getComonentColor(r)/ 256.0),(float)(getComonentColor(g)/ 256.0), 180 (float)(getComonentColor(b)/ 256.0)); 181 } 182 183 private int getComonentColor(String r) { 184 int res = 0; 185 for(int i = 0;i<r.length();++i) { 186 char current = r.charAt(r.length() - i - 1); 187 if(this.hexMap.contains(""+current)) { 188 res += Math.pow(16,i)*this.hexMap.get(""+current); 189 } else { 190 return 0; 191 } 192 } 193 return res; 194 } 195 196 141 197 }