diff --git a/Fb2File/Fb2File.cpp b/Fb2File/Fb2File.cpp index 2a9287324b..4542dd1610 100644 --- a/Fb2File/Fb2File.cpp +++ b/Fb2File/Fb2File.cpp @@ -95,6 +95,7 @@ struct STitleInfo }; // Описание информации о fb2-документе. Тэг document-info +/* struct SDocumentInfo { std::vector m_arAuthors; // Авторы @@ -125,8 +126,10 @@ struct SDocumentInfo RELEASEARRAYOBJECTS(m_pHistory); } }; +*/ // Информация о бумажном издании. Тэг publish-info +/* struct SPublishInfo { std::wstring* m_pBookName; // Название @@ -157,33 +160,33 @@ struct SPublishInfo RELEASEARRAYOBJECTS(m_pIsbn); } }; +*/ class CFb2File_Private { public: XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader STitleInfo m_oTitleInfo; // Данные о книге - SDocumentInfo m_oDocumentInfo; // Информация об fb2-документе - std::wstring m_sTmpFolder; // Рабочая папка + // SDocumentInfo m_oDocumentInfo; // Информация об fb2-документе + // std::wstring m_sTmpFolder; // Рабочая папка int m_nContentsId; // ID содержания int m_nCrossReferenceId; // ID перекрестной ссылки - STitleInfo* m_pSrcTitleInfo; // Данные об исходнике книги - SPublishInfo* m_pPublishInfo; // Сведения об издании книги + // STitleInfo* m_pSrcTitleInfo; // Данные об исходнике книги + // SPublishInfo* m_pPublishInfo; // Сведения об издании книги std::map m_mFootnotes; // Сноски std::map> m_mImages; // Картинки - std::map m_mCustomInfo; // Произвольная информация + // std::map m_mCustomInfo; // Произвольная информация public: CFb2File_Private() { - m_pSrcTitleInfo = NULL; - m_pPublishInfo = NULL; + // m_pSrcTitleInfo = NULL; + // m_pPublishInfo = NULL; m_nContentsId = 1; m_nCrossReferenceId = 1; - m_sTmpFolder = L""; } ~CFb2File_Private() @@ -191,11 +194,13 @@ public: m_oLightReader.Clear(); m_mFootnotes.clear(); m_mImages.clear(); + /* m_mCustomInfo.clear(); if(m_pSrcTitleInfo) delete m_pSrcTitleInfo; if(m_pPublishInfo) delete m_pPublishInfo; + */ } // wrapper для чтения из файла @@ -206,12 +211,12 @@ public: return m_oLightReader.FromStringA(sFileContentUtf8); } - // Читает и проверят соответствует ли текущий раздел ожиданиям - bool isSection(const std::wstring& sName) + // Проверяет наличие тэга FictionBook + bool isFictionBook() { if(!m_oLightReader.ReadNextNode()) return false; - if(m_oLightReader.GetName() != sName) + if(m_oLightReader.GetName() != L"FictionBook") return false; return true; } @@ -256,7 +261,11 @@ public: std::wstring sName = m_oLightReader.GetName(); size_t nLen = (sName.length() > 4 ? sName.length() - 4 : 0); if(sName.substr(nLen) == L"href") - sImageName = m_oLightReader.GetText().substr(1); + { + std::wstring sText = m_oLightReader.GetText(); + if(sText.length() > 1) + sImageName = sText.substr(1); + } } m_oLightReader.MoveToElement(); @@ -266,41 +275,33 @@ public: if(it != m_mImages.end()) { // Пишем картинку в файл - oBuilder += L""; // extent - oBuilder += L"second[1]; oBuilder += L"\" cy=\""; oBuilder += it->second[2]; - oBuilder += L"\"/>"; // docPr - oBuilder += L"second[0]; - oBuilder += L"\" name=\"\"/>"; // graphic - oBuilder += L""; // pic:nvPicPr - oBuilder += L"second[0]; - oBuilder += L"\" name=\"\"/>"; // pic:blipFill // рельсы rPic + id - oBuilder += L"second[0]; - oBuilder += L"\"/>"; // pic:spPr - oBuilder += L"second[1]; oBuilder += L"\" cy=\""; oBuilder += it->second[2]; - oBuilder += L"\"/>"; // Конец записи - oBuilder += L""; + oBuilder += L"\"/>"; } } // Читает title - // имеет право писать p void readTitle(std::wstring sLevel, NSStringUtils::CStringBuilder& oBuilder) { if(m_oLightReader.IsEmptyNode()) @@ -349,7 +350,6 @@ public: } // Читает epigraph - // имеет право писать p void readEpigraph(NSStringUtils::CStringBuilder& oBuilder) { readCrossReference(oBuilder); @@ -373,6 +373,7 @@ public: readCite(oBuilder); else if(sName == L"empty-line") oBuilder += L""; + // Автор эпиграфа выделяется полужирным else if(sName == L"text-author") { oBuilder += L""; @@ -399,13 +400,11 @@ public: // Читаем обычный текст if(sName == L"#text") { - oBuilder += L""; // Стиль текста - oBuilder += L""; + oBuilder += L""; oBuilder += sRStyle; - oBuilder += L""; // Сам текст - oBuilder += L""; + oBuilder += L""; oBuilder.WriteEncodeXmlString(m_oLightReader.GetText()); oBuilder += L""; @@ -430,7 +429,9 @@ public: size_t nLen = (sTName.length() > 4 ? sTName.length() - 4 : 0); if(sTName.substr(nLen) == L"href") { - sFootnoteName = m_oLightReader.GetText().substr(1); + std::wstring sText = m_oLightReader.GetText(); + if(sText.length() > 1) + sFootnoteName = sText.substr(1); break; } } @@ -478,7 +479,6 @@ public: } // Читает poem - // имеет право писать p void readPoem(NSStringUtils::CStringBuilder& oBuilder) { readCrossReference(oBuilder); @@ -490,13 +490,10 @@ public: while(m_oLightReader.ReadNextSiblingNode(nDeath)) { std::wstring sName = m_oLightReader.GetName(); - // Читаем title (ноль или один) if(sName == L"title") readTitle(L"title4", oBuilder); - // Читаем epigraph (любое) else if(sName == L"epigraph") readEpigraph(oBuilder); - // Читаем stanza (один или более) else if(sName == L"stanza") { if(m_oLightReader.IsEmptyNode()) @@ -506,11 +503,8 @@ public: while(m_oLightReader.ReadNextSiblingNode(nSDeath)) { std::wstring sSName = m_oLightReader.GetName(); - // Читаем title (ноль или один) if(sSName == L"title") readTitle(L"title5", oBuilder); - // Читаем subtitle (ноль или один) - // Читаем v (один или более) else if(sSName == L"v" || sSName == L"subtitle") { oBuilder += L""; @@ -519,14 +513,13 @@ public: } } } - // Читаем text-author (любое) + // Автор поэмы выделяется полужирным else if(sName == L"text-author") { oBuilder += L""; readP(L"", oBuilder); oBuilder += L""; } - // Читаем date (ноль или один) else if(sName == L"date") { oBuilder += L""; @@ -537,7 +530,6 @@ public: } // Читает cite - // имеет право писать p void readCite(NSStringUtils::CStringBuilder& oBuilder) { readCrossReference(oBuilder); @@ -561,6 +553,7 @@ public: readPoem(oBuilder); else if(sName == L"table") readTable(oBuilder); + // Автор цитаты выделяется полужирным else if(sName == L"text-author") { oBuilder += L""; @@ -586,6 +579,7 @@ public: int nDeath = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nDeath)) { + // tr - строки в таблице if(m_oLightReader.GetName() == L"tr") { if(m_oLightReader.IsEmptyNode()) @@ -597,8 +591,7 @@ public: while(m_oLightReader.ReadNextSiblingNode(nTrDeath)) { oTmpBuilder += L""; - - // Читаем th (любое) + // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным if(m_oLightReader.GetName() == L"th") { if(++nTCol > nGridCol) @@ -606,7 +599,7 @@ public: oTmpBuilder += L""; readP(L"", oTmpBuilder); } - // Читаем td (любое) + // Читаем td. Ячейка таблицы. Выравнивание вправо else if(m_oLightReader.GetName() == L"td") { if(++nTCol > nGridCol) @@ -634,12 +627,11 @@ public: // Конец таблицы oBuilder += oTmpBuilder.GetData(); oBuilder += L""; - // Пустая строка после таблицы + // Пустая строка после таблицы, чтобы следующий текст не приклеивался oBuilder += L""; } // Читает annotation - // имеет право писать p void readAnnotation(NSStringUtils::CStringBuilder& oBuilder) { readCrossReference(oBuilder); @@ -691,7 +683,6 @@ public: } // Читает section - // имеет право писать p void readSection(unsigned int nLevel, NSStringUtils::CStringBuilder& oBuilder) { readCrossReference(oBuilder); @@ -703,41 +694,33 @@ public: while(m_oLightReader.ReadNextSiblingNode(nDeath)) { std::wstring sName = m_oLightReader.GetName(); - // Читаем title (ноль или один) if(sName == L"title") { - std::wstring sTitle = L""; + std::wstring sTitle = L"section-p"; if(nLevel < 10) sTitle = L"title" + std::to_wstring(nLevel); readTitle(sTitle, oBuilder); } - // Читаем epigraph (любое) else if(sName == L"epigraph") readEpigraph(oBuilder); - // Читаем image (ноль или один) else if(sName == L"image") { oBuilder += L""; readImage(oBuilder); oBuilder += L""; } - // Читаем annotation (ноль или один) else if(sName == L"annotation") readAnnotation(oBuilder); - // Читаем вложенные section (любое) else if(sName == L"section") readSection(nLevel + 1, oBuilder); - // Читаем произвольный набор else if(sName == L"p") { - // Стиль section-p oBuilder += L""; readP(L"", oBuilder); oBuilder += L""; } else if(sName == L"subtitle") { - // Стиль section-subtitle oBuilder += L""; readP(L"", oBuilder); oBuilder += L""; @@ -754,7 +737,6 @@ public: } // Читает body - // имеет право писать p void readBody(NSStringUtils::CStringBuilder& oBuilder) { if(m_oLightReader.IsEmptyNode()) @@ -764,21 +746,16 @@ public: while(m_oLightReader.ReadNextSiblingNode(nDeath)) { std::wstring sName = m_oLightReader.GetName(); - // Читаем image (ноль или один) if(sName == L"image") { oBuilder += L""; readImage(oBuilder); oBuilder += L""; } - // Читаем title (ноль или один) - // 0 - заголовок книги else if(sName == L"title") readTitle(L"title", oBuilder); - // Читаем epigraph (любое) else if(sName == L"epigraph") readEpigraph(oBuilder); - // Читаем section (один или более) else if(sName == L"section") readSection(1, oBuilder); } @@ -793,7 +770,7 @@ public: if (!OpenFromFile(sPath)) return false; // Читаем FictionBook - if(!isSection(L"FictionBook")) + if(!isFictionBook()) return false; } @@ -845,7 +822,7 @@ public: if(m_oLightReader.IsEmptyNode()) return; - bool bFirstP = true; + bool bFirstTitle = true; int nBDeath = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nBDeath)) { @@ -868,13 +845,13 @@ public: std::wstring sContentsId = std::to_wstring(nContentsId++); oContents += L""; // Абзац с новой страницы - if(bFirstP) + if(bFirstTitle) oContents += L""; oContents += L""; - if(bFirstP) + if(bFirstTitle) { oContents += L"TOC \\n \\h "; - bFirstP = false; + bFirstTitle = false; } oContents += L"", oContents); - // Вставляем пробел между словами - oContents += L" "; + // Вставляем пробел между словами + oContents += L" "; + } } oContents += L""; } } } } - if(!bFirstP) + if(!bFirstTitle) oContents += L""; } @@ -907,7 +885,6 @@ public: int nBDepth = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nBDepth)) { - // Читаем section (один или более) if(m_oLightReader.GetName() == L"section") { // Читаем id @@ -948,9 +925,7 @@ public: { if(m_oLightReader.GetName() == L"p") { - // Стиль section-p - oFootnotes += L""; - oFootnotes += L""; + oFootnotes += L""; readP(L"", oFootnotes); oFootnotes += L""; } @@ -958,9 +933,7 @@ public: } else if(sName == L"p" || sName == L"subtitle") { - // Стиль section-p - oFootnotes += L""; - oFootnotes += L""; + oFootnotes += L""; readP(L"", oFootnotes); oFootnotes += L""; } @@ -985,8 +958,7 @@ public: // Читаем v (один или более) if(m_oLightReader.GetName() == L"v") { - oFootnotes += L""; - oFootnotes += L""; + oFootnotes += L""; readP(L"", oFootnotes); oFootnotes += L""; } @@ -995,8 +967,7 @@ public: // Читаем text-author (любое) else if(sPName == L"text-author") { - oFootnotes += L""; - oFootnotes += L""; + oFootnotes += L""; readP(L"", oFootnotes); oFootnotes += L""; } @@ -1059,13 +1030,10 @@ public: { nW = 7000000; nHy = (int)((double)nHy * (double)nW / (double)nWx); - nWx = nW; } else - { - nWx = nW; nHy = nH; - } + nWx = nW; } std::vector vImage; vImage.push_back(sImageId); @@ -1119,6 +1087,7 @@ public: } // Читает custom-info + /* void getCustomInfo() { std::wstring sIntoType = L""; @@ -1128,8 +1097,11 @@ public: std::wstring sCustomInfo = content(); m_mCustomInfo.insert(std::make_pair(sIntoType, sCustomInfo)); } + */ + // Читает publish-info + /* void getPublishInfo() { if(m_oLightReader.IsEmptyNode()) @@ -1196,8 +1168,10 @@ public: } } } + */ // Читает document-info + /* void getDocumentInfo() { if(m_oLightReader.IsEmptyNode()) @@ -1248,6 +1222,7 @@ public: } } } + */ // Читает title-info и src-title-info void getTitleInfo(STitleInfo& oTitleInfo, NSStringUtils::CStringBuilder& oBuilder) @@ -1259,16 +1234,13 @@ public: while(m_oLightReader.ReadNextSiblingNode(nDepth)) { std::wstring sName = m_oLightReader.GetName(); - // Читаем annotation (ноль или один) if(sName == L"annotation") readAnnotation(oBuilder); - // Читаем coverpage (ноль или один) else if(sName == L"coverpage") { if(m_oLightReader.IsEmptyNode()) continue; - // Читаем image (один или более) int nCDepth = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nCDepth)) { @@ -1280,13 +1252,10 @@ public: } } } - // Читаем genre (один или более) else if(sName == L"genre") oTitleInfo.m_arGenres.push_back(content()); - // Читаем author (один или более) else if(sName == L"author") getAuthor(oTitleInfo.m_arAuthors); - // Читаем book-title else if(sName == L"book-title") oTitleInfo.m_sBookTitle = content(); /* @@ -1385,7 +1354,7 @@ bool CFb2File::IsFb2File(const std::wstring& sFile) if (!m_internal->OpenFromFile(sFile)) return false; // Читаем FictionBook - if(!m_internal->isSection(L"FictionBook")) + if(!m_internal->isFictionBook()) return false; return true; } @@ -1393,7 +1362,7 @@ bool CFb2File::IsFb2File(const std::wstring& sFile) // Выставление рабочей папки void CFb2File::SetTmpDirectory(const std::wstring& sFolder) { - m_internal->m_sTmpFolder = sFolder; + // m_internal->m_sTmpFolder = sFolder; } // Проверяет, соответствует ли fb2 файл формату @@ -1406,15 +1375,12 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory // Начало файла NSStringUtils::CStringBuilder oDocument; - oDocument += L""; - oDocument += L""; + oDocument += L""; // Создаем сноски NSStringUtils::CStringBuilder oFootnotes; - oFootnotes += L""; - oFootnotes += L""; - oFootnotes += L""; - oFootnotes += L""; + oFootnotes += L""; + oFootnotes += L""; // Создаем рельсы NSStringUtils::CStringBuilder oRels; @@ -1432,15 +1398,16 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory NSStringUtils::CStringBuilder oBuilder; NSStringUtils::CStringBuilder oDescription; + NSStringUtils::CStringBuilder oContents; // Читаем содержание, картинки, сноски bool bNeedContents = false; if(oParams) bNeedContents = oParams->bNeedContents; - NSStringUtils::CStringBuilder oContents; if(!m_internal->readText(sPath, sMediaDirectory, oContents, oRels, oFootnotes)) return S_FALSE; + // Переходим в начало if(!m_internal->m_oLightReader.MoveToStart()) return S_FALSE; @@ -1448,10 +1415,8 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory while(m_internal->m_oLightReader.ReadNextSiblingNode(nDeath)) { std::wstring sName = m_internal->m_oLightReader.GetName(); - // Читаем description if(sName == L"description") m_internal->readDescription(oDescription); - // Читаем body else if(sName == L"body") { bool bNotes = false; @@ -1471,9 +1436,8 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory // Конец сносок oFootnotes += L""; // Пишем сноски в файл - std::wstring sFootnotesDirectory = sDirectory + L"/word"; NSFile::CFileBinary oFootnotesWriter; - if (oFootnotesWriter.CreateFileW(sFootnotesDirectory + L"/footnotes.xml")) + if (oFootnotesWriter.CreateFileW(sDirectory + L"/word/footnotes.xml")) { oFootnotesWriter.WriteStringUTF8(oFootnotes.GetData()); oFootnotesWriter.CloseFile(); @@ -1487,8 +1451,7 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory // Вставляем основное тело oDocument += oBuilder.GetData(); // Конец документа - oDocument += L""; - oDocument += L""; + oDocument += L""; // Пишем документ в файл NSFile::CFileBinary oDocumentXmlWriter; if (oDocumentXmlWriter.CreateFileW(sDirectory + L"/word/document.xml")) @@ -1500,9 +1463,8 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory // Конец рельсов oRels += L""; // Пишем рельсы в файл - std::wstring sRelsDirectory = sDirectory + L"/word/_rels"; NSFile::CFileBinary oRelsWriter; - if (oRelsWriter.CreateFileW(sRelsDirectory + L"/document.xml.rels")) + if (oRelsWriter.CreateFileW(sDirectory + L"/word/_rels/document.xml.rels")) { oRelsWriter.WriteStringUTF8(oRels.GetData()); oRelsWriter.CloseFile(); @@ -1514,22 +1476,17 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory // Создаем core.xml NSStringUtils::CStringBuilder oCore; - oCore += L""; - oCore += L""; // Заголовок - oCore += L""; + oCore += L""; oCore.WriteEncodeXmlString(m_internal->m_oTitleInfo.m_sBookTitle); - oCore += L""; // Жанры - oCore += L""; + oCore += L""; oCore.WriteEncodeXmlString(m_internal->m_oTitleInfo.getGenres()); - oCore += L""; // Авторы - oCore += L""; + oCore += L""; oCore.WriteEncodeXmlString(m_internal->m_oTitleInfo.getAuthors()); - oCore += L""; // Конец core - oCore += L"1"; + oCore += L"1"; // Пишем core в файл NSFile::CFileBinary oCoreWriter; if (oCoreWriter.CreateFileW(sDocPropsDirectory + L"/core.xml")) @@ -1549,13 +1506,9 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory sApplication += UTF8_TO_U(sVersion); // Создаем app.xml NSStringUtils::CStringBuilder oApp; - oApp += L""; - oApp += L""; - oApp += L""; + oApp += L""; oApp += sApplication; - oApp += L""; - oApp += L"000false1false11falsefalse10"; - oApp += L""; + oApp += L"000false1false11falsefalse10"; // Пишем app в файл NSFile::CFileBinary oAppWriter; if (oAppWriter.CreateFileW(sDocPropsDirectory + L"/app.xml")) @@ -1574,6 +1527,5 @@ HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory HRESULT oRes = oZip.CompressFileOrDirectory(sDirectory, sDirectory + L"/" + NSFile::GetFileName(sPath) + L".docx"); return oRes; } - return S_OK; } diff --git a/Fb2File/examples/1-posledneye-zhelaniye.fb2 b/Fb2File/examples/1-posledneye-zhelaniye.fb2 index ee239faea7..69278fe9c5 100644 --- a/Fb2File/examples/1-posledneye-zhelaniye.fb2 +++ b/Fb2File/examples/1-posledneye-zhelaniye.fb2 @@ -71,29 +71,6 @@

Глас рассудка I

- - - - - - - - - - - - - - - - - - - - - - -
заг1заг2заг1заг4заг1
текс11текс12текс11текс14текс11
текс21текс22текс21текс24текс21

Она пришла под утро.

Вошла осторожно, тихо, бесшумно ступая, плывя по комнате, словно призрак, привидение, а единственным звуком, выдававшим ее движение, был шорох накидки, прикасавшейся к голому телу. Однако именно этот исчезающе тихий, едва уловимый шелест разбудил ведьмака, а может, только вырвал из полусна, в котором он мерно колыхался, словно погруженный в бездонную топь, висящий между дном и поверхностью спокойного моря, среди легонько извивающихся нитей водорослей.

Он не пошевелился, даже не дрогнул. Девушка подпорхнула ближе, сбросила накидку, медленно, нерешительно оперлась коленом о край ложа. Он наблюдал за ней из-под опущенных ресниц, не выдавая себя. Девушка осторожно поднялась на постель, легла на него, обхватила бедрами. Опираясь на напряженные руки, скользнула по его лицу волосами. Волосы пахли ромашкой. Решительно и как бы нетерпеливо наклонилась, коснулась сосочком его века, щеки, губ. Он улыбнулся, медленно, осторожно, нежно взял ее руки в свои. Она выпрямилась, ускользая от его пальцев, лучистая, подсвеченная и от этого света нечеткая в туманном отблеске зари. Он пошевелился, но она решительным нажимом обеих рук остановила его и легкими, но настойчивыми движениями бедер добилась ответа.

diff --git a/Fb2File/test/main.cpp b/Fb2File/test/main.cpp index 4b24879322..c525f3a0a0 100644 --- a/Fb2File/test/main.cpp +++ b/Fb2File/test/main.cpp @@ -65,6 +65,7 @@ int main() { std::cout << "Success" << std::endl; oZip.CompressFileOrDirectory(sTmp, sOutputDirectory + L"/" + sFileName + L".docx"); + NSDirectory::DeleteDirectory(sTmp + L"/word/media"); } else {