Exemple #1
0
 /**
  * loop through entry types to get required, optional, general and utility fields for this type.
  */
 private static void refreshFields() {
   if (SQLUtil.allFields == null) {
     SQLUtil.allFields = new ArrayList<>();
   } else {
     SQLUtil.allFields.clear();
   }
   SQLUtil.uniqueListInsert(SQLUtil.allFields, BibtexFields.getAllFieldNames());
   SQLUtil.uniqueListInsert(SQLUtil.allFields, BibtexFields.getAllPrivateFieldNames());
 }
  /**
   * Formats the content of a field.
   *
   * @param s the content of the field
   * @param fieldName the name of the field - used to trigger different serializations, e.g.,
   *     turning off resolution for some strings
   * @return a formatted string suitable for output
   * @throws IllegalArgumentException if s is not a correct bibtex string, e.g., because of
   *     improperly balanced braces or using # not paired
   */
  public String format(String text, String fieldName) throws IllegalArgumentException {

    if (text == null) {
      return valueDelimiterStartOfValue + "" + valueDelimiterEndOfValue;
    }

    if (Globals.prefs.putBracesAroundCapitals(fieldName) && !BIBTEX_STRING.equals(fieldName)) {
      text = StringUtil.putBracesAroundCapitals(text);
    }

    // normalize newlines
    if (!text.contains(Globals.NEWLINE) && text.contains("\n")) {
      // if we don't have real new lines, but pseudo newlines, we replace them
      // On Win 8.1, this is always true for multiline fields
      text = text.replaceAll("\n", Globals.NEWLINE);
    }

    // If the field is non-standard, we will just append braces,
    // wrap and write.
    boolean resolveStrings = true;
    if (resolveStringsAllFields) {
      // Resolve strings for all fields except some:

      String[] exceptions = doNotResolveStringsFors;
      for (String exception : exceptions) {
        if (exception.equals(fieldName)) {
          resolveStrings = false;
          break;
        }
      }
    } else {
      // Default operation - we only resolve strings for standard fields:
      resolveStrings = BibtexFields.isStandardField(fieldName) || BIBTEX_STRING.equals(fieldName);
    }
    if (!resolveStrings) {
      int numberOfBrackets = 0;
      boolean ok = true;
      for (int i = 0; i < text.length(); i++) {
        char c = text.charAt(i);
        // Util.pr(""+c);
        if (c == '{') {
          numberOfBrackets++;
        }
        if (c == '}') {
          numberOfBrackets--;
        }
        if (numberOfBrackets < 0) {
          ok = false;
          break;
        }
      }
      if (numberOfBrackets > 0) {
        ok = false;
      }
      if (!ok) {
        throw new IllegalArgumentException("Curly braces { and } must be balanced.");
      }

      stringBuilder = new StringBuilder(valueDelimiterStartOfValue + "");
      // No formatting at all for these fields, to allow custom formatting?
      //            if (Globals.prefs.getBoolean("preserveFieldFormatting"))
      //              sb.append(text);
      //            else
      //             currently, we do not do any more wrapping
      // these two are also hard coded in
      // net.sf.jabref.importer.fileformat.FieldContentParser.multiLineFields
      // there, JabRefPreferences.NON_WRAPPABLE_FIELDS are also included
      boolean isAbstract = "abstract".equals(fieldName);
      boolean isReview = "review".equals(fieldName);
      boolean doWrap = !isAbstract || !isReview;
      boolean strangePrefSettings =
          writefieldWrapfield && !Globals.prefs.isNonWrappableField(fieldName);

      if (strangePrefSettings && doWrap) {
        stringBuilder.append(
            parser.format(StringUtil.wrap(text, GUIGlobals.LINE_LENGTH), fieldName));
      } else {
        stringBuilder.append(parser.format(text, fieldName));
      }

      stringBuilder.append(valueDelimiterEndOfValue);

      return stringBuilder.toString();
    }

    stringBuilder = new StringBuilder();
    int pivot = 0;
    int pos1;
    int pos2;
    // Here we assume that the user encloses any bibtex strings in #, e.g.:
    // #jan# - #feb#
    // ...which will be written to the file like this:
    // jan # { - } # feb
    checkBraces(text);

    while (pivot < text.length()) {
      int goFrom = pivot;
      pos1 = pivot;
      while (goFrom == pos1) {
        pos1 = text.indexOf('#', goFrom);
        if (pos1 > 0 && text.charAt(pos1 - 1) == '\\') {
          goFrom = pos1 + 1;
          pos1++;
        } else {
          goFrom = pos1 - 1; // Ends the loop.
        }
      }

      if (pos1 == -1) {
        pos1 = text.length(); // No more occurrences found.
        pos2 = -1;
      } else {
        pos2 = text.indexOf('#', pos1 + 1);
        if (pos2 == -1) {
          if (!neverFailOnHashes) {
            throw new IllegalArgumentException(
                Localization.lang(
                        "The # character is not allowed in BibTeX strings unless escaped as in '\\#'.")
                    + '\n'
                    + Localization.lang(
                        "In JabRef, use pairs of # characters to indicate a string.")
                    + '\n'
                    + Localization.lang(
                        "Note that the entry causing the problem has been selected."));
          } else {
            pos1 = text.length(); // just write out the rest of the text, and throw no exception
          }
        }
      }

      if (pos1 > pivot) {
        writeText(text, pivot, pos1);
      }
      if (pos1 < text.length() && pos2 - 1 > pos1) {
        // We check that the string label is not empty. That means
        // an occurrence of ## will simply be ignored. Should it instead
        // cause an error message?
        writeStringLabel(text, pos1 + 1, pos2, pos1 == pivot, pos2 + 1 == text.length());
      }

      if (pos2 > -1) {
        pivot = pos2 + 1;
      } else {
        pivot = pos1 + 1;
        // if (tell++ > 10) System.exit(0);
      }
    }

    // currently, we do not add newlines and new formatting
    if (writefieldWrapfield && !Globals.prefs.isNonWrappableField(fieldName)) {
      //             introduce a line break to be read at the parser
      return parser.format(
          StringUtil.wrap(stringBuilder.toString(), GUIGlobals.LINE_LENGTH),
          fieldName); // , but that lead to ugly .tex

    } else {
      return parser.format(stringBuilder.toString(), fieldName);
    }
  }