@Override public AbstractUndoableEdit add(BibtexEntry[] entries) { if (!supportsAdd()) { return null; } if (entries != null && entries.length > 0) { NamedCompound ce = new NamedCompound(Globals.lang("add entries to group")); boolean modified = false; for (BibtexEntry entry : entries) { if (!getSearchRule().applyRule(SearchRule.NULL_QUERY, entry)) { String oldContent = entry.getField(searchField); String pre = Globals.prefs.get(JabRefPreferences.GROUP_KEYWORD_SEPARATOR); String newContent = (oldContent == null ? "" : oldContent + pre) + searchExpression; entry.setField(searchField, newContent); // Store undo information. ce.addEdit(new UndoableFieldChange(entry, searchField, oldContent, newContent)); modified = true; } } if (modified) { ce.end(); } return modified ? ce : null; } return null; }
/** * Removes matches of searchString in the entry's field. This is only possible if the search * expression is not a regExp. */ private void removeMatches(BibtexEntry entry) { String content = entry.getField(searchField); if (content == null) { return; // nothing to modify } StringBuffer sbOrig = new StringBuffer(content); StringBuffer sbLower = new StringBuffer(content.toLowerCase()); StringBuffer haystack = caseSensitive ? sbOrig : sbLower; String needle = caseSensitive ? searchExpression : searchExpression.toLowerCase(); int i; int j; int k; final String separator = Globals.prefs.get(JabRefPreferences.GROUP_KEYWORD_SEPARATOR); while ((i = haystack.indexOf(needle)) >= 0) { sbOrig.replace(i, i + needle.length(), ""); sbLower.replace(i, i + needle.length(), ""); // reduce spaces at i to 1 j = i; k = i; while (j - 1 >= 0 && separator.indexOf(haystack.charAt(j - 1)) >= 0) { --j; } while (k < haystack.length() && separator.indexOf(haystack.charAt(k)) >= 0) { ++k; } sbOrig.replace(j, k, j >= 0 && k < sbOrig.length() ? separator : ""); sbLower.replace(j, k, j >= 0 && k < sbOrig.length() ? separator : ""); } String result = sbOrig.toString().trim(); entry.setField(searchField, !result.isEmpty() ? result : null); }
@Override public AbstractUndoableEdit remove(BibtexEntry[] entries) { if (!supportsRemove()) { return null; } if (entries != null && entries.length > 0) { NamedCompound ce = new NamedCompound(Globals.lang("remove from group")); boolean modified = false; for (BibtexEntry entry : entries) { if (getSearchRule().applyRule(SearchRule.NULL_QUERY, entry)) { String oldContent = entry.getField(searchField); removeMatches(entry); // Store undo information. ce.addEdit( new UndoableFieldChange(entry, searchField, oldContent, entry.getField(searchField))); modified = true; } } if (modified) { ce.end(); } return modified ? ce : null; } return null; }
/** * Returns the text stored in the given field of the given bibtex entry which belongs to the given * database. * * <p>If a database is given, this function will try to resolve any string references in the * field-value. Also, if a database is given, this function will try to find values for unset * fields in the entry linked by the "crossref" field, if any. * * @param field The field to return the value of. * @param bibtex maybenull The bibtex entry which contains the field. * @param database maybenull The database of the bibtex entry. * @return The resolved field value or null if not found. */ public static String getResolvedField(String field, BibtexEntry bibtex, BibtexDatabase database) { if (field.equals("bibtextype")) return bibtex.getType().getName(); // TODO: Changed this to also consider alias fields, which is the expected // behavior for the preview layout and for the check whatever all fields are present. // But there might be unwanted side-effects?! Object o = bibtex.getFieldOrAlias(field); // If this field is not set, and the entry has a crossref, try to look up the // field in the referred entry: Do not do this for the bibtex key. if ((o == null) && (database != null) && database.followCrossrefs && !field.equals(BibtexFields.KEY_FIELD)) { Object crossRef = bibtex.getField("crossref"); if (crossRef != null) { BibtexEntry referred = database.getEntryByKey((String) crossRef); if (referred != null) { // Ok, we found the referred entry. Get the field value from that // entry. If it is unset there, too, stop looking: o = referred.getField(field); } } } return getText((String) o, database); }
@Override public void run() { if (!searchAllBases.isSelected()) { // Search only the current database: for (BibtexEntry entry : panel.getDatabase().getEntries()) { boolean hit = rule.applyRule(searchTerm, entry) > 0; entry.setSearchHit(hit); if (hit) { hits++; } } } else { // Search all databases: for (int i = 0; i < frame.getTabbedPane().getTabCount(); i++) { BasePanel p = frame.baseAt(i); for (BibtexEntry entry : p.getDatabase().getEntries()) { boolean hit = rule.applyRule(searchTerm, entry) > 0; entry.setSearchHit(hit); if (hit) { hits++; } } } } }
public BibtexEntry makeBibtexEntry() { BibtexEntry e = new BibtexEntry(IdGenerator.next(), BibtexEntryTypes.INCOLLECTION); e.setField("title", "Marine finfish larviculture in Europe"); e.setField("bibtexkey", "shields01"); e.setField("year", "2001"); e.setField("author", "Kevin Shields"); return e; }
public synchronized boolean setCiteKeyForEntry(String id, String key) { if (!_entries.containsKey(id)) return false; // Entry doesn't exist! BibtexEntry entry = getEntryById(id); String oldKey = entry.getCiteKey(); if (key != null) entry.setField(BibtexFields.KEY_FIELD, key); else entry.clearField(BibtexFields.KEY_FIELD); return checkForDuplicateKeyAndAdd(oldKey, entry.getCiteKey(), false); }
public synchronized BibtexEntry[] getEntriesByKey(String key) { ArrayList<BibtexEntry> entries = new ArrayList<BibtexEntry>(); for (BibtexEntry entry : _entries.values()) { if (key.equals(entry.getCiteKey())) entries.add(entry); } return entries.toArray(new BibtexEntry[entries.size()]); }
/** * Check the database to find out whether any of a set of fields are used for any of the entries. * * @param database The bib database. * @param fields The set of fields to look for. * @return true if at least one of the given fields is set in at least one entry, false otherwise. */ private boolean linksFound(BibtexDatabase database, String[] fields) { for (BibtexEntry entry : database.getEntries()) { for (String field : fields) { if (entry.getField(field) != null) { return true; } } } return false; }
/** * Take the given BibtexEntry and resolve any string references. * * @param entry A BibtexEntry in which all strings of the form #xxx# will be resolved against the * hash map of string references stored in the databasee. * @param inPlace If inPlace is true then the given BibtexEntry will be modified, if false then a * copy is made using close made before resolving the strings. * @return a BibtexEntry with all string references resolved. It is dependent on the value of * inPlace whether a copy is made or the given BibtexEntries is modified. */ public BibtexEntry resolveForStrings(BibtexEntry entry, boolean inPlace) { if (!inPlace) { entry = (BibtexEntry) entry.clone(); } for (Object field : entry.getAllFields()) { entry.setField(field.toString(), this.resolveForStrings(entry.getField(field.toString()))); } return entry; }
/** * Removes the entry with the given string. * * <p>Returns null if not found. */ public synchronized BibtexEntry removeEntry(String id) { BibtexEntry oldValue = _entries.remove(id); if (oldValue == null) return null; removeKeyFromSet(oldValue.getCiteKey()); oldValue.removePropertyChangeListener(listener); fireDatabaseChanged( new DatabaseChangeEvent(this, DatabaseChangeEvent.ChangeType.REMOVED_ENTRY, oldValue)); return oldValue; }
/** * Cycle through all databases, and make sure everything is updated with the new type * customization. This includes making sure all entries have a valid type, that no obsolete entry * editors are around, and that the right-click menus' change type menu is up-to-date. */ private void updateTypesForEntries(String typeName) { if (frame.getTabbedPane().getTabCount() == 0) { return; } for (int i = 0; i < frame.getTabbedPane().getTabCount(); i++) { BasePanel bp = (BasePanel) frame.getTabbedPane().getComponentAt(i); // Invalidate associated cached entry editor bp.entryEditors.remove(typeName); for (BibtexEntry entry : bp.database().getEntries()) { entry.updateType(); } } }
/** * Inserts the entry, given that its ID is not already in use. use Util.createId(...) to make up a * unique ID for an entry. */ public synchronized boolean insertEntry(BibtexEntry entry) throws KeyCollisionException { String id = entry.getId(); if (getEntryById(id) != null) { throw new KeyCollisionException("ID is already in use, please choose another"); } entry.addPropertyChangeListener(listener); _entries.put(id, entry); fireDatabaseChanged( new DatabaseChangeEvent(this, DatabaseChangeEvent.ChangeType.ADDED_ENTRY, entry)); return checkForDuplicateKeyAndAdd(null, entry.getCiteKey(), false); }
private Object getField(BibtexEntry entry) { for (int i = 0; i < field.length; i++) { Object o = entry.getField(field[i]); if (o != null) return o; } return null; }
/** Returns the entry with the given bibtex key. */ public synchronized BibtexEntry getEntryByKey(String key) { BibtexEntry back = null; int keyHash = key.hashCode(); // key hash for better performance Set<String> keySet = _entries.keySet(); for (String entrieID : keySet) { BibtexEntry entry = getEntryById(entrieID); if ((entry != null) && (entry.getCiteKey() != null)) { String citeKey = entry.getCiteKey(); if (citeKey != null) { if (keyHash == citeKey.hashCode()) { back = entry; } } } } return back; }
public void setEntry(BibtexEntry entry) { try { updating = true; for (FieldEditor editor : editors.values()) { Object content = entry.getField(editor.getFieldName()); String toSet = (content == null) ? "" : content.toString(); if (!toSet.equals(editor.getText())) editor.setText(toSet); } this.entry = entry; } finally { updating = false; } }
@Override public boolean contains(BibtexEntry entry) { String content = entry.getField(searchField); if (content == null) { return false; } if (regExp) { return pattern.matcher(content).find(); } if (caseSensitive) { return KeywordGroup.containsWord(searchExpression, content); } return KeywordGroup.containsWord(searchExpression.toLowerCase(), content.toLowerCase()); }
private void parse(ImportInspector dialog, String text, int startIndex, int firstEntryNumber) { piv = startIndex; int entryNumber = firstEntryNumber; if (importBibtex) { // TODO: Login ArrayList<String> idSelected = new ArrayList<String>(); String id; while ((id = parseNextEntryId(text, piv)) != null && shouldContinue) { idSelected.add(id); entryNumber++; } try { BibtexDatabase dbase = parseBibtexDatabase(idSelected, includeAbstract); Collection<BibtexEntry> items = dbase.getEntries(); for (BibtexEntry entry : items) { dialog.addEntry(cleanup(entry)); dialog.setProgress(parsed + unparseable, hits); parsed++; } } catch (IOException e) { e.printStackTrace(); } // for } else { BibtexEntry entry; while ((entry = parseNextEntry(text, piv)) != null && shouldContinue) { if (entry.getField("title") != null) { dialog.addEntry(entry); dialog.setProgress(parsed + unparseable, hits); parsed++; } entryNumber++; } } }
public void setEntry(BibtexEntry entry) { try { updating = true; Iterator<FieldEditor> i = editors.values().iterator(); while (i.hasNext()) { FieldEditor editor = i.next(); Object content = entry.getField(editor.getFieldName()); String toSet = (content == null) ? "" : content.toString(); if (!toSet.equals(editor.getText())) editor.setText(toSet); } this.entry = entry; } finally { updating = false; } }
private void index() { /* Old version, from when set was a TreeSet. // The boolean "changing" is true in the situation that an entry is about to change, // and has temporarily been removed from the entry set in this sorter. So, if we index // now, we will cause exceptions other places because one entry has been left out of // the indexed array. Simply waiting foth this to change can lead to deadlocks, // so we have no other choice than to return without indexing. if (changing) return; */ synchronized (set) { // Resort if necessary: if (changed) { Collections.sort(set, comp); changed = false; } // Create an array of IDs for quick access, since getIdAt() is called by // getValueAt() in EntryTableModel, which *has* to be efficient. int count = set.size(); idArray = new String[count]; entryArray = new BibtexEntry[count]; int piv = 0; for (BibtexEntry entry : set) { // for (int i=0; i<idArray.length; i++) { idArray[piv] = entry.getId(); entryArray[piv] = entry; piv++; } } }
/** * Check whether this entry's required fields are set, taking crossreferenced entries and * either-or fields into account: * * @param entry The entry to check. * @param database The entry's database. * @return True if required fields are set, false otherwise. */ @Override public boolean hasAllRequiredFields(BibtexEntry entry, BibtexDatabase database) { // First check if the bibtex key is set: if (entry.getField(BibtexFields.KEY_FIELD) == null) { return false; } // Then check other fields: boolean[] isSet = new boolean[req.length]; // First check for all fields, whether they are set here or in a crossref'd entry: for (int i = 0; i < req.length; i++) { isSet[i] = BibtexDatabase.getResolvedField(req[i], entry, database) != null; } // Then go through all fields. If a field is not set, see if it is part of an either-or // set where another field is set. If not, return false: for (int i = 0; i < req.length; i++) { if (!isSet[i]) { if (!isCoupledFieldSet(req[i], entry, database)) { return false; } } } // Passed all fields, so return true: return true; }
public int compare(BibtexEntry one, BibtexEntry two) { return one.getId().compareTo(two.getId()); }
@Override public void update() { panel.output(Globals.lang("Searched database. Number of hits") + ": " + hits); // Show the result in the chosen way: if (searchAllBases.isSelected()) { // Search all databases. This means we need to use the search results dialog. // Turn off other search mode, if activated: if (startedFloatSearch) { panel.mainTable.stopShowingFloatSearch(); startedFloatSearch = false; } if (startedFilterSearch) { panel.stopShowingSearchResults(); startedFilterSearch = false; } // Make sure the search dialog is instantiated and cleared: instantiateSearchDialog(); searchDialog.clear(); for (int i = 0; i < frame.getTabbedPane().getTabCount(); i++) { BasePanel p = frame.baseAt(i); for (BibtexEntry entry : p.getDatabase().getEntries()) { if (entry.isSearchHit()) { searchDialog.addEntry(entry, p); } } } searchDialog.selectFirstEntry(); searchDialog.setVisible(true); } else if (showResultsInDialog.isSelected()) { // Turn off other search mode, if activated: if (startedFloatSearch) { panel.mainTable.stopShowingFloatSearch(); startedFloatSearch = false; } if (startedFilterSearch) { panel.stopShowingSearchResults(); startedFilterSearch = false; } // Make sure the search dialog is instantiated and cleared: instantiateSearchDialog(); searchDialog.clear(); for (BibtexEntry entry : panel.getDatabase().getEntries()) { if (entry.isSearchHit()) { searchDialog.addEntry(entry, panel); } } searchDialog.selectFirstEntry(); searchDialog.setVisible(true); } else if (hideSearch.isSelected()) { // Filtering search - removes non-hits from the table: if (startedFloatSearch) { panel.mainTable.stopShowingFloatSearch(); startedFloatSearch = false; } startedFilterSearch = true; panel.setSearchMatcher(new SearchMatcher()); } else { // Float search - floats hits to the top of the table: if (startedFilterSearch) { panel.stopShowingSearchResults(); startedFilterSearch = false; } startedFloatSearch = true; panel.mainTable.showFloatSearch(new SearchMatcher()); } // Afterwards, select all text in the search field. searchField.select(0, searchField.getText().length()); }
public boolean hasAllRequiredFields(BibtexEntry entry, BibtexDatabase database) { return entry.allFieldsPresent(getRequiredFields(), database); }
private BibtexEntry parseNextEntry(String allText, int startIndex) { BibtexEntry entry = null; int index = allText.indexOf("<div class=\"detail", piv); int endIndex = allText.indexOf("</div>", index); if (index >= 0 && endIndex > 0) { endIndex += 6; piv = endIndex; String text = allText.substring(index, endIndex); BibtexEntryType type = null; String sourceField = null; String typeName = ""; Matcher typeMatcher = typePattern.matcher(text); if (typeMatcher.find()) { typeName = typeMatcher.group(1); if (typeName.equalsIgnoreCase("IEEE Journals & Magazines") || typeName.equalsIgnoreCase("IEEE Early Access Articles") || typeName.equalsIgnoreCase("IET Journals & Magazines") || typeName.equalsIgnoreCase("AIP Journals & Magazines") || typeName.equalsIgnoreCase("AVS Journals & Magazines") || typeName.equalsIgnoreCase("IBM Journals & Magazines") || typeName.equalsIgnoreCase("TUP Journals & Magazines") || typeName.equalsIgnoreCase("BIAI Journals & Magazines")) { type = BibtexEntryType.getType("article"); sourceField = "journal"; } else if (typeName.equalsIgnoreCase("IEEE Conference Publications") || typeName.equalsIgnoreCase("IET Conference Publications") || typeName.equalsIgnoreCase("VDE Conference Publications")) { type = BibtexEntryType.getType("inproceedings"); sourceField = "booktitle"; } else if (typeName.equalsIgnoreCase("IEEE Standards") || typeName.equalsIgnoreCase("Standards")) { type = BibtexEntryType.getType("standard"); sourceField = "number"; } else if (typeName.equalsIgnoreCase("IEEE eLearning Library Courses")) { type = BibtexEntryType.getType("Electronic"); sourceField = "note"; } else if (typeName.equalsIgnoreCase("Wiley-IEEE Press eBook Chapters") || typeName.equalsIgnoreCase("MIT Press eBook Chapters") || typeName.equalsIgnoreCase("IEEE USA Books & eBooks")) { type = BibtexEntryType.getType("inCollection"); sourceField = "booktitle"; } } if (type == null) { type = BibtexEntryType.getType("misc"); sourceField = "note"; System.err.println("Type detection failed. Use MISC instead."); unparseable++; System.err.println(text); } entry = new BibtexEntry(IdGenerator.next(), type); if (typeName.equalsIgnoreCase("IEEE Standards")) { entry.setField("organization", "IEEE"); } if (typeName.equalsIgnoreCase("Wiley-IEEE Press eBook Chapters")) { entry.setField("publisher", "Wiley-IEEE Press"); } else if (typeName.equalsIgnoreCase("MIT Press eBook Chapters")) { entry.setField("publisher", "MIT Press"); } else if (typeName.equalsIgnoreCase("IEEE USA Books & eBooks")) { entry.setField("publisher", "IEEE USA"); } if (typeName.equalsIgnoreCase("IEEE Early Access Articles")) { entry.setField("note", "Early Access"); } Set<String> fields = fieldPatterns.keySet(); for (String field : fields) { Matcher fieldMatcher = Pattern.compile(fieldPatterns.get(field)).matcher(text); if (fieldMatcher.find()) { entry.setField(field, htmlConverter.format(fieldMatcher.group(1))); if (field.equals("title") && fieldMatcher.find()) { String sec_title = htmlConverter.format(fieldMatcher.group(1)); if (entry.getType() == BibtexEntryType.getStandardType("standard")) { sec_title = sec_title.replaceAll("IEEE Std ", ""); } entry.setField(sourceField, sec_title); } if (field.equals("pages") && fieldMatcher.groupCount() == 2) { entry.setField(field, fieldMatcher.group(1) + "-" + fieldMatcher.group(2)); } } } Matcher authorMatcher = authorPattern.matcher(text); // System.out.println(text); StringBuilder authorNames = new StringBuilder(""); int authorCount = 0; while (authorMatcher.find()) { if (authorCount >= 1) { authorNames.append(" and "); } authorNames.append(htmlConverter.format(authorMatcher.group(1))); // System.out.println(authorCount + ": " + authorMatcher.group(1)); authorCount++; } entry.setField("author", authorNames.toString()); if (entry.getField("author") == null || entry.getField("author").startsWith("a href") || entry .getField("author") .startsWith("Topic(s)")) { // Fix for some documents without authors entry.setField("author", ""); } if (entry.getType() == BibtexEntryType.getStandardType("inproceedings") && entry.getField("author").equals("")) { entry.setType(BibtexEntryType.getStandardType("proceedings")); } if (includeAbstract) { index = text.indexOf("id=\"abstract"); if (index >= 0) { endIndex = text.indexOf("</div>", index) + 6; text = text.substring(index, endIndex); Matcher absMatcher = absPattern.matcher(text); if (absMatcher.find()) { // Clean-up abstract String abstr = absMatcher.group(1); abstr = abstr.replaceAll("<span class='snippet'>([\\w]+)</span>", "$1"); entry.setField("abstract", htmlConverter.format(abstr)); } } } } if (entry == null) { return null; } else { return cleanup(entry); } }
private BibtexEntry cleanup(BibtexEntry entry) { if (entry == null) { return null; } // clean up title String title = entry.getField("title"); if (title != null) { // USe the alt-text and replace image links title = title.replaceAll("[ ]?img src=[^ ]+ alt=\"([^\"]+)\">[ ]?", "\\$$1\\$"); // Try to sort out most of the /spl / conversions // Deal with this specific nested type first title = title.replaceAll("/sub /spl infin//", "\\$_\\\\infty\\$"); title = title.replaceAll("/sup /spl infin//", "\\$\\^\\\\infty\\$"); // Replace general expressions title = title.replaceAll("/[sS]pl ([^/]+)/", "\\$\\\\$1\\$"); // Deal with subscripts and superscripts if (Globals.prefs.getBoolean(JabRefPreferences.USE_CONVERT_TO_EQUATION)) { title = title.replaceAll("/sup ([^/]+)/", "\\$\\^\\{$1\\}\\$"); title = title.replaceAll("/sub ([^/]+)/", "\\$_\\{$1\\}\\$"); title = title.replaceAll("\\(sup\\)([^(]+)\\(/sup\\)", "\\$\\^\\{$1\\}\\$"); title = title.replaceAll("\\(sub\\)([^(]+)\\(/sub\\)", "\\_\\{$1\\}\\$"); } else { title = title.replaceAll("/sup ([^/]+)/", "\\\\textsuperscript\\{$1\\}"); title = title.replaceAll("/sub ([^/]+)/", "\\\\textsubscript\\{$1\\}"); title = title.replaceAll("\\(sup\\)([^(]+)\\(/sup\\)", "\\\\textsuperscript\\{$1\\}"); title = title.replaceAll("\\(sub\\)([^(]+)\\(/sub\\)", "\\\\textsubscript\\{$1\\}"); } // Replace \infin with \infty title = title.replaceAll("\\\\infin", "\\\\infty"); // Unit formatting if (Globals.prefs.getBoolean(JabRefPreferences.USE_UNIT_FORMATTER_ON_SEARCH)) { title = unitFormatter.format(title); } // Automatic case keeping if (Globals.prefs.getBoolean(JabRefPreferences.USE_CASE_KEEPER_ON_SEARCH)) { title = caseKeeper.format(title); } // Write back entry.setField("title", title); } // clean up author /* String author = (String)entry.getField("author"); if (author != null) { if (author.indexOf("a href=") >= 0) { // Author parsing failed because it was empty entry.setField("author",""); // Maybe not needed anymore due to another change } else { author = author.replaceAll("\\s+", " "); author = author.replaceAll("\\.", ". "); author = author.replaceAll("([^;]+),([^;]+),([^;]+)","$1,$3,$2"); // Change order in case of Jr. etc author = author.replaceAll(" ", " "); author = author.replaceAll("\\. -", ".-"); author = author.replaceAll("; ", " and "); author = author.replaceAll(" ,", ","); author = author.replaceAll(" ", " "); author = author.replaceAll("[ ,;]+$", ""); entry.setField("author", author); } }*/ // clean up month String month = entry.getField("month"); if (month != null && !month.isEmpty()) { month = month.replaceAll("\\.", ""); month = month.toLowerCase(); Pattern monthPattern = Pattern.compile("(\\d*+)\\s*([a-z]*+)-*(\\d*+)\\s*([a-z]*+)"); Matcher mm = monthPattern.matcher(month); String date = month; if (mm.find()) { if (mm.group(3).isEmpty()) { if (!mm.group(2).isEmpty()) { date = "#" + mm.group(2).substring(0, 3) + "#"; if (!mm.group(1).isEmpty()) { date += " " + mm.group(1) + ","; } } else { date = mm.group(1) + ","; } } else if (mm.group(2).isEmpty()) { if (!mm.group(4).isEmpty()) { date = "#" + mm.group(4).substring(0, 3) + "# " + mm.group(1) + "--" + mm.group(3) + ","; } else { date += ","; } } else { date = "#" + mm.group(2).substring(0, 3) + "# " + mm.group(1) + "--#" + mm.group(4).substring(0, 3) + "# " + mm.group(3) + ","; } } // date = date.trim(); // if (!date.isEmpty()) { entry.setField("month", date); // } } // clean up pages String field = "pages"; String pages = entry.getField(field); if (pages != null) { String[] pageNumbers = pages.split("-"); if (pageNumbers.length == 2) { if (pageNumbers[0].equals(pageNumbers[1])) { // single page entry.setField(field, pageNumbers[0]); } else { entry.setField(field, pages.replaceAll("-", "--")); } } } // clean up publication field BibtexEntryType type = entry.getType(); String sourceField = ""; if (type.getName().equals("Article")) { sourceField = "journal"; entry.clearField("booktitle"); } else if (type.getName().equals("Inproceedings")) { sourceField = "booktitle"; } String fullName = entry.getField(sourceField); if (fullName != null) { if (type.getName().equals("Article")) { int ind = fullName.indexOf(": Accepted for future publication"); if (ind > 0) { fullName = fullName.substring(0, ind); entry.setField("year", "to be published"); entry.clearField("month"); entry.clearField("pages"); entry.clearField("number"); } String[] parts = fullName.split("[\\[\\]]"); // [see also...], [legacy...] fullName = parts[0]; if (parts.length == 3) { fullName += parts[2]; } if (entry.getField("note").equals("Early Access")) { entry.setField("year", "to be published"); entry.clearField("month"); entry.clearField("pages"); entry.clearField("number"); } } else { fullName = fullName .replace("Conference Proceedings", "Proceedings") .replace("Proceedings of", "Proceedings") .replace("Proceedings.", "Proceedings"); fullName = fullName.replaceAll("International", "Int."); fullName = fullName.replaceAll("Symposium", "Symp."); fullName = fullName.replaceAll("Conference", "Conf."); fullName = fullName.replaceAll(" on", " ").replace(" ", " "); } Matcher m1 = publicationPattern.matcher(fullName); String abrvPattern = ".*[^,] '?\\d+\\)?"; if (m1.find()) { String prefix = m1.group(2).trim(); String postfix = m1.group(1).trim(); String abrv = ""; String[] parts = prefix.split("\\. ", 2); if (parts.length == 2) { if (parts[0].matches(abrvPattern)) { prefix = parts[1]; abrv = parts[0]; } else { prefix = parts[0]; abrv = parts[1]; } } if (!prefix.matches(abrvPattern)) { fullName = prefix + " " + postfix + " " + abrv; fullName = fullName.trim(); } else { fullName = postfix + " " + prefix; } } if (type.getName().equals("Article")) { fullName = fullName.replace(" - ", "-"); // IEE Proceedings- fullName = fullName.trim(); if (Globals.prefs.getBoolean(JabRefPreferences.USE_IEEE_ABRV)) { fullName = Globals.journalAbbrev.getMedlineAbbreviation(fullName).orElse(fullName); } } if (type.getName().equals("Inproceedings")) { Matcher m2 = proceedingPattern.matcher(fullName); if (m2.find()) { String prefix = m2.group(2); String postfix = m2.group(1).replaceAll("\\.$", ""); if (!prefix.matches(abrvPattern)) { String abrv = ""; String[] parts = postfix.split("\\. ", 2); if (parts.length == 2) { if (parts[0].matches(abrvPattern)) { postfix = parts[1]; abrv = parts[0]; } else { postfix = parts[0]; abrv = parts[1]; } } fullName = prefix.trim() + " " + postfix.trim() + " " + abrv; } else { fullName = postfix.trim() + " " + prefix.trim(); } } fullName = fullName.trim(); fullName = fullName.replaceAll("^[tT]he ", "").replaceAll("^\\d{4} ", "").replaceAll("[,.]$", ""); String year = entry.getField("year"); fullName = fullName.replaceAll(", " + year + "\\.?", ""); if (!fullName.contains("Abstract") && !fullName.contains("Summaries") && !fullName.contains("Conference Record")) { fullName = "Proc. " + fullName; } } entry.setField(sourceField, fullName); } // clean up abstract String abstr = entry.getField("abstract"); if (abstr != null) { // Try to sort out most of the /spl / conversions // Deal with this specific nested type first abstr = abstr.replaceAll("/sub /spl infin//", "\\$_\\\\infty\\$"); abstr = abstr.replaceAll("/sup /spl infin//", "\\$\\^\\\\infty\\$"); // Replace general expressions abstr = abstr.replaceAll("/[sS]pl ([^/]+)/", "\\$\\\\$1\\$"); // Deal with subscripts and superscripts if (Globals.prefs.getBoolean(JabRefPreferences.USE_CONVERT_TO_EQUATION)) { abstr = abstr.replaceAll("/sup ([^/]+)/", "\\$\\^\\{$1\\}\\$"); abstr = abstr.replaceAll("/sub ([^/]+)/", "\\$_\\{$1\\}\\$"); abstr = abstr.replaceAll("\\(sup\\)([^(]+)\\(/sup\\)", "\\$\\^\\{$1\\}\\$"); abstr = abstr.replaceAll("\\(sub\\)([^(]+)\\(/sub\\)", "\\_\\{$1\\}\\$"); } else { abstr = abstr.replaceAll("/sup ([^/]+)/", "\\\\textsuperscript\\{$1\\}"); abstr = abstr.replaceAll("/sub ([^/]+)/", "\\\\textsubscript\\{$1\\}"); abstr = abstr.replaceAll("\\(sup\\)([^(]+)\\(/sup\\)", "\\\\textsuperscript\\{$1\\}"); abstr = abstr.replaceAll("\\(sub\\)([^(]+)\\(/sub\\)", "\\\\textsubscript\\{$1\\}"); } // Replace \infin with \infty abstr = abstr.replaceAll("\\\\infin", "\\\\infty"); // Write back entry.setField("abstract", abstr); } // Clean up url String url = entry.getField("url"); if (url != null) { entry.setField("url", "http://ieeexplore.ieee.org" + url.replace("tp=&", "")); } return entry; }
private boolean importPdfFiles(List<String> fileNames) { if (panel == null) return false; for (String fileName : fileNames) { List<BibtexEntry> xmpEntriesInFile = readXmpEntries(fileName); ImportDialog importDialog = new ImportDialog(dropRow, fileName); if (!hasXmpEntries(xmpEntriesInFile)) { importDialog.getRadioButtonXmp().setEnabled(false); } Tools.centerRelativeToWindow(importDialog, frame); importDialog.showDialog(); if (importDialog.getResult() == JOptionPane.OK_OPTION) { if (importDialog.getRadioButtonXmp().isSelected()) { // SplDatabaseChangeListener dataListener = new SplDatabaseChangeListener(frame, panel, // entryTable, fileName); // panel.database().addDatabaseChangeListener(dataListener); ImportMenuItem importer = new ImportMenuItem(frame, (entryTable == null)); importer.automatedImport(new String[] {fileName}); } else if (importDialog.getRadioButtonMrDlib().isSelected()) { MetaDataListDialog metaDataListDialog = new MetaDataListDialog(fileName, true); Tools.centerRelativeToWindow(metaDataListDialog, frame); metaDataListDialog.showDialog(); XmlDocuments documents = metaDataListDialog.getXmlDocuments(); if (documents != null && documents.getDocuments() != null && documents.getDocuments().size() > 0 && metaDataListDialog.getResult() == JOptionPane.OK_OPTION) { int selected = metaDataListDialog.getTableMetadata().getSelectedRow(); if (selected > -1 && selected < documents.getDocuments().size()) { XmlDocument document = documents.getDocuments().get(selected); String id = Util.createNeutralId(); BibtexEntry entry = new BibtexEntry(id); if (fieldExists(document.getType())) { BibtexEntryType type = BibtexEntryType.getStandardType(document.getType()); if (type == null) { type = BibtexEntryType.ARTICLE; } entry.setType(type); } else { entry.setType(BibtexEntryType.ARTICLE); } ArrayList<BibtexEntry> list = new ArrayList<BibtexEntry>(); list.add(entry); Util.setAutomaticFields(list, true, true, false); insertFields(entry.getRequiredFields(), entry, document); insertFields(entry.getGeneralFields(), entry, document); insertFields(entry.getOptionalFields(), entry, document); panel.database().insertEntry(entry); DroppedFileHandler dfh = new DroppedFileHandler(frame, panel); dfh.linkPdfToEntry(fileName, entryTable, entry); LabelPatternUtil.makeLabel(Globals.prefs.getKeyPattern(), panel.database(), entry); } else { createNewBlankEntry(fileName); } } else if (metaDataListDialog.getResult() == JOptionPane.CANCEL_OPTION) { continue; } else if (metaDataListDialog.getResult() == JOptionPane.NO_OPTION) { createNewBlankEntry(fileName); } else if (documents == null || documents.getDocuments() == null || documents.getDocuments().size() <= 0 && metaDataListDialog.getResult() == JOptionPane.OK_OPTION) { createNewBlankEntry(fileName); } } else if (importDialog.getRadioButtonNoMeta().isSelected()) { createNewBlankEntry(fileName); } else if (importDialog.getRadioButtonUpdateEmptyFields().isSelected()) { MetaDataListDialog metaDataListDialog = new MetaDataListDialog(fileName, false); Tools.centerRelativeToWindow(metaDataListDialog, frame); metaDataListDialog.showDialog(); XmlDocuments documents = metaDataListDialog.getXmlDocuments(); if (documents != null && documents.getDocuments() != null && documents.getDocuments().size() > 0 && metaDataListDialog.getResult() == JOptionPane.OK_OPTION) { int selected = metaDataListDialog.getTableMetadata().getSelectedRow(); if (selected > -1 && selected < documents.getDocuments().size()) { XmlDocument document = documents.getDocuments().get(selected); BibtexEntry entry = entryTable.getEntryAt(dropRow); if (fieldExists(document.getType())) { BibtexEntryType type = BibtexEntryType.getStandardType(document.getType()); if (type != null) { entry.setType(type); } } insertFields(entry.getRequiredFields(), entry, document); insertFields(entry.getGeneralFields(), entry, document); insertFields(entry.getOptionalFields(), entry, document); DroppedFileHandler dfh = new DroppedFileHandler(frame, panel); dfh.linkPdfToEntry(fileName, entryTable, dropRow); } } } else if (importDialog.getRadioButtononlyAttachPDF().isSelected()) { DroppedFileHandler dfh = new DroppedFileHandler(frame, panel); dfh.linkPdfToEntry(fileName, entryTable, dropRow); } } } return true; }
private void insertFields(String[] fields, BibtexEntry entry, XmlDocument xmlDocument) { DocumentWrapper document = new DocumentWrapper(xmlDocument); for (String field : fields) { if (entry.getField(field) != null) { continue; } if (field.equalsIgnoreCase("author")) { entry.setField(field, document.getAuthors("and")); } if (field.equalsIgnoreCase("title")) { entry.setField(field, document.getTitle()); } if (field.equalsIgnoreCase("abstract")) { entry.setField(field, document.getAbstract()); } if (field.equalsIgnoreCase("keywords")) { entry.setField(field, document.getKeyWords()); } if (field.equalsIgnoreCase("doi")) { entry.setField(field, document.getDoi()); } if (field.equalsIgnoreCase("pages")) { entry.setField(field, document.getPages()); } if (field.equalsIgnoreCase("volume")) { entry.setField(field, document.getVolume()); } if (field.equalsIgnoreCase("number")) { entry.setField(field, document.getNumber()); } if (field.equalsIgnoreCase("year")) { entry.setField(field, document.getYear()); } if (field.equalsIgnoreCase("month")) { entry.setField(field, document.getMonth()); } if (field.equalsIgnoreCase("day")) { entry.setField(field, document.getDay()); } if (field.equalsIgnoreCase("booktitle")) { entry.setField(field, document.getVenue()); } if (field.equalsIgnoreCase("journal")) { entry.setField(field, document.getVenue()); } } }
public void run() { if (!goOn) return; for (int i = 0; i < entries.length; i++) { BibtexEntry entry = entries[i]; // Make a list of all PDFs linked from this entry: List<File> files = new ArrayList<File>(); // First check the (legacy) "pdf" field: String pdf = entry.getField("pdf"); String dir = panel.metaData().getFileDirectory("pdf"); File f = Util.expandFilename(pdf, new String[] {dir, "."}); if (f != null) files.add(f); // Then check the "file" field: dir = panel.metaData().getFileDirectory(GUIGlobals.FILE_FIELD); String field = entry.getField(GUIGlobals.FILE_FIELD); if (field != null) { FileListTableModel tm = new FileListTableModel(); tm.setContent(field); for (int j = 0; j < tm.getRowCount(); j++) { FileListEntry flEntry = tm.getEntry(j); if ((flEntry.getType() != null) && (flEntry.getType().getName().toLowerCase().equals("pdf"))) { f = Util.expandFilename(flEntry.getLink(), new String[] {dir, "."}); if (f != null) files.add(f); } } } optDiag.progressArea.append(entry.getCiteKey() + "\n"); if (files.size() == 0) { skipped++; optDiag.progressArea.append(" " + Globals.lang("Skipped - No PDF linked") + ".\n"); } else for (File file : files) { if (!file.exists()) { skipped++; optDiag.progressArea.append( " " + Globals.lang("Skipped - PDF does not exist") + ":\n"); optDiag.progressArea.append(" " + file.getPath() + "\n"); } else { try { XMPUtil.writeXMP(file, entry, database); optDiag.progressArea.append(" " + Globals.lang("Ok") + ".\n"); entriesChanged++; } catch (Exception e) { optDiag.progressArea.append( " " + Globals.lang("Error while writing") + " '" + file.getPath() + "':\n"); optDiag.progressArea.append(" " + e.getLocalizedMessage() + "\n"); errors++; } } } if (optDiag.canceled) { optDiag.progressArea.append("\n" + Globals.lang("Operation canceled.\n")); break; } } optDiag.progressArea.append( "\n" + Globals.lang( "Finished writing XMP for %0 file (%1 skipped, %2 errors).", String.valueOf(entriesChanged), String.valueOf(skipped), String.valueOf(errors))); optDiag.done(); }
public int compare(BibtexEntry e1, BibtexEntry e2) { Object f1, f2; if (isTypeHeader) { // Sort by type. f1 = e1.getType().getName(); f2 = e2.getType().getName(); } else { // If the field is author or editor, we rearrange names so they are // sorted according to last name. f1 = getField(e1); f2 = getField(e2); } /* * [ 1598777 ] Month sorting * * http://sourceforge.net/tracker/index.php?func=detail&aid=1598777&group_id=92314&atid=600306 */ int localMultiplier = multiplier; if (isMonthField) localMultiplier = -localMultiplier; // Catch all cases involving null: if (f1 == null) return f2 == null ? 0 : localMultiplier; if (f2 == null) return -localMultiplier; // Now we now that both f1 and f2 are != null if (isNameField) { f1 = AuthorList.fixAuthorForAlphabetization((String) f1); f2 = AuthorList.fixAuthorForAlphabetization((String) f2); } else if (isYearField) { /* * [ 1285977 ] Impossible to properly sort a numeric field * * http://sourceforge.net/tracker/index.php?func=detail&aid=1285977&group_id=92314&atid=600307 */ f1 = Util.toFourDigitYear((String) f1); f2 = Util.toFourDigitYear((String) f2); } else if (isMonthField) { /* * [ 1535044 ] Month sorting * * http://sourceforge.net/tracker/index.php?func=detail&aid=1535044&group_id=92314&atid=600306 */ f1 = new Integer(Util.getMonthNumber((String) f1)); f2 = new Integer(Util.getMonthNumber((String) f2)); } if (isNumeric) { Integer i1 = null, i2 = null; try { i1 = Integer.parseInt((String) f1); } catch (NumberFormatException ex) { // Parsing failed. } try { i2 = Integer.parseInt((String) f2); } catch (NumberFormatException ex) { // Parsing failed. } if (i2 != null && i1 != null) { // Ok, parsing was successful. Update f1 and f2: f1 = i1; f2 = i2; } else if (i1 != null) { // The first one was parseable, but not the second one. // This means we consider one < two f1 = i1; f2 = new Integer(i1.intValue() + 1); } else if (i2 != null) { // The second one was parseable, but not the first one. // This means we consider one > two f2 = i2; f1 = new Integer(i2.intValue() + 1); } // Else none of them were parseable, and we can fall back on comparing strings. } int result = 0; if ((f1 instanceof Integer) && (f2 instanceof Integer)) { result = (((Integer) f1).compareTo((Integer) f2)); } else if (f2 instanceof Integer) { Integer f1AsInteger = new Integer(f1.toString()); result = -((f1AsInteger).compareTo((Integer) f2)); } else if (f1 instanceof Integer) { Integer f2AsInteger = new Integer(f2.toString()); result = -(((Integer) f1).compareTo(f2AsInteger)); } else { String ours = ((String) f1).toLowerCase(), theirs = ((String) f2).toLowerCase(); result = collator.compare(ours, theirs); // ours.compareTo(theirs); } return result * localMultiplier; }