Initial import

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@5 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2009-02-20 09:37:06 +00:00
parent 75e32b1e8f
commit b0b66fcae9
252 changed files with 49000 additions and 0 deletions

View file

@ -0,0 +1,697 @@
/************************************************************************
*
* ClassicI18n.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2009 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.0 (2009-02-16)
*
*/
package writer2latex.latex.i18n;
import java.io.*;
import java.util.Hashtable;
import java.util.Stack;
//import java.util.Vector;
//import java.util.Enumeration;
import java.util.Iterator;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import writer2latex.util.CSVList;
import writer2latex.office.*;
import writer2latex.latex.LaTeXConfig;
import writer2latex.latex.LaTeXDocumentPortion;
import writer2latex.latex.ConverterPalette;
import writer2latex.latex.util.BeforeAfter;
/** This class (and the helpers in the same package) takes care of i18n in
* Writer2LaTeX. In classic LaTeX, i18n is a mixture of inputencodings, fontencodings
* and babel languages. The class ClassicI18n thus manages these, and in particular
* implements a Unicode->LaTeX translation that can handle different
* inputencodings and fontencodings.
* The translation is table driven, using symbols.xml (embedded in the jar)
* Various sections of symbols.xml handles different cases:
* <ul>
* <li>common symbols in various font encodings such as T1, T2A, LGR etc.</li>
* <li>input encodings such as ISO-8859-1 (latin-1), ISO-8859-7 (latin/greek) etc.</li>
* <li>additional symbol fonts such as wasysym, dingbats etc.</li>
* <li>font-specific symbols, eg. for 8-bit fonts/private use area</li>
* </ul>
* The class uses the packages inputenc, fontenc, babel, tipa, bbding,
* ifsym, pifont, eurosym, amsmath, wasysym, amssymb, amsfonts and textcomp
* in various combinations depending on the configuration.
*/
public class ClassicI18n extends I18n {
// **** Static data and methods: Inputencodings ****
public static final int ASCII = 0;
public static final int LATIN1 = 1; // ISO Latin 1 (ISO-8859-1)
public static final int LATIN2 = 2; // ISO Latin 1 (ISO-8859-1)
public static final int ISO_8859_7 = 3; // ISO latin/greek
public static final int CP1250 = 4; // Microsoft Windows Eastern European
public static final int CP1251 = 5; // Microsoft Windows Cyrillic
public static final int KOI8_R = 6; // Latin/russian
public static final int UTF8 = 7; // UTF-8
// Read an inputencoding from a string
public static final int readInputenc(String sInputenc) {
if ("ascii".equals(sInputenc)) return ASCII;
else if ("latin1".equals(sInputenc)) return LATIN1;
else if ("latin2".equals(sInputenc)) return LATIN2;
else if ("iso-8859-7".equals(sInputenc)) return ISO_8859_7;
else if ("cp1250".equals(sInputenc)) return CP1250;
else if ("cp1251".equals(sInputenc)) return CP1251;
else if ("koi8-r".equals(sInputenc)) return KOI8_R;
else if ("utf8".equals(sInputenc)) return UTF8;
else return ASCII; // unknown = ascii
}
// Return the LaTeX name of an inputencoding
public static final String writeInputenc(int nInputenc) {
switch (nInputenc) {
case ASCII : return "ascii";
case LATIN1 : return "latin1";
case LATIN2 : return "latin2";
case ISO_8859_7 : return "iso-8859-7";
case CP1250 : return "cp1250";
case CP1251 : return "cp1251";
case KOI8_R : return "koi8-r";
case UTF8 : return "utf8";
default : return "???";
}
}
// Return the java i18n name of an inputencoding
public static final String writeJavaEncoding(int nInputenc) {
switch (nInputenc) {
case ASCII : return "ASCII";
case LATIN1 : return "ISO8859_1";
case LATIN2 : return "ISO8859_2";
case ISO_8859_7 : return "ISO8859_7";
case CP1250 : return "Cp1250";
case CP1251 : return "Cp1251";
case KOI8_R : return "KOI8_R";
case UTF8 : return "UTF-8";
default : return "???";
}
}
// **** Static data and methods: Fontencodings ****
private static final int T1_ENC = 1;
private static final int T2A_ENC = 2;
private static final int T3_ENC = 4;
private static final int LGR_ENC = 8;
private static final int ANY_ENC = 15;
// read set of font encodings from a string
public static final int readFontencs(String sFontencs) {
sFontencs = sFontencs.toUpperCase();
if ("ANY".equals(sFontencs)) return ANY_ENC;
int nFontencs = 0;
if (sFontencs.indexOf("T1")>=0) nFontencs+=T1_ENC;
if (sFontencs.indexOf("T2A")>=0) nFontencs+=T2A_ENC;
if (sFontencs.indexOf("T3")>=0) nFontencs+=T3_ENC;
if (sFontencs.indexOf("LGR")>=0) nFontencs+=LGR_ENC;
return nFontencs;
}
// return string representation of a single font encoding
/*private static final String writeFontenc(int nFontenc) {
switch (nFontenc) {
case T1_ENC: return "T1";
case T2A_ENC: return "T2A";
case T3_ENC: return "T3";
case LGR_ENC: return "LGR";
}
return null;
}*/
// check that a given set of font encodings contains a specific font encoding
private static final boolean supportsFontenc(int nFontencs, int nFontenc) {
return (nFontencs & nFontenc) != 0;
}
// get one fontencoding from a set of fontencodings
private static final int getFontenc(int nFontencs) {
if (supportsFontenc(nFontencs,T1_ENC)) return T1_ENC;
if (supportsFontenc(nFontencs,T2A_ENC)) return T2A_ENC;
if (supportsFontenc(nFontencs,T3_ENC)) return T3_ENC;
if (supportsFontenc(nFontencs,LGR_ENC)) return LGR_ENC;
return 0;
}
// get the font encoding for a specific iso language
private static final int getFontenc(String sLang) {
// Greek uses "local greek" encoding
if ("el".equals(sLang)) return LGR_ENC;
// Russian, ukrainian, bulgarian and serbian uses T2A encoding
else if ("ru".equals(sLang)) return T2A_ENC;
else if ("uk".equals(sLang)) return T2A_ENC;
else if ("bg".equals(sLang)) return T2A_ENC;
else if ("sr".equals(sLang)) return T2A_ENC;
// Other languages uses T1 encoding
else return T1_ENC;
}
// return cs for a fontencoding
private static final String getFontencCs(int nFontenc) {
switch (nFontenc) {
case T1_ENC: return "\\textlatin"; // requires babel
case T2A_ENC: return "\\textcyrillic"; // requires babel with russian, bulgarian or ukrainian option
case T3_ENC: return "\\textipa"; // requires tipa.sty
case LGR_ENC: return "\\textgreek"; // requires babel with greek option
default: return null;
}
}
// End of static part of I18n!
// **** Global variables ****
private Hashtable babelLanguages; // mappings iso->babel language
// Unicode translation
private Hashtable tableSet; // all tables
private UnicodeTable table; // currently active table (top of stack)
private Stack tableStack; // stack of active tables
private UnicodeStringParser ucparser; // Unicode string parser
// Collected data
private int nDefaultFontenc; // Fontenc for the default language
private boolean bT2A = false; // Do we use cyrillic letters?
private boolean bGreek = false; // Do we use greek letters?
private boolean bPolytonicGreek = false; // Do we use polytonic greek letters?
// **** Constructors ****
/** Construct a new ClassicI18n as ConverterHelper
* @param ofr the OfficeReader to get language information from
* @param config the configuration which determines the symbols to use
* @param palette the ConverterPalette (unused)
*/
public ClassicI18n(OfficeReader ofr, LaTeXConfig config, ConverterPalette palette) {
super(ofr,config,palette);
// We don't need the palette and the office reader is only used to
// identify the default language
// Set up table for iso->babel translation
prepareBabelLanguages();
nDefaultFontenc = getFontenc(sDefaultLanguage);
// Unicode stuff
ucparser = new UnicodeStringParser();
String sSymbols="ascii"; // always load common symbols
if (config.getInputencoding()!=ASCII) {
sSymbols+="|"+writeInputenc(config.getInputencoding());
}
if (config.useWasysym()) sSymbols+="|wasysym";
if (config.useBbding()) sSymbols+="|bbding";
if (config.useIfsym()) sSymbols+="|ifsym";
if (config.usePifont()) sSymbols+="|dingbats";
if (config.useEurosym()) sSymbols+="|eurosym";
if (config.useTipa()) sSymbols+="|tipa";
tableSet = new Hashtable();
UnicodeTableHandler handler=new UnicodeTableHandler(tableSet, sSymbols);
SAXParserFactory factory=SAXParserFactory.newInstance();
InputStream is = this.getClass().getResourceAsStream("symbols.xml");
try {
SAXParser saxParser=factory.newSAXParser();
saxParser.parse(is,handler);
}
catch (Throwable t){
System.err.println("Oops - Unable to read symbols.xml");
t.printStackTrace();
}
// put root table at top of stack
tableStack = new Stack();
tableStack.push((UnicodeTable) tableSet.get("root"));
table = (UnicodeTable) tableSet.get("root");
}
/** Construct a new I18n for general use
* @param config the configuration which determines the symbols to use
*/
public ClassicI18n(LaTeXConfig config) {
this (null, config, null);
}
/** Add declarations to the preamble to load the required packages
* @param pack usepackage declarations
* @param decl other declarations
*/
public void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl) {
pack.append("\\usepackage[")
.append(writeInputenc(config.getInputencoding()))
.append("]{inputenc}").nl();
// usepackage fontenc
CSVList fontencs = new CSVList(',');
if (bT2A) { fontencs.addValue("T2A"); }
if (bGreek) { fontencs.addValue("LGR"); }
if (config.useTipa()) { fontencs.addValue("T3"); }
fontencs.addValue("T1");
pack.append("\\usepackage[").append(fontencs.toString())
.append("]{fontenc}").nl();
// usepackage babel
// If the document contains "anonymous" greek letters we need greek in any case
// If the document contains "anonymous cyrillic letters we need one of the
// languages russian, ukrainian or bulgarian
if (greek() && !languages.contains("el")) languages.add("el");
if (cyrillic() && !(languages.contains("ru") || languages.contains("uk") || languages.contains("bg"))) {
languages.add("ru");
}
// Load babel with the used languages
CSVList babelopt = new CSVList(",");
Iterator langiter = languages.iterator();
while (langiter.hasNext()) {
String sLang = (String) langiter.next();
if (!sLang.equals(sDefaultLanguage)) {
if ("el".equals(sLang) && this.polytonicGreek()) {
babelopt.addValue("polutonikogreek");
}
else {
babelopt.addValue(getBabelLanguage(sLang));
}
}
}
// The default language must be the last one
if (sDefaultLanguage!=null) {
if ("el".equals(sDefaultLanguage) && this.polytonicGreek()) {
babelopt.addValue("polutonikogreek");
}
else {
babelopt.addValue(getBabelLanguage(sDefaultLanguage));
}
}
if (!babelopt.isEmpty()) {
pack.append("\\usepackage[")
.append(babelopt.toString())
.append("]{babel}").nl();
}
// usepackage tipa
if (config.useTipa()) {
pack.append("\\usepackage[noenc]{tipa}").nl()
.append("\\usepackage{tipx}").nl();
}
// usepackage bbding (Has to avoid some nameclashes.)
if (config.useBbding()) {
pack.append("\\usepackage{bbding}").nl()
.append("\\let\\bbCross\\Cross\\let\\Cross\\undefined").nl()
.append("\\let\\bbSquare\\Square\\let\\Square\\undefined").nl()
.append("\\let\\bbTrianbleUp\\TriangleUp\\let\\TriangleUp\\undefined").nl()
.append("\\let\\bbTrianlgeDown\\TriangleDown\\let\\TriangleDown\\undefined").nl();
}
// usepackage ifsym
if (config.useIfsym()) {
pack.append("\\usepackage[geometry,weather,misc,clock]{ifsym}").nl();
}
// usepackage pifont
if (config.usePifont()) { pack.append("\\usepackage{pifont}").nl(); }
// usepackage eurosym
if (config.useEurosym()) { pack.append("\\usepackage{eurosym}").nl(); }
// usepackage amsmath (always!)
pack.append("\\usepackage{amsmath}").nl();
// usepackage wasysym (*must* be loaded between amsmath and amsfonts!)
if (config.useWasysym()) {
pack.append("\\usepackage{wasysym}").nl();
}
// usepackage amssymb, amsfonts, textcomp (always!)
pack.append("\\usepackage{amssymb,amsfonts,textcomp}").nl();
}
/** Apply a language language
* @param style the OOo style to read attributesfrom
* @param bDecl true if declaration form is required
* @param bInherit true if inherited properties should be used
* @param ba the <code>BeforeAfter</code> to add LaTeX code to.
*/
public void applyLanguage(StyleWithProperties style, boolean bDecl, boolean bInherit, BeforeAfter ba) {
if (!bAlwaysUseDefaultLang && style!=null) {
String sISOLang = style.getProperty(XMLString.FO_LANGUAGE,bInherit);
if (sISOLang!=null) {
languages.add(sISOLang);
String sLang = getBabelLanguage(sISOLang);
if (sLang!=null) {
if (bDecl) {
ba.add("\\selectlanguage{"+sLang+"}","");
//ba.add("\\begin{otherlanguage}{"+sLang+"}","\\end{otherlanguage}");
}
else {
ba.add("\\foreignlanguage{"+sLang+"}{","}");
}
}
}
}
}
/** Push a font to the font stack
* @param sName the name of the font
*/
public void pushSpecialTable(String sName) {
// If no name is specified we should keep the current table
// Otherwise try to find the table, and use root if it's not available
if (sName!=null) {
table = (UnicodeTable) tableSet.get(sName);
if (table==null) { table = (UnicodeTable) tableSet.get("root"); }
}
tableStack.push(table);
}
/** Pop a font from the font stack
*/
public void popSpecialTable() {
tableStack.pop();
table = (UnicodeTable) tableStack.peek();
}
/** Get the number of characters defined in the current table
* (for informational purposes only)
* @return the number of characters
*/
public int getCharCount() { return table.getCharCount(); }
/** Convert a string of characters into LaTeX
* @param s the source string
* @param bMathMode true if the string should be rendered in math mode
* @param sLang the iso language of the string
* @return the LaTeX string
*/
public String convert(String s, boolean bMathMode, String sLang){
if (!bAlwaysUseDefaultLang && sLang!=null) { languages.add(sLang); }
StringBuffer buf=new StringBuffer();
int nFontenc = bAlwaysUseDefaultLang ? nDefaultFontenc : getFontenc(sLang);
int nLen = s.length();
int i = 0;
int nStart = i;
while (i<nLen) {
ReplacementTrieNode node = stringReplace.get(s,i,nLen);
if (node!=null) {
if (i>nStart) {
convert(s,nStart,i,bMathMode,sLang,buf,nFontenc);
}
boolean bOtherFontenc = !supportsFontenc(node.getFontencs(),nFontenc);
if (bOtherFontenc) {
buf.append(getFontencCs(getFontenc(node.getFontencs()))).append("{");
}
buf.append(node.getLaTeXCode());
if (bOtherFontenc) {
buf.append("}");
}
i += node.getInputLength();
nStart = i;
}
else {
i++;
}
}
if (nStart<nLen) {
convert(s,nStart,nLen,bMathMode,sLang,buf,nFontenc);
}
return buf.toString();
}
private void convert(String s, int nStart, int nEnd, boolean bMathMode, String sLang, StringBuffer buf, int nFontenc) {
int nCurFontenc = nFontenc;
ucparser.reset(table,s,nStart,nEnd);
boolean bProtectDashes = true;
boolean bTempMathMode = false;
while (ucparser.next()) {
char c = ucparser.getChar();
if (bMathMode) {
buf.append(convertMathChar(c,nFontenc));
}
else if (greekMath(c,nFontenc) || (table.hasMathChar(c) && !table.hasTextChar(c))) {
if (!bTempMathMode) { // switch to math mode
buf.append("$");
bTempMathMode = true;
}
buf.append(convertMathChar(c,nFontenc));
bProtectDashes = false;
}
else if (table.hasTextChar(c)) {
if (bTempMathMode) { // switch to text mode
buf.append("$");
bTempMathMode = false;
}
int nFontencs = table.getFontencs(c);
if (supportsFontenc(nFontencs,nCurFontenc)) {
// The text character is valid in the current font encoding
// Note: Change of font encoding is greedy - change?
// Prevent unwanted --- ligatures
if (table.isDashes(c)) {
if (bProtectDashes) { buf.append("{}"); }
bProtectDashes = true;
}
else {
bProtectDashes = false;
}
setFlags(c,nCurFontenc);
if (ucparser.hasCombiningChar()) {
char cc = ucparser.getCombiningChar();
if (supportsFontenc(table.getFontencs(cc),nCurFontenc)) {
buf.append(table.getTextChar(cc)).append("{")
.append(table.getTextChar(c)).append("}");
}
else { // ignore combining char if not valid in this font encoding
buf.append(table.getTextChar(c));
}
}
else {
buf.append(table.getTextChar(c));
}
}
else {
// The text character is valid in another font encoding
bProtectDashes = table.isDashes(c);
int nFontenc1 = getFontenc(nFontencs);
setFlags(c,nFontenc1);
if (nCurFontenc!=nFontenc) { // end "other font encoding"
buf.append("}");
}
if (nFontenc1!=nFontenc) { // start "other font encoding"
buf.append(getFontencCs(nFontenc1)).append("{");
}
if (ucparser.hasCombiningChar()) {
char cc = ucparser.getCombiningChar();
if (supportsFontenc(table.getFontencs(cc),nCurFontenc)) {
buf.append(table.getTextChar(cc)).append("{")
.append(table.getTextChar(c)).append("}");
}
else { // ignore combining char if not valid in this font encoding
buf.append(table.getTextChar(c));
}
}
else {
buf.append(table.getTextChar(c));
}
nCurFontenc = nFontenc1;
}
}
else {
buf.append(notFound(c,nCurFontenc));
}
}
if (bTempMathMode) { // turn of math mode
buf.append("$");
}
if (nCurFontenc!=nFontenc) { // end unfinished "other font encoding"
buf.append("}");
}
}
// convert a single math character
private String convertMathChar(char c, int nFontenc) {
if (table.hasMathChar(c)) {
return table.getMathChar(c);
}
else if (table.hasTextChar(c)) { // use text mode as a fallback
int nFontencs = table.getFontencs(c);
if (supportsFontenc(nFontencs,nFontenc)) {
// The text character is valid in the current font encoding
setFlags(c,nFontenc);
if (table.getCharType(c)==UnicodeCharacter.COMBINING) {
return "\\text{" + table.getTextChar(c) +"{}}";
}
else {
return "\\text{" + table.getTextChar(c) +"}";
}
}
else {
// The text character is valid in another font encoding
int nFontenc1 = getFontenc(nFontencs);
setFlags(c,nFontenc1);
if (table.getCharType(c)==UnicodeCharacter.COMBINING) {
return "\\text{" + getFontencCs(nFontenc1) + "{" + table.getTextChar(c) +"{}}}";
}
else {
return "\\text{" + getFontencCs(nFontenc1) + "{" + table.getTextChar(c) +"}}";
}
}
}
else {
return "\\text{" + notFound(c,nFontenc) + "}";
}
}
// Missing symbol
private String notFound(char c,int nFontenc) {
//String sErrorMsg = "[Warning: Missing symbol " + Integer.toHexString(c).toUpperCase() +"]";
String sErrorMsg = "["+Integer.toHexString(c).toUpperCase() +"?]";
if (nFontenc==T1_ENC) return sErrorMsg;
else return "\\textlatin{"+sErrorMsg+"}";
}
// Convert a single character
/*private String convert(char c, boolean bMathMode, String sLang){
int nFontenc = bAlwaysUseDefaultLang ? nDefaultFontenc : getFontenc(sLang);
if (bMathMode) {
return convertMathChar(c,nFontenc);
}
else if (greekMath(c,nFontenc) || (table.hasMathChar(c) && !table.hasTextChar(c))) {
return "$" + convertMathChar(c,nFontenc) + "$";
}
else if (table.hasTextChar(c)) {
int nFontencs = table.getFontencs(c);
if (supportsFontenc(nFontencs,nFontenc)) {
// The text character is valid in the current font encoding
setFlags(c,nFontenc);
if (table.getCharType(c)==UnicodeCharacter.COMBINING) {
return table.getTextChar(c)+"{}";
}
else {
return table.getTextChar(c);
}
}
else {
// The text character is valid in another font encoding
int nFontenc1 = getFontenc(nFontencs);
setFlags(c,nFontenc1);
if (table.getCharType(c)==UnicodeCharacter.COMBINING) {
return getFontencCs(nFontenc1) + "{" + table.getTextChar(c) +"{}}";
}
else {
return getFontencCs(nFontenc1) + "{" + table.getTextChar(c) +"}";
}
}
}
else {
return notFound(c,nFontenc);
}
}*/
// **** Languages ****
// Convert iso language to babel language
// todo: include iso country
// todo: support automatic choice of inputenc (see comments)?
private String getBabelLanguage(String sLang) {
if (babelLanguages.containsKey(sLang)) {
return (String) babelLanguages.get(sLang);
}
else {
return "english"; // interpret unknown languages as English
}
}
private void prepareBabelLanguages() {
babelLanguages = new Hashtable();
babelLanguages.put("en", "english"); // latin1
babelLanguages.put("bg", "bulgarian"); // cp1251?
babelLanguages.put("cs", "czech"); // latin2
babelLanguages.put("da", "danish"); // latin1
babelLanguages.put("de", "ngerman"); // latin1
babelLanguages.put("el", "greek"); // iso-8859-7
babelLanguages.put("es", "spanish"); // latin1
babelLanguages.put("fi", "finnish"); // latin1 (latin9?)
babelLanguages.put("fr", "french"); // latin1 (latin9?)
babelLanguages.put("ga", "irish"); // latin1
babelLanguages.put("hr", "croatian"); // latin2
babelLanguages.put("hu", "magyar"); // latin2
babelLanguages.put("la", "latin"); // ascii
babelLanguages.put("is", "icelandic"); // latin1
babelLanguages.put("it", "italian"); // latin1
babelLanguages.put("nl", "dutch"); // latin1
babelLanguages.put("no", "norsk"); // latin1
babelLanguages.put("pl", "polish"); // latin2
babelLanguages.put("pt", "portuges"); // latin1
babelLanguages.put("ro", "romanian"); // latin2
babelLanguages.put("ru", "russian"); // cp1251?
babelLanguages.put("sk", "slovak"); // latin2
babelLanguages.put("sl", "slovene"); // latin2
babelLanguages.put("sr", "serbian"); // cp1251?
babelLanguages.put("sv", "swedish"); // latin1
babelLanguages.put("tr", "turkish");
babelLanguages.put("uk", "ukrainian"); // cp1251?
}
// **** Helpers to collect various information ****
// Did we use cyrillic?
private boolean cyrillic() { return bT2A; }
// Did we use greek?
private boolean greek() { return bGreek; }
// Did we use polytonic greek?
private boolean polytonicGreek() { return bPolytonicGreek; }
// Outside greek text, greek letters may be rendered in math mode,
// if the user requires that in the configuration.
private boolean greekMath(char c, int nFontenc) {
return bGreekMath && nFontenc!=LGR_ENC && table.getFontencs(c)==LGR_ENC;
}
// Set cyrillic and greek flags
private void setFlags(char c, int nFontenc) {
if ((c>='\u1F00') && (c<='\u1FFF')) bPolytonicGreek = true;
if (nFontenc==LGR_ENC) bGreek = true;
if (nFontenc==T2A_ENC) bT2A = true;
}
}

View file

@ -0,0 +1,118 @@
/************************************************************************
*
* I18n.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2009 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.0 (2009-02-16)
*
*/
package writer2latex.latex.i18n;
import java.util.HashSet;
import writer2latex.office.*;
import writer2latex.latex.LaTeXConfig;
import writer2latex.latex.LaTeXDocumentPortion;
import writer2latex.latex.ConverterPalette;
import writer2latex.latex.util.BeforeAfter;
/** This abstract class takes care of i18n in the LaTeX export.
* Since i18n is handled quite differently in LaTeX "Classic"
* and XeTeX, we use two different classes
*/
public abstract class I18n {
// **** Global variables ****
// Configuration items
protected LaTeXConfig config;
protected ReplacementTrie stringReplace;
protected boolean bGreekMath; // Use math mode for greek letters
protected boolean bAlwaysUseDefaultLang; // Ignore sLang parameter to convert()
// Collected data
protected String sDefaultLanguage; // The default iso language to use
protected HashSet languages = new HashSet(); // All languages used
// **** Constructors ****
/** Construct a new I18n as ConverterHelper
* @param ofr the OfficeReader to get language information from
* @param config the configuration which determines the symbols to use
* @param palette the ConverterPalette (unused)
*/
public I18n(OfficeReader ofr, LaTeXConfig config, ConverterPalette palette) {
// We don't need the palette and the office reader is only used to
// identify the default language
// Set up config items
this.config = config;
stringReplace = config.getStringReplace();
bGreekMath = config.greekMath();
bAlwaysUseDefaultLang = !config.multilingual();
// Default language
if (ofr!=null) {
if (config.multilingual()) {
// Read the default language from the default paragraph style
StyleWithProperties style = ofr.getDefaultParStyle();
if (style!=null) {
sDefaultLanguage = style.getProperty(XMLString.FO_LANGUAGE);
}
}
else {
// the most common language is the only language
sDefaultLanguage = ofr.getMajorityLanguage();
}
}
if (sDefaultLanguage==null) { sDefaultLanguage="en"; }
}
/** Add declarations to the preamble to load the required packages
* @param pack usepackage declarations
* @param decl other declarations
*/
public abstract void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl);
/** Apply a language language
* @param style the OOo style to read attributesfrom
* @param bDecl true if declaration form is required
* @param bInherit true if inherited properties should be used
* @param ba the <code>BeforeAfter</code> to add LaTeX code to.
*/
public abstract void applyLanguage(StyleWithProperties style, boolean bDecl, boolean bInherit, BeforeAfter ba);
/** Push a font to the font stack
* @param sName the name of the font
*/
public abstract void pushSpecialTable(String sName);
/** Pop a font from the font stack
*/
public abstract void popSpecialTable();
/** Convert a string of characters into LaTeX
* @param s the source string
* @param bMathMode true if the string should be rendered in math mode
* @param sLang the iso language of the string
* @return the LaTeX string
*/
public abstract String convert(String s, boolean bMathMode, String sLang);
}

View file

@ -0,0 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>The package writer2latex.xhtml.i18n</title>
</head>
<body>
<p>This package takes care of i18n for LaTeX.</p>
<p>In LaTeX, i18n is a mixture of inputencodings, fontencodings
and babel languages. In particualar, the package provides a Unicode->LaTeX
translation that can handle different inputencodings and fontencodings.</p>
<p>The pacakge could (with modification) in theory be used in other programs
that convert unicode to LaTeX.</p>
</body>
</html>

View file

@ -0,0 +1,56 @@
/************************************************************************
*
* ReplacementTrie.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2006 by Henrik Just
*
* All Rights Reserved.
*
* Version 0.5 (2006-11-02)
*
*/
package writer2latex.latex.i18n;
/** This class contains a trie of string -> LaTeX code replacements
*/
public class ReplacementTrie extends ReplacementTrieNode {
public ReplacementTrie() {
super('*',0);
}
public ReplacementTrieNode get(String sInput) {
return get(sInput,0,sInput.length());
}
public ReplacementTrieNode get(String sInput, int nStart, int nEnd) {
if (sInput.length()==0) { return null; }
else { return super.get(sInput,nStart,nEnd); }
}
public void put(String sInput, String sLaTeXCode, int nFontencs) {
if (sInput.length()==0) { return; }
else { super.put(sInput,sLaTeXCode,nFontencs); }
}
public String[] getInputStrings() {
return null; //TODO
}
}

View file

@ -0,0 +1,127 @@
/************************************************************************
*
* ReplacementTrieNode.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2006 by Henrik Just
*
* All Rights Reserved.
*
* Version 0.5 (2006-11-02)
*
*/
package writer2latex.latex.i18n;
/** This class contains a node in a trie of string -> LaTeX code replacements
*/
public class ReplacementTrieNode {
private char cLetter;
private int nInputLength;
private String sLaTeXCode = null;
private int nFontencs = 0;
private ReplacementTrieNode son = null;
private ReplacementTrieNode brother = null;
public ReplacementTrieNode(char cLetter, int nInputLength) {
this.cLetter = cLetter;
this.nInputLength = nInputLength;
}
public char getLetter() { return this.cLetter; }
public int getInputLength() { return this.nInputLength; }
public String getLaTeXCode() { return this.sLaTeXCode; }
public int getFontencs() { return this.nFontencs; }
protected void setLaTeXCode(String sLaTeXCode) {
this.sLaTeXCode = sLaTeXCode;
}
protected void setFontencs(int nFontencs) {
this.nFontencs = nFontencs;
}
protected ReplacementTrieNode getFirstChild() {
return this.son;
}
protected ReplacementTrieNode getNextSibling() {
return this.brother;
}
protected ReplacementTrieNode getChildByLetter(char cLetter) {
ReplacementTrieNode child = this.getFirstChild();
while (child!=null) {
if (cLetter==child.getLetter()) { return child; }
child = child.getNextSibling();
}
return null;
}
protected void appendChild(ReplacementTrieNode node) {
if (son==null) { son = node; }
else { son.appendSibling(node); }
}
protected void appendSibling(ReplacementTrieNode node) {
if (brother==null) { brother = node; }
else { brother.appendSibling(node); }
}
protected ReplacementTrieNode get(String sInput, int nStart, int nEnd) {
if (nStart>=nEnd) { return null; }
char c = sInput.charAt(nStart);
ReplacementTrieNode child = this.getFirstChild();
while (child!=null) {
if (child.getLetter()==c) {
if (child.getLaTeXCode()!=null) { return child; }
else { return child.get(sInput,nStart+1,nEnd); }
}
child = child.getNextSibling();
}
return null;
}
protected void put(String sInput, String sLaTeXCode, int nFontencs) {
char c = sInput.charAt(0);
ReplacementTrieNode child = this.getChildByLetter(c);
if (child==null) {
child = new ReplacementTrieNode(c,this.getInputLength()+1);
this.appendChild(child);
}
if (sInput.length()>1) {
child.put(sInput.substring(1),sLaTeXCode,nFontencs);
}
else {
child.setLaTeXCode(sLaTeXCode);
child.setFontencs(nFontencs);
}
}
public String toString() {
String s = Character.toString(cLetter);
if (brother!=null) { s+=brother.toString(); }
if (son!=null) { s+="\nInputLength "+(nInputLength+1)+", "+son.toString(); }
else { s+="\n"; }
return s;
}
}

View file

@ -0,0 +1,52 @@
/************************************************************************
*
* UnicodeCharacter.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2007 by Henrik Just
*
* All Rights Reserved.
*
* Version 0.5 (2007-07-24)
*
*/
package writer2latex.latex.i18n;
// Helper class: A struct to hold the LaTeX representations of a unicode character
class UnicodeCharacter implements Cloneable {
final static int NORMAL = 0; // this is a normal character
final static int COMBINING = 1; // this character should be ignored
final static int IGNORE = 2; // this is a combining character
final static int UNKNOWN = 3; // this character is unknown
int nType; // The type of character
String sMath; // LaTeX representation in math mode
String sText; // LaTeX representation in text mode
int nFontencs; // Valid font encoding(s) for the text mode representation
boolean bDashes; // This character is represented by dashes (-,--,---)
protected Object clone() {
UnicodeCharacter uc = new UnicodeCharacter();
uc.nType = this.nType;
uc.sMath = this.sMath;
uc.sText = this.sText;
uc.nFontencs = this.nFontencs;
uc.bDashes = this.bDashes;
return uc;
}
}

View file

@ -0,0 +1,43 @@
/************************************************************************
*
* UnicodeRow.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2007 by Henrik Just
*
* All Rights Reserved.
*
* Version 0.5 (2007-07-24)
*
*/
package writer2latex.latex.i18n;
// Helper class: A row of 256 unicode characters
class UnicodeRow implements Cloneable {
UnicodeCharacter[] entries;
UnicodeRow(){ entries=new UnicodeCharacter[256]; }
protected Object clone() {
UnicodeRow ur = new UnicodeRow();
for (int i=0; i<256; i++) {
if (this.entries[i]!=null) {
ur.entries[i] = (UnicodeCharacter) this.entries[i].clone();
}
}
return ur;
}
}

View file

@ -0,0 +1,79 @@
/************************************************************************
*
* UnicodeStringParser.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2007 by Henrik Just
*
* All Rights Reserved.
*
* Version 0.5 (2007-07-24)
*
*/
package writer2latex.latex.i18n;
// Helper class: Parse a unicode string.
// Note: Some 8-bit fonts have additional "spacer" characters that are used
// for manual placement of accents. These are ignored between the base character
// and the combining character, thus we are parsing according to the rule
// <base char> <spacer char>* <combining char>?
class UnicodeStringParser {
private UnicodeTable table; // the table to use
private String s; // the string
private int i; // the current index
private int nEnd; // the maximal index
private char c; // the current character
private char cc; // the current combining character
protected void reset(UnicodeTable table, String s, int i, int nEnd) {
this.table=table;
this.s=s;
this.i=i;
this.nEnd=nEnd;
}
protected boolean next() {
if (i>=nEnd) { return false; }
// Pick up base character
c = s.charAt(i++);
if (table.getCharType(c)==UnicodeCharacter.COMBINING) {
// Lonely combining character - combine with space
cc = c;
c = ' ';
return true;
}
// Skip characters that should be ignored
while (i<s.length() && table.getCharType(s.charAt(i))==UnicodeCharacter.IGNORE) { i++; }
// Pick up combining character, if any
if (i<s.length() && table.getCharType(s.charAt(i))==UnicodeCharacter.COMBINING) {
cc = s.charAt(i++);
}
else {
cc = '\u0000';
}
return true;
}
protected char getChar() { return c; }
protected boolean hasCombiningChar() { return cc!='\u0000'; }
protected char getCombiningChar() { return cc; }
}

View file

@ -0,0 +1,169 @@
/************************************************************************
*
* UnicodeTable.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2007 by Henrik Just
*
* All Rights Reserved.
*
* Version 0.5 (2007-07-24)
*
*/
package writer2latex.latex.i18n;
// Helper class: Table of up to 65536 unicode characters
class UnicodeTable {
protected UnicodeRow[] table=new UnicodeRow[256];
private UnicodeTable parent;
// Constructor; creates a new table, possibly based on a parent
// Note: The parent must be fully loaded before the child is created.
public UnicodeTable(UnicodeTable parent){
this.parent = parent;
if (parent!=null) {
// *Copy* the rows from the parent
for (int i=0; i<256; i++) {
table[i] = parent.table[i];
}
}
}
// Make sure the required entry exists
private void createEntry(int nRow, int nCol) {
if (table[nRow]==null) {
table[nRow]=new UnicodeRow();
}
else if (parent!=null && table[nRow]==parent.table[nRow]) {
// Before changing a row it must be *cloned*
table[nRow] = (UnicodeRow) parent.table[nRow].clone();
}
if (table[nRow].entries[nCol]==null) {
table[nRow].entries[nCol]=new UnicodeCharacter();
}
}
// Addd a single character (type only), by number
protected void addCharType(char c, int nType) {
int nRow=c/256; int nCol=c%256;
createEntry(nRow,nCol);
table[nRow].entries[nCol].nType = nType;
}
// Addd a single character (type only), by name
protected void addCharType(char c, String sType) {
int nRow=c/256; int nCol=c%256;
createEntry(nRow,nCol);
if ("combining".equals(sType)) {
table[nRow].entries[nCol].nType = UnicodeCharacter.COMBINING;
}
else if ("ignore".equals(sType)) {
table[nRow].entries[nCol].nType = UnicodeCharacter.IGNORE;
}
else {
table[nRow].entries[nCol].nType = UnicodeCharacter.NORMAL;
}
}
// Add a single math character to the table
protected void addMathChar(char c, String sLaTeX){
int nRow=c/256; int nCol=c%256;
createEntry(nRow,nCol);
table[nRow].entries[nCol].sMath=sLaTeX;
}
// Add a single text character to the table
protected void addTextChar(char c, String sLaTeX, int nFontencs, boolean bDashes){
int nRow=c/256; int nCol=c%256;
createEntry(nRow,nCol);
table[nRow].entries[nCol].sText=sLaTeX;
table[nRow].entries[nCol].nFontencs=nFontencs;
table[nRow].entries[nCol].bDashes=bDashes;
}
// Retrieve entry for a character (or null)
private UnicodeCharacter getEntry(char c) {
int nRow=c/256; int nCol=c%256;
if (table[nRow]==null) return null;
return table[nRow].entries[nCol];
}
// Get character type
public int getCharType(char c) {
UnicodeCharacter entry = getEntry(c);
if (entry==null) return UnicodeCharacter.UNKNOWN;
return entry.nType;
}
// Check to see if this math character exists?
public boolean hasMathChar(char c) {
UnicodeCharacter entry = getEntry(c);
if (entry==null) return false;
return entry.sMath!=null;
}
// Get math character (or null)
public String getMathChar(char c) {
UnicodeCharacter entry = getEntry(c);
if (entry==null) return null;
return entry.sMath;
}
// Check to see if this text character exists?
public boolean hasTextChar(char c) {
UnicodeCharacter entry = getEntry(c);
if (entry==null) return false;
return entry.sText!=null;
}
// Get text character (or null)
public String getTextChar(char c) {
UnicodeCharacter entry = getEntry(c);
if (entry==null) return null;
return entry.sText;
}
// Get font encoding(s) for text character (or 0)
public int getFontencs(char c) {
UnicodeCharacter entry = getEntry(c);
if (entry==null) return 0;
return entry.nFontencs;
}
// Get dashes for text character
public boolean isDashes(char c) {
UnicodeCharacter entry = getEntry(c);
if (entry==null) return false;
return entry.bDashes;
}
// Get number of defined characters
public int getCharCount() {
int nCount = 0;
for (int nRow=0; nRow<256; nRow++) {
if (table[nRow]!=null) {
for (int nCol=0; nCol<256; nCol++) {
UnicodeCharacter entry = table[nRow].entries[nCol];
if (entry!=null) nCount++;
}
}
}
return nCount;
}
}

View file

@ -0,0 +1,166 @@
/************************************************************************
*
* UnicodeTableHandler.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2009 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.0 (2009-02-17)
*
*/
package writer2latex.latex.i18n;
import java.util.Hashtable;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
// Helper classs: SAX handler to parse symbols.xml from jar
class UnicodeTableHandler extends DefaultHandler{
private Hashtable tableSet; // collection of all tables
private UnicodeTable table; // the current table
private String sSymbolSets;
private boolean bGlobalReadThisSet;
private boolean bReadThisSet;
private int nGlobalFontencs = 0; // The global fontencodings for current symbol set
private int nFontencs = 0; // The currently active fontencodings
private boolean b8bit = false;
UnicodeTableHandler(Hashtable tableSet, String sSymbolSets){
this.sSymbolSets = sSymbolSets;
this.tableSet = tableSet;
}
public void startElement(String nameSpace, String localName, String qName, Attributes attributes){
if (qName.equals("symbols")) {
//root element - create root table!
table = new UnicodeTable(null);
tableSet.put("root",table);
}
else if (qName.equals("symbol-set")) {
// start a new symbol set; maybe we want to include it?
bGlobalReadThisSet = sSymbolSets.indexOf(attributes.getValue("name")) >= 0;
bReadThisSet = bGlobalReadThisSet;
// Change global and current fontencodings
nGlobalFontencs = ClassicI18n.readFontencs(attributes.getValue("fontenc"));
nFontencs = nGlobalFontencs;
}
else if (qName.equals("special-symbol-set")) {
// start a new special symbol set; this requires a new table
table = new UnicodeTable((UnicodeTable) tableSet.get("root"));
tableSet.put(attributes.getValue("name"),table);
// Read it if it requires nothing, or something we read
bGlobalReadThisSet = attributes.getValue("requires")==null ||
sSymbolSets.indexOf(attributes.getValue("requires")) >= 0;
bReadThisSet = bGlobalReadThisSet;
b8bit = "true".equals(attributes.getValue("eight-bit"));
// Change global and current fontencodings
nGlobalFontencs = ClassicI18n.readFontencs(attributes.getValue("fontenc"));
nFontencs = nGlobalFontencs;
}
else if (qName.equals("symbol-subset")) {
// Do we requires something here?
if (attributes.getValue("requires")!=null) {
bReadThisSet = sSymbolSets.indexOf(attributes.getValue("requires")) >= 0;
}
// Change current fontencodings
nFontencs = ClassicI18n.readFontencs(attributes.getValue("fontenc"));
}
else if (qName.equals("symbol")) {
if (bReadThisSet) {
char c=(char)Integer.parseInt(attributes.getValue("char"),16);
String sEqChar=attributes.getValue("eq-char");
if (sEqChar!=null) { // copy existing definitions, if any
char eqc = (char)Integer.parseInt(sEqChar,16);
if (table.getCharType(eqc)!=UnicodeCharacter.UNKNOWN) {
table.addCharType(c,table.getCharType(eqc));
}
if (table.hasMathChar(eqc)) {
table.addMathChar(c,table.getMathChar(eqc));
}
if (table.hasTextChar(eqc)) {
table.addTextChar(c,table.getTextChar(eqc),table.getFontencs(eqc),table.isDashes(eqc));
}
}
else {
String sType=attributes.getValue("char-type");
String sMath=attributes.getValue("math");
String sText=attributes.getValue("text");
boolean bDashes="true".equals(attributes.getValue("dashes"));
if (sType!=null) table.addCharType(c,sType);
if (sMath!=null) table.addMathChar(c,sMath);
if (sText!=null) table.addTextChar(c,sText,nFontencs,bDashes);
}
}
}
else if (qName.equals("preserve-symbol")) {
if (bReadThisSet) {
String sMode=attributes.getValue("mode");
char c=(char)Integer.parseInt(attributes.getValue("char"),16);
table.addCharType(c,attributes.getValue("char-type"));
if ("math".equals(sMode) || "both".equals(sMode)) {
table.addMathChar(c,Character.toString(c));
}
if ("text".equals(sMode) || "both".equals(sMode)) {
table.addTextChar(c,Character.toString(c),nFontencs,false);
}
}
}
else if (qName.equals("preserve-symbols")) {
if (bReadThisSet) {
String sMode=attributes.getValue("mode");
String sType=attributes.getValue("char-type");
char c1=(char)Integer.parseInt(attributes.getValue("first-char"),16);
char c2=(char)Integer.parseInt(attributes.getValue("last-char"),16);
boolean bMath = "math".equals(sMode) || "both".equals(sMode);
boolean bText = "text".equals(sMode) || "both".equals(sMode);
for (char c=c1; c<=c2; c++) {
table.addCharType(c,sType);
if (bMath) {
table.addMathChar(c,Character.toString(c));
}
if (bText) {
table.addTextChar(c,Character.toString(c),nFontencs,false);
}
}
}
}
}
public void endElement(String nameSpace, String localName, String qName){
if (qName.equals("symbol-subset")) {
// Revert to global setting of reading status
bReadThisSet = bGlobalReadThisSet;
// Revert to global fontencoding
nFontencs = nGlobalFontencs;
}
else if (qName.equals("special-symbol-set")) {
if (b8bit) {
// Row 0 = Row 240 (F0)
// Note: 8-bit fonts are supposed to be relocated to F000..F0FF
// This may fail on import from msword, hence this hack
table.table[0] = table.table[240];
}
b8bit = false;
}
}
}

View file

@ -0,0 +1,120 @@
/************************************************************************
*
* XeTeXI18n.java
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2009 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.0 (2009-02-17)
*
*/
package writer2latex.latex.i18n;
import writer2latex.office.*;
import writer2latex.latex.LaTeXConfig;
import writer2latex.latex.LaTeXDocumentPortion;
import writer2latex.latex.ConverterPalette;
import writer2latex.latex.util.BeforeAfter;
/** This class takes care of i18n in XeLaTeX
*/
public class XeTeXI18n extends I18n {
// **** Constructors ****
/** Construct a new XeTeXI18n as ConverterHelper
* @param ofr the OfficeReader to get language information from
* @param config the configuration which determines the symbols to use
* @param palette the ConverterPalette (unused)
*/
public XeTeXI18n(OfficeReader ofr, LaTeXConfig config, ConverterPalette palette) {
super(ofr,config,palette);
}
/** Add declarations to the preamble to load the required packages
* @param pack usepackage declarations
* @param decl other declarations
*/
public void appendDeclarations(LaTeXDocumentPortion pack, LaTeXDocumentPortion decl) {
pack.append("\\usepackage{fontspec}").nl()
.append("\\usepackage{xunicode}").nl()
.append("\\usepackage{xltxtra}").nl()
.append("\\usepackage{amsmath,amssymb,amsfonts}").nl();
}
/** Apply a language language
* @param style the OOo style to read attributesfrom
* @param bDecl true if declaration form is required
* @param bInherit true if inherited properties should be used
* @param ba the <code>BeforeAfter</code> to add LaTeX code to.
*/
public void applyLanguage(StyleWithProperties style, boolean bDecl, boolean bInherit, BeforeAfter ba) {
// TODO (polyglossia)
}
/** Push a font to the font stack
* @param sName the name of the font
*/
public void pushSpecialTable(String sName) {
// TODO
}
/** Pop a font from the font stack
*/
public void popSpecialTable() {
// TODO
}
/** Convert a string of characters into LaTeX
* @param s the source string
* @param bMathMode true if the string should be rendered in math mode
* @param sLang the iso language of the string
* @return the LaTeX string
*/
public String convert(String s, boolean bMathMode, String sLang){
StringBuffer buf = new StringBuffer();
int nLen = s.length();
char c;
for (int i=0; i<nLen; i++) {
c = s.charAt(i);
switch (c) {
case '"' : buf.append("\\textquotedbl{}"); break;
case '#' : buf.append("\\#"); break;
case '$' : buf.append("\\$"); break;
case '%' : buf.append("\\%"); break;
case '&' : buf.append("\\&"); break;
case '\'' : buf.append("\\textbackslash{}"); break;
case '<' : buf.append("\\textless{}"); break;
case '>' : buf.append("\\textgreater{}"); break;
case '\\' : buf.append("\\textbackslash{}"); break;
case '\u005e' : buf.append("\\^{}"); break;
case '_' : buf.append("\\_"); break;
case '\u0060' : buf.append("\\textasciigrave{}"); break;
case '{' : buf.append("\\{"); break;
case '|' : buf.append("\\textbar{}"); break;
case '}' : buf.append("\\}"); break;
case '~' : buf.append("\\~{}"); break;
default: buf.append(c);
}
}
return buf.toString();
}
}

File diff suppressed because it is too large Load diff