Beispiel #1
0
        private IEnumerable <Bibitem> GetBibitemsInOrderOfAppearance(BibtexDatabase bibtexDatabase)
        {
            // Build up unique collection of bibitems.
            var citationKeys = new HashSet <string>();

            foreach (var auxEntry in _auxEntries.Where(x => x.Type == AuxEntryType.Citation))
            {
                if (!citationKeys.Contains(auxEntry.Key))
                {
                    citationKeys.Add(auxEntry.Key);

                    if (bibtexDatabase.Entries.TryGetFirst(bibtexEntry => bibtexEntry.CitationKey == auxEntry.Key, out var bibtexEntry))
                    {
                        var style = BibliographyStyle.EntryStyles.FirstOrDefault(s => s.Type == bibtexEntry.EntryType) ?? EntryStyle.Default;
                        yield return(new Bibitem(citationKeys.Count, auxEntry, bibtexEntry, style));
                    }
                    else
                    {
                        var warning = $"No bibliography entry matching citation key: '{auxEntry.Key}' found.";
                        _logger.LogWarning(warning);
                        yield return(new Bibitem(citationKeys.Count, auxEntry.Key, auxEntry.Label, warning));
                    }
                }
            }
        }
Beispiel #2
0
        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);
                }
            }
        }
Beispiel #3
0
        /// <inheritdoc />
        public BibtexDatabase ParseStream(string databaseName, Stream stream)
        {
            var database = new BibtexDatabase(databaseName);

            int failedTags = 0;

            using var sr = new StreamReader(stream);
            while (sr.Peek() >= 0)
            {
                try
                {
                    var entryType = GetEntryType(sr);

                    if (entryType.HasValue)
                    {
                        switch (entryType)
                        {
                        case EntryType.Comment:
                            database.Comments.Add(GetComment(sr));
                            break;

                        case EntryType.Preamble:
                            database.Preambles.Add(GetPreamble(sr));
                            break;

                        case EntryType.String:
                            database.Strings.Add(GetStringEntry(sr));
                            break;

                        default:
                            database.Entries.Add(GetEntryContent(entryType.Value, sr));
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"An error occurred parsing the Bibtex stream at entry: {database.AllEntriesCount + ++failedTags} - this tag will be skipped.");
                }
            }

            return(database);
        }
Beispiel #4
0
        /**
         * Will parse the BibTex-Data found when reading from reader.
         *
         * The reader will be consumed.
         *
         * Multiple calls to parse() return the same results
         *
         * @return ParserResult
         * @throws IOException
         */
        public ParserResult Parse()
        {
            // If we already parsed this, just return it.
            if (_pr != null)
            return _pr;

            _db = new BibtexDatabase(); // Bibtex related contents.
            _meta = new Dictionary<string, string>(); // Metadata in comments for Bibkeeper.
            entryTypes = new Dictionary<string, BibtexEntryType>(); // To store custem entry types parsed.
            _pr = new ParserResult(_db, _meta, entryTypes);

            // First see if we can find the version number of the JabRef version that
            // wrote the file:
            string versionNum = ReadJabRefVersionNumber();
            if (versionNum != null) {
            _pr.JabrefVersion = versionNum;
            SetMajorMinorVersions();
            }
            else {
            // No version number found. However, we have only
            }

            SkipWhitespace();

            try {
            while (!_eof) {
                bool found = ConsumeUncritically('@');
                if (!found)
                    break;
                SkipWhitespace();
                string entryType = ParseTextToken();
                BibtexEntryType tp = BibtexEntryType.getType(entryType);
                bool isEntry = (tp != null);
                // Util.pr(tp.getName());
                if (!isEntry) {
                    // The entry type name was not recognized. This can mean
                    // that it is a string, preamble, or comment. If so,
                    // parse and set accordingly. If not, assume it is an entry
                    // with an unknown type.
                    if (entryType.ToLower().Equals("preamble")) {
                        _db.setPreamble(ParsePreamble());
                    } else if (entryType.ToLower().Equals("string")) {
                        BibtexString bs = ParseString();
                        try {
                            _db.addString(bs);
                        } catch (KeyCollisionException) {
                            _pr.AddWarning(Globals.lang("Duplicate string name") + ": "
                                + bs.getName());
                            // ex.printStackTrace();
                        }
                    } else if (entryType.ToLower().Equals("comment")) {
                        StringBuilder commentBuf = ParseBracketedTextExactly();
                        /**
                         *
                         * Metadata are used to store Bibkeeper-specific
                         * information in .bib files.
                         *
                         * Metadata are stored in bibtex files in the format
                         *
                         * @comment{jabref-meta: type:data0;data1;data2;...}
                         *
                         * Each comment that starts with the META_FLAG is stored
                         * in the meta Dictionary, with type as key. Unluckily, the
                         * old META_FLAG bibkeeper-meta: was used in JabRef 1.0
                         * and 1.1, so we need to support it as well. At least
                         * for a while. We'll always save with the new one.
                         */
                        // TODO: unicode escape sequences
                        string comment = commentBuf.ToString().Replace("[\\x0d\\x0a]", "");
                        if (comment.Substring(0,
                            Math.Min(comment.Length, Globals.META_FLAG.Length)).Equals(
                            Globals.META_FLAG)
                            || comment.Substring(0,
                                Math.Min(comment.Length, Globals.META_FLAG_OLD.Length))
                                .Equals(Globals.META_FLAG_OLD)) {

                            string rest;
                            if (comment.Substring(0, Globals.META_FLAG.Length).Equals(
                                Globals.META_FLAG))
                                rest = comment.Substring(Globals.META_FLAG.Length);
                            else
                                rest = comment.Substring(Globals.META_FLAG_OLD.Length);

                            int pos = rest.IndexOf(':');

                            if (pos > 0)
                                _meta.Add(rest.Substring(0, pos), rest.Substring(pos + 1));
                            // We remove all line breaks in the metadata - these
                            // will have been inserted
                            // to prevent too long lines when the file was
                            // saved, and are not part of the data.
                        }

                        /**
                         * A custom entry type can also be stored in a
                         *
                         * @comment:
                         */
                        if (comment.Substring(0,
                            Math.Min(comment.Length, Globals.ENTRYTYPE_FLAG.Length)).Equals(
                            Globals.ENTRYTYPE_FLAG)) {

                            CustomEntryType typ = CustomEntryType.parseEntryType(comment);
                            entryTypes.Add(typ.getName().ToLower(), typ);

                        }
                    } else {
                        // The entry type was not recognized. This may mean that
                        // it is a custom entry type whose definition will
                        // appear
                        // at the bottom of the file. So we use an
                        // UnknownEntryType
                        // to remember the type name by.
                        tp = new UnknownEntryType(entryType.ToLower());
                        // System.out.println("unknown type: "+entryType);
                        isEntry = true;
                    }
                }

                if (isEntry) // True if not comment, preamble or string.
                {
                    /**
                     * Morten Alver 13 Aug 2006: Trying to make the parser more
                     * robust. If an exception is thrown when parsing an entry,
                     * drop the entry and try to resume parsing. Add a warning
                     * for the user.
                     *
                     * An alternative solution is to try rescuing the entry for
                     * which parsing failed, by returning the entry with the
                     * exception and adding it before parsing is continued.
                     */
                    try {
                        BibtexEntry be = ParseEntry(tp);

                        bool duplicateKey = _db.insertEntry(be);
                        if (duplicateKey) // JZTODO lyrics
                            _pr.AddDuplicateKey(be.getCiteKey());
                            /*_pr.AddWarning(Globals.lang("duplicate BibTeX key") + ": "
                                + be.getCiteKey() + " ("
                                + Globals.lang("grouping may not work for this entry") + ")");                        */
                        else if (be.getCiteKey() == null || be.getCiteKey().Equals("")) {
                            _pr.AddWarning(Globals.lang("empty BibTeX key") + ": "
                                + be.getAuthorTitleYear(40) + " ("
                                + Globals.lang("grouping may not work for this entry") + ")");
                        }
                    } catch (IOException ex) {
                        _pr.AddWarning(Globals.lang("Error occured when parsing entry") + ": '"
                            + ex.Message + "'. " + Globals.lang("Skipped entry."));

                    }
                }

                SkipWhitespace();
            }

            // Before returning the database, update entries with unknown type
            // based on parsed type definitions, if possible.
            CheckEntryTypes(_pr);

            return _pr;
            } catch (KeyCollisionException kce) {
            // kce.printStackTrace();
            throw new IOException("Duplicate ID in bibtex file: " + kce.ToString());
            }
        }
Beispiel #5
0
 public ParserResult(BibtexDatabase database, Dictionary<string, string> metaData, Dictionary<string, BibtexEntryType> entryTypes)
 {
     Database = database;
     MetaData = metaData;
     EntryTypes = entryTypes;
 }
Beispiel #6
0
        private List <(AuxEntry AuxEntry, BibtexEntry BibtexEntry, EntryStyle EntryStyle)> GetMatchedEntries(BibtexDatabase bibtexDatabase)
        {
            // Build up unique collection of bibtex entries.
            var matchedEntries = new List <(AuxEntry AuxEntry, BibtexEntry BibtexEntry, EntryStyle EntryStyle)>();
            var citationKeys   = new HashSet <string>();

            foreach (var auxEntry in _auxEntries.Where(x => x.Type == AuxEntryType.Citation))
            {
                if (!citationKeys.Contains(auxEntry.Key))
                {
                    citationKeys.Add(auxEntry.Key);
                    var bibtexEntry = bibtexDatabase.Entries.FirstOrDefault(bibtexEntry => bibtexEntry.CitationKey == auxEntry.Key);
                    var entryStyle  = bibtexEntry != null ? (BibliographyStyle.EntryStyles.FirstOrDefault(s => s.Type == bibtexEntry.EntryType) ?? EntryStyle.Default) : null;
                    matchedEntries.Add((auxEntry, bibtexEntry, entryStyle));
                }
            }

            return(matchedEntries);
        }
Beispiel #7
0
 private List <Bibitem> GetBibitemsOrderedByTitle(BibtexDatabase bibtexDatabase) => GetOrderedItems(GetMatchedEntries(bibtexDatabase), x => x.BibtexEntry?.Title).ToList();
Beispiel #8
0
 private List <Bibitem> GetBibitemsOrderedByFirstAuthorLastName(BibtexDatabase bibtexDatabase) => GetOrderedItems(GetMatchedEntries(bibtexDatabase), x => BibtexAuthor.GetFirstAuthorLastName(x.BibtexEntry?.Author) ?? x.BibtexEntry?.Title).ToList();