From abcf8f19b365fb54becd113bfe2f8058799aecb1 Mon Sep 17 00:00:00 2001 From: dchandler Date: Sat, 2 Nov 2002 03:38:59 +0000 Subject: [PATCH] Factored TibetanDocument into two classes, one that is a DefaultStyledDocument, and another consisting entirely of static utility methods for processing Tibetan text. Moved TibetanDocument.DuffData into its own class. I think this makes things a bit more transparent, and gets us a little closer to making clean use of Swing. --- source/org/thdl/quilldriver/QD.java | 11 +- source/org/thdl/savant/SavantShell.java | 6 +- source/org/thdl/savant/tib/Tibetan.java | 12 +- .../org/thdl/savant/tib/TibetanEnglish.java | 8 +- source/org/thdl/savant/tib/TibetanWylie.java | 8 +- .../thdl/savant/tib/TibetanWylieEnglish.java | 8 +- source/org/thdl/savant/tib/Wylie.java | 2 +- source/org/thdl/savant/tib/WylieEnglish.java | 4 +- source/org/thdl/tib/input/DuffPane.java | 56 +- .../org/thdl/tib/input/Jskad2JavaScript.java | 6 +- .../org/thdl/tib/input/Jskad4JavaScript.java | 9 +- .../thdl/tib/input/JskadConversionTool.java | 3 +- .../thdl/tib/scanner/AppletScannerFilter.java | 3 +- .../tib/scanner/DictionaryTableModel.java | 8 +- .../thdl/tib/scanner/DuffCellRenderer.java | 5 +- .../thdl/tib/scanner/DuffScannerPanel.java | 5 +- .../thdl/tib/scanner/WindowScannerFilter.java | 3 +- .../org/thdl/tib/text/DuffCellRenderer.java | 5 +- source/org/thdl/tib/text/DuffData.java | 53 + source/org/thdl/tib/text/TibTextUtils.java | 1100 ++++++++++++++++ source/org/thdl/tib/text/TibetanDocument.java | 1124 +---------------- source/org/thdl/tib/text/TibetanHTML.java | 369 +++--- source/org/thdl/tib/text/TibetanQTText.java | 4 +- source/org/thdl/tib/text/TibetanQTText2.java | 4 +- source/org/thdl/util/ThdlDebug.java | 11 + 25 files changed, 1490 insertions(+), 1337 deletions(-) create mode 100644 source/org/thdl/tib/text/DuffData.java create mode 100644 source/org/thdl/tib/text/TibTextUtils.java diff --git a/source/org/thdl/quilldriver/QD.java b/source/org/thdl/quilldriver/QD.java index bd8c615..64d9779 100644 --- a/source/org/thdl/quilldriver/QD.java +++ b/source/org/thdl/quilldriver/QD.java @@ -34,7 +34,6 @@ import java.lang.reflect.*; import org.thdl.tib.input.*; import org.thdl.tib.text.*; -import org.thdl.tib.text.TibetanDocument.*; import org.thdl.savant.JdkVersionHacks; import org.thdl.media.*; @@ -80,6 +79,8 @@ public class QD extends JDesktopPane { public Style componentStyle; public DataFlavor timeFlavor; + /** Either "qt4j" or "jmf", corresponding to the thdl.media.player + property. */ protected String thdl_mediaplayer_property = null; //class fields because they are affected depending on whether we're @@ -95,8 +96,8 @@ public class QD extends JDesktopPane { protected DuffPane sharedDP = new DuffPane(); protected DuffPane sharedDP2 = new DuffPane(); - protected TibetanDocument findDoc = null; - protected TibetanDocument replaceDoc = null; + protected AbstractDocument findDoc = null; + protected AbstractDocument replaceDoc = null; protected KeyStroke cutKey, copyKey, pasteKey, selectAllKey; protected KeyStroke insert1TimeKey, insert2TimesKey, insertSpeakerKey; @@ -1385,7 +1386,7 @@ class SpeakerData extends AbstractTableModel if (column == 0) return spIcon[sp.getIconID()]; try { //otherwise column 1, the speaker name - return TibetanDocument.getTibetanMachineWeb(sp.getName().trim()); + return TibTextUtils.getTibetanMachineWeb(sp.getName().trim()); } catch (InvalidWylieException iwe) { iwe.printStackTrace(); ThdlDebug.noteIffyCode(); @@ -1653,7 +1654,7 @@ public void replaceText() { java.util.List replaceDCs = new ArrayList(); for (int k=0; k 1 && isStackingRightToLeft) { String s = (String)charList.remove(charList.size() - 1); - newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); + newGlyphList = TibTextUtils.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); initKeyboard(); charList.add(s); - newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); + newGlyphList = TibTextUtils.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); holdCurrent = new StringBuffer(); isTopHypothesis = false; @@ -1355,7 +1343,7 @@ public void paste(int offset) { s = TibetanMachineWeb.getWylieForChar(s); charList.add(s); isTopHypothesis = true; - newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); + newGlyphList = TibTextUtils.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); changedStatus = true; updateStatus("You typed a non-vowel, Tibetan character."); @@ -1379,7 +1367,7 @@ public void paste(int offset) { if (isTopHypothesis) { if (TibetanMachineWeb.isAChungConsonant() && isStackingOn && charList.size()>1 && s2.equals(TibetanMachineWeb.ACHUNG)) { charList.remove(charList.size() - 1); - newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); + newGlyphList = TibTextUtils.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); putVowel(TibetanMachineWeb.A_VOWEL); initKeyboard(); @@ -1388,7 +1376,7 @@ public void paste(int offset) { break key_block; } charList.set(charList.size()-1, s2); - newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); + newGlyphList = TibTextUtils.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); } else { if (!isStackingOn) { @@ -1406,7 +1394,7 @@ public void paste(int offset) { charList.add(s2); isTopHypothesis = true; - newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); + newGlyphList = TibTextUtils.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); } } else { //the holding string is not a character @@ -1441,7 +1429,7 @@ public void paste(int offset) { } charList.add(s2); - newGlyphList = TibetanDocument.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); + newGlyphList = TibTextUtils.getGlyphs(charList, isStackingRightToLeft, isDefinitelyTibetan, isDefinitelySanskrit); oldGlyphList = redrawGlyphs(oldGlyphList, newGlyphList); changedStatus = true; updateStatus("added character to charList"); @@ -1511,7 +1499,7 @@ public void paste(int offset) { dc_array = new DuffCode[0]; dc_array = (DuffCode[])dcs.toArray(dc_array); doc.remove(start, i-start); - append(start, TibetanDocument.getWylie(dc_array), romanAttributeSet); + append(start, TibTextUtils.getWylie(dc_array), romanAttributeSet); dcs.clear(); } start = i+1; @@ -1552,7 +1540,7 @@ public void paste(int offset) { ThdlDebug.noteIffyCode(); } } else { - TibetanDocument.DuffData[] dd = TibetanDocument.getTibetanMachineWeb(next); + DuffData[] dd = TibTextUtils.getTibetanMachineWeb(next); offset = doc.insertDuff(offset, dd); } } @@ -1603,7 +1591,7 @@ public void paste(int offset) { if ((0 != (fontNum = TibetanMachineWeb.getTMWFontNumber(fontName))) || i==endPos.getOffset()) { if (i != start) { try { - TibetanDocument.DuffData[] duffdata = TibetanDocument.getTibetanMachineWeb(sb.toString()); + DuffData[] duffdata = TibTextUtils.getTibetanMachineWeb(sb.toString()); doc.remove(start, i-start); doc.insertDuff(start, duffdata); } @@ -1630,4 +1618,14 @@ public void paste(int offset) { } } +/** +* Converts the entire associated document into Extended Wylie. If the +* document consists of both Tibetan and non-Tibetan fonts, however, +* the conversion stops at the first non-Tibetan font. +* @return the string of Wylie corresponding to the associated document +* @see org.thdl.tib.text.TibetanDocument.getWylie() */ + public String getWylie() { + return doc.getWylie(); + } + } diff --git a/source/org/thdl/tib/input/Jskad2JavaScript.java b/source/org/thdl/tib/input/Jskad2JavaScript.java index 7b2f01b..fa66e4a 100644 --- a/source/org/thdl/tib/input/Jskad2JavaScript.java +++ b/source/org/thdl/tib/input/Jskad2JavaScript.java @@ -47,6 +47,7 @@ public class Jskad2JavaScript extends JApplet { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { + ThdlDebug.noteIffyCode(); } setContentPane(makeContentPane()); } @@ -61,11 +62,10 @@ public class Jskad2JavaScript extends JApplet { public void theRealActionPerformed(ActionEvent e) { try { - TibetanDocument t_doc = (TibetanDocument)jskad.dp.getDocument(); - String wylie = t_doc.getWylie(); - Object[] args = {wylie}; + Object[] args = { jskad.dp.getWylie() }; JSObject.getWindow(Jskad2JavaScript.this).call("settext", args); } catch (Exception ex) { + ThdlDebug.noteIffyCode(); } } }); diff --git a/source/org/thdl/tib/input/Jskad4JavaScript.java b/source/org/thdl/tib/input/Jskad4JavaScript.java index bcfc2b7..0a4325b 100644 --- a/source/org/thdl/tib/input/Jskad4JavaScript.java +++ b/source/org/thdl/tib/input/Jskad4JavaScript.java @@ -68,11 +68,11 @@ public class Jskad4JavaScript extends JApplet { public void setWylie(String wylie) { try { - TibetanDocument.DuffData[] dd = TibetanDocument.getTibetanMachineWeb(wylie); + DuffData[] dd = TibTextUtils.getTibetanMachineWeb(wylie); TibetanDocument t_doc = (TibetanDocument)jskad.dp.getDocument(); if (t_doc.getLength() > 0) - jskad.dp.newDocument(); - TibetanDocument.DuffData[] duffdata = TibetanDocument.getTibetanMachineWeb(wylie); + jskad.dp.newDocument(); // DLC FIXME: is it intended that t_doc is the new document? Because it is the old document at present. + DuffData[] duffdata = TibTextUtils.getTibetanMachineWeb(wylie); t_doc.insertDuff(0, duffdata); } catch (InvalidWylieException iwe) { @@ -84,7 +84,6 @@ public class Jskad4JavaScript extends JApplet { } public String getWylie() { - TibetanDocument t_doc = (TibetanDocument)jskad.dp.getDocument(); - return t_doc.getWylie(); + return jskad.dp.getWylie(); } } diff --git a/source/org/thdl/tib/input/JskadConversionTool.java b/source/org/thdl/tib/input/JskadConversionTool.java index 37f133f..4af3ed3 100644 --- a/source/org/thdl/tib/input/JskadConversionTool.java +++ b/source/org/thdl/tib/input/JskadConversionTool.java @@ -61,8 +61,7 @@ public class JskadConversionTool extends JApplet { public void theRealActionPerformed(ActionEvent e) { try { - TibetanDocument t_doc = (TibetanDocument)jskad.dp.getDocument(); - String wylie = t_doc.getWylie(); + String wylie = jskad.dp.getWylie(); String html = "\n\n\n\n\n"; diff --git a/source/org/thdl/tib/scanner/AppletScannerFilter.java b/source/org/thdl/tib/scanner/AppletScannerFilter.java index 559bfd2..40b5a45 100644 --- a/source/org/thdl/tib/scanner/AppletScannerFilter.java +++ b/source/org/thdl/tib/scanner/AppletScannerFilter.java @@ -25,7 +25,6 @@ import javax.swing.text.JTextComponent; import java.awt.event.*; import java.awt.datatransfer.*; import org.thdl.tib.input.DuffPane; -import org.thdl.tib.text.TibetanDocument; /** Inputs a Tibetan text and displays the words with their definitions through through a graphical interfase using a @@ -244,7 +243,7 @@ public class AppletScannerFilter extends JApplet implements ActionListener, Focu { try { - ((TibetanDocument)t.getDocument()).remove(t.getSelectionStart(), t.getSelectionEnd()); + t.getDocument().remove(t.getSelectionStart(), t.getSelectionEnd()); } catch (Exception ex) { diff --git a/source/org/thdl/tib/scanner/DictionaryTableModel.java b/source/org/thdl/tib/scanner/DictionaryTableModel.java index 1202b77..6f20fe7 100644 --- a/source/org/thdl/tib/scanner/DictionaryTableModel.java +++ b/source/org/thdl/tib/scanner/DictionaryTableModel.java @@ -19,8 +19,8 @@ package org.thdl.tib.scanner; import javax.swing.*; import javax.swing.table.*; -import org.thdl.tib.text.TibetanDocument; -import org.thdl.tib.text.TibetanDocument.DuffData; +import org.thdl.tib.text.TibTextUtils; +import org.thdl.tib.text.DuffData; /** Stores the words being displayed in a DictionaryTable. @@ -114,7 +114,7 @@ public class DictionaryTableModel extends AbstractTableModel try { for (i=0; i +* 1 - TibetanMachineWeb
+* 2 - TibetanMachineWeb1
+* ...
+* 10 - TibetanMachineWeb9
+*

+* The string represents a contiguous stretch of data in that +* font, i.e. a stretch of TibetanMachineWeb that doesn't require a font change. +*/ +public class DuffData { +/** +* a string of text +*/ + public String text; +/** +* the font number for this text (see class description) +*/ + public int font; + +/** +* @param s a string of TibetanMachineWeb text +* @param i a TibetanMachineWeb font number +*/ + public DuffData(String s, int i) { + text = s; + font = i; + } +} diff --git a/source/org/thdl/tib/text/TibTextUtils.java b/source/org/thdl/tib/text/TibTextUtils.java new file mode 100644 index 0000000..02b67fc --- /dev/null +++ b/source/org/thdl/tib/text/TibTextUtils.java @@ -0,0 +1,1100 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.text; + +import java.util.*; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.text.rtf.RTFEditorKit; +import java.io.*; + +import org.thdl.util.ThdlDebug; + +/** +* Provides methods for converting back and forth between Extended +* Wylie and TibetanMachineWeb. This class is not instantiable. +* +*

+* The class provides a variety of static methods for converting +* back and forth between Extended Wylie and TibetanMachineWeb. The +* Wylie can be accessed as a String, while the TibetanMachineWeb can +* be exported as Rich Text Format. +* +* @author Edward Garrett, Tibetan and Himalayan Digital Library */ +public class TibTextUtils { + /** Do not use this contructor. */ + private TibTextUtils() { super(); } + + +/** +* Converts a list of glyphs into an array of {@link DuffData DuffData}. +* The motivation for this is that most processes - for example using +* TibetanMachineWeb in HTML - only need to know what +* text to output, and when to change fonts. In general, they don't +* need to have an explicit indication for each glyph of the font +* for that glyph. +* @param glyphs the list of TibetanMachineWeb glyphs +* you want to convert +* @return an array of DuffData corresponding to this +* list of glyphs +*/ + public static DuffData[] convertGlyphs(List glyphs) { + if (glyphs.size() == 0) + return null; + List data = new ArrayList(); + StringBuffer sb = new StringBuffer(); + Iterator iter = glyphs.iterator(); + DuffCode dc = (DuffCode)iter.next(); + int lastfont = dc.fontNum; + sb.append(dc.character); + + while (iter.hasNext()) { + dc = (DuffCode)iter.next(); + if (dc.fontNum == lastfont) + sb.append(dc.character); + else { + data.add(new DuffData(sb.toString(), lastfont)); + lastfont = dc.fontNum; + sb = new StringBuffer(); + sb.append(dc.character); + } + } + + data.add(new DuffData(sb.toString(), lastfont)); + + DuffData[] dd = new DuffData[0]; + dd = (DuffData[])data.toArray(dd); + return dd; + } + +/** +* Figures out how to arrange a list of characters into glyphs. For example, if the user types 'bsgr' +* using the Extended Wylie keyboard, this method figures out that this should be represented +* as a 'b' glyph followed by a 's-g-r' glyph. If you know that the characters do not +* contain Sanskrit stacks, or do not contain Tibetan stacks, then you can specify this +* to speed the process up. Otherwise, the method will first check to see if the characters +* correspond to any Tibetan stacks, and if not, then it will check for Sanskrit stacks. +* @param chars the list of Tibetan characters you want to find glyphs for +* @param areStacksOnRight whether stacking should try to maximize from right to left (true) +* or from left to right (false). In the Extended Wylie keyboard, you try to stack from +* right to left. Thus, the character sequence r-g-r would be stacked as r followed by gr, +* rather than rg followed by r. In the Sambhota and TCC keyboards, the stack direction +* is reversed. +* @param definitelyTibetan should be true if the characters are known to be Tibetan and +* not Sanskrit +* @param definitelySanskrit should be true if the characters are known to be Sanskrit and +* not Tibetan +*/ + public static List getGlyphs(List chars, boolean areStacksOnRight, boolean definitelyTibetan, boolean definitelySanskrit) { + StringBuffer tibBuffer, sanBuffer; + String tibCluster, sanCluster; + + boolean checkTibetan, checkSanskrit; + + if (!(definitelyTibetan || definitelySanskrit)) { + checkTibetan = true; + checkSanskrit = true; + } + else { + checkTibetan = definitelyTibetan; + checkSanskrit = definitelySanskrit; + } + + int length = chars.size(); + + List glyphs = new ArrayList(); + glyphs.clear(); + + if (areStacksOnRight) { + for (int i=0; i-1; i--) { + tibBuffer = new StringBuffer(); + tibCluster = null; + + sanBuffer = new StringBuffer(); + sanCluster = null; + + Iterator iter = chars.iterator(); + + for (int k=0; k 1) { + dc = (DuffCode)glyphs.get(glyphs.size()-1); + if (!TibetanMachineWeb.isWyliePunc(TibetanMachineWeb.getWylieForGlyph(dc))) { + DuffCode dc_2 = (DuffCode)glyphs.removeLast(); + DuffCode dc_1 = (DuffCode)glyphs.removeLast(); + glyphs.addAll(getVowel(dc_1, dc_2, next)); + break vowel_block; + } + } + DuffCode[] dc_array = (DuffCode[])TibetanMachineWeb.getTibHash().get(TibetanMachineWeb.ACHEN); + dc = dc_array[TibetanMachineWeb.TMW]; + glyphs.addAll(getVowel(dc, next)); + } + + chars.clear(); + } + + isSanskrit = false; + } + + else if (TibetanMachineWeb.isWylieChar(next)) { + if (!isSanskrit) //add char to list - it is not sanskrit + chars.add(next); + + else if (wasLastSanskritStackingKey) { //add char to list - it is still part of sanskrit stack + chars.add(next); + wasLastSanskritStackingKey = false; + } + + else { //char is no longer part of sanskrit stack, therefore compute and add previous stack + glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); + chars.clear(); + chars.add(next); + isSanskrit = false; + wasLastSanskritStackingKey = false; + } + } + + else if (next.equals(String.valueOf(TibetanMachineWeb.WYLIE_DISAMBIGUATING_KEY))) { + if (!chars.isEmpty()) + glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); + + chars.clear(); + isSanskrit = false; + } + + else if (next.equals(String.valueOf(TibetanMachineWeb.WYLIE_SANSKRIT_STACKING_KEY))) { + if (!isSanskrit) { //begin sanskrit stack + switch (chars.size()) { + case 0: + break; //'+' is not "pre-stacking" key + + case 1: + isSanskrit = true; + wasLastSanskritStackingKey = true; + break; + + default: + String top_char = (String)chars.get(chars.size()-1); + chars.remove(chars.size()-1); + glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); + chars.clear(); + chars.add(top_char); + isSanskrit = true; + wasLastSanskritStackingKey = true; + break; + } + } + } + + else if (TibetanMachineWeb.isFormatting(next.charAt(0))) { + if (!chars.isEmpty()) + glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); + + dc = new DuffCode(1,next.charAt(0)); + glyphs.add(dc); + chars.clear(); + isSanskrit = false; + } + + if (next != null) + start += next.length(); + } + + if (!chars.isEmpty()) { + glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); + chars.clear(); + } + + DuffData[] dd = convertGlyphs(glyphs); + return dd; + } + +/** +* Gets the bindu sequence for a given context. +* In the TibetanMachineWeb fonts, bindu (anusvara) is realized +* differently depending on which vowel it attaches to. Although +* the default bindu glyph is affixed to consonants and subscript vowels, +* for superscript vowels (i, e, o, etc), there is a single glyph +* which merges the bindu and that vowel together. When you pass this +* method a glyph context, it will return a List of glyphs which +* will either consist of the original glyph followed by the default +* bindu glyph, or a composite vowel+bindu glyph. +* Note that there is only one glyph in the context. This means that +* bindus will not affix properly if superscript vowels are allowed to directly +* precede subscript vowels (e.g. pou). +* @param dc the DuffCode of the glyph you +* want to attach a bindu to +* @return a List of DuffCode glyphs that include the +* original dc, as well as a bindu +*/ + public static List getBindu(DuffCode dc) { + List bindus = new ArrayList(); + + if (null == dc) { + bindus.add(TibetanMachineWeb.getGlyph(String.valueOf(TibetanMachineWeb.BINDU))); + return bindus; + } + + if (!TibetanMachineWeb.getBinduMap().containsKey(dc)) { + bindus.add(dc); + bindus.add(TibetanMachineWeb.getGlyph(String.valueOf(TibetanMachineWeb.BINDU))); + return bindus; + } + + bindus.add((DuffCode)TibetanMachineWeb.getBinduMap().get(dc)); + return bindus; + } + +/** +* Gets the vowel sequence for a given vowel in a given context. +* Given a context, this method affixes a vowel and returns the +* context plus the vowel. Generally, it is enough to provide just +* one glyph for context. +* @param context the glyph preceding the vowel you want to affix +* @param vowel the vowel you want to affix, in Wylie +* @return a List of glyphs equal to the vowel in context +*/ + public static List getVowel(DuffCode context, String vowel) { + return getVowel(null, context, vowel); + } + +/** +* Gets the vowel sequence for a given vowel in a given context. +* Given a context, this method affixes a vowel and returns the context plus the vowel. +* Since the choice of vowel glyph depends on the consonant to which it is attached, +* generally it is enough to provide just the immediately preceding context. However, +* in some cases, double vowels are allowed - for example 'buo'. To find the correct +* glyph for 'o', we need 'b' in this case, not 'u'. Note also that some Extended +* Wylie vowels correspond to multiple glyphs in TibetanMachineWeb. For example, +* the vowel I consists of both an achung and a reverse gigu. All required glyphs +* are part of the returned List. +* @param context_1 the glyph occurring two glyphs before the vowel you want to affix +* @param context_2 the glyph immediately before the vowel you want to affix +* @param vowel the vowel you want to affix, in Wylie +* @return a List of glyphs equal to the vowel in context +*/ + + public static List getVowel(DuffCode context_1, DuffCode context_2, String vowel) { + List vowels = new ArrayList(); + +//this vowel doesn't correspond to a glyph - +//so you just return the original context + + if ( vowel.equals(TibetanMachineWeb.WYLIE_aVOWEL) || + TibetanMachineWeb.isTopVowel(context_2)) { + if (context_1 != null) + vowels.add(context_1); + + vowels.add(context_2); + return vowels; + } + +//first, the three easiest cases: ai, au, and 0 || !glyphList.isEmpty()) { + if (needsVowel) + wylieBuffer.append(withA(glyphList)); + else + wylieBuffer.append(withoutA(glyphList)); + + glyphList.clear(); + needsVowel = true; + isLastVowel = false; + } + + wylieBuffer.append(ch); + } + else { + wylie = TibetanMachineWeb.getWylieForGlyph(dcs[i]); + + boolean containsBindu = false; + if (wylie.length() > 1 && wylie.charAt(wylie.length()-1) == TibetanMachineWeb.BINDU) { + char[] cArray = wylie.toCharArray(); + wylie = new String(cArray, 0, wylie.length()-1); + containsBindu = true; + } + + process_block: { + if (TibetanMachineWeb.isWyliePunc(wylie)) { + isLastVowel = false; + + if (glyphList.isEmpty()) + wylieBuffer.append(wylie); + + else { + if (needsVowel) + wylieBuffer.append(withA(glyphList)); + else + wylieBuffer.append(withoutA(glyphList)); + + wylieBuffer.append(wylie); //append the punctuation + + glyphList.clear(); + } + needsVowel = true; //next consonants are syllable onset, so we are awaiting vowel + } + + //isChar must come before isVowel because ACHEN has priority over WYLIE_aVOWEL + else if (TibetanMachineWeb.isWylieChar(wylie)) { + isLastVowel = false; + glyphList.add(dcs[i]); + } + + else if (TibetanMachineWeb.isWylieVowel(wylie)) { + if (isLastVowel) { + int len = wylieBuffer.length(); + int A_len = TibetanMachineWeb.A_VOWEL.length(); + + if (wylieBuffer.substring(len-A_len).equals(TibetanMachineWeb.A_VOWEL)) { + try { + if (wylie.equals(TibetanMachineWeb.i_VOWEL)) { + wylieBuffer.delete(len-A_len, len); + wylieBuffer.append(TibetanMachineWeb.I_VOWEL); + isLastVowel = false; + break process_block; + } + else if (wylie.equals(TibetanMachineWeb.reverse_i_VOWEL)) { + wylieBuffer.delete(len-A_len, len); + wylieBuffer.append(TibetanMachineWeb.reverse_I_VOWEL); + isLastVowel = false; + break process_block; + } + } + catch (StringIndexOutOfBoundsException se) { + ThdlDebug.noteIffyCode(); + } + + wylieBuffer.append(wylie); //append current vowel + isLastVowel = false; + } + else + wylieBuffer.append(wylie); //append current vowel + } + else { + int glyphCount = glyphList.size(); + boolean insertDisAmbig = false; + + if (0 != glyphCount) { + DuffCode top_dc = (DuffCode)glyphList.get(glyphCount-1); + String top_wylie = TibetanMachineWeb.getWylieForGlyph(top_dc); + + if (top_wylie.equals(TibetanMachineWeb.ACHEN)) { + glyphList.remove(glyphCount-1); + + if (glyphCount-1 == 0) + top_dc = null; + else { + insertDisAmbig = true; + top_dc = (DuffCode)glyphList.get(glyphCount-2); + } + } + + if (top_dc == null || !TibetanMachineWeb.getWylieForGlyph(top_dc).equals(TibetanMachineWeb.ACHUNG)) + wylieBuffer.append(withoutA(glyphList)); //append consonants in glyphList + else { + glyphCount = glyphList.size(); + glyphList.remove(glyphCount-1); + + if (glyphCount-1 != 0) + wylieBuffer.append(withA(glyphList)); + + wylieBuffer.append(TibetanMachineWeb.ACHUNG); + } + } + + if (insertDisAmbig) + wylieBuffer.append(TibetanMachineWeb.WYLIE_DISAMBIGUATING_KEY); + + wylieBuffer.append(wylie); //append vowel + + glyphList.clear(); + isLastVowel = true; + needsVowel = false; + } + } + else { //must be a stack + isLastVowel = false; + glyphList.add(dcs[i]); + } + } + + if (containsBindu) { + isLastVowel = false; + wylieBuffer.append(withoutA(glyphList)); + wylieBuffer.append(TibetanMachineWeb.BINDU); //append the bindu + glyphList.clear(); + } + } + } + + //replace TMW with Wylie + + if (!glyphList.isEmpty()) { + if (needsVowel) + wylieBuffer.append(withA(glyphList)); + else + wylieBuffer.append(withoutA(glyphList)); + } + + if (wylieBuffer.length() > 0) + return wylieBuffer.toString(); + else + return null; + } +} diff --git a/source/org/thdl/tib/text/TibetanDocument.java b/source/org/thdl/tib/text/TibetanDocument.java index aaf1115..c7aee59 100644 --- a/source/org/thdl/tib/text/TibetanDocument.java +++ b/source/org/thdl/tib/text/TibetanDocument.java @@ -27,25 +27,22 @@ import java.io.*; import org.thdl.util.ThdlDebug; /** -* Provides methods for converting back and forth between -* Extended Wylie and TibetanMachineWeb, and for inserting Tibetan -* into a styled document. -*

-* The class provides a variety of static methods for -* converting back and forth between Extended Wylie and TibetanMachineWeb. -* The Wylie can be accessed as a String, while the TibetanMachineWeb -* can be exported as Rich Text Format. -*

-* When instantiated as an instance object, -* this class also provides methods for inserting Tibetan -* (as TibetanMachineWeb) into a styled document. +* A TibetanDocument is a styled document that knows about Tibetan and +* will respect line breaks and the like. It allows you to insert +* Tibetan also. * @author Edward Garrett, Tibetan and Himalayan Digital Library -* @version 1.0 -*/ +* @version 1.0 */ public class TibetanDocument extends DefaultStyledDocument { - private static List chars = new ArrayList(); private int tibetanFontSize = 36; + /** Do not use this contructor. */ + private TibetanDocument() { super(); } + + /** Do not use this contructor. */ + private TibetanDocument(AbstractDocument.Content c, StyleContext styles ) { + super(c, styles); + } + /** * Creates a TibetanDocument. * @param styles a StyleContext, which is simply passed on @@ -82,6 +79,7 @@ public class TibetanDocument extends DefaultStyledDocument { rtf.write(out, this, 0, getLength()); } catch (BadLocationException ble) { + ThdlDebug.noteIffyCode(); } } @@ -99,6 +97,7 @@ public class TibetanDocument extends DefaultStyledDocument { insertString(offset, s, attr); } catch (BadLocationException ble) { + ThdlDebug.noteIffyCode(); } } @@ -120,917 +119,6 @@ public class TibetanDocument extends DefaultStyledDocument { return pos; } -/** -* A wrapper object for a stretch of TibetanMachineWeb data that shares the same font. -* A piece of DuffData consists of a font number and a string. -* The font number is a number from one to ten, corresponding -* to the ten TibetanMachineWeb fonts, as follows: -*

-* 1 - TibetanMachineWeb
-* 2 - TibetanMachineWeb1
-* ...
-* 10 - TibetanMachineWeb9
-*

-* The string represents a contiguous stretch of data in that -* font, i.e. a stretch of TibetanMachineWeb that doesn't require a font change. -*/ - public static class DuffData { -/** -* a string of text -*/ - public String text; -/** -* the font number for this text -*/ - public int font; - -/** -* @param s a string of TibetanMachineWeb text -* @param i a TibetanMachineWeb font number -*/ - public DuffData(String s, int i) { - text = s; - font = i; - } - } - -/** -* Converts a list of glyphs into an array of {@link TibetanDocument.DuffData DuffData}. -* The motivation for this is that most processes - for example using -* TibetanMachineWeb in HTML - only need to know what -* text to output, and when to change fonts. In general, they don't -* need to have an explicit indication for each glyph of the font -* for that glyph. -* @param glyphs the list of TibetanMachineWeb glyphs -* you want to convert -* @return an array of DuffData corresponding to this -* list of glyphs -*/ - public static DuffData[] convertGlyphs(List glyphs) { - if (glyphs.size() == 0) - return null; - List data = new ArrayList(); - StringBuffer sb = new StringBuffer(); - Iterator iter = glyphs.iterator(); - DuffCode dc = (DuffCode)iter.next(); - int lastfont = dc.fontNum; - sb.append(dc.character); - - while (iter.hasNext()) { - dc = (DuffCode)iter.next(); - if (dc.fontNum == lastfont) - sb.append(dc.character); - else { - data.add(new DuffData(sb.toString(), lastfont)); - lastfont = dc.fontNum; - sb = new StringBuffer(); - sb.append(dc.character); - } - } - - data.add(new DuffData(sb.toString(), lastfont)); - - DuffData[] dd = new DuffData[0]; - dd = (DuffData[])data.toArray(dd); - return dd; - } - -/** -* Figures out how to arrange a list of characters into glyphs. For example, if the user types 'bsgr' -* using the Extended Wylie keyboard, this method figures out that this should be represented -* as a 'b' glyph followed by a 's-g-r' glyph. If you know that the characters do not -* contain Sanskrit stacks, or do not contain Tibetan stacks, then you can specify this -* to speed the process up. Otherwise, the method will first check to see if the characters -* correspond to any Tibetan stacks, and if not, then it will check for Sanskrit stacks. -* @param chars the list of Tibetan characters you want to find glyphs for -* @param areStacksOnRight whether stacking should try to maximize from right to left (true) -* or from left to right (false). In the Extended Wylie keyboard, you try to stack from -* right to left. Thus, the character sequence r-g-r would be stacked as r followed by gr, -* rather than rg followed by r. In the Sambhota and TCC keyboards, the stack direction -* is reversed. -* @param definitelyTibetan should be true if the characters are known to be Tibetan and -* not Sanskrit -* @param definitelySanskrit should be true if the characters are known to be Sanskrit and -* not Tibetan -*/ - public static List getGlyphs(List chars, boolean areStacksOnRight, boolean definitelyTibetan, boolean definitelySanskrit) { - StringBuffer tibBuffer, sanBuffer; - String tibCluster, sanCluster; - - boolean checkTibetan, checkSanskrit; - - if (!(definitelyTibetan || definitelySanskrit)) { - checkTibetan = true; - checkSanskrit = true; - } - else { - checkTibetan = definitelyTibetan; - checkSanskrit = definitelySanskrit; - } - - int length = chars.size(); - - List glyphs = new ArrayList(); - glyphs.clear(); - - if (areStacksOnRight) { - for (int i=0; i-1; i--) { - tibBuffer = new StringBuffer(); - tibCluster = null; - - sanBuffer = new StringBuffer(); - sanCluster = null; - - Iterator iter = chars.iterator(); - - for (int k=0; k 1) { - dc = (DuffCode)glyphs.get(glyphs.size()-1); - if (!TibetanMachineWeb.isWyliePunc(TibetanMachineWeb.getWylieForGlyph(dc))) { - DuffCode dc_2 = (DuffCode)glyphs.removeLast(); - DuffCode dc_1 = (DuffCode)glyphs.removeLast(); - glyphs.addAll(getVowel(dc_1, dc_2, next)); - break vowel_block; - } - } - DuffCode[] dc_array = (DuffCode[])TibetanMachineWeb.getTibHash().get(TibetanMachineWeb.ACHEN); - dc = dc_array[TibetanMachineWeb.TMW]; - glyphs.addAll(getVowel(dc, next)); - } - - chars.clear(); - } - - isSanskrit = false; - } - - else if (TibetanMachineWeb.isWylieChar(next)) { - if (!isSanskrit) //add char to list - it is not sanskrit - chars.add(next); - - else if (wasLastSanskritStackingKey) { //add char to list - it is still part of sanskrit stack - chars.add(next); - wasLastSanskritStackingKey = false; - } - - else { //char is no longer part of sanskrit stack, therefore compute and add previous stack - glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); - chars.clear(); - chars.add(next); - isSanskrit = false; - wasLastSanskritStackingKey = false; - } - } - - else if (next.equals(String.valueOf(TibetanMachineWeb.WYLIE_DISAMBIGUATING_KEY))) { - if (!chars.isEmpty()) - glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); - - chars.clear(); - isSanskrit = false; - } - - else if (next.equals(String.valueOf(TibetanMachineWeb.WYLIE_SANSKRIT_STACKING_KEY))) { - if (!isSanskrit) { //begin sanskrit stack - switch (chars.size()) { - case 0: - break; //'+' is not "pre-stacking" key - - case 1: - isSanskrit = true; - wasLastSanskritStackingKey = true; - break; - - default: - String top_char = (String)chars.get(chars.size()-1); - chars.remove(chars.size()-1); - glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); - chars.clear(); - chars.add(top_char); - isSanskrit = true; - wasLastSanskritStackingKey = true; - break; - } - } - } - - else if (TibetanMachineWeb.isFormatting(next.charAt(0))) { - if (!chars.isEmpty()) - glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); - - dc = new DuffCode(1,next.charAt(0)); - glyphs.add(dc); - chars.clear(); - isSanskrit = false; - } - - if (next != null) - start += next.length(); - } - - if (!chars.isEmpty()) { - glyphs.addAll(getGlyphs(chars, true, !isSanskrit, isSanskrit)); - chars.clear(); - } - - DuffData[] dd = convertGlyphs(glyphs); - return dd; - } - -/** -* Gets the bindu sequence for a given context. -* In the TibetanMachineWeb fonts, bindu (anusvara) is realized -* differently depending on which vowel it attaches to. Although -* the default bindu glyph is affixed to consonants and subscript vowels, -* for superscript vowels (i, e, o, etc), there is a single glyph -* which merges the bindu and that vowel together. When you pass this -* method a glyph context, it will return a List of glyphs which -* will either consist of the original glyph followed by the default -* bindu glyph, or a composite vowel+bindu glyph. -* Note that there is only one glyph in the context. This means that -* bindus will not affix properly if superscript vowels are allowed to directly -* precede subscript vowels (e.g. pou). -* @param dc the DuffCode of the glyph you -* want to attach a bindu to -* @return a List of DuffCode glyphs that include the -* original dc, as well as a bindu -*/ - public static List getBindu(DuffCode dc) { - List bindus = new ArrayList(); - - if (null == dc) { - bindus.add(TibetanMachineWeb.getGlyph(String.valueOf(TibetanMachineWeb.BINDU))); - return bindus; - } - - if (!TibetanMachineWeb.getBinduMap().containsKey(dc)) { - bindus.add(dc); - bindus.add(TibetanMachineWeb.getGlyph(String.valueOf(TibetanMachineWeb.BINDU))); - return bindus; - } - - bindus.add((DuffCode)TibetanMachineWeb.getBinduMap().get(dc)); - return bindus; - } - -/** -* Gets the vowel sequence for a given vowel in a given context. -* Given a context, this method affixes a vowel and returns the -* context plus the vowel. Generally, it is enough to provide just -* one glyph for context. -* @param context the glyph preceding the vowel you want to affix -* @param vowel the vowel you want to affix, in Wylie -* @return a List of glyphs equal to the vowel in context -*/ - public static List getVowel(DuffCode context, String vowel) { - return getVowel(null, context, vowel); - } - -/** -* Gets the vowel sequence for a given vowel in a given context. -* Given a context, this method affixes a vowel and returns the context plus the vowel. -* Since the choice of vowel glyph depends on the consonant to which it is attached, -* generally it is enough to provide just the immediately preceding context. However, -* in some cases, double vowels are allowed - for example 'buo'. To find the correct -* glyph for 'o', we need 'b' in this case, not 'u'. Note also that some Extended -* Wylie vowels correspond to multiple glyphs in TibetanMachineWeb. For example, -* the vowel I consists of both an achung and a reverse gigu. All required glyphs -* are part of the returned List. -* @param context_1 the glyph occurring two glyphs before the vowel you want to affix -* @param context_2 the glyph immediately before the vowel you want to affix -* @param vowel the vowel you want to affix, in Wylie -* @return a List of glyphs equal to the vowel in context -*/ - - public static List getVowel(DuffCode context_1, DuffCode context_2, String vowel) { - List vowels = new ArrayList(); - -//this vowel doesn't correspond to a glyph - -//so you just return the original context - - if ( vowel.equals(TibetanMachineWeb.WYLIE_aVOWEL) || - TibetanMachineWeb.isTopVowel(context_2)) { - if (context_1 != null) - vowels.add(context_1); - - vowels.add(context_2); - return vowels; - } - -//first, the three easiest cases: ai, au, and 0) { DuffCode[] dc_array = new DuffCode[0]; dc_array = (DuffCode[])dcs.toArray(dc_array); - wylieBuffer.append(TibetanDocument.getWylie(dc_array)); + wylieBuffer.append(TibTextUtils.getWylie(dc_array)); dcs.clear(); } wylieBuffer.append(ch); @@ -1089,7 +176,7 @@ public class TibetanDocument extends DefaultStyledDocument { if (dcs.size() > 0) { DuffCode[] dc_array = new DuffCode[0]; dc_array = (DuffCode[])dcs.toArray(dc_array); - wylieBuffer.append(TibetanDocument.getWylie(dc_array)); + wylieBuffer.append(TibTextUtils.getWylie(dc_array)); dcs.clear(); } } @@ -1104,7 +191,7 @@ public class TibetanDocument extends DefaultStyledDocument { if (dcs.size() > 0) { DuffCode[] dc_array = new DuffCode[0]; dc_array = (DuffCode[])dcs.toArray(dc_array); - wylieBuffer.append(TibetanDocument.getWylie(dc_array)); + wylieBuffer.append(TibTextUtils.getWylie(dc_array)); } return wylieBuffer.toString(); } @@ -1115,181 +202,4 @@ public class TibetanDocument extends DefaultStyledDocument { return ""; } - -/** -* Gets the Extended Wylie for a set of glyphs. -* @param dcs an array of glyphs -* @return the Extended Wylie corresponding to these glyphs -*/ - public static String getWylie(DuffCode[] dcs) { - if (dcs.length == 0) - return null; - - AttributeSet attr; - String fontName; - int fontNum; - char ch; - String wylie; - - List glyphList = new ArrayList(); - boolean needsVowel = true; - boolean isLastVowel = false; - int start = 0; - StringBuffer wylieBuffer = new StringBuffer(); - - for (int i=start; i 0 || !glyphList.isEmpty()) { - if (needsVowel) - wylieBuffer.append(withA(glyphList)); - else - wylieBuffer.append(withoutA(glyphList)); - - glyphList.clear(); - needsVowel = true; - isLastVowel = false; - } - - wylieBuffer.append(ch); - } - else { - wylie = TibetanMachineWeb.getWylieForGlyph(dcs[i]); - - boolean containsBindu = false; - if (wylie.length() > 1 && wylie.charAt(wylie.length()-1) == TibetanMachineWeb.BINDU) { - char[] cArray = wylie.toCharArray(); - wylie = new String(cArray, 0, wylie.length()-1); - containsBindu = true; - } - - process_block: { - if (TibetanMachineWeb.isWyliePunc(wylie)) { - isLastVowel = false; - - if (glyphList.isEmpty()) - wylieBuffer.append(wylie); - - else { - if (needsVowel) - wylieBuffer.append(withA(glyphList)); - else - wylieBuffer.append(withoutA(glyphList)); - - wylieBuffer.append(wylie); //append the punctuation - - glyphList.clear(); - } - needsVowel = true; //next consonants are syllable onset, so we are awaiting vowel - } - - //isChar must come before isVowel because ACHEN has priority over WYLIE_aVOWEL - else if (TibetanMachineWeb.isWylieChar(wylie)) { - isLastVowel = false; - glyphList.add(dcs[i]); - } - - else if (TibetanMachineWeb.isWylieVowel(wylie)) { - if (isLastVowel) { - int len = wylieBuffer.length(); - int A_len = TibetanMachineWeb.A_VOWEL.length(); - - if (wylieBuffer.substring(len-A_len).equals(TibetanMachineWeb.A_VOWEL)) { - try { - if (wylie.equals(TibetanMachineWeb.i_VOWEL)) { - wylieBuffer.delete(len-A_len, len); - wylieBuffer.append(TibetanMachineWeb.I_VOWEL); - isLastVowel = false; - break process_block; - } - else if (wylie.equals(TibetanMachineWeb.reverse_i_VOWEL)) { - wylieBuffer.delete(len-A_len, len); - wylieBuffer.append(TibetanMachineWeb.reverse_I_VOWEL); - isLastVowel = false; - break process_block; - } - } - catch (StringIndexOutOfBoundsException se) { - } - - wylieBuffer.append(wylie); //append current vowel - isLastVowel = false; - } - else - wylieBuffer.append(wylie); //append current vowel - } - else { - int glyphCount = glyphList.size(); - boolean insertDisAmbig = false; - - if (0 != glyphCount) { - DuffCode top_dc = (DuffCode)glyphList.get(glyphCount-1); - String top_wylie = TibetanMachineWeb.getWylieForGlyph(top_dc); - - if (top_wylie.equals(TibetanMachineWeb.ACHEN)) { - glyphList.remove(glyphCount-1); - - if (glyphCount-1 == 0) - top_dc = null; - else { - insertDisAmbig = true; - top_dc = (DuffCode)glyphList.get(glyphCount-2); - } - } - - if (top_dc == null || !TibetanMachineWeb.getWylieForGlyph(top_dc).equals(TibetanMachineWeb.ACHUNG)) - wylieBuffer.append(withoutA(glyphList)); //append consonants in glyphList - else { - glyphCount = glyphList.size(); - glyphList.remove(glyphCount-1); - - if (glyphCount-1 != 0) - wylieBuffer.append(withA(glyphList)); - - wylieBuffer.append(TibetanMachineWeb.ACHUNG); - } - } - - if (insertDisAmbig) - wylieBuffer.append(TibetanMachineWeb.WYLIE_DISAMBIGUATING_KEY); - - wylieBuffer.append(wylie); //append vowel - - glyphList.clear(); - isLastVowel = true; - needsVowel = false; - } - } - else { //must be a stack - isLastVowel = false; - glyphList.add(dcs[i]); - } - } - - if (containsBindu) { - isLastVowel = false; - wylieBuffer.append(withoutA(glyphList)); - wylieBuffer.append(TibetanMachineWeb.BINDU); //append the bindu - glyphList.clear(); - } - } - } - - //replace TMW with Wylie - - if (!glyphList.isEmpty()) { - if (needsVowel) - wylieBuffer.append(withA(glyphList)); - else - wylieBuffer.append(withoutA(glyphList)); - } - - if (wylieBuffer.length() > 0) - return wylieBuffer.toString(); - else - return null; - } } diff --git a/source/org/thdl/tib/text/TibetanHTML.java b/source/org/thdl/tib/text/TibetanHTML.java index 81b8ee0..a117d1e 100644 --- a/source/org/thdl/tib/text/TibetanHTML.java +++ b/source/org/thdl/tib/text/TibetanHTML.java @@ -1,144 +1,225 @@ -package org.thdl.tib.text; - -public class TibetanHTML { - static String[] styleNames = - {"tmw","tmw1","tmw2","tmw3","tmw4","tmw5","tmw6","tmw7","tmw8","tmw9"}; - - public static String getStyles(String fontSize) { - return ".tmw {font: "+fontSize+"pt TibetanMachineWeb}\n"+ - ".tmw1 {font: "+fontSize+"pt TibetanMachineWeb1}\n"+ - ".tmw2 {font: "+fontSize+"pt TibetanMachineWeb2}\n"+ - ".tmw3 {font: "+fontSize+"pt TibetanMachineWeb3}\n"+ - ".tmw4 {font: "+fontSize+"pt TibetanMachineWeb4}\n"+ - ".tmw5 {font: "+fontSize+"pt TibetanMachineWeb5}\n"+ - ".tmw6 {font: "+fontSize+"pt TibetanMachineWeb6}\n"+ - ".tmw7 {font: "+fontSize+"pt TibetanMachineWeb7}\n"+ - ".tmw8 {font: "+fontSize+"pt TibetanMachineWeb8}\n"+ - ".tmw9 {font: "+fontSize+"pt TibetanMachineWeb9}\n"; - } - - - public static String getHTML(String wylie) { - try { - return getHTML(TibetanDocument.getTibetanMachineWeb(wylie)); - } - catch (InvalidWylieException ive) { - return null; - } - } - - public static String getHTML(TibetanDocument.DuffData[] duffData) { - String[] styleNames = - {"tmw","tmw1","tmw2","tmw3","tmw4","tmw5","tmw6","tmw7","tmw8","tmw9"}; - - StringBuffer htmlBuffer = new StringBuffer(); - htmlBuffer.append(""); - - for (int i=0; i"); - - switch (c[k]) { - case '"': - htmlBuffer.append("""); - break; - case '<': - htmlBuffer.append("<"); - break; - case '>': - htmlBuffer.append(">"); - break; - case '&': - htmlBuffer.append("&"); - break; - default: - htmlBuffer.append(c[k]); - break; - } - - htmlBuffer.append(""); - if (c[k] < 32) //must be formatting, like carriage return or tab - htmlBuffer.append("
"); - - else { - String wylie = TibetanMachineWeb.getWylieForGlyph(duffData[i].font, c[k]); - if (TibetanMachineWeb.isWyliePunc(wylie)) - htmlBuffer.append(""); - } - } - } - - htmlBuffer.append("
"); - return htmlBuffer.toString(); - } -} - - - -//import org.apache.xerces.dom.DOMImplementationImpl; -//import org.w3c.dom.*; - -/* - public static Node getHTML(String wylie) { - try { - return getHTML(TibetanDocument.getTibetanMachineWeb(wylie)); - } - catch (InvalidWylieException ive) { - return null; - } - } - - public static Node getHTML(TibetanDocument.DuffData[] duffData) { - try { - DOMImplementationImpl impl = new DOMImplementationImpl(); - Document doc = impl.createDocument(null, "root", null); -// DocumentFragment frag = doc.createDocumentFragment() - - - Element nobr = doc.createElement("nobr"); -// frag.appendChild(nobr); - - for (int i=0; i"); + buffer.append(getHTML(TibTextUtils.getTibetanMachineWeb("_"))); + buffer.append(""); + } + else + buffer.append(getHTML(TibTextUtils.getTibetanMachineWeb(next))); + } + return buffer.toString(); + } catch (InvalidWylieException ive) { + return ""; + } + } + + public static String getHTMLX(DuffData[] duffData) { + String[] styleNames = + {"tmw","tmw1","tmw2","tmw3","tmw4","tmw5","tmw6","tmw7","tmw8","tmw9"}; + + StringBuffer htmlBuffer = new StringBuffer(); + htmlBuffer.append(""); + + for (int i=0; i"); + + if (c[k] > 32 && c[k] < 127) { //ie if it's not formatting + switch (c[k]) { + case '"': + htmlBuffer.append("""); + break; + case '<': + htmlBuffer.append("<"); + break; + case '>': + htmlBuffer.append(">"); + break; + case '&': + htmlBuffer.append("&"); + break; + default: + htmlBuffer.append(c[k]); + break; + } + htmlBuffer.append(""); + String wylie = TibetanMachineWeb.getWylieForGlyph(duffData[i].font, c[k]); + if (TibetanMachineWeb.isWyliePunc(wylie)) + htmlBuffer.append(""); + } else { + htmlBuffer.append("
"); + } + } + } + + htmlBuffer.append("
"); + return htmlBuffer.toString(); + } + + public static String getIndentedHTML(String wylie) { + return getHTML("_" + wylie); + } + + public static String getHTML(String wylie) { + try { + StringBuffer buffer = new StringBuffer(); + for (StringTokenizer tokenizer = new StringTokenizer(wylie, " \t\n", true); tokenizer.hasMoreElements();) { + String next = tokenizer.nextToken(); + if (next.equals("\t") || next.equals("\n")) { + buffer.append(""); + buffer.append(getHTML(TibTextUtils.getTibetanMachineWeb("_"))); + buffer.append(""); + } + else + buffer.append(getHTML(TibTextUtils.getTibetanMachineWeb(next))); + } + return buffer.toString(); + } catch (InvalidWylieException ive) { + return ""; + } + } + + public static String getHTML(DuffData[] duffData) { + String[] styleNames = + {"tmw","tmw1","tmw2","tmw3","tmw4","tmw5","tmw6","tmw7","tmw8","tmw9"}; + + StringBuffer htmlBuffer = new StringBuffer(); + htmlBuffer.append(""); + + for (int i=0; i"); + char[] c = duffData[i].text.toCharArray(); + for (int k=0; k 31 && c[k] < 127) { //ie if it's not formatting + switch (c[k]) { + case '"': + htmlBuffer.append("""); + break; + case '<': + htmlBuffer.append("<"); + break; + case '>': + htmlBuffer.append(">"); + break; + case '&': + htmlBuffer.append("&"); + break; + default: + htmlBuffer.append(c[k]); + break; + } + String wylie = TibetanMachineWeb.getWylieForGlyph(duffData[i].font, c[k]); + if (TibetanMachineWeb.isWyliePunc(wylie)) + htmlBuffer.append(""); + } else { + htmlBuffer.append("
"); + } + } + htmlBuffer.append(""); + } + + htmlBuffer.append("
"); + return htmlBuffer.toString(); + } + + public static String getHTMLforJava(String wylie) { + //differences: + // as of 1.4.1, anyway, browser built into java does not accept and
, + // only and
+ + try { + StringBuffer buffer = new StringBuffer(); + for (StringTokenizer tokenizer = new StringTokenizer(wylie, " \t\n", true); tokenizer.hasMoreElements();) { + String next = tokenizer.nextToken(); + if (next.equals("\t") || next.equals("\n")) { + buffer.append(""); + buffer.append(getHTML(TibTextUtils.getTibetanMachineWeb("_"))); + buffer.append(""); + } + else + buffer.append(getHTML(TibTextUtils.getTibetanMachineWeb(next))); + } + return buffer.toString(); + } catch (InvalidWylieException ive) { + return ""; + } + } + + public static String getHTMLforJava(DuffData[] duffData) { + String[] fontNames = { + "TibetanMachineWeb","TibetanMachineWeb1", "TibetanMachineWeb2", + "TibetanMachineWeb3","TibetanMachineWeb4","TibetanMachineWeb5", + "TibetanMachineWeb6","TibetanMachineWeb7","TibetanMachineWeb8", + "TibetanMachineWeb9"}; + + StringBuffer htmlBuffer = new StringBuffer(); + htmlBuffer.append(""); + + for (int i=0; i"); + char[] c = duffData[i].text.toCharArray(); + for (int k=0; k 31 && c[k] < 127) { //ie if it's not formatting + switch (c[k]) { + case '"': + htmlBuffer.append("""); + break; + case '<': + htmlBuffer.append("<"); + break; + case '>': + htmlBuffer.append(">"); + break; + case '&': + htmlBuffer.append("&"); + break; + default: + htmlBuffer.append(c[k]); + break; + } + String wylie = TibetanMachineWeb.getWylieForGlyph(duffData[i].font, c[k]); + if (TibetanMachineWeb.isWyliePunc(wylie)) + htmlBuffer.append(""); + } else { + htmlBuffer.append("
"); + } + } + htmlBuffer.append(""); + } + + htmlBuffer.append("
"); + return htmlBuffer.toString(); + } +} diff --git a/source/org/thdl/tib/text/TibetanQTText.java b/source/org/thdl/tib/text/TibetanQTText.java index 4c539f6..ad452f0 100644 --- a/source/org/thdl/tib/text/TibetanQTText.java +++ b/source/org/thdl/tib/text/TibetanQTText.java @@ -126,14 +126,14 @@ public class TibetanQTText { public static String getQTText(String wylie) { try { - return getQTText(TibetanDocument.getTibetanMachineWeb(wylie)); + return getQTText(TibTextUtils.getTibetanMachineWeb(wylie)); } catch (InvalidWylieException ive) { return null; } } - public static String getQTText(TibetanDocument.DuffData[] duffData) { + public static String getQTText(DuffData[] duffData) { StringBuffer qtBuffer = new StringBuffer(); qtBuffer.append("{size:" + tibFontSize + "}"); diff --git a/source/org/thdl/tib/text/TibetanQTText2.java b/source/org/thdl/tib/text/TibetanQTText2.java index f266648..e647489 100644 --- a/source/org/thdl/tib/text/TibetanQTText2.java +++ b/source/org/thdl/tib/text/TibetanQTText2.java @@ -126,14 +126,14 @@ public class TibetanQTText2 { public static String getQTText(String wylie) { try { - return getQTText(TibetanDocument.getTibetanMachineWeb(wylie)); + return getQTText(TibTextUtils.getTibetanMachineWeb(wylie)); } catch (InvalidWylieException ive) { return null; } } - public static String getQTText(TibetanDocument.DuffData[] duffData) { + public static String getQTText(DuffData[] duffData) { StringBuffer qtBuffer = new StringBuffer(); qtBuffer.append("{size:" + tibFontSize + "}"); diff --git a/source/org/thdl/util/ThdlDebug.java b/source/org/thdl/util/ThdlDebug.java index 177dcbf..6ff6706 100644 --- a/source/org/thdl/util/ThdlDebug.java +++ b/source/org/thdl/util/ThdlDebug.java @@ -119,6 +119,17 @@ public class ThdlDebug { System.exit(1); } + /** Exits the program the hard way. Don't ever call this for code + that you expect to be executed. */ + public static void abort(String message) { + System.err.println("THDL Internal Error. ABORTING."); + if (null != message) { + System.err.println(message); + System.err.println("THDL Internal Error. ABORTING."); + } + System.exit(37); + } + /** Sets it up so that a call to System.out or System.err prints * to standard output/error but ALSO prints to the log file named * (prefix + suffix). Be sure the log file name is a relative