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