Пример #1
0
        private void ParseTopLevel(BibTexLexerCallback callback)
        {
            int prev_c = c;

            while (c < MAX_C)
            {
                // The `@keyword` must always be preceded by at least one whitespace
                // character so as to differentiate it from email addresses, etc.:
                // `joe@article` vs. ` @article`
                if ('@' != bibtex[c] || !Char.IsWhiteSpace(bibtex[c - 1]))
                {
                    ++c;
                }
                else
                {
                    // Hit a `@` BibTeX command start marker.

                    // Everything that we looped through thus far is either whitespace or comment or both:
                    string comment = bibtex.Substring(prev_c, c - prev_c).Trim();
                    if (!String.IsNullOrEmpty(comment))
                    {
                        callback.RaiseComment(comment);
                    }

                    // Get this @entry
                    ParseEntry(callback);

                    // Skip spaces between entries
                    ParseWhiteSpace();

                    prev_c = c;
                }
            }

            callback.RaiseFinished();
        }
Пример #2
0
        private void ParseEntry(BibTexLexerCallback callback)
        {
            // skip initial `@`
            ++c;

            // Get the entry name
            int entry_name_start = c;

            while (IsNameChar(bibtex[c]))
            {
                ++c;
            }
            int entry_name_end = c;

            string entry_name = bibtex.Substring(entry_name_start, entry_name_end - entry_name_start);

            // Check if it is a comment
            if (0 == "comment".CompareTo(entry_name.ToLower()))
            {
                ParseWhiteSpace();

                switch (bibtex[c])
                {
                case '(':
                    callback.RaiseComment(ParseUntilDelim(callback, ')'));
                    return;

                case '{':
                    callback.RaiseComment(ParseUntilDelim(callback, '}'));
                    return;

                default:
                    // b0rked `@comment`: parse until EOL
                    callback.RaiseComment(ParseUntilDelim(callback, '\n'));
                    return;
                }
            }

            callback.RaiseEntryName(entry_name);

            // Check the length of the entry name
            if (entry_name_end == entry_name_start)
            {
                Exception(callback, "The BibTeX type is missing");
            }

            // Skip spaces between name and open brackets
            ParseWhiteSpace();

            // Now an entry is either { xxx } or ( xxx )
            switch (/* c < MAX_C ? */ bibtex[c])    // -- optimization
            {
            case '(':
                ParseEntry_Delim(callback, '(', ')');
                break;

            case '{':
                ParseEntry_Delim(callback, '{', '}');
                break;

            default:
                Exception(callback, "Expecting a {0} or {1} to start a BibTeX reference", "(", "{{");
                return;
            }
        }
        private void ParseEntry(BibTexLexerCallback callback)
        {
            try
            {
                // Check we have our @
                if ('@' != bibtex[c])
                {
                    Exception(callback, "Entry should start with @");
                    return;
                }
                else
                {
                    ++c;
                }

                // Get the entry name
                int entry_name_start = c;
                while (IsNameChar(bibtex[c]))
                {
                    ++c;
                }
                int entry_name_end = c;

                string entry_name = bibtex.Substring(entry_name_start, entry_name_end - entry_name_start);

                // Check if it is a comment
                if (0 == "comment".CompareTo(entry_name.ToLower()))
                {
                    ParseUntilDelim(callback, '{'); //Ensure we have an opening {
                    ++c;                            //Skip it.
                    callback.RaiseComment(ParseUntilDelim(callback, '}'));
                    return;
                }

                callback.RaiseEntryName(entry_name);

                // Check the length of the entry name
                if (entry_name_end == entry_name_start)
                {
                    Exception(callback, "The BibTeX type is missing");
                }

                // Skip spaces between name and open brackets
                ParseWhiteSpace();

                // Now and entry is either { xxx } or ( xxx )
                if (false)
                {
                }
                else if ('(' == bibtex[c])
                {
                    ParseEntry_Delim(callback, '(', ')');
                }
                else if ('{' == bibtex[c])
                {
                    ParseEntry_Delim(callback, '{', '}');
                }
                else
                {
                    Exception(callback, "Expecting a {0} or {1} to start a BibTeX reference", "(", "{{");
                    return;
                }
            }
            catch (IndexOutOfRangeException)
            {
                Exception(callback, "Ran out of characters while reading the entry");
            }
        }