/// <summary>
        /// Checks if a number follows the specified <code>token</code>
        /// </summary>
        /// <param name="category">the category to set if a number follows the <code>token</code></param>
        /// <param name="token">the token</param>
        /// <returns>true if a number follows the token; false otherwise</returns>
        private bool NumberComesAfterPrefix(Element.ElementCategory category, Token token)
        {
            var numberBegin = ParserHelper.IndexOfFirstDigit(token.Content);
            var prefix      = StringHelper.SubstringWithCheck(token.Content, 0, numberBegin).ToUpperInvariant();

            if (!KeywordManager.Contains(category, prefix))
            {
                return(false);
            }
            var number = StringHelper.SubstringWithCheck(token.Content, numberBegin, token.Content.Length - numberBegin);

            switch (category)
            {
            case Element.ElementCategory.ElementEpisodePrefix:
                if (!MatchEpisodePatterns(number, token))
                {
                    SetEpisodeNumber(number, token, false);
                }
                return(true);

            case Element.ElementCategory.ElementVolumePrefix:
                if (!MatchVolumePatterns(number, token))
                {
                    SetVolumeNumber(number, token, false);
                }
                return(true);

            default:
                return(false);
            }
        }
        /// <summary>
        /// Match type and episode. e.g. "ED1", "OP4a", "OVA2".
        /// </summary>
        /// <param name="word">the word</param>
        /// <param name="token">the token</param>
        /// <returns>true if the token matched</returns>
        private bool MatchTypeAndEpisodePattern(string word, Token token)
        {
            var numberBegin = ParserHelper.IndexOfFirstDigit(word);
            var prefix      = StringHelper.SubstringWithCheck(word, 0, numberBegin);

            var category = Element.ElementCategory.ElementAnimeType;
            var options  = new KeywordOptions();

            if (!KeywordManager.FindAndSet(KeywordManager.Normalize(prefix), ref category, ref options))
            {
                return(false);
            }
            _parser.Elements.Add(new Element(Element.ElementCategory.ElementAnimeType, prefix));
            var number = word.Substring(numberBegin);

            if (!MatchEpisodePatterns(number, token) && !SetEpisodeNumber(number, token, true))
            {
                return(false);
            }
            var foundIdx = _parser.Tokens.IndexOf(token);

            if (foundIdx == -1)
            {
                return(true);
            }
            token.Content = number;
            _parser.Tokens.Insert(foundIdx,
                                  new Token(options.Identifiable ? Token.TokenCategory.Identifier : Token.TokenCategory.Unknown, prefix, token.Enclosed));

            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Removes the extension from the <see cref="filename"/>
        /// </summary>
        /// <param name="filename">the ref that will be updated with the new filename</param>
        /// <param name="extension">the ref that will be updated with the file extension</param>
        /// <returns>if the extension was successfully separated from the filename</returns>
        private static bool RemoveExtensionFromFilename(ref string filename, ref string extension)
        {
            int position;

            if (string.IsNullOrEmpty(filename) || (position = filename.LastIndexOf('.')) == -1)
            {
                return(false);
            }

            /** remove file extension */
            extension = filename.Substring(position + 1);
            if (extension.Length > 4 || !extension.All(char.IsLetterOrDigit))
            {
                return(false);
            }

            /** check if valid anime extension */
            var keyword = KeywordManager.Normalize(extension);

            if (!KeywordManager.Contains(Element.ElementCategory.ElementFileExtension, keyword))
            {
                return(false);
            }

            filename = filename.Substring(0, position);
            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Tokenize by looking for known anime identifiers
        /// </summary>
        /// <param name="enclosed">whether or not the current <code>range</code> is enclosed in braces</param>
        /// <param name="range">the token range</param>
        private void TokenizeByPreidentified(bool enclosed, TokenRange range)
        {
            var preidentifiedTokens = new List <TokenRange>();

            // Find known anime identifiers
            KeywordManager.PeekAndAdd(_filename, range, _elements, preidentifiedTokens);

            var offset   = range.Offset;
            var subRange = new TokenRange(range.Offset, 0);

            while (offset < range.Offset + range.Size)
            {
                foreach (var preidentifiedToken in preidentifiedTokens)
                {
                    if (offset != preidentifiedToken.Offset)
                    {
                        continue;
                    }
                    if (subRange.Size > 0)
                    {
                        TokenizeByDelimiters(enclosed, subRange);
                    }

                    AddToken(Token.TokenCategory.Identifier, enclosed, preidentifiedToken);
                    subRange.Offset = preidentifiedToken.Offset + preidentifiedToken.Size;
                    offset          = subRange.Offset - 1; // It's going to be incremented below
                }

                subRange.Size = ++offset - subRange.Offset;
            }

            // Either there was no preidentified token range, or we're now about to process the tail of our current range
            if (subRange.Size > 0)
            {
                TokenizeByDelimiters(enclosed, subRange);
            }
        }