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
     
    11package org.sophie2.extra.func.html; 
    22 
     3import java.io.ByteArrayInputStream; 
    34import java.io.File; 
    4 import java.io.FileReader; 
     5import java.io.FileInputStream; 
     6import java.io.FileNotFoundException; 
    57import java.io.IOException; 
    6 import java.io.Reader; 
     8import java.io.InputStream; 
     9import java.util.regex.Matcher; 
     10import java.util.regex.Pattern; 
    711 
    812import javax.swing.JTextPane; 
    913import javax.swing.filechooser.FileFilter; 
     
    2832        /** 
    2933         * The file filter of the html resources. 
    3034         */ 
    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 
    3438        /** 
    3539         * The import role of the <code>HtmlTextImportManager</code>. 
    3640         */ 
    3741        public static final String IMPORT_ROLE = "import html text"; 
    38          
     42 
    3943        @Override 
    4044        public String getImportRole() { 
    4145                return IMPORT_ROLE; 
    4246        } 
    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 
    4551        public ImmHotText getResourceData(File resFile, ResourceH parentResource, 
    4652                        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"))) { 
    4957                        return null; 
    5058                } 
    5159                 
     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                 
    5294                HTMLEditorKit kit = new HTMLEditorKit(); 
    5395                HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument(); 
    54  
    5596                JTextPane pane = new JTextPane(); 
    5697                pane.setEditorKit(kit); 
    5798                pane.setDocument(doc); 
    5899                View view = pane.getUI().getRootView(pane); 
    59  
    60                 Reader reader = null; 
    61                 String htmlPlain; 
    62100                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(); 
    66104 
    67                         htmlPlain = doc.getText(0, doc.getLength()); 
    68105                } catch (BadLocationException e) { 
    69106                        throw new RuntimeException("Could not import HTML file", e); 
    70107                } catch (IOException e) { 
    71108                        throw new RuntimeException("Could not import HTML file", e); 
    72109                } 
    73110 
    74                 ImmHotText text = ImmHotText.createPlain(htmlPlain); 
    75  
    76                 ApplyHtmlStylesUtility.applyStyles(text, view); 
     111      ImmHotText text = null; 
    77112                 
     113                try { 
     114                        ApplyHtmlStylesUtility utility = new ApplyHtmlStylesUtility(); 
     115                        text = utility.createStyled(view); 
     116                } catch (BadLocationException e) { 
     117                        throw new RuntimeException(e); 
     118                } 
     119                 
    78120                return text; 
     121                 
    79122        } 
    80123 
    81124} 
  • src/main/java/org/sophie2/extra/func/html/util/ApplyHtmlStylesUtility.java

     
    11package org.sophie2.extra.func.html.util; 
    22 
     3import java.util.ArrayList; 
    34import java.util.Enumeration; 
    45import java.util.HashMap; 
     6import java.util.List; 
    57import java.util.Map; 
    68 
    79import javax.swing.text.AttributeSet; 
    810import javax.swing.text.BadLocationException; 
    911import javax.swing.text.View; 
    1012 
     13import org.sophie2.base.commons.structures.ImmDosTree; 
     14import org.sophie2.base.commons.structures.ImmTreeMap; 
     15import org.sophie2.base.commons.util.ImmColor; 
     16import org.sophie2.base.commons.util.ImmMap; 
     17import org.sophie2.base.commons.util.ImmMap.ImmEntry; 
    1118import org.sophie2.base.model.text.HotAttr; 
    1219import org.sophie2.base.model.text.smart.HotPos; 
    1320import org.sophie2.base.model.text.smart.ImmHotText; 
    1421import org.sophie2.base.model.text.smart.elements.CommonAttr; 
    1522import org.sophie2.base.model.text.smart.position.HotInterval; 
    1623import org.sophie2.base.model.text.smart.style.HotStyleDef; 
     24import org.sophie2.main.app.commons.element.ElementEntry; 
    1725import org.sophie2.main.app.commons.util.AttributedPair; 
    18 import org.sophie2.main.app.commons.util.TextManipulationUtility; 
    1926 
    2027/** 
    2128 * Helps adding the styles of the html document to the resulting HotText. 
     
    2330 * @author diana 
    2431 */ 
    2532public class ApplyHtmlStylesUtility { 
    26  
     33        private ImmMap<String, HotAttr<?>> htmlMap; 
     34        private ImmMap<String,Integer> hexMap; 
    2735        /** 
     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        /** 
    2865         * Apply the styles for the html document. 
    2966         *  
    30          * @param text 
    31          *            The HotText 
    3267         * @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 
    3473         */ 
    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 { 
    3698                if (view.getViewCount() == 0) { 
     99                view.getDocument().getText(0, view.getDocument().getLength()); 
    37100                        int begin = view.getElement().getStartOffset(); 
    38101                        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                                         
    72114                                } 
    73115                        } 
     116                        entries.add(new ElementEntry(text.length(), styleValues)); 
     117                        builder.append(text); 
    74118                } 
    75119                for (int i = 0; i < view.getViewCount(); ++i) { 
    76120                        View child = view.getView(i); 
    77                         applyStyles(text, child); 
     121                         applyStyles(child,builder,entries); 
    78122                } 
    79123        } 
    80124 
     
    85129         * @param attr 
    86130         *          The attribute we are searching corresponding value for. 
    87131         */ 
    88         public static void addCorrespondingValue(Map<HotAttr<?>, Object> styleValues, 
     132        public void addCorrespondingValue(Map<HotAttr<?>, Object> styleValues, 
    89133                        AttributedPair<Object, Object> attr) { 
    90134                String key = attr.getKey().toString(); 
    91135                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                         
    94141                        try { 
    95                                 int size = Integer.parseInt(value.toString()); 
    96                                 styleValues.put(CommonAttr.FONT_SIZE, 0f + size); 
     142                                res = Float.parseFloat(value.toString()); 
    97143                        } catch (NumberFormatException e) { 
    98144                                // Do nothing 
    99145                        } 
    100                 } else if (key.equals("margin-left")) { 
     146                 
     147                } else if("font-size".equals(key)) { 
    101148                        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)); 
    104151                        } catch (NumberFormatException e) { 
    105152                                // Do nothing 
     153                                 
    106154                        } 
    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()); 
    130158                } else if (key.equals("font-weight")) { 
    131159                        if (value.toString().equals("bold")) { 
    132                                 styleValues.put(CommonAttr.BOLD, true); 
     160                                res = true; 
    133161                        } 
    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                         
    139171                } 
    140172        } 
     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         
    141197}