/// <summary> /// Корректировка описания книги (description) /// </summary> /// <param name="XmlBody">xml текст body (для определения языка книги)</param> /// <param name="XmlDescription">Строка description для корректировки</param> /// <returns>Откорректированная строка типа string</returns> private static string autoCorrectDescription(string FilePath, string XmlBody, string XmlDescription) { if (string.IsNullOrWhiteSpace(XmlDescription) || XmlDescription.Length == 0) { return(XmlDescription); } /* обработка головного тега FictionBook и пространства имен */ FictionBookTagCorrector fbtc = new FictionBookTagCorrector(FilePath); XmlDescription = fbtc.StartTagCorrect(XmlDescription); try { /**************************************** * удаление атрибута в теге description * ****************************************/ // удаление атрибута в теге description try { Regex regex = new Regex("<description>", RegexOptions.IgnoreCase); Match m = regex.Match(XmlDescription); if (!m.Success) { XmlDescription = Regex.Replace( XmlDescription, "(?:<description [^<]+?(?:\"[^\"]*\"|'[^']*')?)(?'more'>)", "<description>", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline ); } } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nУдаление атрибута в теге description. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nУдаление атрибута в теге description. Исключение Exception." ); } /********************* * Обработка графики * *********************/ // удаление "пустого" тега <coverpage></coverpage> try { XmlDescription = Regex.Replace( XmlDescription, @"(?:<coverpage>\s*?</coverpage>)", "", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nУдаление \"пустого\" тега <coverpage></coverpage>. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nУдаление \"пустого\" тега <coverpage></coverpage>. Исключение Exception." ); } // обработка картинок: <image l:href="#img_0.png"> </image> или <image l:href="#img_0.png">\n</image> try { XmlDescription = Regex.Replace( XmlDescription, "(?'img'<image [^<]+?(?:\"[^\"]*\"|'[^']*')?)(?'more'>)(?:\\s*?</image>)", "${img} /${more}", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка раздела <description>:\r\nОбработка картинок: <image l:href=\"img_0.png\"> </image> или <image l:href=\"img_0.png\"></image>. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка картинок: <image l:href=\"img_0.png\"> </image> или <image l:href=\"img_0.png\"></image>. Исключение м." ); } /**************** * Обработка id * ****************/ // обработка пустого id try { XmlDescription = Regex.Replace( XmlDescription, @"(?<=<id>)(?:\s*\s*)(?=</id>)", Guid.NewGuid().ToString().ToUpper(), RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка пустого id. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка пустого id. Исключение Exception." ); } // обработка Либрусековских id try{ XmlDescription = Regex.Replace( XmlDescription, @"(?<=<id>)\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{2}\s+(\d{2}\:){2}\d{2}\s+\d{4}\s*(?=</id>)", Guid.NewGuid().ToString().ToUpper(), RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка Либрусековских id. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка Либрусековских id. Исключение Exception." ); } /****************** * Обработка Жанра * ******************/ if (XmlDescription.IndexOf("<genre", StringComparison.CurrentCulture) != -1) { GenreCorrector genreCorrector = new GenreCorrector(FilePath, ref XmlDescription, false, false); XmlDescription = genreCorrector.correct(); } /****************** * Обработка языка * ******************/ // замена <lang> для русских книг на ru для fb2 без <src-title-info> LangRuUkBeCorrector langRuUkBeCorrector = new LangRuUkBeCorrector(ref XmlDescription, XmlBody); bool IsCorrected = false; XmlDescription = langRuUkBeCorrector.correct(ref IsCorrected); // обработка неверно заданного русского языка try { XmlDescription = Regex.Replace( XmlDescription, @"(?<=<lang>)(?:\s*)(?:RU-ru|Rus)(?:\s*)(?=</lang>)", "ru", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка неверно заданного русского языка. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка неверно заданного русского языка. Исключение Exception." ); } // обработка неверно заданного английского языка try { XmlDescription = Regex.Replace( XmlDescription, @"(?<=<lang>)(?:\s*)(?:EN-en|Eng)(?:\s*)(?=</lang>)", "en", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка неверно заданного английского языка. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка неверно заданного английского языка. Исключение Exception." ); } /***************** * Обработка дат * *****************/ try { if (XmlDescription.IndexOf("<date", StringComparison.CurrentCulture) != -1) { DateCorrector dateCorrector = new DateCorrector(FilePath, ref XmlDescription, false, false); XmlDescription = dateCorrector.correct(); } } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка дат (тег <date>). Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка дат (тег <date>). Исключение Exception." ); } /************************ * Обработка annotation * ************************/ // обработка annotation без тегов <p>: текст annotation обрамляется тегами <p> ... </p> try { XmlDescription = Regex.Replace( XmlDescription, @"(?<=<annotation>)\s*?(?'text_annotation'(?:<(?'tag_s'strong|emphasis)>)?\s*?(?:[^<]+)?(?:</\k'tag_s'>)?\s*?)\s*?(?=</annotation>)", "<p>${text_annotation}</p>", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка annotation без тегов <p>: текст annotation обрамляется тегами <p> ... </p>. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nОбработка annotation без тегов <p>: текст annotation обрамляется тегами <p> ... </p>. Исключение Exception." ); } // обработка annotation: картинка без тегов <p>: <annotation><image l:href="#ficbook_logo.png" /> => <annotation><p><image l:href="#ficbook_logo.png" /></p> try { XmlDescription = Regex.Replace( XmlDescription, "(?<=<annotation>)\\s*?(?'img'<image [^<]+?(?:\"[^\"]*\"|'[^']*')?>)", "<p>${img}</p>", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка annotation: картинка без тегов <p>: <annotation><image l:href=\"#ficbook_logo.png\" /> => <annotation><p><image l:href=\"#ficbook_logo.png\" /></p>. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка annotation: картинка без тегов <p>: <annotation><image l:href=\"#ficbook_logo.png\" /> => <annotation><p><image l:href=\"#ficbook_logo.png\" /></p>. Исключение Exception." ); } // преобразование <title> в аннотации на <subtitle> (Заголовок - без тегов <strong>) и т.п. try { XmlDescription = Regex.Replace( XmlDescription, @"(?<=<annotation>)\s*?(?:<title>\s*?)(?:<p>\s*?)(?'title'[^<]+?)(?:\s*?</p>\s*?</title>)", "<subtitle>${title}</subtitle>", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nПреобразование <title> в аннотации на <subtitle> (Заголовок - без тегов <strong>) и т.п. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nПреобразование <title> в аннотации на <subtitle> (Заголовок - без тегов <strong>) и т.п. Исключение Exception." ); } // преобразование <annotation><annotation><p>Текст.</p><p>Еще текст.</p></annotation></annotation> => <annotation><p>Текст.</p><p>Еще текст.</p></annotation> try { XmlDescription = Regex.Replace( XmlDescription, @"(?:<annotation>\s*?<annotation>\s*?)(?'texts'(<p>\s*?(?:<(?'tag'strong|emphasis)\b>)?[^<]+?(?:</\k'tag'>)?\s*?</p>\s*?){1,}\s*?)(?:</annotation>\s*?</annotation>)", "<annotation>${texts}</annotation>", RegexOptions.IgnoreCase | RegexOptions.Multiline ); } catch (RegexMatchTimeoutException ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nПреобразование <annotation><annotation><p>Текст.</p><p>Еще текст.</p></annotation></annotation> => <annotation><p>Текст.</p><p>Еще текст.</p></annotation>. Исключение RegexMatchTimeoutException." ); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nПреобразование <annotation><annotation><p>Текст.</p><p>Еще текст.</p></annotation></annotation> => <annotation><p>Текст.</p><p>Еще текст.</p></annotation>. Исключение Exception." ); } /********************************** * Обработка history и annotation * **********************************/ // // вставка недостающего <p> : <history>Текст</p></history> => <history><p>Текст</p></history> // try { // XmlDescription = Regex.Replace( // XmlDescription, @"(?'tag'<(history|annotation)>)(?!<p>)", // "${tag}<p>", RegexOptions.IgnoreCase | RegexOptions.Multiline // ); // } catch ( RegexMatchTimeoutException /*ex*/ ) {} // // вставка недостающего </p> : <history><p>Текст</history> => <history><p>Текст</p></history> // try { // XmlDescription = Regex.Replace( // XmlDescription, @"(?<!</p>)(?'tag'</(history|annotation)>)", // "</p>${tag}", RegexOptions.IgnoreCase | RegexOptions.Multiline // ); // } catch ( RegexMatchTimeoutException /*ex*/ ) {} } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "Обработка раздела <description>:\r\nМетод autoCorrectDescription().\r\nОшибка уровня всего метода (главный catch ( Exception ex )):" ); } return(autoCorrect(FilePath, XmlDescription)); }
/// <summary> /// Автокорректировка теста файла FilePath /// </summary> /// <param name="FilePath">Путь к обрабатываемой книге</param> public static void autoCorrector(string FilePath) { if (string.IsNullOrWhiteSpace(FilePath)) { return; } FileInfo fi = new FileInfo(FilePath); if (!fi.Exists) { return; } if (fi.Length < 4) { return; } // обработка головного тега FictionBook и пространства имен FB2Text fb2Text = null; try { fb2Text = new FB2Text(FilePath); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "AutoCorrector.FB2AutoCorrector.autoCorrector():\r\nАвтокорректировка теста файла." ); // Если структура fb2 файла сильно "битая", или же основные разделы располагаются не по стандарту throw ex; } if (fb2Text.Description.IndexOf("<FictionBook", StringComparison.CurrentCulture) == -1) { // тег FictionBook отсутствует в книге FictionBookTagCorrector fbtc = new FictionBookTagCorrector(FilePath); fb2Text.Description = fb2Text.Description.Insert( fb2Text.Description.IndexOf("<description>", StringComparison.CurrentCulture), fbtc.NewFictionBookTag ); } // обработка неверного значения кодировки файла try { Regex regex = new Regex("(?<=encoding=\")(?:(?:wutf-8)|(?:utf8))(?=\")", RegexOptions.IgnoreCase); fb2Text.Description = regex.Replace(fb2Text.Description, "utf-8"); } catch (RegexMatchTimeoutException /*ex*/) {} catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "AutoCorrector.FB2AutoCorrector::autoCorrector():\r\nОбработка неверного значения кодировки файла." ); } /******************************************* * Автокорректировка раздела <description> * *******************************************/ fb2Text.Description = autoCorrectDescription(FilePath, fb2Text.Bodies, fb2Text.Description); /************************************* * Автокорректировка разделов <body> * *************************************/ fb2Text.Bodies = autoCorrect(FilePath, fb2Text.Bodies); /************************************* * Автокорректировка разделов binary * *************************************/ if (fb2Text.BinariesExists) { // обработка ссылок-названий картинок в binary BinaryCorrector binaryCorrector = new BinaryCorrector(FilePath, fb2Text.Binaries); fb2Text.Binaries = binaryCorrector.correct(); } try { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(fb2Text.toXML()); xmlDoc.Save(FilePath); } catch (Exception ex) { Debug.DebugMessage( FilePath, ex, "AutoCorrector.FB2AutoCorrector::autoCorrector():\r\nпересохранение файла." ); fb2Text.saveFile(); } }
/// <summary> /// Автокорректировка теста файла FilePath /// </summary> /// <param name="FilePath">Путь к обрабатываемой книге</param> public static void autoCorrector(string FilePath) { if (string.IsNullOrWhiteSpace(FilePath)) { return; } FileInfo fi = new FileInfo(FilePath); if (!fi.Exists) { return; } if (fi.Length < 4) { return; } // Хэш таблица fb2 тегов Hashtable htTags = FB2CleanCode.getTagsHashtable(); // обработка < > в тексте, кроме fb2 тегов // обработка головного тега FictionBook и пространства имен FB2Text fb2Text = new FB2Text(FilePath); if (fb2Text.Description.IndexOf("<FictionBook", StringComparison.CurrentCulture) == -1) { // тег FictionBook отсутствует в книге FictionBookTagCorrector fbtc = new FictionBookTagCorrector(); fb2Text.Description = fb2Text.Description.Insert( fb2Text.Description.IndexOf("<description>", StringComparison.CurrentCulture), fbtc.NewFictionBookTag ); } // обработка неверного значения кодировки файла try { Regex regex = new Regex("(?<=encoding=\")(?:(?:wutf-8)|(?:utf8))(?=\")", RegexOptions.IgnoreCase); fb2Text.Description = regex.Replace(fb2Text.Description, "utf-8"); } catch (RegexMatchTimeoutException /*ex*/) {} catch (Exception ex) { if (Settings.Settings.ShowDebugMessage) { // Показывать сообщения об ошибках при падении работы алгоритмов MessageBox.Show( string.Format("Обработка раздела <description>:\r\nОбработка неверного значения кодировки файла.\r\nОшибка:\r\n{0}", ex.Message), _MessageTitle, MessageBoxButtons.OK, MessageBoxIcon.Error ); } } /****************************************** * Автокорректировка раздела <description> * *******************************************/ fb2Text.Description = autoCorrectDescription(fb2Text.Bodies, fb2Text.Description, htTags); /* Автокорректировка разделов <body> */ fb2Text.Bodies = autoCorrect(fb2Text.Bodies, htTags); /* автокорректировка разделов binary */ if (fb2Text.BinariesExists) { // обработка ссылок-названий картинок в binary BinaryCorrector binaryCorrector = new BinaryCorrector(fb2Text.Binaries); fb2Text.Binaries = binaryCorrector.correct(); } try { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(fb2Text.toXML()); xmlDoc.Save(FilePath); } catch { fb2Text.saveFile(); } }