Author: spepping
Date: Tue Aug 18 20:05:01 2009
New Revision: 805561

URL: http://svn.apache.org/viewvc?rev=805561&view=rev
Log:
Prepare for new hyphenation pattern files, which do not have their own classes 
and instead use the default classes in FOP. Modified the build process to a 
forked java task, in order to be able to set a larger stack size for the 
compilation of the large number of classes. Added an ant task to generate a new 
default classes file, to be used with an update of the Unicode Character 
Database.

Added:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/SerializeHyphPattern.java
   (with props)
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/UnicodeClasses.java   
(with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/classes.xml   
(with props)
Removed:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java
Modified:
    xmlgraphics/fop/trunk/build.properties
    xmlgraphics/fop/trunk/build.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/PatternParser.java

Modified: xmlgraphics/fop/trunk/build.properties
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/build.properties?rev=805561&r1=805560&r2=805561&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/build.properties (original)
+++ xmlgraphics/fop/trunk/build.properties Tue Aug 18 20:05:01 2009
@@ -50,5 +50,6 @@
 # layoutengine.disabled = test/layoutengine/disabled-testcases.txt
 
 ## Specify an alternate directory to scan for user supplied
-## hyphenation pattern files.
+## hyphenation pattern files and Unicode data files.
 # user.hyph.dir = /home/bart/offo
+# unidata.dir = /usr/share/doc/Unicode/UNIDATA

Modified: xmlgraphics/fop/trunk/build.xml
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/build.xml?rev=805561&r1=805560&r2=805561&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/build.xml (original)
+++ xmlgraphics/fop/trunk/build.xml Tue Aug 18 20:05:01 2009
@@ -157,6 +157,8 @@
   <property name="fo.examples.force" value="false"/>
   <property name="lib.dir" value="${basedir}/lib"/>
   <property name="user.hyph.dir" value="${basedir}/hyph"/>
+  <property name="unidata.dir" value="${basedir}/UNIDATA"/>
+  <property name="hyph.stacksize" value="512k"/>
   <property name="build.dir" value="${basedir}/build"/>
   <property name="build.gensrc.dir" value="${build.dir}/gensrc"/>
   <property name="build.classes.dir" value="${build.dir}/classes"/>
@@ -425,21 +427,51 @@
     </copy>
   </target>
   <target name="compile" depends="compile-java, compile-copy-resources" 
description="Compiles the source code"/>
-<!-- =================================================================== -->
-<!-- compiles hyphenation patterns                                       -->
-<!-- =================================================================== -->
-  <target name="compile-hyphenation" depends="compile">
+  <!-- =================================================================== -->
+  <!-- Helper task to generate source files that have already been checked -->
+  <!-- into the repository. This task uses Unicode Character Database      -->
+  <!-- files. This task need only be run when the latter files have been   -->
+  <!-- updated. This target should never be part of the normal build       -->
+  <!-- process. Output is UnicodeClasses.CLASSES_XML                       -->
+  <!-- (src/java/org/apache/fop/hyphenation/classes.xml). -->
+  <!-- =================================================================== -->
+  <target name="codegen-hyphenation-classes">
+       <java classname="org.apache.fop.hyphenation.UnicodeClasses" 
resultproperty="classes.result" classpath="${build.classes.dir}">
+         <arg value="${unidata.dir}"/>
+       </java>
+       <condition property="classes.result.message" value="Generation of 
classes successful">
+         <not>
+         <isfailure code="${classes.result}"/>
+         </not>
+       </condition>
+       <condition property="classes.result.message" value="Generation of 
classes failed">
+         <isfailure code="${classes.result}"/>
+       </condition>
+       <echo message="${classes.result.message}"/>
+  </target>
+  <!-- =================================================================== -->
+  <!-- compiles hyphenation patterns                                       -->
+  <!-- =================================================================== -->
+  <target name="compile-hyphenation" depends="compile" description="Compiles 
the hyphenation pattern files">
     <path id="hyph-classpath">
       <path refid="libs-build-classpath"/>
       <pathelement location="${build.classes.dir}"/>
     </path>
-    <taskdef name="serHyph" 
classname="org.apache.fop.tools.anttasks.SerializeHyphPattern" 
classpathref="hyph-classpath"/>
     <mkdir dir="${build.classes.dir}/hyph"/>
-    <serHyph targetDir="${build.classes.dir}/hyph">
-      <fileset dir="${user.hyph.dir}">
-        <include name="*.xml"/>
-      </fileset>
-    </serHyph>
+       <java classname="org.apache.fop.hyphenation.SerializeHyphPattern" 
fork="true" resultproperty="hyph.result" classpathref="hyph-classpath">
+         <arg value="${user.hyph.dir}"/>
+         <arg value="${build.classes.dir}/hyph"/>
+         <jvmarg value="-Xss${hyph.stacksize}"/>
+       </java>
+       <condition property="hyph.result.message" value="Hyphenation 
successful">
+         <not>
+         <isfailure code="${hyph.result}"/>
+         </not>
+       </condition>
+       <condition property="hyph.result.message" value="Hyphenation failed">
+         <isfailure code="${hyph.result}"/>
+       </condition>
+       <echo message="${hyph.result.message}"/>
   </target>
   <target name="uptodate-jar-hyphenation" depends="compile-hyphenation">
     <uptodate property="jar.hyphenation.uptodate" 
targetfile="${build.dir}/fop-hyph.jar">

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/PatternParser.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/PatternParser.java?rev=805561&r1=805560&r2=805561&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/PatternParser.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/PatternParser.java 
Tue Aug 18 20:05:01 2009
@@ -30,7 +30,10 @@
 // Java
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
 import java.net.MalformedURLException;
 import java.util.ArrayList;
 
@@ -51,6 +54,7 @@
     ArrayList exception;
     char hyphenChar;
     String errMsg;
+    boolean hasClasses = false;
 
     static final int ELEM_CLASSES = 1;
     static final int ELEM_EXCEPTIONS = 2;
@@ -58,24 +62,19 @@
     static final int ELEM_HYPHEN = 4;
 
     public PatternParser() throws HyphenationException {
+        this.consumer = this;
         token = new StringBuffer();
         parser = createParser();
         parser.setContentHandler(this);
         parser.setErrorHandler(this);
         hyphenChar = '-';    // default
-
     }
 
-    public PatternParser(PatternConsumer consumer)
-            throws HyphenationException {
+    public PatternParser(PatternConsumer consumer) throws HyphenationException 
{
         this();
         this.consumer = consumer;
     }
 
-    public void setConsumer(PatternConsumer consumer) {
-        this.consumer = consumer;
-    }
-
     /**
      * Parses a hyphenation pattern file.
      * @param filename the filename
@@ -249,15 +248,32 @@
         return il.toString();
     }
 
+    protected void getExternalClasses() throws SAXException {
+        XMLReader mainParser = parser;
+        parser = createParser();
+        parser.setContentHandler(this);
+        parser.setErrorHandler(this);
+        InputStream stream = 
this.getClass().getResourceAsStream("classes.xml");
+        InputSource source = new InputSource(stream);
+        try {
+            parser.parse(source);
+        } catch (IOException ioe) {
+            throw new SAXException(ioe.getMessage());
+        } finally {
+            parser = mainParser;
+        }
+    }
+    
     //
     // ContentHandler methods
     //
 
     /**
      * {...@inheritdoc}
+     * @throws SAXException 
      */
     public void startElement(String uri, String local, String raw,
-                             Attributes attrs) {
+                             Attributes attrs) throws SAXException {
         if (local.equals("hyphen-char")) {
             String h = attrs.getValue("value");
             if (h != null && h.length() == 1) {
@@ -266,8 +282,14 @@
         } else if (local.equals("classes")) {
             currElement = ELEM_CLASSES;
         } else if (local.equals("patterns")) {
+            if (!hasClasses) {
+                getExternalClasses();
+            }
             currElement = ELEM_PATTERNS;
         } else if (local.equals("exceptions")) {
+            if (!hasClasses) {
+                getExternalClasses();
+            }
             currElement = ELEM_EXCEPTIONS;
             exception = new ArrayList();
         } else if (local.equals("hyphen")) {
@@ -311,6 +333,9 @@
                 token.setLength(0);
             }
         }
+        if (currElement == ELEM_CLASSES) {
+            hasClasses = true;
+        }
         if (currElement == ELEM_HYPHEN) {
             currElement = ELEM_EXCEPTIONS;
         } else {
@@ -403,23 +428,46 @@
 
     // PatternConsumer implementation for testing purposes
     public void addClass(String c) {
-        System.out.println("class: " + c);
+        testOut.println("class: " + c);
     }
 
     public void addException(String w, ArrayList e) {
-        System.out.println("exception: " + w + " : " + e.toString());
+        testOut.println("exception: " + w + " : " + e.toString());
     }
 
     public void addPattern(String p, String v) {
-        System.out.println("pattern: " + p + " : " + v);
+        testOut.println("pattern: " + p + " : " + v);
+    }
+    
+    private PrintStream testOut = System.out;
+    
+    /**
+     * @param testOut the testOut to set
+     */
+    public void setTestOut(PrintStream testOut) {
+        this.testOut = testOut;
+    }
+    
+    public void closeTestOut() {
+        testOut.flush();
+        testOut.close();
     }
 
     public static void main(String[] args) throws Exception {
         if (args.length > 0) {
             PatternParser pp = new PatternParser();
-            pp.setConsumer(pp);
+            PrintStream p = null;
+            if (args.length > 1) {
+                FileOutputStream f = new FileOutputStream(args[1]);
+                p = new PrintStream(f, false, "utf-8");
+                pp.setTestOut(p);
+            }
             pp.parse(args[0]);
+            if (pp != null) {
+                pp.closeTestOut();
+            }
         }
     }
 
+ 
 }

Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/SerializeHyphPattern.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/SerializeHyphPattern.java?rev=805561&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/SerializeHyphPattern.java
 (added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/SerializeHyphPattern.java
 Tue Aug 18 20:05:01 2009
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.hyphenation;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+
+/**
+ * Serialize hyphenation patterns
+ * For all xml files in the source directory a pattern file is built in the 
target directory
+ * This class may be called from the ant build file in a java task  
+ */
+public class SerializeHyphPattern {
+    
+    private boolean errorDump = false;
+
+    /**
+     * Controls the amount of error information dumped.
+     * @param errorDump True if more error info should be provided
+     */
+    public void setErrorDump(boolean errorDump) {
+        this.errorDump = errorDump;
+    }
+
+    /**
+     * {...@inheritdoc}
+     */
+    public void serializeDir(File sourceDir, File targetDir) {
+        final String extension = ".xml";
+        String[] sourceFiles = sourceDir.list(new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                return(name.endsWith(extension));
+            }
+        });
+        for (int j = 0; j < sourceFiles.length; j++) {
+            File infile = new File(sourceDir, sourceFiles[j]);
+            String outfilename =
+                sourceFiles[j].substring(0, sourceFiles[j].length() - 
extension.length()) + ".hyp";
+            File outfile = new File(targetDir, outfilename);
+            serializeFile(infile, outfile);
+        }
+    }
+
+    /*
+     * checks whether input or output files exists or the latter is older than 
input file
+     * and start build if necessary
+     */
+    private void serializeFile(File infile, File outfile) {
+        boolean startProcess;
+        startProcess = rebuild(infile, outfile);
+        if (startProcess) {
+            HyphenationTree hTree = buildPatternFile(infile);
+            // serialize class
+            try {
+                ObjectOutputStream out = new ObjectOutputStream(
+                        new java.io.BufferedOutputStream(
+                        new java.io.FileOutputStream(outfile)));
+                out.writeObject(hTree);
+                out.close();
+            } catch (IOException ioe) {
+                System.err.println("Can't write compiled pattern file: "
+                                   + outfile);
+                System.err.println(ioe);
+            }
+        }
+    }
+
+    /*
+     * serializes pattern files
+     */
+    private HyphenationTree buildPatternFile(File infile) {
+        System.out.println("Processing " + infile);
+        HyphenationTree hTree = new HyphenationTree();
+        try {
+            hTree.loadPatterns(infile.toString());
+            if (errorDump) {
+                System.out.println("Stats: ");
+                hTree.printStats();
+            }
+        } catch (HyphenationException ex) {
+            System.err.println("Can't load patterns from xml file " + infile
+                               + " - Maybe hyphenation.dtd is missing?");
+            if (errorDump) {
+                System.err.println(ex.toString());
+            }
+        }
+        return hTree;
+    }
+
+    /**
+     * Checks for existence of output file and compares
+     * dates with input and stylesheet file
+     */
+    private boolean rebuild(File infile, File outfile) {
+        if (outfile.exists()) {
+            // checks whether output file is older than input file
+            if (outfile.lastModified() < infile.lastModified()) {
+                return true;
+            }
+        } else {
+            // if output file does not exist, start process
+            return true;
+        }
+        return false;
+    }    // end rebuild
+
+
+    public static void main (String args[]) {
+        SerializeHyphPattern ser = new SerializeHyphPattern();
+        ser.serializeDir(new File(args[0]), new File(args[1]));
+    }
+
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/SerializeHyphPattern.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/SerializeHyphPattern.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/UnicodeClasses.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/UnicodeClasses.java?rev=805561&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/UnicodeClasses.java 
(added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/UnicodeClasses.java 
Tue Aug 18 20:05:01 2009
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.hyphenation;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Create the default classes file classes.xml,
+ * for use in building hyphenation patterns
+ * from pattern files which do not contain their own classes  
+ */
+public class UnicodeClasses {
+    
+    // default path relative to the FOP base directory
+    static String CLASSES_XML = 
"src/java/org/apache/fop/hyphenation/classes.xml";
+
+    /**
+     * Generate classes.xml from Java's compiled-in Unicode Character Database
+     * @param hexcode whether to prefix each class with the hexcode (only for 
debugging purposes)
+     * @param outfilePath output file
+     * @throws IOException
+     */
+    public static void fromJava(boolean hexcode, String outfilePath) throws 
IOException {
+        File f = new File(outfilePath);
+        if (f.exists()) {
+            f.delete();
+        }
+        f.createNewFile();
+        FileOutputStream fw = new FileOutputStream(f);
+        OutputStreamWriter ow = new OutputStreamWriter(fw, "utf-8");
+        int maxChar;
+        maxChar = Character.MAX_VALUE;
+
+        ow.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 
+        "<classes>\n");
+        // loop over the first Unicode plane
+        for (int code = Character.MIN_VALUE; code <= maxChar; ++code) {
+            
+            // skip surrogate area
+            if (code == Character.MIN_SURROGATE) {
+                code = Character.MAX_SURROGATE;
+                continue;
+            }
+
+            // we are only interested in LC, UC and TC letters which are their 
own LC, and in 'other letters'
+            if (!(((Character.isLowerCase(code) || Character.isUpperCase(code) 
|| Character.isTitleCase(code))
+                    && code == Character.toLowerCase(code))
+                    || Character.getType(code) == Character.OTHER_LETTER)) {
+                continue;
+            }
+            
+            // skip a number of blocks
+            Character.UnicodeBlock ubi = Character.UnicodeBlock.of(code);
+            if (ubi.equals(Character.UnicodeBlock.SUPERSCRIPTS_AND_SUBSCRIPTS)
+                    || ubi.equals(Character.UnicodeBlock.LETTERLIKE_SYMBOLS)
+                    || 
ubi.equals(Character.UnicodeBlock.ALPHABETIC_PRESENTATION_FORMS)
+                    || 
ubi.equals(Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS)
+                    || 
ubi.equals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS)
+                    || 
ubi.equals(Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A)
+                    || ubi.equals(Character.UnicodeBlock.HANGUL_SYLLABLES)) {
+                continue;
+            }
+
+            int uppercode = Character.toUpperCase(code);
+            int titlecode = Character.toTitleCase(code);
+            StringBuilder s = new StringBuilder();
+            if (hexcode) {
+                s.append("0x" + Integer.toHexString(code) + " ");
+            }
+            s.append(Character.toChars(code));
+            if (uppercode != code) {
+                s.append(Character.toChars(uppercode));
+            }
+            if (titlecode != code && titlecode != uppercode) {
+                s.append(Character.toChars(titlecode));
+            }
+            ow.write(s.toString() + "\n");
+        }
+        ow.write("</classes>\n");
+        ow.flush();
+        ow.close();
+    }
+    
+    static public int UNICODE = 0, GENERAL_CATEGORY = 2, 
SIMPLE_UPPERCASE_MAPPING = 12,
+    SIMPLE_LOWERCASE_MAPPING = 13, SIMPLE_TITLECASE_MAPPING = 14, NUM_FIELDS = 
15;
+    
+    /**
+     * Generate classes.xml from Unicode Character Database files
+     * @param hexcode whether to prefix each class with the hexcode (only for 
debugging purposes)
+     * @param unidataPath path to the directory with UCD files  
+     * @param outfilePath output file
+     * @throws IOException
+     */
+    public static void fromUCD(boolean hexcode, String unidataPath, String 
outfilePath) throws IOException {
+        File unidata = new File(unidataPath);
+        
+        File f = new File(outfilePath);
+        if (f.exists()) {
+            f.delete();
+        }
+        f.createNewFile();
+        FileOutputStream fw = new FileOutputStream(f);
+        OutputStreamWriter ow = new OutputStreamWriter(fw, "utf-8");
+        
+        File in = new File(unidata, "Blocks.txt");
+        FileInputStream inis = new FileInputStream(in);
+        InputStreamReader insr = new InputStreamReader(inis, "utf-8");
+        BufferedReader inbr = new BufferedReader(insr);
+        Map blocks = new HashMap();
+        for (String line = inbr.readLine(); line != null; line = 
inbr.readLine()) {
+            if (line.startsWith("#") || line.matches("^\\s*$")) {
+                continue;
+            }
+            String[] parts = line.split(";");
+            String block = parts[1].trim();
+            String[] indices = parts[0].split("\\.\\.");
+            int[] ind = {Integer.parseInt(indices[0], 16), 
Integer.parseInt(indices[1], 16)};
+            blocks.put(block, ind);
+        }
+        inbr.close();
+
+        in = new File(unidata, "UnicodeData.txt");
+        inis = new FileInputStream(in);
+        insr = new InputStreamReader(inis, "utf-8");
+        inbr = new BufferedReader(insr);
+        int maxChar;
+        maxChar = Character.MAX_VALUE;
+
+        ow.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 
+        "<classes>\n");
+        for (String line = inbr.readLine(); line != null; line = 
inbr.readLine()) {
+            String[] fields = line.split(";", NUM_FIELDS);
+            int code = Integer.parseInt(fields[UNICODE], 16);
+            if (code > maxChar) {
+                break;
+            }
+            if (((fields[GENERAL_CATEGORY].equals("Ll") || 
fields[GENERAL_CATEGORY].equals("Lu")
+                            || fields[GENERAL_CATEGORY].equals("Lt"))
+                        && ("".equals(fields[SIMPLE_LOWERCASE_MAPPING])
+                                || 
fields[UNICODE].equals(fields[SIMPLE_LOWERCASE_MAPPING])))
+                    || fields[GENERAL_CATEGORY].equals("Lo")) {
+                String[] blockNames = {"Superscripts and Subscripts", 
"Letterlike Symbols",
+                                       "Alphabetic Presentation Forms", 
"Halfwidth and Fullwidth Forms",
+                                       "CJK Unified Ideographs", "CJK Unified 
Ideographs Extension A",
+                                       "Hangul Syllables"};
+                int j;
+                for (j = 0; j < blockNames.length; ++j) {
+                    int[] ind = (int[]) blocks.get(blockNames[j]);
+                    if (code >= ind[0] && code <= ind[1]) {
+                        break;
+                    }
+                }
+                if (j < blockNames.length) {
+                    continue;
+                }
+            
+                int uppercode = -1, titlecode = -1;
+                if (!"".equals(fields[SIMPLE_UPPERCASE_MAPPING])) {
+                    uppercode = 
Integer.parseInt(fields[SIMPLE_UPPERCASE_MAPPING], 16);
+                }
+                if (!"".equals(fields[SIMPLE_TITLECASE_MAPPING])) {
+                    titlecode = 
Integer.parseInt(fields[SIMPLE_TITLECASE_MAPPING], 16);
+                }
+                StringBuilder s = new StringBuilder();
+                if (hexcode) {
+                    s.append("0x" + fields[UNICODE].replaceFirst("^0+", 
"").toLowerCase() + " ");
+                }
+                s.append(Character.toChars(code));
+                if (uppercode != -1 && uppercode != code) {
+                    s.append(Character.toChars(uppercode));
+                }
+                if (titlecode != -1 && titlecode != code && titlecode != 
uppercode) {
+                    s.append(Character.toChars(titlecode));
+                }
+                ow.write(s.toString() + "\n");
+            }
+        }
+        ow.write("</classes>\n");
+        ow.flush();
+        ow.close();
+        inbr.close();
+    }
+
+    /**
+     * Generate classes.xml from XeTeX's Unicode letters file
+     * @param hexcode whether to prefix each class with the hexcode (only for 
debugging purposes)
+     * @param lettersPath path to XeTeX's Unicode letters file 
unicode-letters-XeTeX.tex  
+     * @param outfilePath output file
+     * @throws IOException
+     */
+    public static void fromTeX(boolean hexcode, String lettersPath, String 
outfilePath) throws IOException {
+        File in = new File(lettersPath);
+
+        File f = new File(outfilePath);
+        if (f.exists()) {
+            f.delete();
+        }
+        f.createNewFile();
+        FileOutputStream fw = new FileOutputStream(f);
+        OutputStreamWriter ow = new OutputStreamWriter(fw, "utf-8");
+
+        FileInputStream inis = new FileInputStream(in);
+        InputStreamReader insr = new InputStreamReader(inis, "utf-8");
+        BufferedReader inbr = new BufferedReader(insr);
+
+        ow.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + 
+        "<classes>\n");
+        for (String line = inbr.readLine(); line != null; line = 
inbr.readLine()) {
+            String[] codes = line.split("\\s+");
+            if (!(codes[0].equals("\\L") || codes[0].equals("\\l"))) {
+                continue;
+            }
+            if (codes.length == 3) {
+                ow.write("\"" + line + "\" has two codes");
+                continue;
+            }
+            if (codes[0].equals("\\l") && codes.length != 2) {
+                ow.write("\"" + line + "\" should have one code");
+                continue;
+            }
+            else if (codes[0].equals("\\L") && codes.length != 4) {
+                ow.write("\"" + line + "\" should have three codes");
+                continue;
+            }
+            if (codes[0].equals("\\l") || (codes[0].equals("\\L") && 
codes[1].equals(codes[3]))) {
+                StringBuilder s = new StringBuilder();
+                if (hexcode) {
+                    s.append("0x" + codes[1].replaceFirst("^0+", 
"").toLowerCase() + " ");
+                }
+                s.append(Character.toChars(Integer.parseInt(codes[1], 16)));
+                if (codes[0].equals("\\L")) {
+                    s.append(Character.toChars(Integer.parseInt(codes[2], 
16)));
+                }
+                ow.write(s.toString() + "\n");
+            }
+        }
+        ow.write("</classes>\n");
+        ow.flush();
+        ow.close();
+        inbr.close();
+    }
+
+    
+    public static void main(String[] args) throws IOException {
+        String type = "ucd", prefix = "--", infile = null, outfile = 
CLASSES_XML;
+        boolean hexcode = false;
+        for (int i = 0; i < args.length; ++i) {
+            if (args[i].startsWith(prefix)) {
+                String option = args[i].substring(prefix.length());
+                if (option.equals("java") || option.equals("ucd") || 
option.equals("tex")) {
+                    type = option;
+                } else if (option.equals("hexcode")) {
+                    hexcode = true;
+                } else if (option.equals("out")) {
+                    outfile = args[++i];
+                } else {
+                    System.err.println("Unknown option: " + option);
+                    System.exit(1);
+                }
+            } else {
+                if (infile != null) {
+                    System.err.println("Only one non-option argument can be 
given, for infile");
+                    System.exit(1);
+                }
+                infile = args[i];
+            }
+        }
+        
+        if (type.equals("java")) {
+            if (infile != null) {
+                System.err.println("Type java does not allow an infile");
+                System.exit(1);
+            }
+        } else {
+            if (infile == null) {
+                System.err.println("Types ucd and tex require an infile");
+                System.exit(1);
+            }
+        }
+        if (type.equals("java")) {
+            fromJava(hexcode, outfile);
+        } else if (type.equals("ucd")) {
+            fromUCD(hexcode, infile, outfile);
+        } else if (type.equals("tex")) {
+            fromTeX(hexcode, infile, outfile);
+        } else {
+            System.err.println("Unknown type: " + type + ", nothing done");
+            System.exit(1);
+        }
+    }
+
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/UnicodeClasses.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/hyphenation/UnicodeClasses.java
------------------------------------------------------------------------------
    svn:keywords = Id



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to