From 347c1f82a904a4d70786be9ee72b5f0f51ff413a Mon Sep 17 00:00:00 2001 From: Kirill Polyakov Date: Sun, 25 Jan 2026 01:39:48 +0300 Subject: [PATCH] Migrated most of the html conversion to the new architecture --- .../html/css/src/CCssCalculator_Private.cpp | 4 +- HtmlFile2/HTMLInterpretator.h | 31 -- HtmlFile2/HTMLReader.cpp | 222 +++++----- HtmlFile2/HTMLReader.h | 29 +- HtmlFile2/HtmlFile2.pro | 11 +- HtmlFile2/Interpretators/HTMLInterpretator.h | 69 ++++ .../OOXMLInterpretator.cpp} | 382 +++++++++++++----- .../OOXMLInterpretator.h} | 71 +++- HtmlFile2/Tags/HTMLTags.h | 73 ---- HtmlFile2/Tags/HTMLTags2OOXML.h | 291 ------------- HtmlFile2/TextSettings.h | 55 --- 11 files changed, 544 insertions(+), 694 deletions(-) delete mode 100644 HtmlFile2/HTMLInterpretator.h create mode 100644 HtmlFile2/Interpretators/HTMLInterpretator.h rename HtmlFile2/{HTML2OOXMLInterpretator.cpp => Interpretators/OOXMLInterpretator.cpp} (84%) rename HtmlFile2/{HTML2OOXMLInterpretator.h => Interpretators/OOXMLInterpretator.h} (50%) delete mode 100644 HtmlFile2/Tags/HTMLTags.h delete mode 100644 HtmlFile2/Tags/HTMLTags2OOXML.h delete mode 100644 HtmlFile2/TextSettings.h diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index ed082aba8b..bc7ef905ed 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -661,8 +661,8 @@ namespace NSCSS std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); + [](std::wstring sRes, const std::wstring& sClass) + {return sRes += L'.' + sClass + L' ';})); } else arNodes.push_back(L'.' + oNode->m_wsClass); diff --git a/HtmlFile2/HTMLInterpretator.h b/HtmlFile2/HTMLInterpretator.h deleted file mode 100644 index 1db5ff8725..0000000000 --- a/HtmlFile2/HTMLInterpretator.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HTMLINTERPRETATOR_H -#define HTMLINTERPRETATOR_H - -#include "../Common/3dParty/html/css/src/CNode.h" -#include "HTMLParams.h" - -namespace HTML -{ -class IHTMLInterpretator -{ -public: - IHTMLInterpretator() = default; - virtual ~IHTMLInterpretator() = default; - - virtual void Begin(const std::wstring& wsDst, const THtmlParams* pParams) = 0; - virtual void End(const std::wstring& wsDst) = 0; - - virtual bool WriteText(const std::wstring& wsText, const std::vector& arSelectors) = 0; - - virtual void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) = 0; - - virtual void BeginBlock(std::vector& arSelectors) = 0; - virtual void EndBlock(bool bAddBlock, std::vector& arSelectors) = 0; - - #ifdef _DEBUG - virtual void PrintData() = 0; - #endif -}; -} - -#endif // HTMLINTERPRETATOR_H diff --git a/HtmlFile2/HTMLReader.cpp b/HtmlFile2/HTMLReader.cpp index 9b6b660146..d9bb491dd6 100644 --- a/HtmlFile2/HTMLReader.cpp +++ b/HtmlFile2/HTMLReader.cpp @@ -4,8 +4,10 @@ #include "../DesktopEditor/common/File.h" #include "../DesktopEditor/common/Path.h" +#include "../Common/3dParty/html/gumbo-parser/src/gumbo.h" + #include "Common.h" -#include "Tags/HTMLTags2OOXML.h" +#include "Interpretators/OOXMLInterpretator.h" namespace HTML { @@ -21,7 +23,7 @@ const std::map m_HTML_TAGS ADD_TAG(L"acronym", ACRONYM), ADD_TAG(L"address", ADDRESS), ADD_TAG(L"applet", APPLET), - ADD_TAG(L"area", AREA), + ADD_TAG(L"area", AREA), ADD_TAG(L"article", ARTICLE), ADD_TAG(L"aside", ASIDE), ADD_TAG(L"audio", AUDIO), @@ -161,27 +163,36 @@ inline bool TagIsUnprocessed(const std::wstring& wsTagName); m_mTags[HTML_TAG(tag_name)] = new struct_name() CHTMLReader::CHTMLReader() - : m_pInterpretator(new CHTML2OOXMLInterpretator()) + : m_pInterpretator(nullptr) { - ADD_EMPTY_OOXML_TAG(B, TBold); - ADD_EMPTY_OOXML_TAG(BR, TCenter); - ADD_EMPTY_OOXML_TAG(I, TItalic); - ADD_EMPTY_OOXML_TAG(CODE, TCode); - ADD_EMPTY_OOXML_TAG(S, TStrike); - ADD_EMPTY_OOXML_TAG(U, TUnderline); - ADD_EMPTY_OOXML_TAG(MARK, TMark); - ADD_EMPTY_OOXML_TAG(SUP, TSup); - ADD_EMPTY_OOXML_TAG(SUB, TSub); - ADD_EMPTY_OOXML_TAG(DD, TDD); - ADD_EMPTY_OOXML_TAG(H1, THeader); + COOXMLInterpretator *pInterpretator = new COOXMLInterpretator(); - ADD_OOXML_TAG(A, TAnchor); - ADD_OOXML_TAG(ABBR, TAbbr); - ADD_OOXML_TAG(BR, TBr); - ADD_OOXML_TAG(BDO, TBidirectional); - ADD_OOXML_TAG(Q, TQuotation); - ADD_OOXML_TAG(SPAN, TSpan); - ADD_OOXML_TAG(PRE, TPreformatted); + if (nullptr == pInterpretator) + return; + + pInterpretator->SetCSSCalculator(&m_oCSSCalculator); + m_pInterpretator = pInterpretator; + + // ADD_EMPTY_OOXML_TAG(B, TBold); + // ADD_EMPTY_OOXML_TAG(BR, TCenter); + // ADD_EMPTY_OOXML_TAG(I, TItalic); + // ADD_EMPTY_OOXML_TAG(CODE, TCode); + // ADD_EMPTY_OOXML_TAG(S, TStrike); + // ADD_EMPTY_OOXML_TAG(U, TUnderline); + // ADD_EMPTY_OOXML_TAG(MARK, TMark); + // ADD_EMPTY_OOXML_TAG(SUP, TSup); + // ADD_EMPTY_OOXML_TAG(SUB, TSub); + // ADD_EMPTY_OOXML_TAG(DD, TDD); + // ADD_EMPTY_OOXML_TAG(H1, THeader); + + // ADD_OOXML_TAG(A, TAnchor); + // ADD_OOXML_TAG(ABBR, TAbbr); + // ADD_OOXML_TAG(BR, TBr); + // ADD_OOXML_TAG(BDO, TBidirectional); + // ADD_OOXML_TAG(Q, TQuotation); + // ADD_OOXML_TAG(SPAN, TSpan); + // ADD_OOXML_TAG(PRE, TPreformatted); + // ADD_OOXML_TAG(PRE, TDiv); } CHTMLReader::~CHTMLReader() @@ -200,6 +211,8 @@ HRESULT CHTMLReader::ConvertFromTo(const std::wstring& wsFrom, const std::wstrin m_sSrc = NSSystemPath::GetDirectoryName(wsFrom); // m_sDst = sDst; + m_oLightReader.MoveToStart(); + m_oLightReader.ReadNextNode(); ReadStyle(); // Переходим в начало @@ -217,7 +230,7 @@ HRESULT CHTMLReader::ConvertFromTo(const std::wstring& wsFrom, const std::wstrin bool CHTMLReader::IsHTML() { - return ((m_oLightReader.MoveToStart() && m_oLightReader.ReadNextNode()) ? m_oLightReader.GetName() == L"html" : false) && m_oLightReader.MoveToStart(); + return ((m_oLightReader.MoveToStart() && m_oLightReader.ReadNextNode()) ? m_oLightReader.GetName() == L"html" : false); } bool CHTMLReader::HTML2XHTML(const std::wstring& wsFileName) @@ -296,7 +309,7 @@ void CHTMLReader::ReadStyle() } // тэг style содержит стили для styles.xml else if(sName == L"style") - m_oStylesCalculator.AddStyles(m_oLightReader.GetText2()); + m_oCSSCalculator.AddStyles(m_oLightReader.GetText2()); else ReadStyle(); } @@ -315,7 +328,7 @@ void CHTMLReader::ReadStyle2() } // тэг style содержит стили для styles.xml else if(sName == L"style") - m_oStylesCalculator.AddStyles(m_oLightReader.GetText2()); + m_oCSSCalculator.AddStyles(m_oLightReader.GetText2()); const int nDeath = m_oLightReader.GetDepth(); while(m_oLightReader.ReadNextSiblingNode(nDeath)) @@ -341,14 +354,14 @@ void CHTMLReader::ReadStyleFromNetwork() oDownloadStyle.SetFilePath(sFName); if(oDownloadStyle.DownloadSync()) { - m_oStylesCalculator.AddStylesFromFile(sFName); + m_oCSSCalculator.AddStylesFromFile(sFName); NSFile::CFileBinary::Remove(sFName); } } else { - m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sFName); - m_oStylesCalculator.AddStylesFromFile(m_sSrc + L'/' + sRef); + m_oCSSCalculator.AddStylesFromFile(m_sSrc + L'/' + sFName); + m_oCSSCalculator.AddStylesFromFile(m_sSrc + L'/' + sRef); } } @@ -478,34 +491,34 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) case HTML_TAG(A): case HTML_TAG(AREA): { - bResult = ReadA(arSelectors); + bResult = ReadAnchor(arSelectors); break; } case HTML_TAG(ABBR): { - bResult = ReadDefaultTag(HTML_TAG(ABBR), arSelectors); + bResult = ReadAbbreviation(arSelectors); break; } case HTML_TAG(B): case HTML_TAG(STRONG): { - bResult = ReadDefaultTag(HTML_TAG(B), arSelectors); + bResult = ReadBold(arSelectors); break; } case HTML_TAG(BDO): case HTML_TAG(BDI): { - bResult = ReadDefaultTag(HTML_TAG(BDO), arSelectors); + bResult = ReadBidirectional(arSelectors); break; } case HTML_TAG(BR): { - bResult = ReadBr(arSelectors); + bResult = ReadBreak(arSelectors); break; } case HTML_TAG(CENTER): { - bResult = ReadDefaultTag(HTML_TAG(CENTER), arSelectors); + bResult = ReadStream(arSelectors); break; } case HTML_TAG(CITE): @@ -514,26 +527,26 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) case HTML_TAG(I): case HTML_TAG(VAR): { - bResult = ReadDefaultTag(HTML_TAG(I), arSelectors); + bResult = ReadItalic(arSelectors); break; } case HTML_TAG(CODE): case HTML_TAG(SAMP): case HTML_TAG(TT): { - bResult = ReadDefaultTag(HTML_TAG(CODE), arSelectors); + bResult = ReadPreformatted(arSelectors); break; } case HTML_TAG(KBD): { - bResult = ReadDefaultTag(HTML_TAG(KBD), arSelectors); + bResult = ReadKBD(arSelectors); break; } case HTML_TAG(DEL): case HTML_TAG(S): case HTML_TAG(STRIKE): { - bResult = ReadDefaultTag(HTML_TAG(S), arSelectors); + bResult = ReadStrikethrough(arSelectors); break; } // case HTML_TAG(FONT): @@ -549,27 +562,27 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) case HTML_TAG(INS): case HTML_TAG(U): { - bResult = ReadDefaultTag(HTML_TAG(U), arSelectors); + bResult = ReadUnderline(arSelectors); break; } case HTML_TAG(MARK): { - bResult = ReadDefaultTag(HTML_TAG(MARK), arSelectors); + bResult = ReadStream(arSelectors); break; } case HTML_TAG(Q): { - bResult = ReadDefaultTag(HTML_TAG(Q), arSelectors); + bResult = ReadQuotation(arSelectors); break; } case HTML_TAG(SUP): { - bResult = ReadDefaultTag(HTML_TAG(SUP), arSelectors); + bResult = ReadStream(arSelectors); break; } case HTML_TAG(SUB): { - bResult = ReadDefaultTag(HTML_TAG(SUB), arSelectors); + bResult = ReadStream(arSelectors); break; } // case HTML_TAG(SVG): @@ -610,12 +623,12 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) } case HTML_TAG(SPAN): { - bResult = ReadDefaultTag(HTML_TAG(SPAN), arSelectors); + bResult = ReadStream(arSelectors); break; } case HTML_TAG(NOBR): { - bResult = ReadDefaultTag(HTML_TAG(PRE), arSelectors); + bResult = ReadPreformatted(arSelectors); break; } // case HTML_TAG(BASEFONT): @@ -642,18 +655,18 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) } default: { - m_pInterpretator->BeginBlock(arSelectors); + m_pInterpretator->BeginBlock(); switch(eHtmlTag) { case HTML_TAG(ADDRESS): { - bResult = ReadDefaultTag(HTML_TAG(I), arSelectors); + bResult = ReadItalic(arSelectors); break; } case HTML_TAG(DD): { - bResult = ReadDefaultTag(HTML_TAG(DD), arSelectors); + bResult = ReadStream(arSelectors); break; } case HTML_TAG(H1): @@ -663,15 +676,16 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) case HTML_TAG(H5): case HTML_TAG(H6): { - bResult = ReadDefaultTag(HTML_TAG(H1), arSelectors); + bResult = ReadHeader(arSelectors); + break; + } + case HTML_TAG(ASIDE): + case HTML_TAG(DIV): + { + m_pInterpretator->UpdatePageStyle(arSelectors); + bResult = ReadStream(arSelectors); break; } - // case HTML_TAG(ASIDE): - // case HTML_TAG(DIV): - // { - // bResult = ReadDiv(&oXmlData, sSelectors, oTS); - // break; - // } // case HTML_TAG(BLOCKQUOTE): // { // bResult = ReadBlockquote(&oXmlData, sSelectors, oTS); @@ -730,7 +744,7 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) case HTML_TAG(PRE): case HTML_TAG(XMP): { - bResult = ReadDefaultTag(HTML_TAG(PRE), arSelectors); + bResult = ReadPreformatted(arSelectors); break; } // case HTML_TAG(TABLE): @@ -761,7 +775,7 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors) } } - m_pInterpretator->EndBlock(bResult, arSelectors); + m_pInterpretator->EndBlock(bResult); } } @@ -792,41 +806,47 @@ bool CHTMLReader::ReadText(std::vector& arSelectors) return bResult; } -bool CHTMLReader::ReadA(std::vector& arSelectors) +bool CHTMLReader::ReadAnchor(std::vector& arSelectors) { - if (!m_mTags[HTML_TAG(A)]->Open(arSelectors)) - return false; + m_pInterpretator->OpenAnchor(arSelectors); if(!ReadStream(arSelectors)) - m_pInterpretator->WriteEmptyParagraph(true); + m_pInterpretator->WriteEmptyParagraph(true, true); - m_mTags[HTML_TAG(A)]->Close(arSelectors); + m_pInterpretator->CloseAnchor(arSelectors); return true; } -bool CHTMLReader::ReadBr(std::vector& arSelectors) +#define CREATE_DEFAULT_READ(PROPERTY_NAME)\ +bool CHTMLReader::Read##PROPERTY_NAME(std::vector& arSelectors)\ +{\ + if (!m_pInterpretator->Open##PROPERTY_NAME(arSelectors))\ + return false;\ +\ + const bool bResult{ReadStream(arSelectors)};\ +\ + m_pInterpretator->Close##PROPERTY_NAME(arSelectors);\ +\ + return bResult;\ +} + +bool CHTMLReader::ReadBreak(const std::vector& arSelectors) { - if (!m_mTags[HTML_TAG(BR)]->Open(arSelectors)) - return false; - - m_mTags[HTML_TAG(BR)]->Close(arSelectors); - + m_pInterpretator->Break(arSelectors); return true; } - -bool CHTMLReader::ReadDefaultTag(HtmlTag eTag, std::vector& arSelectors) -{ - if (!m_mTags[eTag]->Open(arSelectors)) - return false; - - const bool bResult = ReadStream(arSelectors); - - m_mTags[eTag]->Close(arSelectors); - - return bResult; -} +CREATE_DEFAULT_READ(Abbreviation) +CREATE_DEFAULT_READ(Bold) +CREATE_DEFAULT_READ(Bidirectional) +CREATE_DEFAULT_READ(Italic) +CREATE_DEFAULT_READ(Preformatted) +CREATE_DEFAULT_READ(KBD) +CREATE_DEFAULT_READ(Strikethrough) +CREATE_DEFAULT_READ(Underline) +CREATE_DEFAULT_READ(Quotation) +CREATE_DEFAULT_READ(Header) void CHTMLReader::GetSubClass(std::vector& arSelectors) { @@ -834,31 +854,37 @@ void CHTMLReader::GetSubClass(std::vector& arSelectors) oNode.m_wsName = m_oLightReader.GetName(); // Стиль по атрибуту - while(m_oLightReader.MoveToNextAttribute()) - { - std::wstring sName = m_oLightReader.GetName(); - if(sName == L"class") - oNode.m_wsClass = EncodeXmlString(m_oLightReader.GetText()); - else if(sName == L"id") - { - oNode.m_wsId = EncodeXmlString(m_oLightReader.GetText()); - // WriteEmptyBookmark(oXml, oNode.m_wsId); + std::wstring wsAttributeName; - if (!m_oStylesCalculator.HaveStylesById(oNode.m_wsId)) - oNode.m_wsId.clear(); - } - else if(sName == L"style") - oNode.m_wsStyle += m_oLightReader.GetText(); - else + if (m_oLightReader.MoveToFirstAttribute()) + { + do { - if (CheckArgumentMath(oNode.m_wsName, sName)) - oNode.m_mAttributes[sName] = m_oLightReader.GetText(); - } + wsAttributeName = m_oLightReader.GetName(); + if(wsAttributeName == L"class") + oNode.m_wsClass = EncodeXmlString(m_oLightReader.GetText()); + else if(wsAttributeName == L"id") + { + oNode.m_wsId = EncodeXmlString(m_oLightReader.GetText()); + // WriteEmptyBookmark(oXml, oNode.m_wsId); + + // if (!m_oStylesCalculator.HaveStylesById(oNode.m_wsId)) + // oNode.m_wsId.clear(); + } + else if(wsAttributeName == L"style") + oNode.m_wsStyle += m_oLightReader.GetText(); + else + { + if (CheckArgumentMath(oNode.m_wsName, wsAttributeName)) + oNode.m_mAttributes[wsAttributeName] = m_oLightReader.GetText(); + } + }while(m_oLightReader.MoveToNextAttribute()); } + m_oLightReader.MoveToElement(); arSelectors.push_back(oNode); - m_oStylesCalculator.CalculateCompiledStyle(arSelectors); + m_oCSSCalculator.CalculateCompiledStyle(arSelectors); } inline std::wstring GetArgumentValue(XmlUtils::CXmlLiteReader& oLiteReader, const std::wstring& wsArgumentName, const std::wstring& wsDefaultValue) diff --git a/HtmlFile2/HTMLReader.h b/HtmlFile2/HTMLReader.h index b0a86f99fc..b2b76f2882 100644 --- a/HtmlFile2/HTMLReader.h +++ b/HtmlFile2/HTMLReader.h @@ -4,10 +4,7 @@ #include "../Common/3dParty/html/css/src/CCssCalculator.h" #include "../DesktopEditor/xml/include/xmlutils.h" -#include "HTMLInterpretator.h" -#include "Tags/HTMLTags.h" - -#include "../Common/3dParty/html/gumbo-parser/src/gumbo.h" +#include "Interpretators/HTMLInterpretator.h" namespace HTML { @@ -16,7 +13,7 @@ namespace HTML class CHTMLReader { XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader - NSCSS::CCssCalculator m_oStylesCalculator; // Css калькулятор + NSCSS::CCssCalculator m_oCSSCalculator; // Css калькулятор std::wstring m_sTmp; // Temp папка std::wstring m_sSrc; // Директория источника @@ -26,12 +23,16 @@ class CHTMLReader IHTMLInterpretator *m_pInterpretator; - std::map m_mTags; + // std::map m_mTags; public: CHTMLReader(); ~CHTMLReader(); + void SetInterpretator(IHTMLInterpretator* pInterpretator); + HRESULT ConvertFromTo(const std::wstring& wsFrom, const std::wstring& wsTo); + + NSCSS::CCssCalculator* GetCSSCalculator(); private: bool IsHTML(); @@ -49,10 +50,20 @@ private: bool ReadInside(std::vector& arSelectors); bool ReadText(std::vector& arSelectors); - bool ReadA(std::vector& arSelectors); - bool ReadBr(std::vector& arSelectors); - bool ReadDefaultTag(HtmlTag eTag, std::vector& arSelectors); + bool ReadAnchor(std::vector& arSelectors); + bool ReadBreak(const std::vector& arSelectors); + + bool ReadAbbreviation(std::vector& arSelectors); + bool ReadBold(std::vector& arSelectors); + bool ReadBidirectional(std::vector& arSelectors); + bool ReadItalic(std::vector& arSelectors); + bool ReadPreformatted(std::vector& arSelectors); + bool ReadKBD(std::vector& arSelectors); + bool ReadStrikethrough(std::vector& arSelectors); + bool ReadUnderline(std::vector& arSelectors); + bool ReadQuotation(std::vector& arSelectors); + bool ReadHeader(std::vector& arSelectors); void GetSubClass(std::vector& arSelectors); }; diff --git a/HtmlFile2/HtmlFile2.pro b/HtmlFile2/HtmlFile2.pro index a68bf52f97..1f1b5c5a57 100644 --- a/HtmlFile2/HtmlFile2.pro +++ b/HtmlFile2/HtmlFile2.pro @@ -32,17 +32,14 @@ include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) ADD_DEPENDENCY(kernel, UnicodeConverter, graphics, kernel_network) SOURCES += htmlfile2.cpp \ - HTML2OOXMLInterpretator.cpp \ + ./Interpretators/OOXMLInterpretator.cpp \ HTMLReader.cpp HEADERS += htmlfile2.h \ ./src/StringFinder.h \ ./src/Languages.h \ Common.h \ - HTML2OOXMLInterpretator.h \ - HTMLInterpretator.h \ + ./Interpretators/OOXMLInterpretator.h \ + ./Interpretators/HTMLInterpretator.h \ HTMLParams.h \ - HTMLReader.h \ - Tags/HTMLTags.h \ - Tags/HTMLTags2OOXML.h \ - TextSettings.h + HTMLReader.h diff --git a/HtmlFile2/Interpretators/HTMLInterpretator.h b/HtmlFile2/Interpretators/HTMLInterpretator.h new file mode 100644 index 0000000000..03ff3d757d --- /dev/null +++ b/HtmlFile2/Interpretators/HTMLInterpretator.h @@ -0,0 +1,69 @@ +#ifndef HTMLINTERPRETATOR_H +#define HTMLINTERPRETATOR_H + +#include "../Common/3dParty/html/css/src/CNode.h" +#include "HTMLParams.h" + +namespace HTML +{ +class IHTMLInterpretator +{ +public: + IHTMLInterpretator() = default; + virtual ~IHTMLInterpretator() = default; + + virtual void Begin(const std::wstring& wsDst, const THtmlParams* pParams) = 0; + virtual void End(const std::wstring& wsDst) = 0; + + virtual bool WriteText(const std::wstring& wsText, const std::vector& arSelectors) = 0; + + virtual void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) = 0; + + virtual void BeginBlock() = 0; + virtual void EndBlock(bool bAddBlock) = 0; + + virtual void UpdatePageStyle(const std::vector& arSelectors) = 0; + + //Conversion methods + virtual bool OpenAnchor(const std::vector& arSelectors) = 0; + virtual void CloseAnchor(const std::vector& arSelectors) = 0; + + virtual void Break(const std::vector& arSelectors) = 0; + + virtual bool OpenAbbreviation(const std::vector& arSelectors) = 0; + virtual void CloseAbbreviation(const std::vector& arSelectors) = 0; + + virtual bool OpenBold(const std::vector& arSelectors) = 0; + virtual void CloseBold(const std::vector& arSelectors) = 0; + + virtual bool OpenBidirectional(const std::vector& arSelectors) = 0; + virtual void CloseBidirectional(const std::vector& arSelectors) = 0; + + virtual bool OpenItalic(const std::vector& arSelectors) = 0; + virtual void CloseItalic(const std::vector& arSelectors) = 0; + + virtual bool OpenPreformatted(const std::vector& arSelectors) = 0; + virtual void ClosePreformatted(const std::vector& arSelectors) = 0; + + virtual bool OpenKBD(const std::vector& arSelectors) = 0; + virtual void CloseKBD(const std::vector& arSelectors) = 0; + + virtual bool OpenStrikethrough(const std::vector& arSelectors) = 0; + virtual void CloseStrikethrough(const std::vector& arSelectors) = 0; + + virtual bool OpenUnderline(const std::vector& arSelectors) = 0; + virtual void CloseUnderline(const std::vector& arSelectors) = 0; + + virtual bool OpenQuotation(const std::vector& arSelectors) = 0; + virtual void CloseQuotation(const std::vector& arSelectors) = 0; + + virtual bool OpenHeader(const std::vector& arSelectors) = 0; + virtual void CloseHeader(const std::vector& arSelectors) = 0; + + #ifdef _DEBUG + virtual void PrintData() = 0; + #endif +}; +} + +#endif // HTMLINTERPRETATOR_H diff --git a/HtmlFile2/HTML2OOXMLInterpretator.cpp b/HtmlFile2/Interpretators/OOXMLInterpretator.cpp similarity index 84% rename from HtmlFile2/HTML2OOXMLInterpretator.cpp rename to HtmlFile2/Interpretators/OOXMLInterpretator.cpp index 5205aef544..3edaf1da09 100644 --- a/HtmlFile2/HTML2OOXMLInterpretator.cpp +++ b/HtmlFile2/Interpretators/OOXMLInterpretator.cpp @@ -1,4 +1,4 @@ -#include "HTML2OOXMLInterpretator.h" +#include "OOXMLInterpretator.h" #include @@ -33,6 +33,31 @@ namespace HTML #define DEFAULT_IMAGE_WIDTH 304800 #define DEFAULT_IMAGE_HEIGHT 304800 +struct TImageData +{ + UINT m_unWidth; + UINT m_unHeight; + + int m_nHSpace; + int m_nVSpace; + + std::wstring m_wsAlign; + + TImageData() + : m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left") + {} + + bool ZeroSize() const + { + return 0 == m_unWidth || 0 == m_unHeight; + } + + bool ZeroSpaces() const + { + return 0 == m_nHSpace && 0 == m_nVSpace; + } +}; + inline bool ElementInTable(const std::vector& arSelectors); inline void WriteToStringBuilder(NSStringUtils::CStringBuilder& oSrcStringBuilder, NSStringUtils::CStringBuilder& oDstStringBuilder); inline bool ElementInHeader(const std::vector arSelsectors); @@ -44,7 +69,7 @@ inline void ReplaceSpaces(std::wstring& wsValue); inline void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2); inline std::wstring EncodeXmlString(std::wstring wsString); -CHTML2OOXMLInterpretator::CHTML2OOXMLInterpretator() +COOXMLInterpretator::COOXMLInterpretator() : m_pCurrentDocument(&m_oDocXml), m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1), m_nShapeId(1) { m_oPageData.SetWidth (DEFAULT_PAGE_WIDTH, NSCSS::UnitMeasure::Twips, 0, true); @@ -54,7 +79,12 @@ CHTML2OOXMLInterpretator::CHTML2OOXMLInterpretator() m_oPageData.SetHeader(720, NSCSS::UnitMeasure::Twips, 0, true); } -void CHTML2OOXMLInterpretator::Begin(const std::wstring& wsDst, const THtmlParams* pParams) +void COOXMLInterpretator::SetCSSCalculator(NSCSS::CCssCalculator* pCSSCalculator) +{ + m_pStylesCalculator = pCSSCalculator; +} + +void COOXMLInterpretator::Begin(const std::wstring& wsDst, const THtmlParams* pParams) { // Создаем пустые папки NSDirectory::CreateDirectory(wsDst + L"/_rels"); @@ -251,7 +281,7 @@ void CHTML2OOXMLInterpretator::Begin(const std::wstring& wsDst, const THtmlParam m_oStylesXml += L""; } -void CHTML2OOXMLInterpretator::End(const std::wstring& wsDst) +void COOXMLInterpretator::End(const std::wstring& wsDst) { m_oDocXmlRels.WriteString(L""); NSFile::CFileBinary oRelsWriter; @@ -348,7 +378,7 @@ void CHTML2OOXMLInterpretator::End(const std::wstring& wsDst) } } -bool CHTML2OOXMLInterpretator::OpenP() +bool COOXMLInterpretator::OpenP() { if (m_oState.m_bInP) return false; @@ -360,7 +390,7 @@ bool CHTML2OOXMLInterpretator::OpenP() return true; } -bool CHTML2OOXMLInterpretator::OpenR() +bool COOXMLInterpretator::OpenR() { if (m_oState.m_bInR) return false; @@ -370,7 +400,7 @@ bool CHTML2OOXMLInterpretator::OpenR() return true; } -bool CHTML2OOXMLInterpretator::OpenT() +bool COOXMLInterpretator::OpenT() { if (m_oState.m_bInT) return false; @@ -380,7 +410,7 @@ bool CHTML2OOXMLInterpretator::OpenT() return true; } -void CHTML2OOXMLInterpretator::CloseP(std::vector& arSelectors) +void COOXMLInterpretator::CloseP() { m_oState.m_bWasSpace = true; @@ -390,20 +420,11 @@ void CHTML2OOXMLInterpretator::CloseP(std::vector& arSelectors) CloseT(); CloseR(); - if (m_oState.m_bInHyperlink) - { - if (arSelectors.rend() != std::find_if(arSelectors.rbegin(), arSelectors.rend(), [](const NSCSS::CNode& oNode) { return L"a" == oNode.m_wsName; })) - { - m_pCurrentDocument->WriteString(L""); - m_oState.m_bInHyperlink = false; - } - } - m_pCurrentDocument->WriteString(L""); m_oState.m_bInP = false; } -void CHTML2OOXMLInterpretator::CloseR() +void COOXMLInterpretator::CloseR() { if (!m_oState.m_bInR) return; @@ -412,7 +433,7 @@ void CHTML2OOXMLInterpretator::CloseR() m_oState.m_bInR = false; } -void CHTML2OOXMLInterpretator::CloseT() +void COOXMLInterpretator::CloseT() { if (!m_oState.m_bInT) return; @@ -421,22 +442,22 @@ void CHTML2OOXMLInterpretator::CloseT() m_oState.m_bInT = false; } -void CHTML2OOXMLInterpretator::BeginBlock(std::vector& arSelectors) +void COOXMLInterpretator::BeginBlock() { m_pCurrentDocument = new XmlString(); //Сохранить состояние - CloseP(arSelectors); + CloseP(); } -void CHTML2OOXMLInterpretator::EndBlock(bool bAddBlock, std::vector& arSelectors) +void COOXMLInterpretator::EndBlock(bool bAddBlock) { if (m_pCurrentDocument == &m_oDocXml) return; // readNote(&oXmlData, sSelectors, sNote); - CloseP(arSelectors); + CloseP(); if (bAddBlock) WriteToStringBuilder(*m_pCurrentDocument, m_oDocXml); @@ -447,37 +468,49 @@ void CHTML2OOXMLInterpretator::EndBlock(bool bAddBlock, std::vector& arSelectors) +bool COOXMLInterpretator::OpenAnchor(const std::vector& arSelectors) { + std::wstring wsRef, wsAlt, wsName; + bool bCross = false; + + if (arSelectors.back().GetAttributeValue(L"href", wsRef) && wsRef.find('#') != std::wstring::npos) + bCross = true; + + if (arSelectors.back().GetAttributeValue(L"name", wsName)) + WriteBookmark(wsName); + + arSelectors.back().GetAttributeValue(L"alt", wsAlt); + + std::wstring wsTooltip(wsRef); + + arSelectors.back().GetAttributeValue(L"title", wsTooltip); + if (!OpenP()) CloseR(); else WritePPr(arSelectors); - m_oState.m_bInHyperlink = true; + if (bCross) + { + m_oState.m_bInHyperlink = true; - m_pCurrentDocument->WriteString(L"WriteString(L"WriteEncodeXmlString(AddAnchor(wsAnchorValue)); + if (!wsAnchorValue.empty()) + m_pCurrentDocument->WriteEncodeXmlString(AddAnchor(wsAnchorValue)); - m_pCurrentDocument->WriteString(L"\">"); -} + m_pCurrentDocument->WriteString(L"\">"); -void CHTML2OOXMLInterpretator::OpenExternalHyperlink(const std::wstring& wsRef, const std::wstring& wsTooltip, std::vector& arSelectors) -{ - if (!OpenP()) - CloseR(); - else - WritePPr(arSelectors); + return true; + } // Пишем рельсы XmlString& oRelationshipXml(m_oDocXmlRels); @@ -498,72 +531,119 @@ void CHTML2OOXMLInterpretator::OpenExternalHyperlink(const std::wstring& wsRef, m_pCurrentDocument->WriteString(L"\" r:id=\"rHyp"); m_pCurrentDocument->WriteString(std::to_wstring(m_nHyperlinkId++)); m_pCurrentDocument->WriteString(L"\">"); + + return true; } -void CHTML2OOXMLInterpretator::CloseCrossHyperlink(std::vector& arSelectors, std::wstring wsFootnote, const std::wstring& wsRef) +void COOXMLInterpretator::CloseAnchor(const std::vector& arSelectors) { + bool bCross = false; + std::wstring wsFootnote; + + if (arSelectors.back().m_wsStyle.find(L"mso-footnote-id") != std::wstring::npos) + wsFootnote = arSelectors.back().m_wsStyle.substr(arSelectors.back().m_wsStyle.rfind(L':') + 1); + else + { + if (arSelectors.back().GetAttributeValue(L"epub:type", wsFootnote) && wsFootnote.find(L"noteref")) + wsFootnote = L"href"; + } + + std::wstring wsRef; + + if (arSelectors.back().GetAttributeValue(L"href", wsRef)) + { + if(wsRef.find('#') != std::wstring::npos) + bCross = true; + } + if (!m_oState.m_bInP) return; - CloseExternalHyperlink(); - - bool bFootnote = false; - if (arSelectors.size() > 1) + if (m_oState.m_bInHyperlink) { - const NSCSS::CNode& oNode = arSelectors[arSelectors.size() - 2]; - bFootnote = oNode.m_wsName == L"p" && oNode.m_wsClass == L"MsoFootnoteText"; + CloseT(); + CloseR(); + m_pCurrentDocument->WriteString(L""); + m_oState.m_bInHyperlink = false; } - // Сноска - if (!wsFootnote.empty()) + if (bCross) { - if (!bFootnote) + if (wsFootnote == L"href") + wsFootnote = wsRef.substr(wsRef.find('#') + 1); + + bool bFootnote = false; + if (arSelectors.size() > 1) { - std::wstring sFootnoteID = std::to_wstring(m_nFootnoteId++); - OpenR(); - m_pCurrentDocument->WriteString(L"WriteString(sFootnoteID); - m_pCurrentDocument->WriteString(L"\"/>"); - CloseR(); - m_mFootnotes.insert(std::make_pair(wsFootnote, sFootnoteID)); + const NSCSS::CNode& oNode = arSelectors[arSelectors.size() - 2]; + bFootnote = oNode.m_wsName == L"p" && oNode.m_wsClass == L"MsoFootnoteText"; } - else + + // Сноска + if (!wsFootnote.empty()) { - OpenR(); - m_pCurrentDocument->WriteString(L""); - CloseR(); + if (!bFootnote) + { + std::wstring sFootnoteID = std::to_wstring(m_nFootnoteId++); + OpenR(); + m_pCurrentDocument->WriteString(L"WriteString(sFootnoteID); + m_pCurrentDocument->WriteString(L"\"/>"); + CloseR(); + m_mFootnotes.insert(std::make_pair(wsFootnote, sFootnoteID)); + } + else + { + OpenR(); + m_pCurrentDocument->WriteString(L""); + CloseR(); + } } } } -void CHTML2OOXMLInterpretator::CloseExternalHyperlink() +void COOXMLInterpretator::Break(const std::vector& arSelectors) { - if (!m_oState.m_bInP && !m_oState.m_bInHyperlink) - return; + if (m_oState.m_bInP) + { + OpenR(); + if(arSelectors.back().m_pCompiledStyle->m_oText.GetAlign() == L"both") + m_pCurrentDocument->WriteString(L""); + m_pCurrentDocument->WriteString(L""); + CloseR(); + } + else + WriteEmptyParagraph(false, m_oState.m_bInP); - CloseT(); - CloseR(); - m_pCurrentDocument->WriteString(L""); - m_oState.m_bInHyperlink = false; + m_oState.m_bWasSpace = true; } -void CHTML2OOXMLInterpretator::OpenFldChar(const std::wstring& wsNote) +bool COOXMLInterpretator::OpenAbbreviation(const std::vector& arSelectors) { + std::wstring wsTitle; + + if (!arSelectors.back().GetAttributeValue(L"title", wsTitle)) + return false; + + WritePPr(arSelectors); + const std::wstring wsName{L"Bookmark" + std::to_wstring(m_mBookmarks.size() + 1)}; m_mBookmarks.insert(std::make_pair(wsName, m_mBookmarks.size() + 1)); m_pCurrentDocument->WriteString(L"HYPERLINK \\l \"" + wsName + L"\" \\o \""); - m_pCurrentDocument->WriteEncodeXmlString(wsNote); + m_pCurrentDocument->WriteEncodeXmlString(wsTitle); m_pCurrentDocument->WriteString(L"\""); m_pCurrentDocument->WriteString(L""); + + return true; } -void CHTML2OOXMLInterpretator::CloseFldChar() +void COOXMLInterpretator::CloseAbbreviation(const std::vector& arSelectors) { m_pCurrentDocument->WriteString(L""); } -std::wstring CHTML2OOXMLInterpretator::WritePPr(const std::vector& arSelectors) +std::wstring COOXMLInterpretator::WritePPr(const std::vector& arSelectors) { OpenP(); @@ -617,7 +697,7 @@ std::wstring CHTML2OOXMLInterpretator::WritePPr(const std::vector& return sPStyle; } -std::wstring CHTML2OOXMLInterpretator::WriteRPr(XmlString& oXml, const std::vector& arSelectors) +std::wstring COOXMLInterpretator::WriteRPr(XmlString& oXml, const std::vector& arSelectors) { if (!m_oState.m_bInP) return L""; @@ -676,7 +756,7 @@ std::wstring CHTML2OOXMLInterpretator::WriteRPr(XmlString& oXml, const std::vect return sRStyle; } -bool CHTML2OOXMLInterpretator::WriteText(const std::wstring& wsText, const std::vector& arSelectors) +bool COOXMLInterpretator::WriteText(const std::wstring& wsText, const std::vector& arSelectors) { if (wsText.empty()) return false; @@ -823,23 +903,7 @@ bool CHTML2OOXMLInterpretator::WriteText(const std::wstring& wsText, const std:: return true; } -void CHTML2OOXMLInterpretator::WriteBr(std::vector& arSelectors) -{ - if (m_oState.m_bInP) - { - OpenR(); - if(arSelectors.back().m_pCompiledStyle->m_oText.GetAlign() == L"both") - m_pCurrentDocument->WriteString(L""); - m_pCurrentDocument->WriteString(L""); - CloseR(); - } - else - WriteEmptyParagraph(false, m_oState.m_bInP); - - m_oState.m_bWasSpace = true; -} - -void CHTML2OOXMLInterpretator::WriteEmptyParagraph(bool bVahish, bool bInP) +void COOXMLInterpretator::WriteEmptyParagraph(bool bVahish, bool bInP) { if (!bInP) m_pCurrentDocument->WriteString(L""); @@ -855,7 +919,7 @@ void CHTML2OOXMLInterpretator::WriteEmptyParagraph(bool bVahish, bool bInP) m_pCurrentDocument->WriteString(L""); } -void CHTML2OOXMLInterpretator::WriteSpace() +void COOXMLInterpretator::WriteSpace() { OpenR(); m_pCurrentDocument->WriteString(L" "); @@ -863,7 +927,7 @@ void CHTML2OOXMLInterpretator::WriteSpace() m_oState.m_bWasSpace = true; } -void CHTML2OOXMLInterpretator::WriteEmptyBookmark(const std::wstring& wsId) +void COOXMLInterpretator::WriteEmptyBookmark(const std::wstring& wsId) { const std::wstring wsCrossId{WriteBookmark(wsId)}; @@ -875,7 +939,7 @@ void CHTML2OOXMLInterpretator::WriteEmptyBookmark(const std::wstring& wsId) m_pCurrentDocument->WriteString(L"\"/>"); } -std::wstring CHTML2OOXMLInterpretator::WriteBookmark(const std::wstring& wsId) +std::wstring COOXMLInterpretator::WriteBookmark(const std::wstring& wsId) { const std::wstring sCrossId = std::to_wstring(m_mBookmarks.size() + 1); std::wstring sName; @@ -903,7 +967,7 @@ std::wstring CHTML2OOXMLInterpretator::WriteBookmark(const std::wstring& wsId) return sCrossId; } -std::wstring CHTML2OOXMLInterpretator::AddAnchor(const std::wstring& wsAnchorValue) +std::wstring COOXMLInterpretator::AddAnchor(const std::wstring& wsAnchorValue) { const anchors_map::iterator itFound = m_mAnchors.find(wsAnchorValue); @@ -916,7 +980,106 @@ std::wstring CHTML2OOXMLInterpretator::AddAnchor(const std::wstring& wsAnchorVal return wsAnchorId; } -std::wstring CHTML2OOXMLInterpretator::GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bParagraphStyle) +void COOXMLInterpretator::WriteImage(const std::vector& arSelectors) +{ + const std::wstring wsAlt{arSelectors.back().GetAttributeValue(L"alt")}; + const std::wstring wsSrc{arSelectors.back().GetAttributeValue(L"src")}; + + TImageData oImageData; + + std::wstring wsTempValue; + NSCSS::NSProperties::CDigit oTempDigit; + + #define GET_UNIT_DATA(variable_data, data_variable)\ + if (NSCSS::UnitMeasure::None == data_variable.GetUnitMeasure())\ + variable_data = static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(data_variable.ToDouble(), NSCSS::Inch, 96) * 914400);\ + else\ + variable_data = static_cast(data_variable.ToDouble(NSCSS::Inch) * 914400) + + #define READ_IMAGE_DATA(name_data, variable_data)\ + if (arSelectors.back().GetAttributeValue(name_data, wsTempValue))\ + {\ + if (oTempDigit.SetValue(wsTempValue))\ + {\ + GET_UNIT_DATA(variable_data, oTempDigit);\ + }\ + } + + READ_IMAGE_DATA(L"width", oImageData.m_unWidth); + READ_IMAGE_DATA(L"height", oImageData.m_unHeight); + READ_IMAGE_DATA(L"hspace", oImageData.m_nHSpace); + READ_IMAGE_DATA(L"vspace", oImageData.m_nVSpace); + + if (nullptr != arSelectors.back().m_pCompiledStyle) + { + oTempDigit = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetWidth(); + + if (0 == oImageData.m_unWidth && !oTempDigit.Empty()) + { + GET_UNIT_DATA(oImageData.m_unWidth, oTempDigit); + } + + oTempDigit = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetHeight(); + + if (0 == oImageData.m_unHeight && !oTempDigit.Empty()) + { + GET_UNIT_DATA(oImageData.m_unHeight, oTempDigit); + } + } + + if (wsSrc.empty()) + { + WriteAlternativeImage(wsAlt, wsSrc, oImageData); + return; + } + + bool bRes = false; +} + +void COOXMLInterpretator::WriteAlternativeImage(const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData) +{ + m_oDocXmlRels.WriteString(L""); + + const bool bOpenedP{OpenP()}; + + WriteEmptyImage((0 != oImageData.m_unWidth) ? oImageData.m_unWidth : DEFAULT_IMAGE_WIDTH, (0 != oImageData.m_unHeight) ? oImageData.m_unHeight : DEFAULT_IMAGE_HEIGHT, L"", wsAlt); + + if (bOpenedP) + CloseP(); +} +void COOXMLInterpretator::WriteEmptyImage(int nWidth, int nHeight, const std::wstring& wsName, const std::wstring& wsDescr) +{ + OpenR(); + + #define WRITE_ENCODE_ARGUMENT(argumentName, argumentValue) \ + m_pCurrentDocument->WriteString(L" " + std::wstring(argumentName) + L"=\""); \ + m_pCurrentDocument->WriteEncodeXmlString(argumentValue); \ + m_pCurrentDocument->WriteString(L"\"") + + m_pCurrentDocument->WriteString(L""); + m_pCurrentDocument->WriteString(L"WriteString(L"/>"); + m_pCurrentDocument->WriteString(L""); + m_pCurrentDocument->WriteString(L""); + m_pCurrentDocument->WriteString(L"WriteString(L"/>"); + m_pCurrentDocument->WriteString(L""); + m_pCurrentDocument->WriteString(L""); + m_pCurrentDocument->WriteString(L""); + m_pCurrentDocument->WriteString(L""); + + CloseR(); +} + +std::wstring COOXMLInterpretator::GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bParagraphStyle) { if ((bParagraphStyle && !m_oXmlStyle.WritePStyle(oStyle)) || (!bParagraphStyle && !m_oXmlStyle.WriteRStyle(oStyle))) return L""; @@ -925,52 +1088,53 @@ std::wstring CHTML2OOXMLInterpretator::GetStyle(const NSCSS::CCompiledStyle& oSt return m_oXmlStyle.GetIdAndClear(); } -CTextSettings& CHTML2OOXMLInterpretator::GetTextSettings() +void COOXMLInterpretator::UpdatePageStyle(const std::vector& arSelectors) { - return m_oTextSettings; + if (nullptr != m_pStylesCalculator) + m_pStylesCalculator->CalculatePageStyle(m_oPageData, arSelectors); } -XmlString& CHTML2OOXMLInterpretator::GetStylesXml() +XmlString& COOXMLInterpretator::GetStylesXml() { return m_oStylesXml; } -XmlString& CHTML2OOXMLInterpretator::GetDocRelsXml() +XmlString& COOXMLInterpretator::GetDocRelsXml() { return m_oDocXmlRels; } -XmlString& CHTML2OOXMLInterpretator::GetNotesRelsXml() +XmlString& COOXMLInterpretator::GetNotesRelsXml() { return m_oNoteXmlRels; } -XmlString& CHTML2OOXMLInterpretator::GetDocumentXml() +XmlString& COOXMLInterpretator::GetDocumentXml() { return m_oDocXml; } -XmlString& CHTML2OOXMLInterpretator::GetNotesXml() +XmlString& COOXMLInterpretator::GetNotesXml() { return m_oNoteXml; } -XmlString& CHTML2OOXMLInterpretator::GetNumberingXml() +XmlString& COOXMLInterpretator::GetNumberingXml() { return m_oNumberXml; } -XmlString& CHTML2OOXMLInterpretator::GetWebSettingsXml() +XmlString& COOXMLInterpretator::GetWebSettingsXml() { return m_oWebSettings; } -XmlString& CHTML2OOXMLInterpretator::GetCurrentDocument() +XmlString& COOXMLInterpretator::GetCurrentDocument() { return *m_pCurrentDocument; } -void CHTML2OOXMLInterpretator::PrintData() +void COOXMLInterpretator::PrintData() { std::wcout << m_oDocXml.GetData() << std::endl; } diff --git a/HtmlFile2/HTML2OOXMLInterpretator.h b/HtmlFile2/Interpretators/OOXMLInterpretator.h similarity index 50% rename from HtmlFile2/HTML2OOXMLInterpretator.h rename to HtmlFile2/Interpretators/OOXMLInterpretator.h index 8563ae4a1d..f29dc8837f 100644 --- a/HtmlFile2/HTML2OOXMLInterpretator.h +++ b/HtmlFile2/Interpretators/OOXMLInterpretator.h @@ -1,18 +1,19 @@ -#ifndef HTML2OOXMLINTERPRETATOR_H -#define HTML2OOXMLINTERPRETATOR_H +#ifndef OOXMLINTERPRETATOR_H +#define OOXMLINTERPRETATOR_H // #include "HTMLInterpretator.h" #include "../DesktopEditor/common/StringBuilder.h" #include "../Common/3dParty/html/css/src/xhtml/CDocumentStyle.h" -#include "../TextSettings.h" +#include "../Common/3dParty/html/css/src/CCssCalculator.h" #include "HTMLInterpretator.h" namespace HTML { using XmlString = NSStringUtils::CStringBuilder; -class CHTML2OOXMLInterpretator : public IHTMLInterpretator +struct TImageData; +class COOXMLInterpretator : public IHTMLInterpretator { XmlString m_oStylesXml; // styles.xml XmlString m_oDocXmlRels; // document.xml.rels @@ -27,6 +28,8 @@ class CHTML2OOXMLInterpretator : public IHTMLInterpretator NSCSS::CDocumentStyle m_oXmlStyle; // Ooxml стиль NSCSS::NSProperties::CPage m_oPageData; // Стили страницы + NSCSS::CCssCalculator *m_pStylesCalculator; + struct TState { bool m_bInP; // открыт? @@ -47,8 +50,6 @@ class CHTML2OOXMLInterpretator : public IHTMLInterpretator {} } m_oState; - CTextSettings m_oTextSettings; - int m_nFootnoteId; // ID сноски int m_nHyperlinkId; // ID ссылки int m_nNumberingId; // ID списка @@ -61,7 +62,9 @@ class CHTML2OOXMLInterpretator : public IHTMLInterpretator anchors_map m_mAnchors; // Map якорей с индивидуальными id std::map m_mDivs; // Div элементы public: - CHTML2OOXMLInterpretator(); + COOXMLInterpretator(); + + void SetCSSCalculator(NSCSS::CCssCalculator* pCSSCalculator); void Begin(const std::wstring& wsDst, const THtmlParams* pParams) override; void End(const std::wstring& wsDst) override; @@ -70,27 +73,53 @@ public: bool OpenR(); bool OpenT(); - void CloseP(std::vector& sSelectors); + void CloseP(); void CloseR(); void CloseT(); - void BeginBlock(std::vector& arSelectors) override; - void EndBlock(bool bAddBlock, std::vector& arSelectors) override; + void BeginBlock() override; + void EndBlock(bool bAddBlock) override; - void OpenCrossHyperlink(const std::wstring& wsRef, std::vector& arSelectors); - void OpenExternalHyperlink(const std::wstring& wsRef, const std::wstring& wsTooltip, std::vector& arSelectors); + //Conversion methods + bool OpenAnchor(const std::vector& arSelectors) override; + void CloseAnchor(const std::vector& arSelectors) override; - void CloseCrossHyperlink(std::vector& arSelectors, std::wstring wsFootnote, const std::wstring& wsRef); - void CloseExternalHyperlink(); + void Break(const std::vector& arSelectors) override; - void OpenFldChar(const std::wstring& wsNote); - void CloseFldChar(); + bool OpenAbbreviation(const std::vector& arSelectors) override; + void CloseAbbreviation(const std::vector& arSelectors) override; + + bool OpenBold(const std::vector& arSelectors) override { return true; }; + void CloseBold(const std::vector& arSelectors) override {}; + + bool OpenBidirectional(const std::vector& arSelectors) override { return true; }; //TODO:: проверить необходимо ли для md + void CloseBidirectional(const std::vector& arSelectors) override {}; + + bool OpenItalic(const std::vector& arSelectors) override { return true; }; + void CloseItalic(const std::vector& arSelectors) override {}; + + bool OpenPreformatted(const std::vector& arSelectors) override { return true; }; //TODO:: проверить необходимо ли для md + void ClosePreformatted(const std::vector& arSelectors) override {}; + + bool OpenKBD(const std::vector& arSelectors) override { return true; }; //TODO:: проверить необходимо ли для md + void CloseKBD(const std::vector& arSelectors) override {}; + + bool OpenStrikethrough(const std::vector& arSelectors) override { return true; }; //TODO:: проверить необходимо ли для md + void CloseStrikethrough(const std::vector& arSelectors) override {}; + + bool OpenUnderline(const std::vector& arSelectors) override { return true; }; //TODO:: проверить необходимо ли для md + void CloseUnderline(const std::vector& arSelectors) override {}; + + bool OpenQuotation(const std::vector& arSelectors) override { return true; }; //TODO:: проверить необходимо ли для md + void CloseQuotation(const std::vector& arSelectors) override {} + + bool OpenHeader(const std::vector& arSelectors) override { return true; };; + void CloseHeader(const std::vector& arSelectors) override {}; std::wstring WritePPr(const std::vector& arSelectors); std::wstring WriteRPr(XmlString& oXml, const std::vector& arSelectors); bool WriteText(const std::wstring& wsText, const std::vector& arSelectors) override; - void WriteBr(std::vector& arSelectors); void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) override; void WriteSpace(); @@ -98,9 +127,13 @@ public: std::wstring WriteBookmark(const std::wstring& wsId); std::wstring AddAnchor(const std::wstring& wsAnchorValue); + void WriteImage(const std::vector& arSelectors); + void WriteAlternativeImage(const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData); + void WriteEmptyImage(int nWidth, int nHeight, const std::wstring& wsName = L"", const std::wstring& wsDescr = L""); + std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bParagraphStyle); - CTextSettings& GetTextSettings(); + void UpdatePageStyle(const std::vector& arSelectors); XmlString& GetStylesXml(); XmlString& GetDocRelsXml(); @@ -117,4 +150,4 @@ public: }; } -#endif // HTML2OOXMLINTERPRETATOR_H +#endif // OOXMLINTERPRETATOR_H diff --git a/HtmlFile2/Tags/HTMLTags.h b/HtmlFile2/Tags/HTMLTags.h deleted file mode 100644 index a65c2601fc..0000000000 --- a/HtmlFile2/Tags/HTMLTags.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef HTMLTAGS_H -#define HTMLTAGS_H - -#include "../Common/3dParty/html/css/src/CNode.h" - -namespace HTML -{ -struct ITag -{ - virtual ~ITag() = default; - virtual bool Open(std::vector& sSelectors) = 0; - virtual void Close(std::vector& sSelectors) = 0; -}; - -struct TEmptyTag : public ITag -{ - virtual ~TEmptyTag() = default; - virtual bool Open(std::vector& sSelectors) - { - return true; - }; - virtual void Close(std::vector& sSelectors) {}; -}; - -template -struct TTag : public ITag -{ - T* m_pInterpretator; - - TTag(T* pInterpretator) - : m_pInterpretator(pInterpretator) - {} - virtual ~TTag() = default; - virtual bool Open(std::vector& sSelectors) = 0; - virtual void Close(std::vector& sSelectors) = 0; - - bool ValidInterpretator() const - { - return nullptr != m_pInterpretator; - } -}; - -#define CREATE_TAG(tag_name)\ -template\ -struct tag_name : public TTag\ -{\ - virtual bool Open(std::vector& sSelectors) = 0;\ - virtual void Close(std::vector& sSelectors) = 0;\ -} - -CREATE_TAG(TAnchor); -CREATE_TAG(TAbbr); -CREATE_TAG(TBold); -CREATE_TAG(TBidirectional); -CREATE_TAG(TBr); -CREATE_TAG(TCenter); -CREATE_TAG(TItalic); -CREATE_TAG(TCode); -CREATE_TAG(TKbd); -CREATE_TAG(TStrike); -CREATE_TAG(TUnderline); -CREATE_TAG(TMark); -CREATE_TAG(TQuotation); -CREATE_TAG(TSup); -CREATE_TAG(TSub); -CREATE_TAG(TSpan); -CREATE_TAG(TDD); -CREATE_TAG(TPreformatted); -CREATE_TAG(THeader); - -} - -#endif // HTMLTAGS_H diff --git a/HtmlFile2/Tags/HTMLTags2OOXML.h b/HtmlFile2/Tags/HTMLTags2OOXML.h deleted file mode 100644 index 5c62d95d3e..0000000000 --- a/HtmlFile2/Tags/HTMLTags2OOXML.h +++ /dev/null @@ -1,291 +0,0 @@ -#ifndef HTMLTAGS2OOXML_H -#define HTMLTAGS2OOXML_H - -#include "HTMLTags.h" -#include "HTML2OOXMLInterpretator.h" - -namespace HTML -{ -inline bool GetTitle(const std::vector& arSelectors, std::wstring& wsTitle); - -template<> -struct TAnchor : public TTag -{ - TAnchor(CHTML2OOXMLInterpretator* pInterpretator) - : TTag(pInterpretator) - {} - - virtual bool Open(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return false; - - std::wstring wsRef, wsAlt, wsName; - bool bCross = false; - - if (arSelectors.back().GetAttributeValue(L"href", wsRef) && wsRef.find('#') != std::wstring::npos) - bCross = true; - - if (arSelectors.back().GetAttributeValue(L"name", wsName)) - m_pInterpretator->WriteBookmark(wsName); - - arSelectors.back().GetAttributeValue(L"alt", wsAlt); - - std::wstring wsTooltip(wsRef); - - GetTitle(arSelectors, wsTooltip); - - if (bCross) - m_pInterpretator->OpenCrossHyperlink(wsRef, arSelectors); - else - m_pInterpretator->OpenExternalHyperlink(wsRef, wsTooltip, arSelectors); - - return true; - } - - virtual void Close(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return; - - bool bCross = false; - std::wstring wsFootnote; - - // std::map& mAttributes(arSelectors.back().m_mAttributes); - // std::map::const_iterator itFound; - - if (arSelectors.back().m_wsStyle.find(L"mso-footnote-id") != std::wstring::npos) - wsFootnote = arSelectors.back().m_wsStyle.substr(arSelectors.back().m_wsStyle.rfind(L':') + 1); - else - { - if (arSelectors.back().GetAttributeValue(L"epub:type", wsFootnote) && wsFootnote.find(L"noteref")) - wsFootnote = L"href"; - } - - std::wstring wsRef; - - if (arSelectors.back().GetAttributeValue(L"href", wsRef)) - { - if(wsRef.find('#') != std::wstring::npos) - bCross = true; - } - - if (bCross) - { - if (wsFootnote == L"href") - wsFootnote = wsRef.substr(wsRef.find('#') + 1); - - m_pInterpretator->CloseCrossHyperlink(arSelectors, wsFootnote, wsRef); - } - else - m_pInterpretator->CloseExternalHyperlink(); - } -}; - -template<> -struct TAbbr : public TTag -{ - TAbbr(CHTML2OOXMLInterpretator* pInterpretator) - : TTag(pInterpretator) - {} - - virtual bool Open(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return false; - - std::wstring wsTitle; - - if (!GetTitle(arSelectors, wsTitle)) - return false; - - m_pInterpretator->WritePPr(arSelectors); - m_pInterpretator->OpenFldChar(wsTitle); - - return true; - } - - virtual void Close(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return; - - m_pInterpretator->CloseFldChar(); - } -}; - -template<> -struct TBr : public TTag -{ - TBr(CHTML2OOXMLInterpretator* pInterpretator) - : TTag(pInterpretator) - {} - - virtual bool Open(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return false; - - m_pInterpretator->WriteBr(arSelectors); - - return true; - } - - virtual void Close(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return; - } -}; - -template<> -struct TBidirectional : public TTag -{ - TBidirectional(CHTML2OOXMLInterpretator* pInterpretator) - : TTag(pInterpretator) - {} - - virtual bool Open(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return false; - - if (L"bdo" == arSelectors.back().m_wsName) - { - std::wstring wsDir; - - arSelectors.back().GetAttributeValue(L"dir", wsDir); - - m_pInterpretator->GetTextSettings().SetNewBidirectional(wsDir == L"rtl"); - } - else - //TODO:: по идее можно оптимизировать при условии, что и так false - //Но основная проблема в RollBackBdo - m_pInterpretator->GetTextSettings().SetNewBidirectional(false); - - return true; - } - - virtual void Close(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return; - - m_pInterpretator->GetTextSettings().RollBackBidirectional(); - } -}; - -template<> -struct TQuotation : public TTag -{ - TQuotation(CHTML2OOXMLInterpretator* pInterpretator) - : TTag(pInterpretator) - {} - - virtual bool Open(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return false; - - m_pInterpretator->GetTextSettings().SetNewQuotation(true); - - return true; - } - - virtual void Close(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return; - - m_pInterpretator->GetTextSettings().RollBackQuotation(); - } -}; - -template<> -struct TSpan : public TTag -{ - TSpan(CHTML2OOXMLInterpretator* pInterpretator) - : TTag(pInterpretator) - {} - - virtual bool Open(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return false; - - m_pInterpretator->GetTextSettings().SetNewAddSpaces(false); - - return true; - } - - virtual void Close(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return; - - m_pInterpretator->GetTextSettings().RollBackAddSpaces(); - } -}; - -template<> -struct TPreformatted : public TTag -{ - TPreformatted (CHTML2OOXMLInterpretator* pInterpretator) - : TTag(pInterpretator) - {} - - virtual bool Open(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return false; - - m_pInterpretator->GetTextSettings().SetNewPreformatted(false); - - return true; - } - - virtual void Close(std::vector& arSelectors) - { - if (!ValidInterpretator()) - return; - - m_pInterpretator->GetTextSettings().RollBackPreformatted(); - } -}; - -#define CREATE_EMPTY_TAG(tag_name)\ -template<>\ -struct tag_name : public TEmptyTag\ -{\ - tag_name(){}\ -} - -CREATE_EMPTY_TAG(TBold); -CREATE_EMPTY_TAG(TCenter); -CREATE_EMPTY_TAG(TItalic); -CREATE_EMPTY_TAG(TCode); -CREATE_EMPTY_TAG(TKbd); -CREATE_EMPTY_TAG(TStrike); -CREATE_EMPTY_TAG(TUnderline); -CREATE_EMPTY_TAG(TMark); -CREATE_EMPTY_TAG(TSup); -CREATE_EMPTY_TAG(TSub); -CREATE_EMPTY_TAG(TDD); -CREATE_EMPTY_TAG(THeader); - -inline bool GetTitle(const std::vector& arSelectors, std::wstring& wsTitle) -{ - if (arSelectors.empty()) - return false; - - const std::map::const_iterator itFound{arSelectors.back().m_mAttributes.find(L"title")}; - - if (arSelectors.back().m_mAttributes.cend() == itFound) - return false; - - wsTitle= itFound->second; - return true; -} -} - -#endif // HTMLTAGS2OOXML_H diff --git a/HtmlFile2/TextSettings.h b/HtmlFile2/TextSettings.h deleted file mode 100644 index 3a368f35d1..0000000000 --- a/HtmlFile2/TextSettings.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef TEXTSETTINGS_H -#define TEXTSETTINGS_H - -#include "../Common/3dParty/html/css/src/CCompiledStyle.h" -#include - -namespace HTML -{ -// Настройки текста -class CTextSettings -{ - std::stack m_arBidirectional;// Реверс текста - std::stack m_arPreformatted; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк) - std::stack m_arQuotation; // Цитата - std::stack m_arAddSpaces; // Добавлять пробелы перед текстом? - std::stack m_arMergeText; // Объединять подряд идущий текст в 1? - - std::wstring m_sPStyle; - - NSCSS::CCompiledStyle m_oAdditionalStyle; - -public: - CTextSettings() - { - SetNewBidirectional(false); - SetNewPreformatted(false); - SetNewQuotation(false); - SetNewAddSpaces(true); - } - - #define CREATE_METHODS_FROM_ELEMENT(element_name)\ - void SetNew##element_name(bool bValue)\ - {\ - m_ar##element_name.push(bValue);\ - }\ - \ - void RollBack##element_name()\ - {\ - if (m_ar##element_name.size() > 1)\ - m_ar##element_name.pop();\ - }\ - \ - bool Get##element_name() const\ - {\ - return m_ar##element_name.top();\ - } - - CREATE_METHODS_FROM_ELEMENT(Bidirectional) - CREATE_METHODS_FROM_ELEMENT(Preformatted) - CREATE_METHODS_FROM_ELEMENT(Quotation) - CREATE_METHODS_FROM_ELEMENT(AddSpaces) -}; -} - -#endif // TEXTSETTINGS_H