add back files to git repo that got lost somwhere in the conversion ?!
authorgregor herrmann <gregoa@debian.org>
Sat, 31 Mar 2012 02:56:10 +0000 (04:56 +0200)
committergregor herrmann <gregoa@debian.org>
Sat, 31 Mar 2012 02:56:10 +0000 (04:56 +0200)
Git-Dch: Ignore

16 files changed:
LICENSE [new file with mode: 0644]
debian/repack.local [new file with mode: 0644]
debian/repack.stub [new file with mode: 0644]
debian/watch [new file with mode: 0644]
images/connect_no.png [new file with mode: 0755]
net/sf/jabref/export/layout/format/FormatChars.java [new file with mode: 0755]
net/sf/jabref/oo/AlphanumericComparator.java [new file with mode: 0755]
net/sf/jabref/oo/AutoDetectPaths.java [new file with mode: 0755]
net/sf/jabref/oo/BibtexEntryNotFoundException.java [new file with mode: 0755]
net/sf/jabref/oo/BstWrapper.java [new file with mode: 0755]
net/sf/jabref/oo/ComparableMark.java [new file with mode: 0644]
net/sf/jabref/oo/ConnectionLostException.java [new file with mode: 0644]
net/sf/jabref/oo/OOPreFormatter.java [new file with mode: 0755]
net/sf/jabref/oo/UndefinedBibtexEntry.java [new file with mode: 0644]
net/sf/jabref/oo/UndefinedParagraphFormatException.java [new file with mode: 0644]
net/sf/jabref/oo/YearComparator.java [new file with mode: 0755]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d2cc198
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,14 @@
+Copyright 2008-2010, Morten Omholt Alver <mortenalver@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
diff --git a/debian/repack.local b/debian/repack.local
new file mode 100644 (file)
index 0000000..02f8123
--- /dev/null
@@ -0,0 +1,2 @@
+SUFFIX=+ds
+rm lib
diff --git a/debian/repack.stub b/debian/repack.stub
new file mode 100644 (file)
index 0000000..ac56520
--- /dev/null
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+: <<=cut
+=pod
+
+=head1 NAME
+
+repack.stub - script to repack upstream tarballs from uscan
+
+=head1 INSTRUCTIONS
+
+put this in debian/repack.stub and add "debian sh debian/repack.stub" to
+the end of the line in debian/watch. you will also need to add a version
+mangle to debian/watch.
+
+then create a debian/repack.local. this is a shell script that is
+sources under "set -e", so be careful to check returns codes.
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item rm
+
+rm is replaced by a function that does some magic ("rm -rv" by default), but also changes MANIFEST if $MANIFEST is 1
+
+=item mv
+
+mv is replaced by a function that just does mv (by default), but also changes MANIFEST if $MANIFEST is 1
+
+=item requires_version
+
+requires_version is there for future usage for requiring certain versions of the script
+
+=back
+
+=head1 VARIABLES
+
+=over 4
+
+=item SUFFIX
+
+defaults to +dfsg
+
+what to append to the upstream version
+
+=item RM_OPTS
+
+defaults to -vrf
+
+options to pass to rm
+
+=item MANIFEST
+
+defaults to 0, set to 1 to turn on.
+
+this will manipulate MANIFEST files in CPAN tarballs.
+
+=item UP_BASE
+
+this is the directory where the upstream source is.
+
+=back
+
+=cut
+
+if [ -z "$REPACK_SH" ]; then
+    if [ -f ../../scripts/repack.sh ]; then
+        REPACK_SH=../../scripts/repack.sh
+    fi
+    if [ -z "$REPACK_SH" ] && which repack.sh > /dev/null; then
+        REPACK_SH=$(which repack.sh)
+    fi
+fi
+
+if [ ! -f "$REPACK_SH" ]; then
+    echo "Couldn't find a repack.sh. please put it in your PATH, put it at ../../scripts/repack.sh, or put it somewhere else and set the REPACK_SH variable"
+    echo "You can get it from http://svn.debian.org/viewsvn/pkg-perl/scripts/repack.sh"
+    exit 1
+fi
+
+exec "$REPACK_SH" "$@"
diff --git a/debian/watch b/debian/watch
new file mode 100644 (file)
index 0000000..9bc526c
--- /dev/null
@@ -0,0 +1,4 @@
+version=3
+opts=dversionmangle=s/\+ds// \
+       http://jabref.sourceforge.net/OOPlugin-jabref.php plugins/JabRef-oo-([\d.]+)-src.zip$ \
+       debian sh debian/repack.stub
diff --git a/images/connect_no.png b/images/connect_no.png
new file mode 100755 (executable)
index 0000000..3e9f7cf
Binary files /dev/null and b/images/connect_no.png differ
diff --git a/net/sf/jabref/export/layout/format/FormatChars.java b/net/sf/jabref/export/layout/format/FormatChars.java
new file mode 100755 (executable)
index 0000000..506fe60
--- /dev/null
@@ -0,0 +1,433 @@
+package net.sf.jabref.export.layout.format;
+
+import net.sf.jabref.Globals;
+import net.sf.jabref.export.layout.LayoutFormatter;
+
+import java.util.HashMap;
+
+/**
+ * This formatter escapes characters so they are suitable for HTML.
+ * 
+ * @version $Revision: 2488 $ ($Date: 2007-11-14 01:25:31 +0100 (Wed, 14 Nov 2007) $)
+ */
+public class FormatChars implements LayoutFormatter {
+
+    public static HashMap<String, String> CHARS = new HashMap<String, String>();
+
+    static {
+        // Following character definitions contributed by Ervin Kolenovic:
+               // HTML named entities from #192 - #255 (UNICODE Latin-1)
+               CHARS.put("`A", "À"); // #192
+               CHARS.put("'A", "Á"); // #193
+               CHARS.put("^A", "Â"); // #194
+               CHARS.put("~A", "Ã"); // #195
+               CHARS.put("\"A", "Ä"); // #196
+               CHARS.put("AA", "Å"); // #197
+               CHARS.put("AE", "Æ"); // #198
+               CHARS.put("cC", "Ç"); // #199
+        CHARS.put("`E", "È"); // #200
+               CHARS.put("'E", "É"); // #201
+               CHARS.put("^E", "Ê"); // #202
+               CHARS.put("\"E", "Ë"); // #203
+               CHARS.put("`I", "Ì"); // #204
+               CHARS.put("'I", "Í"); // #205
+               CHARS.put("^I", "Î"); // #206
+               CHARS.put("\"I", "Ï"); // #207
+               CHARS.put("DH", "Ð"); // #208
+               CHARS.put("~N", "Ñ"); // #209
+               CHARS.put("`O", "Ò"); // #210
+               CHARS.put("'O", "Ó"); // #211
+               CHARS.put("^O", "Ô"); // #212
+               CHARS.put("~O", "Õ"); // #213
+               CHARS.put("\"O", "Ö"); // #214
+               // According to ISO 8859-1 the "\times" symbol should be placed here
+               // (#215).
+               // Omitting this, because it is a mathematical symbol.
+               CHARS.put("O", "Ø"); // #216
+               CHARS.put("`U", "Ù"); // #217
+               CHARS.put("'U", "Ú"); // #218
+               CHARS.put("^U", "Û"); // #219
+               CHARS.put("\"U", "Ü"); // #220
+               CHARS.put("'Y", "Ý"); // #221
+               CHARS.put("TH", "Þ"); // #222
+               CHARS.put("ss", "ß"); // #223
+               CHARS.put("`a", "à"); // #224
+               CHARS.put("'a", "á"); // #225
+               CHARS.put("^a", "â"); // #226
+               CHARS.put("~a", "ã"); // #227
+               CHARS.put("\"a", "ä"); // #228
+               CHARS.put("aa", "å"); // #229
+               CHARS.put("ae", "æ"); // #230
+               CHARS.put("cc", "ç"); // #231
+               CHARS.put("`e", "è"); // #232
+               CHARS.put("'e", "é"); // #233
+               CHARS.put("^e", "ê"); // #234
+               CHARS.put("\"e", "ë"); // #235
+               CHARS.put("`i", "ì"); // #236
+               CHARS.put("'i", "í"); // #237
+               CHARS.put("^i", "î"); // #238
+               CHARS.put("\"i", "ï"); // #239
+               CHARS.put("dh", "ð"); // #240
+               CHARS.put("~n", "ñ"); // #241
+               CHARS.put("`o", "ò"); // #242
+               CHARS.put("'o", "ó"); // #243
+               CHARS.put("^o", "ô"); // #244
+               CHARS.put("~o", "õ"); // #245
+               CHARS.put("\"o", "ö"); // #246
+               // According to ISO 8859-1 the "\div" symbol should be placed here
+               // (#247).
+               // Omitting this, because it is a mathematical symbol.
+               CHARS.put("o", "ø"); // #248
+               CHARS.put("`u", "ù"); // #249
+               CHARS.put("'u", "ú"); // #250
+               CHARS.put("^u", "û"); // #251
+               CHARS.put("\"u", "ü"); // #252
+               CHARS.put("'y", "ý"); // #253
+               CHARS.put("th", "þ"); // #254
+               CHARS.put("\"y", "ÿ"); // #255
+
+               // HTML special characters without names (UNICODE Latin Extended-A),
+               // indicated by UNICODE number
+               CHARS.put("=A", "Ā"); // "Amacr"
+               CHARS.put("=a", "ā"); // "amacr"
+               CHARS.put("uA", "Ă"); // "Abreve"
+               CHARS.put("ua", "ă"); // "abreve"
+               CHARS.put("kA", "Ą"); // "Aogon"
+               CHARS.put("ka", "ą"); // "aogon"
+               CHARS.put("'C", "Ć"); // "Cacute"
+               CHARS.put("'c", "ć"); // "cacute"
+               CHARS.put("^C", "Ĉ"); // "Ccirc"
+               CHARS.put("^c", "ĉ"); // "ccirc"
+               CHARS.put(".C", "Ċ"); // "Cdot"
+               CHARS.put(".c", "ċ"); // "cdot"
+               CHARS.put("vC", "Č"); // "Ccaron"
+               CHARS.put("vc", "č"); // "ccaron"
+               CHARS.put("vD", "Ď"); // "Dcaron"
+               // Symbol #271 (d�) has no special Latex command
+               CHARS.put("DJ", "Đ"); // "Dstrok"
+               CHARS.put("dj", "đ"); // "dstrok"
+               CHARS.put("=E", "Ē"); // "Emacr"
+               CHARS.put("=e", "ē"); // "emacr"
+               CHARS.put("uE", "Ĕ"); // "Ebreve"
+               CHARS.put("ue", "ĕ"); // "ebreve"
+               CHARS.put(".E", "Ė"); // "Edot"
+               CHARS.put(".e", "ė"); // "edot"
+               CHARS.put("kE", "Ę"); // "Eogon"
+               CHARS.put("ke", "ę"); // "eogon"
+               CHARS.put("vE", "Ě"); // "Ecaron"
+               CHARS.put("ve", "ě"); // "ecaron"
+               CHARS.put("^G", "Ĝ"); // "Gcirc"
+               CHARS.put("^g", "ĝ"); // "gcirc"
+               CHARS.put("uG", "Ğ"); // "Gbreve"
+               CHARS.put("ug", "ğ"); // "gbreve"
+               CHARS.put(".G", "Ġ"); // "Gdot"
+               CHARS.put(".g", "ġ"); // "gdot"
+               CHARS.put("cG", "Ģ"); // "Gcedil"
+               CHARS.put("'g", "ģ"); // "gacute"
+               CHARS.put("^H", "Ĥ"); // "Hcirc"
+               CHARS.put("^h", "ĥ"); // "hcirc"
+               CHARS.put("Hstrok", "Ħ"); // "Hstrok"
+               CHARS.put("hstrok", "ħ"); // "hstrok"
+               CHARS.put("~I", "Ĩ"); // "Itilde"
+               CHARS.put("~i", "ĩ"); // "itilde"
+               CHARS.put("=I", "Ī"); // "Imacr"
+               CHARS.put("=i", "ī"); // "imacr"
+               CHARS.put("uI", "Ĭ"); // "Ibreve"
+               CHARS.put("ui", "ĭ"); // "ibreve"
+               CHARS.put("kI", "Į"); // "Iogon"
+               CHARS.put("ki", "į"); // "iogon"
+               CHARS.put(".I", "İ"); // "Idot"
+               CHARS.put("i", "ı"); // "inodot"
+               // Symbol #306 (IJ) has no special Latex command
+               // Symbol #307 (ij) has no special Latex command
+               CHARS.put("^J", "Ĵ"); // "Jcirc"
+               CHARS.put("^j", "ĵ"); // "jcirc"
+               CHARS.put("cK", "Ķ"); // "Kcedil"
+               CHARS.put("ck", "ķ"); // "kcedil"
+               // Symbol #312 (k) has no special Latex command
+               CHARS.put("'L", "Ĺ"); // "Lacute"
+               CHARS.put("'l", "ĺ"); // "lacute"
+               CHARS.put("cL", "Ļ"); // "Lcedil"
+               CHARS.put("cl", "ļ"); // "lcedil"
+               // Symbol #317 (L�) has no special Latex command
+               // Symbol #318 (l�) has no special Latex command
+               CHARS.put("Lmidot", "Ŀ"); // "Lmidot"
+               CHARS.put("lmidot", "ŀ"); // "lmidot"
+               CHARS.put("L", "Ł"); // "Lstrok"
+               CHARS.put("l", "ł"); // "lstrok"
+               CHARS.put("'N", "Ń"); // "Nacute"
+               CHARS.put("'n", "ń"); // "nacute"
+               CHARS.put("cN", "Ņ"); // "Ncedil"
+               CHARS.put("cn", "ņ"); // "ncedil"
+               CHARS.put("vN", "Ň"); // "Ncaron"
+               CHARS.put("vn", "ň"); // "ncaron"
+               // Symbol #329 (�n) has no special Latex command
+               CHARS.put("NG", "Ŋ"); // "ENG"
+               CHARS.put("ng", "ŋ"); // "eng"
+               CHARS.put("=O", "Ō"); // "Omacr"
+               CHARS.put("=o", "ō"); // "omacr"
+               CHARS.put("uO", "Ŏ"); // "Obreve"
+               CHARS.put("uo", "ŏ"); // "obreve"
+               CHARS.put("HO", "Ő"); // "Odblac"
+               CHARS.put("Ho", "ő"); // "odblac"
+               CHARS.put("OE", "Œ"); // "OElig"
+               CHARS.put("oe", "œ"); // "oelig"
+               CHARS.put("'R", "Ŕ"); // "Racute"
+               CHARS.put("'r", "ŕ"); // "racute"
+               CHARS.put("cR", "Ŗ"); // "Rcedil"
+               CHARS.put("cr", "ŗ"); // "rcedil"
+               CHARS.put("vR", "Ř"); // "Rcaron"
+               CHARS.put("vr", "ř"); // "rcaron"
+               CHARS.put("'S", "Ś"); // "Sacute"
+               CHARS.put("'s", "ś"); // "sacute"
+               CHARS.put("^S", "Ŝ"); // "Scirc"
+               CHARS.put("^s", "ŝ"); // "scirc"
+               CHARS.put("cS", "Ş"); // "Scedil"
+               CHARS.put("cs", "ş"); // "scedil"
+               CHARS.put("vS", "Š"); // "Scaron"
+               CHARS.put("vs", "š"); // "scaron"
+               CHARS.put("cT", "Ţ"); // "Tcedil"
+               CHARS.put("ct", "ţ"); // "tcedil"
+               CHARS.put("vT", "Ť"); // "Tcaron"
+               // Symbol #357 (t�) has no special Latex command
+               CHARS.put("Tstrok", "Ŧ"); // "Tstrok"
+               CHARS.put("tstrok", "ŧ"); // "tstrok"
+               CHARS.put("~U", "Ũ"); // "Utilde"
+               CHARS.put("~u", "ũ"); // "utilde"
+               CHARS.put("=U", "Ū"); // "Umacr"
+               CHARS.put("=u", "ū"); // "umacr"
+               CHARS.put("uU", "Ŭ"); // "Ubreve"
+               CHARS.put("uu", "ŭ"); // "ubreve"
+               CHARS.put("rU", "Ů"); // "Uring"
+               CHARS.put("ru", "ů"); // "uring"
+               CHARS.put("HU", "ů"); // "Odblac"
+               CHARS.put("Hu", "ű"); // "odblac"
+               CHARS.put("kU", "Ų"); // "Uogon"
+               CHARS.put("ku", "ų"); // "uogon"
+               CHARS.put("^W", "Ŵ"); // "Wcirc"
+               CHARS.put("^w", "ŵ"); // "wcirc"
+               CHARS.put("^Y", "Ŷ"); // "Ycirc"
+               CHARS.put("^y", "ŷ"); // "ycirc"
+               CHARS.put("\"Y", "Ÿ"); // "Yuml"
+               CHARS.put("'Z", "Ź"); // "Zacute"
+               CHARS.put("'z", "ź"); // "zacute"
+               CHARS.put(".Z", "Ż"); // "Zdot"
+               CHARS.put(".z", "ż"); // "zdot"
+               CHARS.put("vZ", "Ž"); // "Zcaron"
+               CHARS.put("vz", "ž"); // "zcaron"
+               // Symbol #383 (f) has no special Latex command
+        CHARS.put("%", "%"); // percent sign
+    }
+    
+    public String format(String field) {
+               int i;
+               field = field.replaceAll("&|\\\\&", "&amp;").replaceAll("[\\n]{1,}", "<p>");
+
+               StringBuffer sb = new StringBuffer();
+               StringBuffer currentCommand = null;
+               
+               char c;
+               boolean escaped = false, incommand = false;
+               
+               for (i = 0; i < field.length(); i++) {
+                       c = field.charAt(i);
+                       if (escaped && (c == '\\')) {
+                               sb.append('\\');
+                               escaped = false;
+                       } else if (c == '\\') {
+                               if (incommand){
+                                       /* Close Command */
+                                       String command = currentCommand.toString();
+                                       Object result = CHARS.get(command);
+                                       if (result != null) {
+                                               sb.append((String) result);
+                                       } else {
+                                               sb.append(command);
+                                       }
+                               }
+                               escaped = true;
+                               incommand = true;
+                               currentCommand = new StringBuffer();
+                       } else if (!incommand && (c == '{' || c == '}')) {
+                               // Swallow the brace.
+                       } else if (Character.isLetter(c) || (c == '%')
+                               || (Globals.SPECIAL_COMMAND_CHARS.indexOf(String.valueOf(c)) >= 0)) {
+                               escaped = false;
+
+                if (!incommand)
+                                       sb.append(c);
+                                       // Else we are in a command, and should not keep the letter.
+                               else {
+                                       currentCommand.append(c);
+                    testCharCom: if ((currentCommand.length() == 1)
+                                               && (Globals.SPECIAL_COMMAND_CHARS.indexOf(currentCommand.toString()) >= 0)) {
+                                               // This indicates that we are in a command of the type
+                                               // \^o or \~{n}
+                                               if (i >= field.length() - 1)
+                                                       break testCharCom;
+
+                                               String command = currentCommand.toString();
+                                               i++;
+                                               c = field.charAt(i);
+                                               // System.out.println("next: "+(char)c);
+                                               String combody;
+                                               if (c == '{') {
+                                                       IntAndString part = getPart(field, i, false);
+                                                       i += part.i;
+                                                       combody = part.s;
+                                               } else {
+                                                       combody = field.substring(i, i + 1);
+                                                       // System.out.println("... "+combody);
+                                               }
+                                               Object result = CHARS.get(command + combody);
+
+                                               if (result != null)
+                                                       sb.append((String) result);
+
+                                               incommand = false;
+                                               escaped = false;
+                                       } else { 
+                                               //      Are we already at the end of the string?
+                                               if (i + 1 == field.length()){
+                                                       String command = currentCommand.toString();
+                            Object result = CHARS.get(command);
+                                                       /* If found, then use translated version. If not,
+                                                        * then keep
+                                                        * the text of the parameter intact.
+                                                        */
+                                                       if (result != null) {
+                                                               sb.append((String) result);
+                                                       } else {
+                                                               sb.append(command);
+                                                       }
+                                                       
+                                               }
+                                       }
+                               }
+                       } else {
+                               String argument = null;
+
+                               if (!incommand) {
+                                       sb.append(c);
+                               } else if (Character.isWhitespace(c) || (c == '{') || (c == '}')) {
+                                       // First test if we are already at the end of the string.
+                                       // if (i >= field.length()-1)
+                                       // break testContent;
+
+                                       String command = currentCommand.toString();
+                                                
+                    // Then test if we are dealing with a italics or bold
+                                       // command.
+                                       // If so, handle.
+                                       if (command.equals("em") || command.equals("emph") || command.equals("textit")) {
+                                               IntAndString part = getPart(field, i, true);
+
+                                               i += part.i;
+                                               sb.append("<em>").append(part.s).append("</em>");
+                                       } else if (command.equals("textbf")) {
+                                               IntAndString part = getPart(field, i, true);
+                                               i += part.i;
+                                               sb.append("<b>").append(part.s).append("</b>");
+                                       } else if (c == '{') {
+                                               IntAndString part = getPart(field, i, true);
+                                               i += part.i;
+                                               argument = part.s;
+                                               if (argument != null) {
+                                                       // handle common case of general latex command
+                                                       Object result = CHARS.get(command + argument);
+                                                       // System.out.print("command: "+command+", arg: "+argument);
+                                                       // System.out.print(", result: ");
+                                                       // If found, then use translated version. If not, then keep
+                                                       // the
+                                                       // text of the parameter intact.
+                                                       if (result != null) {
+                                                               sb.append((String) result);
+                                                       } else {
+                                                               sb.append(argument);
+                                                       }
+                                               }
+                    } else if (c == '}') {
+                        // This end brace terminates a command. This can be the case in
+                        // constructs like {\aa}. The correct behaviour should be to
+                        // substitute the evaluated command and swallow the brace:
+                        Object result = CHARS.get(command);
+                        if (result != null) {
+                            sb.append((String) result);
+                        } else {
+                            // If the command is unknown, just print it:
+                            sb.append(command);
+                        }
+                    } else {
+                                               Object result = CHARS.get(command);
+                                               if (result != null) {
+                                                       sb.append((String) result);
+                                               } else {
+                                                       sb.append(command);
+                                               }
+                                               sb.append(' ');
+                                       }
+                               }/* else if (c == '}') {
+                    System.out.printf("com term by }: '%s'\n", currentCommand.toString());
+
+                    argument = "";
+                               }*/ else {
+                                       /*
+                                        * TODO: this point is reached, apparently, if a command is
+                                        * terminated in a strange way, such as with "$\omega$".
+                                        * Also, the command "\&" causes us to get here. The former
+                                        * issue is maybe a little difficult to address, since it
+                                        * involves the LaTeX math mode. We don't have a complete
+                                        * LaTeX parser, so maybe it's better to ignore these
+                                        * commands?
+                                        */
+                               }
+                               
+                               incommand = false;
+                               escaped = false;
+                       }
+               }
+
+               return sb.toString();
+       }
+
+       private IntAndString getPart(String text, int i, boolean terminateOnEndBraceOnly) {
+               char c;
+               int count = 0;
+               
+               StringBuffer part = new StringBuffer();
+               
+               // advance to first char and skip wihitespace
+               i++;
+               while (i < text.length() && Character.isWhitespace(text.charAt(i))){
+                       i++;
+               }
+               
+               // then grab whathever is the first token (counting braces)
+               while (i < text.length()){
+                       c = text.charAt(i);
+                       if (!terminateOnEndBraceOnly && count == 0 && Character.isWhitespace(c)) {
+                               i--; // end argument and leave whitespace for further
+                                        // processing
+                               break;
+                       }
+                       if (c == '}' && --count < 0)
+                               break;
+                       else if (c == '{')
+                               count++;
+                       part.append(c);
+                       i++;
+               }
+               return new IntAndString(part.length(), format(part.toString()));
+       }
+
+       private class IntAndString {
+               public int i;
+
+               String s;
+
+               public IntAndString(int i, String s) {
+                       this.i = i;
+                       this.s = s;
+               }
+       }
+}
diff --git a/net/sf/jabref/oo/AlphanumericComparator.java b/net/sf/jabref/oo/AlphanumericComparator.java
new file mode 100755 (executable)
index 0000000..7b993ad
--- /dev/null
@@ -0,0 +1,36 @@
+package net.sf.jabref.oo;
+
+import net.sf.jabref.BibtexEntry;
+import net.sf.jabref.FieldComparator;
+
+import java.util.Comparator;
+
+/**
+ * Comparator for sorting bibliography entries.
+ *
+ * TODO: is it sufficient with a hardcoded sort algorithm for the bibliography?
+ */
+public class AlphanumericComparator implements Comparator<BibtexEntry> {
+
+    FieldComparator authComp = new FieldComparator("author"),
+        editorComp = new FieldComparator("editor"),
+        yearComp = new FieldComparator("year");
+
+    public AlphanumericComparator() {
+
+    }
+
+    public int compare(BibtexEntry o1, BibtexEntry o2) {
+        // Author as first criterion:
+        int comp = authComp.compare(o1, o2);
+        if (comp != 0)
+            return comp;
+        // TODO: Is it a good idea to try editor if author fields are equal?
+        comp = editorComp.compare(o1, o2);
+        if (comp != 0)
+            return comp;
+        // Year as next criterion:
+        return yearComp.compare(o1, o2);
+
+    }
+}
diff --git a/net/sf/jabref/oo/AutoDetectPaths.java b/net/sf/jabref/oo/AutoDetectPaths.java
new file mode 100755 (executable)
index 0000000..3806a76
--- /dev/null
@@ -0,0 +1,331 @@
+package net.sf.jabref.oo;
+
+import net.sf.jabref.Globals;
+import net.sf.jabref.AbstractWorker;
+
+import javax.swing.*;
+import java.io.File;
+import java.io.FileFilter;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.layout.FormLayout;
+
+/**
+ * Tools for automatically detecting jar and executable paths to OpenOffice.
+ */
+public class AutoDetectPaths extends AbstractWorker {
+
+    boolean foundPaths = false;
+    boolean fileSearchCancelled = false;
+    JDialog prog;
+    private JDialog parent;
+
+    public AutoDetectPaths(JDialog parent) {
+        this.parent = parent;
+    }
+
+    public boolean runAutodetection() {
+        try {
+            if (checkAutoDetectedPaths())
+                return true;
+            init();
+            getWorker().run();
+            update();
+            return foundPaths;
+        } catch (Throwable e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public void run() {
+        foundPaths = autoDetectPaths();
+    }
+
+    public boolean getResult() {
+        return foundPaths;
+    }
+
+    public boolean cancelled() {
+        return fileSearchCancelled;
+    }
+
+    public void init() throws Throwable {
+        prog = showProgressDialog(parent, Globals.lang("Autodetecting paths..."),
+            Globals.lang("Please wait..."), true);
+    }
+
+    public void update() {
+        prog.dispose();
+    }
+
+    public boolean autoDetectPaths() {
+
+        if (Globals.ON_WIN) {
+            File progFiles = findProgramFilesDir(),
+                sOffice = null;
+            if (fileSearchCancelled)
+                return false;
+            if (progFiles != null) {
+                sOffice = findFileDir(progFiles, "soffice.exe");
+            }
+            if (sOffice == null) {
+                JOptionPane.showMessageDialog(parent, Globals.lang("Unable to autodetect OpenOffice installation. Please choose the installation directory manually."),
+                        Globals.lang("Could not find OpenOffice installation"), JOptionPane.INFORMATION_MESSAGE);
+                JFileChooser jfc = new JFileChooser(new File("C:\\"));
+                jfc.setDialogType(JFileChooser.OPEN_DIALOG);
+                jfc.setFileFilter(new javax.swing.filechooser.FileFilter() {
+                    public boolean accept(File file) {
+                        return file.isDirectory();
+                    }
+
+                    public String getDescription() {
+                        return Globals.lang("Directories");
+                    }
+                });
+                jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+                jfc.showOpenDialog(parent);
+                if (jfc.getSelectedFile() != null)
+                    sOffice = jfc.getSelectedFile();
+            }
+            if (sOffice == null)
+                return false;
+
+            Globals.prefs.put("ooExecutablePath", new File(sOffice, "soffice.exe").getPath());
+            File unoil = findFileDir(sOffice.getParentFile(), "unoil.jar");
+            if (fileSearchCancelled)
+                return false;
+            File jurt = findFileDir(sOffice.getParentFile(), "jurt.jar");
+            if (fileSearchCancelled)
+                return false;
+            if ((unoil != null) && (jurt != null)) {
+                Globals.prefs.put("ooUnoilPath", unoil.getPath());
+                Globals.prefs.put("ooJurtPath", jurt.getPath());
+                return true;
+            }
+            else return false;
+
+        }
+        else if (Globals.ON_MAC) {
+            File rootDir = new File("/Applications");
+            File[] files = rootDir.listFiles();
+            for (int i = 0; i < files.length; i++) {
+                File file = files[i];
+                if (file.isDirectory() && file.getName().equals("OpenOffice.org.app")) {
+                    rootDir = file;
+                    //System.out.println("Setting starting dir to: "+file.getPath());
+                    break;
+                }
+            }
+            //System.out.println("Searching for soffice.bin");
+            File sOffice = findFileDir(rootDir, "soffice.bin");
+            //System.out.println("Found: "+(sOffice != null ? sOffice.getPath() : "-"));
+            if (fileSearchCancelled)
+                return false;
+            if (sOffice != null) {
+                Globals.prefs.put("ooExecutablePath", new File(sOffice, "soffice.bin").getPath());
+                //System.out.println("Searching for unoil.jar");
+                File unoil = findFileDir(rootDir, "unoil.jar");
+                //System.out.println("Found: "+(unoil != null ? unoil.getPath(): "-"));
+                if (fileSearchCancelled)
+                    return false;
+                //System.out.println("Searching for jurt.jar");
+                File jurt = findFileDir(rootDir, "jurt.jar");
+                //System.out.println("Found: "+(jurt != null ? jurt.getPath(): "-"));
+                if (fileSearchCancelled)
+                    return false;
+                if ((unoil != null) && (jurt != null)) {
+                    Globals.prefs.put("ooUnoilPath", unoil.getPath());
+                    Globals.prefs.put("ooJurtPath", jurt.getPath());
+                    return true;
+                }
+                else return false;
+            }
+            else return false;
+        }
+        else {
+            // Linux:
+            File inUsr = findFileDir(new File("/usr/lib"), "soffice");
+            if (fileSearchCancelled)
+                return false;
+            File inOpt = findFileDir(new File("/opt"), "soffice");
+            if (fileSearchCancelled)
+                return false;
+            if ((inUsr != null) && (inOpt == null)) {
+                Globals.prefs.put("ooExecutablePath", new File(inUsr, "soffice.bin").getPath());
+                File unoil = findFileDir(new File("/usr/lib"), "unoil.jar");
+                if (fileSearchCancelled)
+                    return false;
+                File jurt = findFileDir(new File("/usr/lib"), "jurt.jar");
+                if (fileSearchCancelled)
+                    return false;
+                if ((unoil != null) && (jurt != null)) {
+                    Globals.prefs.put("ooUnoilPath", unoil.getPath());
+                    Globals.prefs.put("ooJurtPath", jurt.getPath());
+                    return true;
+                }
+                else return false;
+            }
+            else if ((inOpt != null) && (inUsr == null)) {
+                Globals.prefs.put("ooExecutablePath", new File(inOpt, "soffice.bin").getPath());
+                File unoil = findFileDir(new File("/opt"), "unoil.jar");
+                File jurt = findFileDir(new File("/opt"), "jurt.jar");
+                if ((unoil != null) && (jurt != null)) {
+                    Globals.prefs.put("ooUnoilPath", unoil.getPath());
+                    Globals.prefs.put("ooJurtPath", jurt.getPath());
+                    return true;
+                }
+                else return false;
+            }
+            else if (inOpt != null) { // Found both
+                JRadioButton optRB = new JRadioButton(inOpt.getPath(), true);
+                JRadioButton usrRB = new JRadioButton(inUsr.getPath(), false);
+                ButtonGroup bg = new ButtonGroup();
+                bg.add(optRB);
+                bg.add(usrRB);
+                DefaultFormBuilder b = new DefaultFormBuilder(new FormLayout("left:pref", ""));
+                b.append(Globals.lang("Found more than one OpenOffice executable. Please choose which one to connect to:"));
+                b.append(optRB);
+                b.append(usrRB);
+                int answer = JOptionPane.showConfirmDialog(null, b.getPanel(), Globals.lang("Choose OpenOffice executable"),
+                        JOptionPane.OK_CANCEL_OPTION);
+                if (answer == JOptionPane.CANCEL_OPTION)
+                    return false;
+                else {
+                    if (optRB.isSelected()) {
+                        Globals.prefs.put("ooExecutablePath", new File(inOpt, "soffice.bin").getPath());
+                        File unoil = findFileDir(new File("/opt"), "unoil.jar");
+                        if (fileSearchCancelled)
+                            return false;
+                        File jurt = findFileDir(new File("/opt"), "jurt.jar");
+                        if (fileSearchCancelled)
+                            return false;
+                        if ((unoil != null) && (jurt != null)) {
+                            Globals.prefs.put("ooUnoilPath", unoil.getPath());
+                            Globals.prefs.put("ooJurtPath", jurt.getPath());
+                            return true;
+                        }
+                        else return false;
+                    }
+                    else {
+                        Globals.prefs.put("ooExecutablePath", new File(inUsr, "soffice.bin").getPath());
+                        File unoil = findFileDir(new File("/usr/lib"), "unoil.jar");
+                        if (fileSearchCancelled)
+                            return false;
+                        File jurt = findFileDir(new File("/usr/lib"), "jurt.jar");
+                        if (fileSearchCancelled)
+                            return false;
+                        if ((unoil != null) && (jurt != null)) {
+                            Globals.prefs.put("ooUnoilPath", unoil.getPath());
+                            Globals.prefs.put("ooJurtPath", jurt.getPath());
+                            return true;
+                        }
+                        else return false;
+                    }
+
+                }
+            }
+            else return false;
+        }
+
+
+    }
+
+    /**
+     * Search for Program files directory.
+     * @return the File pointing to the Program files directory, or null if not found.
+     *   Since we are not including a library for Windows integration, this method can't
+     *   find the Program files dir in localized Windows installations.
+     */
+    private static File findProgramFilesDir() {
+        File root = new File("C:\\");
+        File[] dirs = root.listFiles(new FileFilter() {
+            public boolean accept(File file) {
+                return file.isDirectory();
+            }
+        });
+        for (int i = 0; i < dirs.length; i++) {
+            File dir = dirs[i];
+            if (dir.getName().toLowerCase().equals("program files"))
+                return dir;
+        }
+        return null;
+    }
+
+    public static boolean checkAutoDetectedPaths() {
+
+        if (Globals.prefs.hasKey("ooUnoilPath") && Globals.prefs.hasKey("ooJurtPath")
+                && Globals.prefs.hasKey("ooExecutablePath")) {
+            if (new File(Globals.prefs.get("ooUnoilPath"), "unoil.jar").exists()
+                && new File(Globals.prefs.get("ooJurtPath"), "jurt.jar").exists()
+                && new File(Globals.prefs.get("ooExecutablePath")).exists()) {
+                return true;
+            }
+            else {
+                return false;
+            }
+        }
+        else return false;
+    }
+
+    /**
+     * Search for a file, starting at the given directory.
+     * @param startDir The starting point.
+     * @param filename The name of the file to search for.
+     * @return The directory where the file was first found, or null if not found.
+     */
+    public File findFileDir(File startDir, String filename) {
+        if (fileSearchCancelled)
+            return null;
+        //System.out.println("Searching: "+startDir.getPath());
+        File[] files = startDir.listFiles();
+        if (files == null)
+            return null;
+        File result = null;
+        for (int i=0; i<files.length; i++) {
+            if (fileSearchCancelled)
+                return null;
+            if (files[i].isDirectory()) {
+                result = findFileDir(files[i], filename);
+                if (result != null)
+                    break;
+            }
+            else if (files[i].getName().equals(filename)) {
+                result = startDir;
+                break;
+            }
+        }
+        return result;
+    }
+
+    public JDialog showProgressDialog(JDialog parent, String title, String message, boolean includeCancelButton) {
+        fileSearchCancelled = false;
+        final JDialog prog;
+        JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL);
+        JButton cancel = new JButton(Globals.lang("Cancel"));
+        cancel.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                fileSearchCancelled = true;
+                ((JButton)event.getSource()).setEnabled(false);
+            }
+        });
+        prog = new JDialog(parent, title, false);
+        bar.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+        bar.setIndeterminate(true);
+        if (includeCancelButton)
+            prog.add(cancel, BorderLayout.SOUTH);
+        prog.add(new JLabel(message), BorderLayout.NORTH);
+        prog.add(bar, BorderLayout.CENTER);
+        prog.pack();
+        prog.setLocationRelativeTo(null);//parent);
+        //SwingUtilities.invokeLater(new Runnable() {
+        //    public void run() {
+                prog.setVisible(true);
+        //    }
+        //});
+        return prog;
+    }
+}
diff --git a/net/sf/jabref/oo/BibtexEntryNotFoundException.java b/net/sf/jabref/oo/BibtexEntryNotFoundException.java
new file mode 100755 (executable)
index 0000000..721136a
--- /dev/null
@@ -0,0 +1,22 @@
+package net.sf.jabref.oo;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: alver
+ * Date: 16-Dec-2007
+ * Time: 10:37:23
+ * To change this template use File | Settings | File Templates.
+ */
+public class BibtexEntryNotFoundException extends Exception {
+    private String bibtexKey;
+
+    public BibtexEntryNotFoundException(String bibtexKey, String message) {
+        super(message);
+
+        this.bibtexKey = bibtexKey;
+    }
+
+    public String getBibtexKey() {
+        return bibtexKey;
+    }
+}
diff --git a/net/sf/jabref/oo/BstWrapper.java b/net/sf/jabref/oo/BstWrapper.java
new file mode 100755 (executable)
index 0000000..876b915
--- /dev/null
@@ -0,0 +1,88 @@
+package net.sf.jabref.oo;
+
+import net.sf.jabref.BibtexDatabase;
+import net.sf.jabref.BibtexEntry;
+import net.sf.jabref.export.layout.LayoutFormatter;
+import net.sf.jabref.export.layout.format.FormatChars;
+import net.sf.jabref.bst.VM;
+import org.antlr.runtime.RecognitionException;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * Wrapper for using JabRef's bst engine for formatting OO bibliography.
+ */
+public class BstWrapper {
+
+    LayoutFormatter formatter = new FormatChars();
+    VM vm = null;
+
+    public BstWrapper() {
+
+    }
+
+    /**
+     * Set the bst file to be used for processing. This method will initiate parsing
+     * of the bst file.
+     * @param f The bst file to load.
+     * @throws IOException On IO errors.
+     * @throws RecognitionException On parsing errors.
+     */
+    public void loadBstFile(File f) throws IOException, RecognitionException {
+        vm = new VM(f);
+    }
+
+    /**
+     * Use the instructions of the loaded bst file for processing a collection of entries.
+     * @param entries The entries to process.
+     * @param database The database the entries belong to.
+     * @return A Map of the entries' bibtex keys linking to their processed strings.
+     */
+    public Map<String,String> processEntries(Collection<BibtexEntry> entries, BibtexDatabase database) {
+        // TODO: how to handle uniquefiers?
+
+        // TODO: need handling of crossrefs?
+        String result = vm.run(entries);
+        return parseResult(result);
+    }
+
+    static Pattern bibitemTag = Pattern.compile("\\\\[a-zA-Z]*item\\{.*\\}");
+
+    private Map<String,String> parseResult(String result) {
+        Map<String,String> map = new HashMap<String,String>();
+        // Look through for instances of \bibitem :
+        Matcher m =  bibitemTag.matcher(result);
+        ArrayList<Integer> indices = new ArrayList<Integer>();
+        ArrayList<Integer> endIndices = new ArrayList<Integer>();
+        ArrayList<String> keys = new ArrayList<String>();
+        while (m.find()) {
+            if (indices.size() > 0)
+                endIndices.add(m.start());
+            System.out.println(m.start()+"  "+m.end());
+            String tag = m.group();
+            String key = tag.substring(9, tag.length()-1);
+            indices.add(m.end());
+            keys.add(key);
+        }
+        int lastI = result.lastIndexOf("\\end{thebibliography}");
+        if ((lastI > 0) && (lastI > indices.get(indices.size()-1)))
+            endIndices.add(lastI);
+        for (int i=0; i<keys.size(); i++) {
+            String key = keys.get(i);
+            int index = indices.get(i);
+            int endIndex = endIndices.get(i);
+            String part = result.substring(index, endIndex);
+            map.put(key, formatter.format(part.trim().replaceAll("\\\\newblock ", " ")));
+        }
+
+        return map;
+    }
+}
diff --git a/net/sf/jabref/oo/ComparableMark.java b/net/sf/jabref/oo/ComparableMark.java
new file mode 100644 (file)
index 0000000..67c1357
--- /dev/null
@@ -0,0 +1,33 @@
+package classes.net.sf.jabref.oo;
+
+import com.sun.star.awt.Point;
+
+/**
+ *
+ */
+public class ComparableMark implements Comparable {
+
+    String name;
+    Point position;
+
+    public ComparableMark(String name, Point position) {
+        this.name = name;
+        this.position = position;
+    }
+
+    public int compareTo(Object o) {
+        ComparableMark other = (ComparableMark)o;
+        if (position.Y != other.position.Y)
+            return position.Y-other.position.Y;
+        else
+            return position.X-other.position.X;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Point getPosition() {
+        return position;
+    }
+}
diff --git a/net/sf/jabref/oo/ConnectionLostException.java b/net/sf/jabref/oo/ConnectionLostException.java
new file mode 100644 (file)
index 0000000..abe8bd5
--- /dev/null
@@ -0,0 +1,11 @@
+package net.sf.jabref.oo;
+
+/**
+ * This exception is used to indicate that connection to OpenOffice has been lost.
+ */
+public class ConnectionLostException extends RuntimeException {
+
+    public ConnectionLostException(String s) {
+        super(s);
+    }
+}
diff --git a/net/sf/jabref/oo/OOPreFormatter.java b/net/sf/jabref/oo/OOPreFormatter.java
new file mode 100755 (executable)
index 0000000..6296f54
--- /dev/null
@@ -0,0 +1,434 @@
+package net.sf.jabref.oo;
+
+import net.sf.jabref.Globals;
+import net.sf.jabref.export.layout.LayoutFormatter;
+import java.util.HashMap;
+
+/**
+ * This formatter preprocesses JabRef fields before they are run through the layout of the
+ * bibliography style. It handles translation of LaTeX italic/bold commands into HTML tags.
+ *
+ * @version $Revision: 2568 $ ($Date: 2008-01-15 18:40:26 +0100 (Tue, 15 Jan 2008) $)
+ */
+public class OOPreFormatter implements LayoutFormatter {
+
+
+    public static HashMap<String, String> CHARS = new HashMap<String, String>();
+
+    static {
+        // Following character definitions contributed by Ervin Kolenovic:
+               // HTML named entities from #192 - #255 (UNICODE Latin-1)
+               CHARS.put("`A", "À"); // #192
+               CHARS.put("'A", "Á"); // #193
+               CHARS.put("^A", "Â"); // #194
+               CHARS.put("~A", "Ã"); // #195
+               CHARS.put("\"A", "Ä"); // #196
+               CHARS.put("AA", "Å"); // #197
+               CHARS.put("AE", "Æ"); // #198
+               CHARS.put("cC", "Ç"); // #199
+        CHARS.put("`E", "È"); // #200
+               CHARS.put("'E", "É"); // #201
+               CHARS.put("^E", "Ê"); // #202
+               CHARS.put("\"E", "Ë"); // #203
+               CHARS.put("`I", "Ì"); // #204
+               CHARS.put("'I", "Í"); // #205
+               CHARS.put("^I", "Î"); // #206
+               CHARS.put("\"I", "Ï"); // #207
+               CHARS.put("DH", "Ð"); // #208
+               CHARS.put("~N", "Ñ"); // #209
+               CHARS.put("`O", "Ò"); // #210
+               CHARS.put("'O", "Ó"); // #211
+               CHARS.put("^O", "Ô"); // #212
+               CHARS.put("~O", "Õ"); // #213
+               CHARS.put("\"O", "Ö"); // #214
+               // According to ISO 8859-1 the "\times" symbol should be placed here
+               // (#215).
+               // Omitting this, because it is a mathematical symbol.
+               CHARS.put("O", "Ø"); // #216
+               CHARS.put("`U", "Ù"); // #217
+               CHARS.put("'U", "Ú"); // #218
+               CHARS.put("^U", "Û"); // #219
+               CHARS.put("\"U", "Ü"); // #220
+               CHARS.put("'Y", "Ý"); // #221
+               CHARS.put("TH", "Þ"); // #222
+               CHARS.put("ss", "ß"); // #223
+               CHARS.put("`a", "à"); // #224
+               CHARS.put("'a", "á"); // #225
+               CHARS.put("^a", "â"); // #226
+               CHARS.put("~a", "ã"); // #227
+               CHARS.put("\"a", "ä"); // #228
+               CHARS.put("aa", "å"); // #229
+               CHARS.put("ae", "æ"); // #230
+               CHARS.put("cc", "ç"); // #231
+               CHARS.put("`e", "è"); // #232
+               CHARS.put("'e", "é"); // #233
+               CHARS.put("^e", "ê"); // #234
+               CHARS.put("\"e", "ë"); // #235
+               CHARS.put("`i", "ì"); // #236
+               CHARS.put("'i", "í"); // #237
+               CHARS.put("^i", "î"); // #238
+               CHARS.put("\"i", "ï"); // #239
+               CHARS.put("dh", "ð"); // #240
+               CHARS.put("~n", "ñ"); // #241
+               CHARS.put("`o", "ò"); // #242
+               CHARS.put("'o", "ó"); // #243
+               CHARS.put("^o", "ô"); // #244
+               CHARS.put("~o", "õ"); // #245
+               CHARS.put("\"o", "ö"); // #246
+               // According to ISO 8859-1 the "\div" symbol should be placed here
+               // (#247).
+               // Omitting this, because it is a mathematical symbol.
+               CHARS.put("o", "ø"); // #248
+               CHARS.put("`u", "ù"); // #249
+               CHARS.put("'u", "ú"); // #250
+               CHARS.put("^u", "û"); // #251
+               CHARS.put("\"u", "ü"); // #252
+               CHARS.put("'y", "ý"); // #253
+               CHARS.put("th", "þ"); // #254
+               CHARS.put("\"y", "ÿ"); // #255
+
+               // HTML special characters without names (UNICODE Latin Extended-A),
+               // indicated by UNICODE number
+               CHARS.put("=A", "Ā"); // "Amacr"
+               CHARS.put("=a", "ā"); // "amacr"
+               CHARS.put("uA", "Ă"); // "Abreve"
+               CHARS.put("ua", "ă"); // "abreve"
+               CHARS.put("kA", "Ą"); // "Aogon"
+               CHARS.put("ka", "ą"); // "aogon"
+               CHARS.put("'C", "Ć"); // "Cacute"
+               CHARS.put("'c", "ć"); // "cacute"
+               CHARS.put("^C", "Ĉ"); // "Ccirc"
+               CHARS.put("^c", "ĉ"); // "ccirc"
+               CHARS.put(".C", "Ċ"); // "Cdot"
+               CHARS.put(".c", "ċ"); // "cdot"
+               CHARS.put("vC", "Č"); // "Ccaron"
+               CHARS.put("vc", "č"); // "ccaron"
+               CHARS.put("vD", "Ď"); // "Dcaron"
+               // Symbol #271 (d�) has no special Latex command
+               CHARS.put("DJ", "Đ"); // "Dstrok"
+               CHARS.put("dj", "đ"); // "dstrok"
+               CHARS.put("=E", "Ē"); // "Emacr"
+               CHARS.put("=e", "ē"); // "emacr"
+               CHARS.put("uE", "Ĕ"); // "Ebreve"
+               CHARS.put("ue", "ĕ"); // "ebreve"
+               CHARS.put(".E", "Ė"); // "Edot"
+               CHARS.put(".e", "ė"); // "edot"
+               CHARS.put("kE", "Ę"); // "Eogon"
+               CHARS.put("ke", "ę"); // "eogon"
+               CHARS.put("vE", "Ě"); // "Ecaron"
+               CHARS.put("ve", "ě"); // "ecaron"
+               CHARS.put("^G", "Ĝ"); // "Gcirc"
+               CHARS.put("^g", "ĝ"); // "gcirc"
+               CHARS.put("uG", "Ğ"); // "Gbreve"
+               CHARS.put("ug", "ğ"); // "gbreve"
+               CHARS.put(".G", "Ġ"); // "Gdot"
+               CHARS.put(".g", "ġ"); // "gdot"
+               CHARS.put("cG", "Ģ"); // "Gcedil"
+               CHARS.put("'g", "ģ"); // "gacute"
+               CHARS.put("^H", "Ĥ"); // "Hcirc"
+               CHARS.put("^h", "ĥ"); // "hcirc"
+               CHARS.put("Hstrok", "Ħ"); // "Hstrok"
+               CHARS.put("hstrok", "ħ"); // "hstrok"
+               CHARS.put("~I", "Ĩ"); // "Itilde"
+               CHARS.put("~i", "ĩ"); // "itilde"
+               CHARS.put("=I", "Ī"); // "Imacr"
+               CHARS.put("=i", "ī"); // "imacr"
+               CHARS.put("uI", "Ĭ"); // "Ibreve"
+               CHARS.put("ui", "ĭ"); // "ibreve"
+               CHARS.put("kI", "Į"); // "Iogon"
+               CHARS.put("ki", "į"); // "iogon"
+               CHARS.put(".I", "İ"); // "Idot"
+               CHARS.put("i", "ı"); // "inodot"
+               // Symbol #306 (IJ) has no special Latex command
+               // Symbol #307 (ij) has no special Latex command
+               CHARS.put("^J", "Ĵ"); // "Jcirc"
+               CHARS.put("^j", "ĵ"); // "jcirc"
+               CHARS.put("cK", "Ķ"); // "Kcedil"
+               CHARS.put("ck", "ķ"); // "kcedil"
+               // Symbol #312 (k) has no special Latex command
+               CHARS.put("'L", "Ĺ"); // "Lacute"
+               CHARS.put("'l", "ĺ"); // "lacute"
+               CHARS.put("cL", "Ļ"); // "Lcedil"
+               CHARS.put("cl", "ļ"); // "lcedil"
+               // Symbol #317 (L�) has no special Latex command
+               // Symbol #318 (l�) has no special Latex command
+               CHARS.put("Lmidot", "Ŀ"); // "Lmidot"
+               CHARS.put("lmidot", "ŀ"); // "lmidot"
+               CHARS.put("L", "Ł"); // "Lstrok"
+               CHARS.put("l", "ł"); // "lstrok"
+               CHARS.put("'N", "Ń"); // "Nacute"
+               CHARS.put("'n", "ń"); // "nacute"
+               CHARS.put("cN", "Ņ"); // "Ncedil"
+               CHARS.put("cn", "ņ"); // "ncedil"
+               CHARS.put("vN", "Ň"); // "Ncaron"
+               CHARS.put("vn", "ň"); // "ncaron"
+               // Symbol #329 (�n) has no special Latex command
+               CHARS.put("NG", "Ŋ"); // "ENG"
+               CHARS.put("ng", "ŋ"); // "eng"
+               CHARS.put("=O", "Ō"); // "Omacr"
+               CHARS.put("=o", "ō"); // "omacr"
+               CHARS.put("uO", "Ŏ"); // "Obreve"
+               CHARS.put("uo", "ŏ"); // "obreve"
+               CHARS.put("HO", "Ő"); // "Odblac"
+               CHARS.put("Ho", "ő"); // "odblac"
+               CHARS.put("OE", "Œ"); // "OElig"
+               CHARS.put("oe", "œ"); // "oelig"
+               CHARS.put("'R", "Ŕ"); // "Racute"
+               CHARS.put("'r", "ŕ"); // "racute"
+               CHARS.put("cR", "Ŗ"); // "Rcedil"
+               CHARS.put("cr", "ŗ"); // "rcedil"
+               CHARS.put("vR", "Ř"); // "Rcaron"
+               CHARS.put("vr", "ř"); // "rcaron"
+               CHARS.put("'S", "Ś"); // "Sacute"
+               CHARS.put("'s", "ś"); // "sacute"
+               CHARS.put("^S", "Ŝ"); // "Scirc"
+               CHARS.put("^s", "ŝ"); // "scirc"
+               CHARS.put("cS", "Ş"); // "Scedil"
+               CHARS.put("cs", "ş"); // "scedil"
+               CHARS.put("vS", "Š"); // "Scaron"
+               CHARS.put("vs", "š"); // "scaron"
+               CHARS.put("cT", "Ţ"); // "Tcedil"
+               CHARS.put("ct", "ţ"); // "tcedil"
+               CHARS.put("vT", "Ť"); // "Tcaron"
+               // Symbol #357 (t�) has no special Latex command
+               CHARS.put("Tstrok", "Ŧ"); // "Tstrok"
+               CHARS.put("tstrok", "ŧ"); // "tstrok"
+               CHARS.put("~U", "Ũ"); // "Utilde"
+               CHARS.put("~u", "ũ"); // "utilde"
+               CHARS.put("=U", "Ū"); // "Umacr"
+               CHARS.put("=u", "ū"); // "umacr"
+               CHARS.put("uU", "Ŭ"); // "Ubreve"
+               CHARS.put("uu", "ŭ"); // "ubreve"
+               CHARS.put("rU", "Ů"); // "Uring"
+               CHARS.put("ru", "ů"); // "uring"
+               CHARS.put("HU", "ů"); // "Odblac"
+               CHARS.put("Hu", "ű"); // "odblac"
+               CHARS.put("kU", "Ų"); // "Uogon"
+               CHARS.put("ku", "ų"); // "uogon"
+               CHARS.put("^W", "Ŵ"); // "Wcirc"
+               CHARS.put("^w", "ŵ"); // "wcirc"
+               CHARS.put("^Y", "Ŷ"); // "Ycirc"
+               CHARS.put("^y", "ŷ"); // "ycirc"
+               CHARS.put("\"Y", "Ÿ"); // "Yuml"
+               CHARS.put("'Z", "Ź"); // "Zacute"
+               CHARS.put("'z", "ź"); // "zacute"
+               CHARS.put(".Z", "Ż"); // "Zdot"
+               CHARS.put(".z", "ż"); // "zdot"
+               CHARS.put("vZ", "Ž"); // "Zcaron"
+               CHARS.put("vz", "ž"); // "zcaron"
+               // Symbol #383 (f) has no special Latex command
+        CHARS.put("%", "%"); // percent sign
+    }
+
+       public String format(String field) {
+               int i;
+               field = field.replaceAll("&|\\\\&", "&");
+
+               StringBuffer sb = new StringBuffer();
+               StringBuffer currentCommand = null;
+
+               char c;
+               boolean escaped = false, incommand = false;
+
+               for (i = 0; i < field.length(); i++) {
+                       c = field.charAt(i);
+                       if (escaped && (c == '\\')) {
+                               sb.append('\\');
+                               escaped = false;
+                       } else if (c == '\\') {
+                               if (incommand){
+                                       /* Close Command */
+                                       String command = currentCommand.toString();
+                                       Object result = CHARS.get(command);
+                                       if (result != null) {
+                                               sb.append((String) result);
+                                       } else {
+                                               sb.append(command);
+                                       }
+                               }
+                               escaped = true;
+                               incommand = true;
+                               currentCommand = new StringBuffer();
+                       } else if (!incommand && (c == '{' || c == '}')) {
+                               // Swallow the brace.
+                       } else if (Character.isLetter(c) || (c == '%')
+                               || (Globals.SPECIAL_COMMAND_CHARS.indexOf(String.valueOf(c)) >= 0)) {
+                               escaped = false;
+
+                if (!incommand)
+                                       sb.append(c);
+                                       // Else we are in a command, and should not keep the letter.
+                               else {
+                                       currentCommand.append(c);
+                    testCharCom: if ((currentCommand.length() == 1)
+                                               && (Globals.SPECIAL_COMMAND_CHARS.indexOf(currentCommand.toString()) >= 0)) {
+                                               // This indicates that we are in a command of the type
+                                               // \^o or \~{n}
+                                               if (i >= field.length() - 1)
+                                                       break testCharCom;
+
+                                               String command = currentCommand.toString();
+                                               i++;
+                                               c = field.charAt(i);
+                                               // System.out.println("next: "+(char)c);
+                                               String combody;
+                                               if (c == '{') {
+                                                       IntAndString part = getPart(field, i, false);
+                                                       i += part.i;
+                                                       combody = part.s;
+                                               } else {
+                                                       combody = field.substring(i, i + 1);
+                                                       // System.out.println("... "+combody);
+                                               }
+                                               Object result = CHARS.get(command + combody);
+
+                                               if (result != null)
+                                                       sb.append((String) result);
+
+                                               incommand = false;
+                                               escaped = false;
+                                       } else {
+                                               //      Are we already at the end of the string?
+                                               if (i + 1 == field.length()){
+                                                       String command = currentCommand.toString();
+                            Object result = CHARS.get(command);
+                                                       /* If found, then use translated version. If not,
+                                                        * then keep
+                                                        * the text of the parameter intact.
+                                                        */
+                                                       if (result != null) {
+                                                               sb.append((String) result);
+                                                       } else {
+                                                               sb.append(command);
+                                                       }
+
+                                               }
+                                       }
+                               }
+                       } else {
+                               String argument = null;
+
+                               if (!incommand) {
+                                       sb.append(c);
+                               } else if (Character.isWhitespace(c) || (c == '{') || (c == '}')) {
+                                       // First test if we are already at the end of the string.
+                                       // if (i >= field.length()-1)
+                                       // break testContent;
+
+                                       String command = currentCommand.toString();
+
+                    // Then test if we are dealing with a italics or bold
+                                       // command.
+                                       // If so, handle.
+                                       if (command.equals("em") || command.equals("emph") || command.equals("textit")) {
+                                               IntAndString part = getPart(field, i, true);
+
+                                               i += part.i;
+                                               sb.append("<em>").append(part.s).append("</em>");
+                                       } else if (command.equals("textbf")) {
+                                               IntAndString part = getPart(field, i, true);
+                                               i += part.i;
+                                               sb.append("<b>").append(part.s).append("</b>");
+                                       } else if (c == '{') {
+                                               IntAndString part = getPart(field, i, true);
+                                               i += part.i;
+                                               argument = part.s;
+                                               if (argument != null) {
+                                                       // handle common case of general latex command
+                                                       Object result = CHARS.get(command + argument);
+                            // System.out.print("command: "+command+", arg: "+argument);
+                                                       // System.out.print(", result: ");
+                                                       // If found, then use translated version. If not, then keep
+                                                       // the
+                                                       // text of the parameter intact.
+                                                       if (result != null) {
+                                                               sb.append((String) result);
+                                                       } else {
+                                                               sb.append(argument);
+                                                       }
+                                               }
+                    } else if (c == '}') {
+                        // This end brace terminates a command. This can be the case in
+                        // constructs like {\aa}. The correct behaviour should be to
+                        // substitute the evaluated command and swallow the brace:
+                        Object result = CHARS.get(command);
+                        if (result != null) {
+                            sb.append((String) result);
+                        } else {
+                            // If the command is unknown, just print it:
+                            sb.append(command);
+                        }
+                    } else {
+                                               Object result = CHARS.get(command);
+                                               if (result != null) {
+                                                       sb.append((String) result);
+                                               } else {
+                                                       sb.append(command);
+                                               }
+                                               sb.append(' ');
+                                       }
+                               }/* else if (c == '}') {
+                    System.out.printf("com term by }: '%s'\n", currentCommand.toString());
+
+                    argument = "";
+                               }*/ else {
+                                       /*
+                                        * TODO: this point is reached, apparently, if a command is
+                                        * terminated in a strange way, such as with "$\omega$".
+                                        * Also, the command "\&" causes us to get here. The former
+                                        * issue is maybe a little difficult to address, since it
+                                        * involves the LaTeX math mode. We don't have a complete
+                                        * LaTeX parser, so maybe it's better to ignore these
+                                        * commands?
+                                        */
+                               }
+
+                               incommand = false;
+                               escaped = false;
+                       }
+               }
+
+               return sb.toString();
+       }
+
+       private IntAndString getPart(String text, int i, boolean terminateOnEndBraceOnly) {
+               char c;
+               int count = 0;
+
+               StringBuffer part = new StringBuffer();
+
+               // advance to first char and skip wihitespace
+               i++;
+               while (i < text.length() && Character.isWhitespace(text.charAt(i))){
+                       i++;
+               }
+
+               // then grab whathever is the first token (counting braces)
+               while (i < text.length()){
+                       c = text.charAt(i);
+                       if (!terminateOnEndBraceOnly && count == 0 && Character.isWhitespace(c)) {
+                               i--; // end argument and leave whitespace for further
+                                        // processing
+                               break;
+                       }
+                       if (c == '}' && --count < 0)
+                               break;
+                       else if (c == '{')
+                               count++;
+                       part.append(c);
+                       i++;
+               }
+               return new IntAndString(part.length(), format(part.toString()));
+       }
+
+       private class IntAndString {
+               public int i;
+
+               String s;
+
+               public IntAndString(int i, String s) {
+                       this.i = i;
+                       this.s = s;
+               }
+       }
+}
diff --git a/net/sf/jabref/oo/UndefinedBibtexEntry.java b/net/sf/jabref/oo/UndefinedBibtexEntry.java
new file mode 100644 (file)
index 0000000..2547777
--- /dev/null
@@ -0,0 +1,22 @@
+package net.sf.jabref.oo;
+
+import net.sf.jabref.BibtexEntry;
+import net.sf.jabref.Util;
+
+/**
+ * Subclass of BibtexEntry for representing entries referenced in a document that can't
+ * be found in JabRef's current database.
+ */
+public class UndefinedBibtexEntry extends BibtexEntry {
+    private String key;
+
+    public UndefinedBibtexEntry(String key) {
+        super(Util.createNeutralId());
+        this.key = key;
+        setField("author", OOBibStyle.UNDEFINED_CITATION_MARKER);
+    }
+
+    public String getKey() {
+        return key;
+    }
+}
diff --git a/net/sf/jabref/oo/UndefinedParagraphFormatException.java b/net/sf/jabref/oo/UndefinedParagraphFormatException.java
new file mode 100644 (file)
index 0000000..99d1841
--- /dev/null
@@ -0,0 +1,19 @@
+package net.sf.jabref.oo;
+
+/**
+ * Exception used to indicate that the plugin attempted to set a paragraph format that is
+ * not defined in the current OpenOffice document.
+ */
+public class UndefinedParagraphFormatException extends Exception {
+
+    String formatName;
+
+    public UndefinedParagraphFormatException(String formatName) {
+        super();
+        this.formatName = formatName;
+    }
+
+    public String getFormatName() {
+        return formatName;
+    }
+}
diff --git a/net/sf/jabref/oo/YearComparator.java b/net/sf/jabref/oo/YearComparator.java
new file mode 100755 (executable)
index 0000000..042d18a
--- /dev/null
@@ -0,0 +1,36 @@
+package net.sf.jabref.oo;
+
+import net.sf.jabref.BibtexEntry;
+import net.sf.jabref.FieldComparator;
+
+import java.util.Comparator;
+
+/**
+ * Comparator for sorting bibliography entries according to publication year. This is used to
+ * sort entries in multiple citations where the oldest publication should appear first.
+ */
+public class YearComparator implements Comparator<BibtexEntry> {
+
+    FieldComparator authComp = new FieldComparator("author"),
+        editorComp = new FieldComparator("editor"),
+        yearComp = new FieldComparator("year");
+
+    public YearComparator() {
+
+    }
+
+    public int compare(BibtexEntry o1, BibtexEntry o2) {
+        // Year as first criterion:
+        int comp = yearComp.compare(o1, o2);
+        if (comp != 0)
+            return comp;
+        // TODO: Is it a good idea to try editor if author fields are equal?
+        // Author as next criterion:
+        comp = authComp.compare(o1, o2);
+        if (comp != 0)
+            return comp;
+        // Editor as next criterion:
+        return editorComp.compare(o1, o2);
+
+    }
+}