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]