1 | /** | | 1 | /** |
2 | * Parse the entries in the source, and return a List of BibtexEntry | | 2 | * Parse the entries in the source, and return a List of BibtexEntry |
3 | * objects. | | 3 | * objects. |
4 | */ | | 4 | */ |
5 | public List<BibtexEntry> importEntries(InputStream stream, OutputPrinter status) throws IOException { | | 5 | public List<BibtexEntry> importEntries(InputStream stream, OutputPrinter status) throws IOException { |
6 | ArrayList<BibtexEntry> bibitems = new ArrayList<BibtexEntry>(); | | 6 | |
7 | StringBuffer sb = new StringBuffer(); | | 7 | ArrayList<BibtexEntry> bibItems = new ArrayList<BibtexEntry>(); |
8 | BufferedReader in = new BufferedReader(ImportFormatReader.getReaderDefaultEncoding(stream)); | | 8 | BufferedReader in = new BufferedReader(ImportFormatReader.getReaderDefaultEncoding(stream)); |
9 | String ENDOFRECORD = "__EOREOR__"; | | 9 | String line; |
10 | | | 10 | HashMap<String, String> hm = new HashMap<String, String>(); |
11 | String str; | | 11 | HashMap<String, StringBuffer> lines = new HashMap<String, StringBuffer>(); |
12 | boolean first = true; | | 12 | StringBuffer previousLine = null; |
13 | while ((str = in.readLine()) != null){ | | 13 | while ((line = in.readLine()) != null){ |
14 | str = str.trim(); | | 14 | if (line.length() == 0) continue; // ignore empty lines, e.g. at file |
15 | // if(str.equals("")) continue; | | 15 | // end |
16 | if (str.indexOf("%0") == 0){ | | 16 | // entry delimiter -> item complete |
17 | if (first){ | | 17 | if (line.equals("------")){ |
18 | first = false; | | 18 | String[] type = new String[2]; |
19 | }else{ | | 19 | String[] pages = new String[2]; |
20 | sb.append(ENDOFRECORD); | | 20 | String country = null; |
21 | } | | 21 | String address = null; |
22 | sb.append(str); | | 22 | String titleST = null; |
23 | }else sb.append(str); | | 23 | String titleTI = null; |
24 | sb.append("\n"); | | 24 | Vector<String> comments = new Vector<String>(); |
25 | } | | 25 | // add item |
26 | | | 26 | for (Map.Entry<String, StringBuffer> entry : lines.entrySet()){ |
27 | String[] entries = sb.toString().split(ENDOFRECORD); | | 27 | if (entry.getKey().equals("AU")) hm.put("author", entry.getValue() |
28 | HashMap<String, String> hm = new HashMap<String, String>(); | | 28 | .toString()); |
29 | String author = "", Type = "", editor = "", artnum = ""; | | 29 | else if (entry.getKey().equals("TI")) titleTI = entry.getValue() |
30 | for (int i = 0; i < entries.length; i++){ | | 30 | .toString(); |
31 | hm.clear(); | | 31 | else if (entry.getKey().equals("ST")) titleST = entry.getValue() |
32 | author = ""; | | 32 | .toString(); |
33 | Type = ""; | | 33 | else if (entry.getKey().equals("YP")) hm.put("year", entry |
34 | editor = ""; | | 34 | .getValue().toString()); |
35 | artnum = ""; | | 35 | else if (entry.getKey().equals("VL")) hm.put("volume", entry |
36 | | | 36 | .getValue().toString()); |
37 | boolean IsEditedBook = false; | | 37 | else if (entry.getKey().equals("NB")) hm.put("number", entry |
38 | String[] fields = entries[i].trim().substring(1).split("\n%"); | | 38 | .getValue().toString()); |
39 | //String lastPrefix = ""; | | 39 | else if (entry.getKey().equals("PS")) pages[0] = entry.getValue() |
40 | for (int j = 0; j < fields.length; j++){ | | 40 | .toString(); |
41 | | | 41 | else if (entry.getKey().equals("PE")) pages[1] = entry.getValue() |
42 | if (fields[j].length() < 3) continue; | | 42 | .toString(); |
43 | | | 43 | else if (entry.getKey().equals("KW")) hm.put("keywords", entry |
44 | /* | | 44 | .getValue().toString()); |
45 | * Details of Refer format for Journal Article and Book: | | 45 | //else if (entry.getKey().equals("RM")) |
46 | * | | 46 | // hm.put("",entry.getValue().toString()); |
47 | * Generic Ref Journal Article Book Code Author %A Author Author Year %D | | 47 | //else if (entry.getKey().equals("RU")) |
48 | * Year Year Title %T Title Title Secondary Author %E Series Editor | | 48 | // hm.put("",entry.getValue().toString()); |
49 | * Secondary Title %B Journal Series Title Place Published %C City | | 49 | else if (entry.getKey().equals("RT")) type[0] = entry.getValue() |
50 | * Publisher %I Publisher Volume %V Volume Volume Number of Volumes %6 | | 50 | .toString(); |
51 | * Number of Volumes Number %N Issue Pages %P Pages Number of Pages | | 51 | else if (entry.getKey().equals("SB")) comments.add("Subject: " |
52 | * Edition %7 Edition Subsidiary Author %? Translator Alternate Title %J | | 52 | + entry.getValue().toString()); |
53 | * Alternate Journal Label %F Label Label Keywords %K Keywords Keywords | | 53 | else if (entry.getKey().equals("SA")) comments |
54 | * Abstract %X Abstract Abstract Notes %O Notes Notes | | 54 | .add("Secondary Authors: " + entry.getValue().toString()); |
55 | */ | | 55 | else if (entry.getKey().equals("NT")) hm.put("note", entry |
56 | | | 56 | .getValue().toString()); |
57 | String prefix = fields[j].substring(0, 1); | | 57 | //else if (entry.getKey().equals("PP")) |
58 | | | 58 | // hm.put("",entry.getValue().toString()); |
59 | String val = fields[j].substring(2); | | 59 | else if (entry.getKey().equals("PB")) hm.put("publisher", entry |
60 | | | 60 | .getValue().toString()); |
61 | if (prefix.equals("A")){ | | 61 | else if (entry.getKey().equals("TA")) comments |
62 | if (author.equals("")) author = val; | | 62 | .add("Tertiary Authors: " + entry.getValue().toString()); |
63 | else author += " and " + val; | | 63 | else if (entry.getKey().equals("TT")) comments |
64 | }else if (prefix.equals("E")){ | | 64 | .add("Tertiary Title: " + entry.getValue().toString()); |
65 | if (editor.equals("")) editor = val; | | 65 | else if (entry.getKey().equals("ED")) hm.put("edition", entry |
66 | else editor += " and " + val; | | 66 | .getValue().toString()); |
67 | }else if (prefix.equals("T")) hm.put("title", val); | | 67 | //else if (entry.getKey().equals("DP")) |
68 | else if (prefix.equals("0")){ | | 68 | // hm.put("",entry.getValue().toString()); |
69 | if (val.indexOf("Journal") == 0) Type = "article"; | | 69 | else if (entry.getKey().equals("TW")) type[1] = entry.getValue() |
70 | else if ((val.indexOf("Book Section") == 0)) Type = "incollection"; | | 70 | .toString(); |
71 | else if ((val.indexOf("Book") == 0)) Type = "book"; | | 71 | else if (entry.getKey().equals("QA")) comments |
72 | else if (val.indexOf("Edited Book") == 0) { | | 72 | .add("Quaternary Authors: " + entry.getValue().toString()); |
73 | Type = "book"; | | 73 | else if (entry.getKey().equals("QT")) comments |
74 | IsEditedBook = true; | | 74 | .add("Quaternary Title: " + entry.getValue().toString()); |
75 | }else if (val.indexOf("Conference") == 0) // Proceedings | | 75 | else if (entry.getKey().equals("IS")) hm.put("isbn", entry |
76 | Type = "inproceedings"; | | 76 | .getValue().toString()); |
77 | else if (val.indexOf("Report") == 0) // Techreport | | 77 | //else if (entry.getKey().equals("LA")) |
78 | Type = "techreport"; | | 78 | // hm.put("",entry.getValue().toString()); |
79 | else if (val.indexOf("Review") == 0) | | 79 | else if (entry.getKey().equals("AB")) hm.put("abstract", entry |
80 | Type = "article"; | | 80 | .getValue().toString()); |
81 | else if (val.indexOf("Thesis") == 0) | | 81 | //else if (entry.getKey().equals("DI")) |
82 | Type = "phdthesis"; | | 82 | // hm.put("",entry.getValue().toString()); |
83 | else Type = "misc"; // | | 83 | //else if (entry.getKey().equals("DM")) |
84 | }else if (prefix.equals("7")) hm.put("edition", val); | | 84 | // hm.put("",entry.getValue().toString()); |
85 | else if (prefix.equals("C")) hm.put("address", val); | | 85 | //else if (entry.getKey().equals("AV")) |
86 | else if (prefix.equals("D")) hm.put("year", val); | | 86 | // hm.put("",entry.getValue().toString()); |
87 | else if (prefix.equals("8")) hm.put("date", val); | | 87 | //else if (entry.getKey().equals("PR")) |
88 | else if (prefix.equals("J")){ | | 88 | // hm.put("",entry.getValue().toString()); |
89 | // "Alternate journal. Let's set it only if no journal | | 89 | //else if (entry.getKey().equals("LO")) |
90 | // has been set with %B. | | 90 | // hm.put("",entry.getValue().toString()); |
91 | if (hm.get("journal") == null) hm.put("journal", val); | | 91 | else if (entry.getKey().equals("AD")) address = entry.getValue() |
92 | }else if (prefix.equals("B")){ | | 92 | .toString(); |
93 | // This prefix stands for "journal" in a journal entry, and | | 93 | else if (entry.getKey().equals("LG")) hm.put("language", entry |
94 | // "series" in a book entry. | | 94 | .getValue().toString()); |
95 | if (Type.equals("article")) hm.put("journal", val); | | 95 | else if (entry.getKey().equals("CO")) country = entry.getValue() |
96 | else if (Type.equals("book") || Type.equals("inbook")) hm.put( | | 96 | .toString(); |
97 | "series", val); | | 97 | else if (entry.getKey().equals("UR") || entry.getKey().equals("AT")){ |
98 | else /* if (Type.equals("inproceedings")) */ | | 98 | String s = entry.getValue().toString().trim(); |
99 | hm.put("booktitle", val); | | 99 | hm.put(s.startsWith("http://") || s.startsWith("ftp://") ? "url" |
100 | }else if (prefix.equals("I")) { | | 100 | : "pdf", entry.getValue().toString()); |
101 | if (Type.equals("phdthesis")) | | 101 | }else if (entry.getKey().equals("C1")) comments.add("Custom1: " |
102 | hm.put("school", val); | | 102 | + entry.getValue().toString()); |
103 | else | | 103 | else if (entry.getKey().equals("C2")) comments.add("Custom2: " |
104 | hm.put("publisher", val); | | 104 | + entry.getValue().toString()); |
105 | } | | 105 | else if (entry.getKey().equals("C3")) comments.add("Custom3: " |
106 | // replace single dash page ranges (23-45) with double dashes (23--45): | | 106 | + entry.getValue().toString()); |
107 | else if (prefix.equals("P")) hm.put("pages", val.replaceAll("([0-9]) *- *([0-9])","$1--$2")); | | 107 | else if (entry.getKey().equals("C4")) comments.add("Custom4: " |
108 | else if (prefix.equals("V")) hm.put("volume", val); | | 108 | + entry.getValue().toString()); |
109 | else if (prefix.equals("N")) hm.put("number", val); | | 109 | //else if (entry.getKey().equals("RD")) |
110 | else if (prefix.equals("U")) hm.put("url", val); | | 110 | // hm.put("",entry.getValue().toString()); |
111 | else if (prefix.equals("R")) { | | 111 | //else if (entry.getKey().equals("MB")) |
112 | String doi = val; | | 112 | // hm.put("",entry.getValue().toString()); |
113 | if (doi.startsWith("doi:")) | | 113 | else if (entry.getKey().equals("C5")) comments.add("Custom5: " |
114 | doi = doi.substring(4); | | 114 | + entry.getValue().toString()); |
115 | hm.put("doi", doi); | | 115 | else if (entry.getKey().equals("C6")) comments.add("Custom6: " |
116 | } | | 116 | + entry.getValue().toString()); |
117 | else if (prefix.equals("O")) { | | 117 | //else if (entry.getKey().equals("FA")) |
118 | // Notes may contain Article number | | 118 | // hm.put("",entry.getValue().toString()); |
119 | if (val.startsWith("Artn")) { | | 119 | //else if (entry.getKey().equals("CN")) |
120 | String[] tokens = val.split("\\s"); | | 120 | // hm.put("",entry.getValue().toString()); |
121 | artnum = tokens[1]; | | 121 | else if (entry.getKey().equals("DE")) hm.put("annote", entry |
122 | } | | 122 | .getValue().toString()); |
123 | else { | | 123 | //else if (entry.getKey().equals("RP")) |
124 | hm.put("note", val); | | 124 | // hm.put("",entry.getValue().toString()); |
125 | } | | 125 | //else if (entry.getKey().equals("DF")) |
126 | } | | 126 | // hm.put("",entry.getValue().toString()); |
127 | else if (prefix.equals("K")) hm.put("keywords", val); | | 127 | //else if (entry.getKey().equals("RS")) |
128 | else if (prefix.equals("X")) hm.put("abstract", val); | | 128 | // hm.put("",entry.getValue().toString()); |
129 | else if (prefix.equals("9")){ | | 129 | else if (entry.getKey().equals("CA")) comments.add("Categories: " |
130 | //Util.pr(val); | | 130 | + entry.getValue().toString()); |
131 | if (val.indexOf("Ph.D.") == 0) Type = "phdthesis"; | | 131 | //else if (entry.getKey().equals("WP")) |
132 | if (val.indexOf("Masters") == 0) Type = "mastersthesis"; | | 132 | // hm.put("",entry.getValue().toString()); |
133 | }else if (prefix.equals("F")) hm.put(BibtexFields.KEY_FIELD, Util | | 133 | else if (entry.getKey().equals("TH")) comments.add("Short Title: " |
134 | .checkLegalKey(val)); | | 134 | + entry.getValue().toString()); |
135 | } | | 135 | //else if (entry.getKey().equals("WR")) |
136 | | | 136 | // hm.put("",entry.getValue().toString()); |
137 | // For Edited Book, EndNote puts the editors in the author field. | | 137 | //else if (entry.getKey().equals("EW")) |
138 | // We want them in the editor field so that bibtex knows it's an edited book | | 138 | // hm.put("",entry.getValue().toString()); |
139 | if (IsEditedBook && editor.equals("")) { | | 139 | else if (entry.getKey().equals("SE")) hm.put("chapter", entry |
140 | editor = author; | | 140 | .getValue().toString()); |
141 | author = ""; | | 141 | //else if (entry.getKey().equals("AC")) |
142 | } | | 142 | // hm.put("",entry.getValue().toString()); |
143 | | | 143 | //else if (entry.getKey().equals("LP")) |
144 | //fixauthorscomma | | 144 | // hm.put("",entry.getValue().toString()); |
145 | if (!author.equals("")) hm.put("author", fixAuthor(author)); | | 145 | } |
146 | if (!editor.equals("")) hm.put("editor", fixAuthor(editor)); | | 146 | |
147 | //if pages missing and article number given, use the article number | | 147 | String bibtexType = "misc"; |
148 | if (((hm.get("pages") == null) || hm.get("pages").equals("-")) && !artnum.equals("")) | | 148 | // to find type, first check TW, then RT |
149 | hm.put("pages", artnum); | | 149 | for (int i = 1; i >= 0 && bibtexType.equals("misc"); --i){ |
150 | | | 150 | if (type[i] == null) continue; |
151 | BibtexEntry b = new BibtexEntry(BibtexFields.DEFAULT_BIBTEXENTRY_ID, Globals | | 151 | type[i] = type[i].toLowerCase(); |
152 | .getEntryType(Type)); // id assumes an existing database so don't | | 152 | if (type[i].indexOf("article") >= 0) bibtexType = "article"; |
153 | // create one here | | 153 | else if (type[i].indexOf("journal") >= 0) bibtexType = "article"; |
154 | b.setField(hm); | | 154 | else if (type[i].indexOf("book section") >= 0) bibtexType = "inbook"; |
155 | //if (hm.isEmpty()) | | 155 | else if (type[i].indexOf("book") >= 0) bibtexType = "book"; |
156 | if (b.getAllFields().size() > 0) | | 156 | else if (type[i].indexOf("conference") >= 0) bibtexType = "inproceedings"; |
157 | bibitems.add(b); | | 157 | else if (type[i].indexOf("proceedings") >= 0) bibtexType = "inproceedings"; |
158 | | | 158 | else if (type[i].indexOf("report") >= 0) bibtexType = "techreport"; |
159 | } | | 159 | else if (type[i].indexOf("thesis") >= 0 |
160 | return bibitems; | | 160 | && type[i].indexOf("master") >= 0) bibtexType = "mastersthesis"; |
161 | | | 161 | else if (type[i].indexOf("thesis") >= 0) bibtexType = "phdthesis"; |
162 | } | | 162 | } |
| | | 163 | |
| | | 164 | // depending on bibtexType, decide where to place the titleRT and |
| | | 165 | // titleTI |
| | | 166 | if (bibtexType.equals("article")){ |
| | | 167 | if (titleST != null) hm.put("journal", titleST); |
| | | 168 | if (titleTI != null) hm.put("title", titleTI); |
| | | 169 | }else if (bibtexType.equals("inbook")){ |
| | | 170 | if (titleST != null) hm.put("booktitle", titleST); |
| | | 171 | if (titleTI != null) hm.put("title", titleTI); |
| | | 172 | }else{ |
| | | 173 | if (titleST != null) hm.put("booktitle", titleST); // should not |
| | | 174 | // happen, I |
| | | 175 | // think |
| | | 176 | if (titleTI != null) hm.put("title", titleTI); |
| | | 177 | } |
| | | 178 | |
| | | 179 | // concatenate pages |
| | | 180 | if (pages[0] != null || pages[1] != null) hm.put("pages", |
| | | 181 | (pages[0] != null ? pages[0] : "") |
| | | 182 | + (pages[1] != null ? "--" + pages[1] : "")); |
| | | 183 | |
| | | 184 | // concatenate address and country |
| | | 185 | if (address != null) hm.put("address", address |
| | | 186 | + (country != null ? ", " + country : "")); |
| | | 187 | |
| | | 188 | if (comments.size() > 0){ // set comment if present |
| | | 189 | StringBuffer s = new StringBuffer(); |
| | | 190 | for (int i = 0; i < comments.size(); ++i) |
| | | 191 | s.append(i > 0 ? "; " : "").append(comments.elementAt(i).toString()); |
| | | 192 | hm.put("comment", s.toString()); |
| | | 193 | } |
| | | 194 | BibtexEntry b = new BibtexEntry(BibtexFields.DEFAULT_BIBTEXENTRY_ID, |
| | | 195 | Globals.getEntryType(bibtexType)); |
| | | 196 | b.setField(hm); |
| | | 197 | bibItems.add(b); |
| | | 198 | |
| | | 199 | hm.clear(); |
| | | 200 | lines.clear(); |
| | | 201 | previousLine = null; |
| | | 202 | |
| | | 203 | continue; |
| | | 204 | } |
| | | 205 | // new key |
| | | 206 | if (line.startsWith("--") && line.length() >= 7 |
| | | 207 | && line.substring(4, 7).equals("-- ")){ |
| | | 208 | lines.put(line.substring(2, 4), previousLine = new StringBuffer(line |
| | | 209 | .substring(7))); |
| | | 210 | continue; |
| | | 211 | } |
| | | 212 | // continuation (folding) of previous line |
| | | 213 | if (previousLine == null) // sanity check; should never happen |
| | | 214 | return null; |
| | | 215 | previousLine.append(line.trim()); |
| | | 216 | } |
| | | 217 | |
| | | 218 | return bibItems; |
| | | 219 | } |