예제 #1
0
  @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;
  }
예제 #2
0
  /**
   * 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);
  }
예제 #3
0
  @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;
  }
예제 #4
0
  /**
   * 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);
  }
예제 #5
0
    @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;
 }
예제 #7
0
 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);
 }
예제 #8
0
  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()]);
  }
예제 #9
0
 /**
  * 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;
 }
예제 #10
0
  /**
   * 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;
  }
예제 #11
0
  /**
   * 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;
  }
예제 #12
0
  /**
   * 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();
      }
    }
  }
예제 #13
0
  /**
   * 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);
  }
예제 #14
0
 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;
 }
예제 #15
0
  /** 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;
  }
예제 #16
0
 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;
   }
 }
예제 #17
0
 @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());
 }
예제 #18
0
  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;
   }
 }
예제 #20
0
  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++;
      }
    }
  }
예제 #21
0
 /**
  * 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;
 }
예제 #22
0
 public int compare(BibtexEntry one, BibtexEntry two) {
   return one.getId().compareTo(two.getId());
 }
예제 #23
0
    @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);
 }
예제 #25
0
  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 &amp; Magazines")
            || typeName.equalsIgnoreCase("IEEE Early Access Articles")
            || typeName.equalsIgnoreCase("IET Journals &amp; Magazines")
            || typeName.equalsIgnoreCase("AIP Journals &amp; Magazines")
            || typeName.equalsIgnoreCase("AVS Journals &amp; Magazines")
            || typeName.equalsIgnoreCase("IBM Journals &amp; Magazines")
            || typeName.equalsIgnoreCase("TUP Journals &amp; Magazines")
            || typeName.equalsIgnoreCase("BIAI Journals &amp; 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 &amp; 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 &amp; 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);
    }
  }
예제 #26
0
  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;
  }
예제 #27
0
  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;
  }
예제 #28
0
 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());
     }
   }
 }
예제 #29
0
  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();
  }
예제 #30
0
  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;
  }