f7e3fe62364360330ffdfd16041b88b2f5d3ac8c
[debian/jabref.git] / src / java / net / sf / jabref / Globals.java
1 /* (C) 2003 Nizar N. Batada, Morten O. Alver
2
3  All programs in this directory and
4  subdirectories are published under the GNU General Public License as
5  described below.
6
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or (at
10  your option) any later version.
11
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  USA
21
22  Further information about the GNU GPL is available at:
23  http://www.gnu.org/copyleft/gpl.ja.html
24
25  */
26 package net.sf.jabref;
27
28 import java.io.* ;
29 import java.nio.charset.Charset;
30 import java.util.* ;
31 import java.util.List;
32 import java.util.logging.* ;
33 import java.util.logging.Filter ;
34
35 import java.awt.* ;
36 import java.nio.charset.Charset;
37 import javax.swing.* ;
38
39 import net.sf.jabref.collab.* ;
40 import net.sf.jabref.imports.* ;
41 import net.sf.jabref.util.* ;
42 import net.sf.jabref.journals.JournalAbbreviations;
43
44 public class Globals {
45
46   public static int SHORTCUT_MASK,// = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
47       FUTURE_YEAR = 2050, // Needs to give a year definitely in the future. Used for guessing the
48                           // year field when parsing textual data.  :-)
49
50       STANDARD_EXPORT_COUNT = 5, // The number of standard export formats.
51       METADATA_LINE_LENGTH = 70; // The line length used to wrap metadata.
52
53   private static String resourcePrefix = "resource/JabRef",
54                         menuResourcePrefix = "resource/Menu",
55                         integrityResourcePrefix = "resource/IntegrityMessage";
56   private static final String buildInfos = "/resource/build.properties" ;
57   public static final String additionalFields = "/resource/fields/fields.xml" ;  // some extra field definitions
58   private static String logfile = "jabref.log";
59   public static ResourceBundle messages, menuTitles, intMessages ;
60   public static FileUpdateMonitor fileUpdateMonitor = new FileUpdateMonitor();
61     public static ImportFormatReader importFormatReader = new ImportFormatReader();
62
63   public static ErrorConsole errorConsole;
64
65    public static String VERSION,
66                        BUILD,
67                        BUILD_DATE ;
68
69   static
70   {
71     TBuildInfo bi = new TBuildInfo(buildInfos) ;
72     VERSION = bi.getBUILD_VERSION() ;
73     BUILD = bi.getBUILD_NUMBER() ;
74     BUILD_DATE = bi.getBUILD_DATE() ;
75
76       // TODO: Error console initialization here. When should it be used?
77       errorConsole = ErrorConsole.getInstance();
78   }
79
80
81
82   //public static ResourceBundle preferences = ResourceBundle.getBundle("resource/defaultPrefs");
83   public static Locale locale;
84   public static final String FILETYPE_PREFS_EXT = "_dir",
85       SELECTOR_META_PREFIX = "selector_",
86       LAYOUT_PREFIX = "/resource/layout/",
87       MAC = "Mac OS X",
88       DOI_LOOKUP_PREFIX = "http://dx.doi.org/",
89       NONE = "_non__",
90       FORMATTER_PACKAGE = "net.sf.jabref.export.layout.format.";
91   public static float duplicateThreshold = 0.75f;
92   private static Handler consoleHandler = new java.util.logging.ConsoleHandler();
93   public static String[] ENCODINGS,
94       ALL_ENCODINGS = //(String[]) Charset.availableCharsets().keySet().toArray(new String[]{});
95           new String[] {"ISO8859_1", "UTF8", "UTF-16", "ASCII",
96               "Cp1250", "Cp1251", "Cp1252", "Cp1253", "Cp1254", "Cp1257",
97               "JIS", "SJIS", "EUC-JP",      // Added Japanese encodings.
98               "Big5", "Big5_HKSCS", "GBK",
99               "ISO8859_2", "ISO8859_3", "ISO8859_4", "ISO8859_5", "ISO8859_6",
100               "ISO8859_7", "ISO8859_8", "ISO8859_9", "ISO8859_13", "ISO8859_15"};
101
102   // String array that maps from month number to month string label:
103   public static String[] MONTHS = new String[] {"jan", "feb", "mar", "apr", "may", "jun",
104           "jul", "aug", "sep", "oct", "nov", "dec"};
105
106   // Map that maps from month string labels to
107   public static Map MONTH_STRINGS = new HashMap();
108   static {
109       MONTH_STRINGS.put("jan", "January");
110       MONTH_STRINGS.put("feb", "February");
111       MONTH_STRINGS.put("mar", "March");
112       MONTH_STRINGS.put("apr", "April");
113       MONTH_STRINGS.put("may", "May");
114       MONTH_STRINGS.put("jun", "June");
115       MONTH_STRINGS.put("jul", "July");
116       MONTH_STRINGS.put("aug", "August");
117       MONTH_STRINGS.put("sep", "September");
118       MONTH_STRINGS.put("oct", "October");
119       MONTH_STRINGS.put("nov", "November");
120       MONTH_STRINGS.put("dec", "December");
121
122       // Build list of encodings, by filtering out all that are not supported
123       // on this system:
124       List encodings = new ArrayList();
125       for (int i=0; i<ALL_ENCODINGS.length; i++) {
126           if (Charset.isSupported(ALL_ENCODINGS[i]))
127             encodings.add(ALL_ENCODINGS[i]);
128       }
129       ENCODINGS = (String[])encodings.toArray(new String[0]);
130
131   }
132
133
134   public static GlobalFocusListener focusListener = new GlobalFocusListener();
135   public static JabRefPreferences prefs = null;
136  public static HelpDialog helpDiag = null;
137   public static String osName = System.getProperty("os.name", "def");
138   public static boolean ON_MAC = (osName.equals(MAC)),
139       ON_WIN = osName.startsWith("Windows");
140
141
142   public static String[] SKIP_WORDS = {"a", "an", "the", "for", "on"};
143     public static SidePaneManager sidePaneManager;
144   public static final String NEWLINE = System.getProperty("line.separator");
145     public static final boolean UNIX_NEWLINE = NEWLINE.equals("\n"); // true if we have unix newlines.
146
147     public static final String BIBTEX_STRING = "__string";
148     // "Fieldname" to indicate that a field should be treated as a bibtex string. Used when writing database to file.
149
150     public static void logger(String s) {
151     Logger.global.info(s);
152   }
153
154   public static void turnOffLogging() { // only log exceptions
155     Logger.global.setLevel(java.util.logging.Level.SEVERE);
156   }
157
158   // should be only called once
159   public static void turnOnConsoleLogging() {
160     Logger.global.addHandler(consoleHandler);
161
162   }
163
164
165
166   public static void turnOnFileLogging() {
167     Logger.global.setLevel(java.util.logging.Level.ALL);
168     java.util.logging.Handler handler;
169     handler = new ConsoleHandler();
170     /*try {
171       handler = new FileHandler(logfile); // this will overwrite
172     }
173     catch (IOException e) { //can't open log file so use console
174         e.printStackTrace();
175
176     } */
177     Logger.global.addHandler(handler);
178
179     handler.setFilter(new Filter() { // select what gets logged
180       public boolean isLoggable(LogRecord record) {
181         return true;
182       }
183     });
184   }
185
186   public static void setLanguage(String language, String country) {
187     locale = new Locale(language, country);
188     messages = ResourceBundle.getBundle(resourcePrefix, locale);
189     menuTitles = ResourceBundle.getBundle(menuResourcePrefix, locale);
190     intMessages = ResourceBundle.getBundle(integrityResourcePrefix, locale);
191     Locale.setDefault(locale);
192     javax.swing.JComponent.setDefaultLocale(locale);
193   }
194
195
196   public static JournalAbbreviations journalAbbrev;
197
198
199   public static String lang(String key, String[] params) {
200     String translation = null;
201     try {
202       if (Globals.messages != null) {
203         translation = Globals.messages.getString(key.replaceAll(" ", "_"));
204       }
205     }
206     catch (MissingResourceException ex) {
207       translation = key;
208       //logger("Warning: could not get translation for \""
209       //                   + key + "\"");
210     }
211     if ((translation != null) && (translation.length() != 0)) {
212       translation = translation.replaceAll("_", " ");
213       StringBuffer sb = new StringBuffer();
214       boolean b = false;
215       char c;
216       for (int i = 0; i < translation.length(); ++i) {
217           c = translation.charAt(i);
218           if (c == '%') {
219               b = true;
220           } else {
221               if (!b) {
222                   sb.append(c);
223               } else {
224                   b = false;
225                   try {
226                       int index = Integer.parseInt(String.valueOf(c));
227                       if (params != null && index >= 0 && index <= params.length)
228                           sb.append(params[index]);
229                   } catch (NumberFormatException e) {
230                       // append literally (for quoting) or insert special symbol
231                       switch (c) {
232                       case 'c': // colon
233                           sb.append(':');
234                           break;
235                       case 'e': // equal
236                           sb.append('=');
237                           break;
238                       default: // anything else, e.g. %
239                           sb.append(c);
240                       }
241                   }
242               }
243           }
244       }
245       return sb.toString();
246     }
247     return key;
248   }
249
250   public static String lang(String key) {
251       return lang(key, (String[])null);
252   }
253
254   public static String lang(String key, String s1) {
255       return lang(key, new String[]{s1});
256   }
257
258   public static String lang(String key, String s1, String s2) {
259       return lang(key, new String[]{s1, s2});
260   }
261
262   public static String lang(String key, String s1, String s2, String s3) {
263       return lang(key, new String[]{s1, s2, s3});
264   }
265
266   public static String menuTitle(String key) {
267     String translation = null;
268     try {
269       if (Globals.messages != null) {
270         translation = Globals.menuTitles.getString(key.replaceAll(" ", "_"));
271       }
272     }
273     catch (MissingResourceException ex) {
274       translation = key;
275
276       //System.err.println("Warning: could not get menu item translation for \""
277       //                   + key + "\"");
278
279     }
280     if ((translation != null) && (translation.length() != 0)) {
281       return translation.replaceAll("_", " ");
282     }
283     else {
284       return key;
285     }
286   }
287
288   public static String getIntegrityMessage(String key)
289   {
290     String translation = null;
291     try {
292       if (Globals.intMessages != null) {
293         translation = Globals.intMessages.getString(key);
294       }
295     }
296     catch (MissingResourceException ex) {
297       translation = key;
298
299 //      System.err.println("Warning: could not get menu item translation for \""
300 //                         + key + "\"");
301     }
302     if ((translation != null) && (translation.length() != 0)) {
303       return translation ;
304     }
305     else {
306       return key;
307     }
308   }
309
310
311   //============================================================
312   // Using the hashmap of entry types found in BibtexEntryType
313   //============================================================
314   public static BibtexEntryType getEntryType(String type) {
315     // decide which entryType object to return
316     Object o = BibtexEntryType.ALL_TYPES.get(type);
317     if (o != null) {
318       return (BibtexEntryType) o;
319     }
320     else {
321       return BibtexEntryType.OTHER;
322     }
323     /*
324       if(type.equals("article"))
325         return BibtexEntryType.ARTICLE;
326       else if(type.equals("book"))
327         return BibtexEntryType.BOOK;
328       else if(type.equals("inproceedings"))
329         return BibtexEntryType.INPROCEEDINGS;
330      */
331   }
332
333     /**
334      * This method provides the correct opening brace to use when writing a field
335      * to BibTeX format.
336      * @return A String containing the braces to use.
337      */
338     public static String getOpeningBrace() {
339         return "{";
340         /*
341             As of version 2.0, storing all fields with double braces is no longer supported, because
342             it causes problems with e.g. the author field.
343
344         if (prefs.getBoolean("autoDoubleBraces"))
345             return "{{";
346         else
347             return "{";
348         */
349     }
350
351     /**
352      * This method provides the correct closing brace to use when writing a field
353      * to BibTeX format.
354      * @return A String containing the braces to use.
355      */
356     public static String getClosingBrace() {
357         return "}";
358         /*
359             As of version 2.0, storing all fields with double braces is no longer supported, because
360             it causes problems with e.g. the author field.
361
362         if (prefs.getBoolean("autoDoubleBraces"))
363             return "}}";
364         else
365         */
366
367     }
368
369     /*    public static void setupKeyBindings(JabRefPreferences prefs) {
370     }*/
371
372   public static String getNewFile(JFrame owner, JabRefPreferences prefs,
373                                   File directory, String extension,
374                                   int dialogType,
375                                   boolean updateWorkingDirectory) {
376     return getNewFile(owner, prefs, directory, extension, null, dialogType,
377                       updateWorkingDirectory, false);
378   }
379
380
381   public static String getNewFile(JFrame owner, JabRefPreferences prefs,
382                                   File directory, String extension,
383                                   String description,
384                                   int dialogType,
385                                   boolean updateWorkingDirectory) {
386     return getNewFile(owner, prefs, directory, extension, description, dialogType,
387                       updateWorkingDirectory, false);
388   }
389
390
391   public static String getNewFile(JFrame owner, JabRefPreferences prefs,
392                                   File directory, String extension, OpenFileFilter off,
393                                   int dialogType,
394                                   boolean updateWorkingDirectory) {
395     return getNewFile(owner, prefs, directory, extension, null, off, dialogType,
396                       updateWorkingDirectory, false);
397   }
398
399   public static String getNewDir(JFrame owner, JabRefPreferences prefs,
400                                  File directory, String extension,
401                                  int dialogType, boolean updateWorkingDirectory) {
402     return getNewFile(owner, prefs, directory, extension, null, dialogType,
403                       updateWorkingDirectory, true);
404   }
405
406   public static String getNewDir(JFrame owner, JabRefPreferences prefs,
407                                  File directory, String extension,
408                                  String description,
409                                  int dialogType, boolean updateWorkingDirectory) {
410     return getNewFile(owner, prefs, directory, extension, description, dialogType,
411                       updateWorkingDirectory, true);
412   }
413
414   private static String getNewFile(JFrame owner, JabRefPreferences prefs,
415                                    File directory, String extension,
416                                    String description,
417                                    int dialogType,
418                                    boolean updateWorkingDirectory,
419                                    boolean dirOnly) {
420
421     OpenFileFilter off = null;
422
423     if (extension == null)
424       off = new OpenFileFilter();
425     else if (!extension.equals(NONE))
426       off = new OpenFileFilter(extension);
427
428     return getNewFile(owner, prefs, directory, extension, description, off, dialogType, updateWorkingDirectory, dirOnly);
429   }
430
431   private static String getNewFile(JFrame owner, JabRefPreferences prefs,
432                                    File directory, String extension,
433                                    String description,
434                                    OpenFileFilter off,
435                                    int dialogType,
436                                    boolean updateWorkingDirectory,
437                                    boolean dirOnly) {
438
439     if (ON_MAC) {
440       return getNewFileForMac(owner, directory, extension, dialogType,
441                               updateWorkingDirectory, dirOnly, off);
442     }
443
444     JFileChooser fc = null;
445     try {
446         fc = new JabRefFileChooser(directory);
447     } catch (InternalError errl) {
448         // This try/catch clause was added because a user reported an
449         // InternalError getting thrown on WinNT, presumably because of a
450         // bug in JGoodies Windows PLAF. This clause can be removed if the
451         // bug is fixed, but for now we just resort to the native file
452         // dialog, using the same method as is always used on Mac:
453         return getNewFileForMac(owner, directory, extension, dialogType,
454                                 updateWorkingDirectory, dirOnly, off);
455     }
456
457     if (dirOnly) {
458       fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
459
460     }
461     fc.addChoosableFileFilter(off);
462     fc.setDialogType(dialogType);
463     int dialogResult = JFileChooser.CANCEL_OPTION ;
464     if (dialogType == JFileChooser.OPEN_DIALOG) {
465       dialogResult = fc.showOpenDialog(owner);
466     }
467     else if (dialogType == JFileChooser.SAVE_DIALOG){
468       dialogResult = fc.showSaveDialog(owner);
469     }
470     else {
471       dialogResult = fc.showDialog(owner, description);
472     }
473
474      // the getSelectedFile method returns a valid fileselection
475      // (if something is selected) indepentently from dialog return status
476     if (dialogResult != JFileChooser.APPROVE_OPTION)
477       return null ;
478
479     // okay button
480     File selectedFile = fc.getSelectedFile();
481     if (selectedFile == null) { // cancel
482       return null;
483     }
484
485     // If this is a save dialog, and the user has not chosen "All files" as filter
486     // we enforce the given extension. But only if extension is not null.
487     if ((extension != null) && (dialogType == JFileChooser.SAVE_DIALOG) && (fc.getFileFilter() == off) &&
488         !off.accept(selectedFile)) {
489
490       // add the first extension if there are multiple extensions
491       selectedFile = new File(selectedFile.getPath() + extension.split("[, ]+",0)[0]);
492     }
493
494     if (updateWorkingDirectory) {
495       prefs.put("workingDirectory", selectedFile.getPath());
496     }
497     return selectedFile.getAbsolutePath();
498   }
499
500   private static String getNewFileForMac(JFrame owner,
501                                          File directory, String extensions,
502                                          int dialogType,
503                                          boolean updateWorkingDirectory,
504                                          boolean dirOnly,
505                                          FilenameFilter filter) {
506
507     FileDialog fc = new FileDialog(owner);
508     //fc.setFilenameFilter(filter);
509     if (directory != null) {
510       fc.setDirectory(directory.getParent());
511     }
512     if (dialogType == JFileChooser.OPEN_DIALOG) {
513       fc.setMode(FileDialog.LOAD);
514     }
515     else {
516       fc.setMode(FileDialog.SAVE);
517     }
518
519     fc.setVisible(true); // fc.show(); -> deprecated since 1.5
520
521     if (fc.getFile() != null) {
522       Globals.prefs.put("workingDirectory", fc.getDirectory() + fc.getFile());
523       return fc.getDirectory() + fc.getFile();
524     }
525     else {
526       return null;
527     }
528   }
529
530
531   public static String SPECIAL_COMMAND_CHARS = "\"`^~'c";
532   public static HashMap HTML_CHARS = new HashMap(),
533           HTMLCHARS = new HashMap(),
534       XML_CHARS = new HashMap(),
535       ASCII2XML_CHARS = new HashMap(),
536       UNICODE_CHARS = new HashMap(),
537       RTFCHARS = new HashMap(),
538         URL_CHARS = new HashMap();
539   static {
540
541       //System.out.println(journalAbbrev.getAbbreviatedName("Journal of Fish Biology", true));
542       //System.out.println(journalAbbrev.getAbbreviatedName("Journal of Fish Biology", false));
543       //System.out.println(journalAbbrev.getFullName("Aquaculture Eng."));
544       /*for (Iterator i=journalAbbrev.fullNameIterator(); i.hasNext();) {
545           String s = (String)i.next();
546           System.out.println(journalAbbrev.getFullName(s)+" : "+journalAbbrev.getAbbreviatedName(s, true));
547       } */
548
549     // Start the thread that monitors file time stamps.
550     //Util.pr("Starting FileUpdateMonitor thread. Globals line 293.");
551     fileUpdateMonitor.start();
552
553     try {
554       SHORTCUT_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
555     } catch (Throwable t) {
556
557     }
558
559       // Special characters in URLs need to be replaced to ensure that the URL
560       // opens properly on all platforms:
561       URL_CHARS.put("<", "%3c");
562       URL_CHARS.put(">", "%3e");
563       URL_CHARS.put("(", "%28");
564       URL_CHARS.put(")", "%29");
565       URL_CHARS.put(" ", "%20");
566       URL_CHARS.put("&", "%26");
567       URL_CHARS.put("$", "%24");
568
569
570
571     HTMLCHARS.put("\"a", "&auml;");
572     HTMLCHARS.put("\"A", "&Auml;");
573     HTMLCHARS.put("\"e", "&euml;");
574     HTMLCHARS.put("\"E", "&Euml;");
575     HTMLCHARS.put("\"i", "&iuml;");
576     HTMLCHARS.put("\"I", "&Iuml;");
577     HTMLCHARS.put("\"o", "&ouml;");
578     HTMLCHARS.put("\"O", "&Ouml;");
579     HTMLCHARS.put("\"u", "&uuml;");
580     HTMLCHARS.put("\"U", "&Uuml;");
581     HTMLCHARS.put("`a", "&agrave;");
582     HTMLCHARS.put("`A", "&Agrave;");
583     HTMLCHARS.put("`e", "&egrave;");
584     HTMLCHARS.put("`E", "&Egrave;");
585     HTMLCHARS.put("`i", "&igrave;");
586     HTMLCHARS.put("`I", "&Igrave;");
587     HTMLCHARS.put("`o", "&ograve;");
588     HTMLCHARS.put("`O", "&Ograve;");
589     HTMLCHARS.put("`u", "&ugrave;");
590     HTMLCHARS.put("`U", "&Ugrave;");
591     HTMLCHARS.put("'e", "&eacute;");
592     HTMLCHARS.put("'E", "&Eacute;");
593     HTMLCHARS.put("'i", "&iacute;");
594     HTMLCHARS.put("'I", "&Iacute;");
595     HTMLCHARS.put("'o", "&oacute;");
596     HTMLCHARS.put("'O", "&Oacute;");
597     HTMLCHARS.put("'u", "&uacute;");
598     HTMLCHARS.put("'U", "&Uacute;");
599     HTMLCHARS.put("'a", "&aacute;");
600     HTMLCHARS.put("'A", "&Aacute;");
601     HTMLCHARS.put("^a", "&ocirc;");
602     HTMLCHARS.put("^A", "&Ocirc;");
603     HTMLCHARS.put("^o", "&ocirc;");
604     HTMLCHARS.put("^O", "&Ocirc;");
605     HTMLCHARS.put("^u", "&ucirc;");
606     HTMLCHARS.put("^U", "&Ucirc;");
607     HTMLCHARS.put("^e", "&ecirc;");
608     HTMLCHARS.put("^E", "&Ecirc;");
609     HTMLCHARS.put("^i", "&icirc;");
610     HTMLCHARS.put("^I", "&Icirc;");
611     HTMLCHARS.put("~o", "&otilde;");
612     HTMLCHARS.put("~O", "&Otilde;");
613     HTMLCHARS.put("~n", "&ntilde;");
614     HTMLCHARS.put("~N", "&Ntilde;");
615     HTMLCHARS.put("~a", "&atilde;");
616     HTMLCHARS.put("~A", "&Atilde;");
617     HTMLCHARS.put("cc", "&ccedil;");
618     HTMLCHARS.put("cC", "&Ccedil;");
619
620     XML_CHARS.put("\\{\\\\\\\"\\{a\\}\\}", "&#x00E4;");
621     XML_CHARS.put("\\{\\\\\\\"\\{A\\}\\}", "&#x00C4;");
622     XML_CHARS.put("\\{\\\\\\\"\\{e\\}\\}", "&#x00EB;");
623     XML_CHARS.put("\\{\\\\\\\"\\{E\\}\\}", "&#x00CB;");
624     XML_CHARS.put("\\{\\\\\\\"\\{i\\}\\}", "&#x00EF;");
625     XML_CHARS.put("\\{\\\\\\\"\\{I\\}\\}", "&#x00CF;");
626     XML_CHARS.put("\\{\\\\\\\"\\{o\\}\\}", "&#x00F6;");
627     XML_CHARS.put("\\{\\\\\\\"\\{O\\}\\}", "&#x00D6;");
628     XML_CHARS.put("\\{\\\\\\\"\\{u\\}\\}", "&#x00FC;");
629     XML_CHARS.put("\\{\\\\\\\"\\{U\\}\\}", "&#x00DC;");
630
631     XML_CHARS.put("\\{\\\\\\`\\{e\\}\\}", "&#x00E8;");
632     XML_CHARS.put("\\{\\\\\\`\\{E\\}\\}", "&#x00C8;");
633     XML_CHARS.put("\\{\\\\\\`\\{i\\}\\}", "&#x00EC;");
634     XML_CHARS.put("\\{\\\\\\`\\{I\\}\\}", "&#x00CC;");
635     XML_CHARS.put("\\{\\\\\\`\\{o\\}\\}", "&#x00F2;");
636     XML_CHARS.put("\\{\\\\\\`\\{O\\}\\}", "&#x00D2;");
637     XML_CHARS.put("\\{\\\\\\`\\{u\\}\\}", "&#x00F9;");
638     XML_CHARS.put("\\{\\\\\\`\\{U\\}\\}", "&#x00D9;");
639     XML_CHARS.put("\\{\\\\\\'\\{e\\}\\}", "&#x00E9;");
640     XML_CHARS.put("\\{\\\\\\\uFFFD\\{E\\}\\}", "&#x00C9;");
641     XML_CHARS.put("\\{\\\\\\\uFFFD\\{i\\}\\}", "&#x00ED;");
642     XML_CHARS.put("\\{\\\\\\\uFFFD\\{I\\}\\}", "&#x00CD;");
643     XML_CHARS.put("\\{\\\\\\\uFFFD\\{o\\}\\}", "&#x00F3;");
644     XML_CHARS.put("\\{\\\\\\\uFFFD\\{O\\}\\}", "&#x00D3;");
645     XML_CHARS.put("\\{\\\\\\\uFFFD\\{u\\}\\}", "&#x00FA;");
646     XML_CHARS.put("\\{\\\\\\\uFFFD\\{U\\}\\}", "&#x00DA;");
647     XML_CHARS.put("\\{\\\\\\\uFFFD\\{a\\}\\}", "&#x00E1;");
648     XML_CHARS.put("\\{\\\\\\\uFFFD\\{A\\}\\}", "&#x00C1;");
649
650     XML_CHARS.put("\\{\\\\\\^\\{o\\}\\}", "&#x00F4;");
651     XML_CHARS.put("\\{\\\\\\^\\{O\\}\\}", "&#x00D4;");
652     XML_CHARS.put("\\{\\\\\\^\\{u\\}\\}", "&#x00F9;");
653     XML_CHARS.put("\\{\\\\\\^\\{U\\}\\}", "&#x00D9;");
654     XML_CHARS.put("\\{\\\\\\^\\{e\\}\\}", "&#x00EA;");
655     XML_CHARS.put("\\{\\\\\\^\\{E\\}\\}", "&#x00CA;");
656     XML_CHARS.put("\\{\\\\\\^\\{i\\}\\}", "&#x00EE;");
657     XML_CHARS.put("\\{\\\\\\^\\{I\\}\\}", "&#x00CE;");
658     XML_CHARS.put("\\{\\\\\\~\\{o\\}\\}", "&#x00F5;");
659     XML_CHARS.put("\\{\\\\\\~\\{O\\}\\}", "&#x00D5;");
660     XML_CHARS.put("\\{\\\\\\~\\{n\\}\\}", "&#x00F1;");
661     XML_CHARS.put("\\{\\\\\\~\\{N\\}\\}", "&#x00D1;");
662     XML_CHARS.put("\\{\\\\\\~\\{a\\}\\}", "&#x00E3;");
663     XML_CHARS.put("\\{\\\\\\~\\{A\\}\\}", "&#x00C3;");
664
665
666     XML_CHARS.put("\\{\\\\\\\"a\\}", "&#x00E4;");
667     XML_CHARS.put("\\{\\\\\\\"A\\}", "&#x00C4;");
668     XML_CHARS.put("\\{\\\\\\\"e\\}", "&#x00EB;");
669     XML_CHARS.put("\\{\\\\\\\"E\\}", "&#x00CB;");
670     XML_CHARS.put("\\{\\\\\\\"i\\}", "&#x00EF;");
671     XML_CHARS.put("\\{\\\\\\\"I\\}", "&#x00CF;");
672     XML_CHARS.put("\\{\\\\\\\"o\\}", "&#x00F6;");
673     XML_CHARS.put("\\{\\\\\\\"O\\}", "&#x00D6;");
674     XML_CHARS.put("\\{\\\\\\\"u\\}", "&#x00FC;");
675     XML_CHARS.put("\\{\\\\\\\"U\\}", "&#x00DC;");
676
677     XML_CHARS.put("\\{\\\\\\`e\\}", "&#x00E8;");
678     XML_CHARS.put("\\{\\\\\\`E\\}", "&#x00C8;");
679     XML_CHARS.put("\\{\\\\\\`i\\}", "&#x00EC;");
680     XML_CHARS.put("\\{\\\\\\`I\\}", "&#x00CC;");
681     XML_CHARS.put("\\{\\\\\\`o\\}", "&#x00F2;");
682     XML_CHARS.put("\\{\\\\\\`O\\}", "&#x00D2;");
683     XML_CHARS.put("\\{\\\\\\`u\\}", "&#x00F9;");
684     XML_CHARS.put("\\{\\\\\\`U\\}", "&#x00D9;");
685     XML_CHARS.put("\\{\\\\\\'e\\}", "&#x00E9;");
686     XML_CHARS.put("\\{\\\\\\'E\\}", "&#x00C9;");
687     XML_CHARS.put("\\{\\\\\\'i\\}", "&#x00ED;");
688     XML_CHARS.put("\\{\\\\\\'I\\}", "&#x00CD;");
689     XML_CHARS.put("\\{\\\\\\'o\\}", "&#x00F3;");
690     XML_CHARS.put("\\{\\\\\\'O\\}", "&#x00D3;");
691     XML_CHARS.put("\\{\\\\\\'u\\}", "&#x00FA;");
692     XML_CHARS.put("\\{\\\\\\'U\\}", "&#x00DA;");
693     XML_CHARS.put("\\{\\\\\\'a\\}", "&#x00E1;");
694     XML_CHARS.put("\\{\\\\\\'A\\}", "&#x00C1;");
695
696     XML_CHARS.put("\\{\\\\\\^a\\}", "&#x00F4;");
697     XML_CHARS.put("\\{\\\\\\^A\\}", "&#x00D4;");
698     XML_CHARS.put("\\{\\\\\\^o\\}", "&#x00F4;");
699     XML_CHARS.put("\\{\\\\\\^O\\}", "&#x00D4;");
700     XML_CHARS.put("\\{\\\\\\^u\\}", "&#x00F9;");
701     XML_CHARS.put("\\{\\\\\\^U\\}", "&#x00D9;");
702     XML_CHARS.put("\\{\\\\\\^e\\}", "&#x00EA;");
703     XML_CHARS.put("\\{\\\\\\^E\\}", "&#x00CA;");
704     XML_CHARS.put("\\{\\\\\\^i\\}", "&#x00EE;");
705     XML_CHARS.put("\\{\\\\\\^I\\}", "&#x00CE;");
706     XML_CHARS.put("\\{\\\\\\~o\\}", "&#x00F5;");
707     XML_CHARS.put("\\{\\\\\\~O\\}", "&#x00D5;");
708     XML_CHARS.put("\\{\\\\\\~n\\}", "&#x00F1;");
709     XML_CHARS.put("\\{\\\\\\~N\\}", "&#x00D1;");
710     XML_CHARS.put("\\{\\\\\\~a\\}", "&#x00E3;");
711     XML_CHARS.put("\\{\\\\\\~A\\}", "&#x00C3;");
712
713     ASCII2XML_CHARS.put("<", "&lt;");
714     ASCII2XML_CHARS.put("\"", "&quot;");
715     ASCII2XML_CHARS.put(">", "&gt;");
716
717
718     UNICODE_CHARS.put("\u00C0", "A");
719     UNICODE_CHARS.put("\u00C1", "A");
720     UNICODE_CHARS.put("\u00C2", "A");
721     UNICODE_CHARS.put("\u00C3", "A");
722     UNICODE_CHARS.put("\u00C4", "A");
723     UNICODE_CHARS.put("\u00C5", "Aa");
724     UNICODE_CHARS.put("\u00C6", "Ae");
725     UNICODE_CHARS.put("\u00C7", "C");
726     UNICODE_CHARS.put("\u00C8", "E");
727     UNICODE_CHARS.put("\u00C9", "E");
728     UNICODE_CHARS.put("\u00CA", "E");
729     UNICODE_CHARS.put("\u00CB", "E");
730     UNICODE_CHARS.put("\u00CC", "I");
731     UNICODE_CHARS.put("\u00CD", "I");
732     UNICODE_CHARS.put("\u00CE", "I");
733     UNICODE_CHARS.put("\u00CF", "I");
734     UNICODE_CHARS.put("\u00D0", "D");
735     UNICODE_CHARS.put("\u00D1", "N");
736     UNICODE_CHARS.put("\u00D2", "O");
737     UNICODE_CHARS.put("\u00D3", "O");
738     UNICODE_CHARS.put("\u00D4", "O");
739     UNICODE_CHARS.put("\u00D5", "O");
740     UNICODE_CHARS.put("\u00D6", "Oe");
741     UNICODE_CHARS.put("\u00D8", "Oe");
742     UNICODE_CHARS.put("\u00D9", "U");
743     UNICODE_CHARS.put("\u00DA", "U");
744     UNICODE_CHARS.put("\u00DB", "U");
745     UNICODE_CHARS.put("\u00DC", "Ue"); // U umlaut ..
746     UNICODE_CHARS.put("\u00DD", "Y");
747     UNICODE_CHARS.put("\u00DF", "ss");
748     UNICODE_CHARS.put("\u00E0", "a");
749     UNICODE_CHARS.put("\u00E1", "a");
750     UNICODE_CHARS.put("\u00E2", "a");
751     UNICODE_CHARS.put("\u00E3", "a");
752     UNICODE_CHARS.put("\u00E4", "ae");
753     UNICODE_CHARS.put("\u00E5", "aa");
754     UNICODE_CHARS.put("\u00E6", "ae");
755     UNICODE_CHARS.put("\u00E7", "c");
756     UNICODE_CHARS.put("\u00E8", "e");
757     UNICODE_CHARS.put("\u00E9", "e");
758     UNICODE_CHARS.put("\u00EA", "e");
759     UNICODE_CHARS.put("\u00EB", "e");
760     UNICODE_CHARS.put("\u00EC", "i");
761     UNICODE_CHARS.put("\u00ED", "i");
762     UNICODE_CHARS.put("\u00EE", "i");
763     UNICODE_CHARS.put("\u00EF", "i");
764     UNICODE_CHARS.put("\u00F0", "o");
765     UNICODE_CHARS.put("\u00F1", "n");
766     UNICODE_CHARS.put("\u00F2", "o");
767     UNICODE_CHARS.put("\u00F3", "o");
768     UNICODE_CHARS.put("\u00F4", "o");
769     UNICODE_CHARS.put("\u00F5", "o");
770     UNICODE_CHARS.put("\u00F6", "oe");
771     UNICODE_CHARS.put("\u00F8", "oe");
772     UNICODE_CHARS.put("\u00F9", "u");
773     UNICODE_CHARS.put("\u00FA", "u");
774     UNICODE_CHARS.put("\u00FB", "u");
775     UNICODE_CHARS.put("\u00FC", "ue"); // u umlaut...
776     UNICODE_CHARS.put("\u00FD", "y");
777     UNICODE_CHARS.put("\u00FF", "y");
778     UNICODE_CHARS.put("\u0100", "A");
779     UNICODE_CHARS.put("\u0101", "a");
780     UNICODE_CHARS.put("\u0102", "A");
781     UNICODE_CHARS.put("\u0103", "a");
782     UNICODE_CHARS.put("\u0104", "A");
783     UNICODE_CHARS.put("\u0105", "a");
784     UNICODE_CHARS.put("\u0106", "C");
785     UNICODE_CHARS.put("\u0107", "c");
786     UNICODE_CHARS.put("\u0108", "C");
787     UNICODE_CHARS.put("\u0109", "c");
788     UNICODE_CHARS.put("\u010A", "C");
789     UNICODE_CHARS.put("\u010B", "c");
790     UNICODE_CHARS.put("\u010C", "C");
791     UNICODE_CHARS.put("\u010D", "c");
792     UNICODE_CHARS.put("\u010E", "D");
793     UNICODE_CHARS.put("\u010F", "d");
794     UNICODE_CHARS.put("\u0110", "D");
795     UNICODE_CHARS.put("\u0111", "d");
796     UNICODE_CHARS.put("\u0112", "E");
797     UNICODE_CHARS.put("\u0113", "e");
798     UNICODE_CHARS.put("\u0114", "E");
799     UNICODE_CHARS.put("\u0115", "e");
800     UNICODE_CHARS.put("\u0116", "E");
801     UNICODE_CHARS.put("\u0117", "e");
802     UNICODE_CHARS.put("\u0118", "E");
803     UNICODE_CHARS.put("\u0119", "e");
804     UNICODE_CHARS.put("\u011A", "E");
805     UNICODE_CHARS.put("\u011B", "e");
806     UNICODE_CHARS.put("\u011C", "G");
807     UNICODE_CHARS.put("\u011D", "g");
808     UNICODE_CHARS.put("\u011E", "G");
809     UNICODE_CHARS.put("\u011F", "g");
810     UNICODE_CHARS.put("\u0120", "G");
811     UNICODE_CHARS.put("\u0121", "g");
812     UNICODE_CHARS.put("\u0122", "G");
813     UNICODE_CHARS.put("\u0123", "g");
814     UNICODE_CHARS.put("\u0124", "H");
815     UNICODE_CHARS.put("\u0125", "h");
816     UNICODE_CHARS.put("\u0127", "h");
817     UNICODE_CHARS.put("\u0128", "I");
818     UNICODE_CHARS.put("\u0129", "i");
819     UNICODE_CHARS.put("\u012A", "I");
820     UNICODE_CHARS.put("\u012B", "i");
821     UNICODE_CHARS.put("\u012C", "I");
822     UNICODE_CHARS.put("\u012D", "i");
823     //UNICODE_CHARS.put("\u0100", "");
824
825     RTFCHARS.put("`a", "\\'e0");
826     RTFCHARS.put("`e", "\\'e8");
827     RTFCHARS.put("`i", "\\'ec");
828     RTFCHARS.put("`o", "\\'f2");
829     RTFCHARS.put("`u", "\\'f9");
830     RTFCHARS.put("?a", "\\'e1");
831     RTFCHARS.put("?e", "\\'e9");
832     RTFCHARS.put("?i", "\\'ed");
833     RTFCHARS.put("?o", "\\'f3");
834     RTFCHARS.put("?u", "\\'fa");
835     RTFCHARS.put("^a", "\\'e2");
836     RTFCHARS.put("^e", "\\'ea");
837     RTFCHARS.put("^i", "\\'ee");
838     RTFCHARS.put("^o", "\\'f4");
839     RTFCHARS.put("^u", "\\'fa");
840     RTFCHARS.put("\"a", "\\'e4");
841     RTFCHARS.put("\"e", "\\'eb");
842     RTFCHARS.put("\"i", "\\'ef");
843     RTFCHARS.put("\"o", "\\'f6");
844     RTFCHARS.put("\"u", "\\'fc");
845     RTFCHARS.put("~n", "\\'f1");
846     RTFCHARS.put("`A", "\\'c0");
847     RTFCHARS.put("`E", "\\'c8");
848     RTFCHARS.put("`I", "\\'cc");
849     RTFCHARS.put("`O", "\\'d2");
850     RTFCHARS.put("`U", "\\'d9");
851     RTFCHARS.put("?A", "\\'c1");
852     RTFCHARS.put("?E", "\\'c9");
853     RTFCHARS.put("?I", "\\'cd");
854     RTFCHARS.put("?O", "\\'d3");
855     RTFCHARS.put("?U", "\\'da");
856     RTFCHARS.put("^A", "\\'c2");
857     RTFCHARS.put("^E", "\\'ca");
858     RTFCHARS.put("^I", "\\'ce");
859     RTFCHARS.put("^O", "\\'d4");
860     RTFCHARS.put("^U", "\\'db");
861     RTFCHARS.put("\"A", "\\'c4");
862     RTFCHARS.put("\"E", "\\'cb");
863     RTFCHARS.put("\"I", "\\'cf");
864     RTFCHARS.put("\"O", "\\'d6");
865     RTFCHARS.put("\"U", "\\'dc");
866
867     //XML_CHARS.put("\\u00E1", "&#x00E1;");
868   }
869
870     public static void initializeJournalNames() {
871         journalAbbrev = new JournalAbbreviations();//"/resource/journalList.txt");
872
873         // Read external lists, if any (in reverse order, so the upper lists override the lower):
874         String[] lists = prefs.getStringArray("externalJournalLists");
875         if ((lists != null) && (lists.length > 0)) {
876             for (int i=lists.length-1; i>=0; i--) {
877                 try {
878                     journalAbbrev.readJournalList(new File(lists[i]));
879                 } catch (FileNotFoundException e) {
880                     // The file couldn't be found... should we tell anyone?
881                     Globals.logger(e.getMessage());
882                 }
883             }
884         }
885
886         // Read personal list, if set up:
887         if (prefs.get("personalJournalList") != null) {
888             try {
889                 journalAbbrev.readJournalList(new File(prefs.get("personalJournalList")));
890             } catch (FileNotFoundException e) {
891                 Globals.logger("Personal journal list file '"+prefs.get("personalJournalList")+
892                     "' not found.");
893             }
894         }
895
896
897     }
898
899 }