public void TestCreateNew() { if (Globals.prefs == null) { Globals.prefs = JabRefPreferences.getInstance(); } BibtexDatabase db = new BibtexDatabase(); BibtexEntry entry = new BibtexEntry(); entry.setType(BibtexEntryType.ARTICLE.Instance); db.insertEntry(entry); db.setCiteKeyForEntry(entry.getId(), "ZXY"); foreach (var f in entry.getRequiredFields()) { string value = BibtexFields.isNumeric(f) ? "1000" : "Test"; entry.setField(f, value); } db.saveDatabase(File.Open(@"C:\Users\Peter\Desktop\bibtest.bib", FileMode.Create)); }
/** * Determines whether this entry has all the given fields present. If a non-null * database argument is given, this method will try to look up missing fields in * entries linked by the "crossref" field, if any. * * @param fields An array of field names to be checked. * @param database The database in which to look up crossref'd entries, if any. This * argument can be null, meaning that no attempt will be made to follow crossrefs. * @return true if all fields are set or could be resolved, false otherwise. */ public bool allFieldsPresent(string[] fields, BibtexDatabase database) { for (int i = 0; i < fields.Length; i++) { if (BibtexDatabase.getResolvedField(fields[i], this, database) == null) { return false; } } return true; }
/** * Returns true if this entry Contains the fields it needs to be * complete. */ public bool hasAllRequiredFields(BibtexDatabase database) { return _type.hasAllRequiredFields(this, database); }
protected bool isCoupledFieldSet(string field, BibtexEntry entry, BibtexDatabase database) { if (reqSets == null) return false; for (int i=0; i<reqSets.Length; i++) { bool takesPart = false, oneSet = false; for (int j=0; j<reqSets[i].Length; j++) { // If this is the field we're looking for, note that the field is part of the set: if (reqSets[i][j].Equals(field, System.StringComparison.CurrentCultureIgnoreCase)) takesPart = true; // If it is a different field, check if it is set: else if (BibtexDatabase.getResolvedField(reqSets[i][j], entry, database) != null) oneSet = true; } // Ths the field is part of the set, and at least one other field is set, return true: if (takesPart && oneSet) return true; } // No hits, so return false: return false; }
/** * 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. */ public override bool hasAllRequiredFields(BibtexEntry entry, BibtexDatabase database) { // First check if the bibtex key is set: if (entry.getField(Globals.KEY_FIELD) == null) return false; // Then check other fields: bool[] isSet = new bool[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; }
/** * Returns the text stored in the given field of the given bibtex entry * which belongs to the given database. * * 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(); object o = bibtex.getField(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(Globals.KEY_FIELD) && (database != null)) { 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); }
/** * Returns a text with references resolved according to an optionally given * database. * @param toResolve maybenull The text to resolve. * @param database maybenull The database to use for resolving the text. * @return The resolved text or the original text if either the text or the database are null */ public static string getText(string toResolve, BibtexDatabase database) { if (toResolve != null && database != null) return database.resolveForStrings(toResolve); return toResolve; }
public override bool hasAllRequiredFields(BibtexEntry entry, BibtexDatabase database) { return true; }
private void importBibTexFromClipBoardToolStripMenuItem_Click(object sender, EventArgs e) { if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Text)) { BibtexParser parser = new BibtexParser(new StringReader(Clipboard.GetDataObject().GetData(DataFormats.Text).ToString())); var result = parser.Parse(); db = result.Database; foreach (var entry in db.getEntries()) AddBibTeXEntry(entry); } }
private static Regex refPat = new Regex("(#[A-Za-z]+#)"); // Used to detect string references in strings #endregion Fields #region Methods /* * We have begun to use getSortedEntries() for both database save operations * and non-database save operations. In a non-database save operation * (such as the exportDatabase call), we do not wish to use the * global preference of saving in standard order. */ public static List<BibtexEntry> getSortedEntries(BibtexDatabase database, ICollection<string> keySet, bool isSaveOperation) { var comparators = new List<IComparer<BibtexEntry>>(); bool inOriginalOrder = isSaveOperation ? Globals.prefs.getBoolean("saveInOriginalOrder") : Globals.prefs.getBoolean("exportInOriginalOrder"); if (inOriginalOrder) { // Sort entries based on their creation order, utilizing the fact // that IDs used for entries are increasing, sortable numbers. comparators.Add(new CrossRefEntryComparator()); comparators.Add(new IdComparator()); } else { string pri, sec, ter; bool priD, secD, terD = false; bool inStandardOrder = isSaveOperation ? Globals.prefs.getBoolean("saveInStandardOrder") : Globals.prefs.getBoolean("exportInStandardOrder"); if (!inStandardOrder) { // The setting is to save according to the current table order. pri = Globals.prefs.get("priSort"); sec = Globals.prefs.get("secSort"); // sorted as they appear on the screen. ter = Globals.prefs.get("terSort"); priD = Globals.prefs.getBoolean("priDescending"); secD = Globals.prefs.getBoolean("secDescending"); terD = Globals.prefs.getBoolean("terDescending"); } else { // The setting is to save in standard order: author, editor, year pri = "author"; sec = "editor"; ter = "year"; priD = false; secD = false; terD = true; } if (isSaveOperation) comparators.Add(new CrossRefEntryComparator()); comparators.Add(new FieldComparator(pri, priD)); comparators.Add(new FieldComparator(sec, secD)); comparators.Add(new FieldComparator(ter, terD)); comparators.Add(new FieldComparator(Globals.KEY_FIELD)); } List<BibtexEntry> entries = new List<BibtexEntry>(); if (keySet == null) keySet = database.getKeySet(); if (keySet != null) { var i = keySet.GetEnumerator(); for (; i.MoveNext(); ) { entries.Add(database.getEntryById((i.Current))); } } entries.Sort(new FieldComparatorStack<BibtexEntry>(comparators)); return entries; }
/** * Write all strings in alphabetical order, modified to produce a safe (for BibTeX) order of the strings * if they reference each other. * @param fw The Writer to send the output to. * @param database The database whose strings we should write. * @throws IOException If anthing goes wrong in writing. */ private static void writeStrings(TextWriter fw, BibtexDatabase database) { List<BibtexString> strings = new List<BibtexString>(); foreach (var s in database.getStringKeySet()) { strings.Add(database.getString(s)); } strings.Sort(new BibtexStringComparator(true)); // First, make a Map of all entries: Dictionary<string, BibtexString> remaining = new Dictionary<string, BibtexString>(); foreach (var str in strings) { // TODO: possible error in translation, though this looks right... remaining.Add(str.getName(), str); } foreach (var bs in strings) { if (remaining.ContainsKey(bs.getName())) writeString(fw, bs, remaining); } }
/** * Saves the database to file, including only the entries included in the * supplied input array bes. * * @return A List containing warnings, if any. */ public static void savePartOfDatabase(BibtexDatabase database, Stream file, JabRefPreferences prefs, BibtexEntry[] bes, string encoding) { var types = new Dictionary<string, BibtexEntryType>(); // Map // to // collect // entry // type // definitions // that we must save along with entries using them. BibtexEntry be = null; bool backup = prefs.getBoolean("backup"); try { // Define our data stream. var fw = new StreamWriter(file); // Write signature. writeBibFileHeader(fw, encoding); // Write preamble if there is one. writePreamble(fw, database.getPreamble()); // Write strings if there are any. writeStrings(fw, database); // Write database entries. Take care, using CrossRefEntry- // IComparable, that referred entries occur after referring // ones. Apart from crossref requirements, entries will be // sorted as they appear on the screen. string pri, sec, ter; bool priD, secD, terD; if (!prefs.getBoolean("saveInStandardOrder")) { // The setting is to save according to the current table order. pri = prefs.get("priSort"); sec = prefs.get("secSort"); // sorted as they appear on the screen. ter = prefs.get("terSort"); priD = prefs.getBoolean("priDescending"); secD = prefs.getBoolean("secDescending"); terD = prefs.getBoolean("terDescending"); } else { // The setting is to save in standard order: author, editor, year pri = "author"; sec = "editor"; ter = "year"; priD = false; secD = false; terD = true; } var comparators = new List<IComparer<BibtexEntry>>(); comparators.Add(new CrossRefEntryComparator()); comparators.Add(new FieldComparator(pri, priD)); comparators.Add(new FieldComparator(sec, secD)); comparators.Add(new FieldComparator(ter, terD)); comparators.Add(new FieldComparator(Globals.KEY_FIELD)); // Use glazed lists to get a sorted view of the entries: List<BibtexEntry> entries = new List<BibtexEntry>(); if ((bes != null) && (bes.Length > 0)) for (int i = 0; i < bes.Length; i++) { entries.Add(bes[i]); } entries.Sort(new FieldComparatorStack<BibtexEntry>(comparators)); FieldFormatter ff = new LatexFieldFormatter(); for (var i = entries.GetEnumerator(); i.MoveNext(); ) { be = i.Current; // Check if we must write the type definition for this // entry, as well. Our criterion is that all non-standard // types (*not* customized standard types) must be written. BibtexEntryType tp = be.getType(); if (BibtexEntryType.getStandardType(tp.getName()) == null) { types.Add(tp.getName(), tp); } be.write(fw, ff, true); fw.Write(Environment.NewLine); } // Write type definitions, if any: if (types.Count > 0) { foreach (var i in types.Keys) { CustomEntryType tp = (CustomEntryType)types[i]; tp.save(fw); fw.Write(Environment.NewLine); } } fw.Dispose(); } catch (Exception ex) { try { // TODO: //session.cancel(); //repairAfterError(file, backup, status); } catch (IOException e) { // Argh, another error? Can we do anything? throw new SaveException(ex.Message + "\n" + Globals.lang("Warning: could not complete file repair; your file may " + "have been corrupted. Error message: ") + e.Message); } throw new SaveException(ex.Message, be); } }
/** * Saves the database to file. Two bool values indicate whether * only entries with a nonzero Globals.SEARCH value and only * entries with a nonzero Globals.GROUPSEARCH value should be * saved. This can be used to let the user save only the results of * a search. False and false means all entries are saved. */ public static void saveDatabase(BibtexDatabase database, Stream file, bool checkSearch, bool checkGroup, string encoding) { var types = new Dictionary<string, BibtexEntryType>(); BibtexEntry exceptionCause = null; try { // Get our data stream. This stream writes only to a temporary file, // until committed. var fw = new StreamWriter(file); // Write signature. writeBibFileHeader(fw, encoding); // Write preamble if there is one. writePreamble(fw, database.getPreamble()); // Write strings if there are any. writeStrings(fw, database); // Write database entries. Take care, using CrossRefEntry- // IComparable, that referred entries occur after referring // ones. Apart from crossref requirements, entries will be // sorted as they appear on the screen. List<BibtexEntry> sorter = getSortedEntries(database, null, true); FieldFormatter ff = new LatexFieldFormatter(); foreach (var be in sorter) { exceptionCause = be; // Check if we must write the type definition for this // entry, as well. Our criterion is that all non-standard // types (*not* customized standard types) must be written. BibtexEntryType tp = be.getType(); if (BibtexEntryType.getStandardType(tp.getName()) == null) { types.Add(tp.getName(), tp); } // Check if the entry should be written. bool write = true; if (checkSearch && !nonZeroField(be, BibtexFields.SEARCH)) { write = false; } if (checkGroup && !nonZeroField(be, BibtexFields.GROUPSEARCH)) { write = false; } if (write) { be.write(fw, ff, true); fw.Write(Environment.NewLine); } } // Write type definitions, if any: if (types.Count > 0) { foreach (var key in types.Keys) { BibtexEntryType type = types[key]; if (type is CustomEntryType) { CustomEntryType tp = (CustomEntryType)type; tp.save(fw); fw.Write(Environment.NewLine); } } } fw.Dispose(); } catch (Exception ex) { try { // TODO: des error handling //session.cancel(); // repairAfterError(file, backup, INIT_OK); } catch (IOException e) { // Argh, another error? Can we do anything? throw new SaveException(ex.Message + "\n" + Globals.lang("Warning: could not complete file repair; your file may " + "have been corrupted. Error message") + ": " + e.Message); } throw new SaveException(ex.Message, exceptionCause); } }