/** * 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); } }