diff --git a/HtmlFile2/HTMLReader.cpp b/HtmlFile2/HTMLReader.cpp index 6761231a2b..53d09c9dd4 100644 --- a/HtmlFile2/HTMLReader.cpp +++ b/HtmlFile2/HTMLReader.cpp @@ -264,7 +264,7 @@ inline bool TagIsUnprocessed(const std::wstring& wsTagName); inline void GetSubClass(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, NSCSS::CCssCalculator& oCSSCalculator); CHTMLReader::CHTMLReader() - : m_bIsTempDirOwner(true), m_pWriter(nullptr) + : m_bIsTempDirOwner(true), m_pWriter(nullptr), m_pTableElement(nullptr) {} CHTMLReader::~CHTMLReader() @@ -274,6 +274,9 @@ CHTMLReader::~CHTMLReader() if (m_bIsTempDirOwner && !m_wsTempDirectory.empty()) NSDirectory::DeleteDirectory(m_wsTempDirectory); + + if (nullptr != m_pTableElement) + delete m_pTableElement; } void CHTMLReader::SetTempDirectory(const std::wstring& wsPath) @@ -338,6 +341,9 @@ void CHTMLReader::Clear() m_wsDstDirectory .clear(); m_wsBaseDirectory.clear(); m_wsCoreDirectory.clear(); + + if (nullptr != m_pTableElement) + delete m_pTableElement; } bool CHTMLReader::InitOOXMLTags(THTMLParameters* pParametrs) @@ -366,6 +372,20 @@ bool CHTMLReader::InitOOXMLTags(THTMLParameters* pParametrs) return false; } + TExternalTableData oExternalData; + + oExternalData.ReadStream = [this](XmlUtils::CXmlLiteReader& oReader, + std::vector& arSelectors) + { return ReadStream(oReader, arSelectors, true); }; + + oExternalData.GetSubClass = [this](XmlUtils::CXmlLiteReader& oReader, + std::vector& arSelectors) + { GetSubClass(oReader, arSelectors, m_oCSSCalculator); }; + + oExternalData.m_pWriter = pWriter; + + m_pTableElement = new COOXMLTable(oExternalData); + m_pWriter = pWriter; return true; @@ -394,6 +414,20 @@ bool CHTMLReader::InitMDTags(TMarkdownParameters* pParametrs) return false; } + TExternalTableData oExternalData; + + oExternalData.ReadStream = [this](XmlUtils::CXmlLiteReader& oReader, + std::vector& arSelectors) + { return ReadStream(oReader, arSelectors, true); }; + + oExternalData.GetSubClass = [this](XmlUtils::CXmlLiteReader& oReader, + std::vector& arSelectors) + { GetSubClass(oReader, arSelectors, m_oCSSCalculator); }; + + oExternalData.m_pWriter = pWriter; + + m_pTableElement = new CMarkdownTable(oExternalData); + m_pWriter = pWriter; return true; @@ -679,34 +713,11 @@ bool CHTMLReader::ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vectorOpen()) - { - bResult = ReadStream(oReader, arSelectors); - m_oTags.m_pBold->Close(); - } - break; - } case HTML_TAG(BR): { bResult = m_oTags.m_pBreak->Read(arSelectors.back()); break; } - case HTML_TAG(CITE): - case HTML_TAG(DFN): - case HTML_TAG(EM): - case HTML_TAG(I): - case HTML_TAG(VAR): - { - if (m_oTags.m_pItalic->Open()) - { - bResult = ReadStream(oReader, arSelectors); - m_oTags.m_pItalic->Close(); - } - break; - } case HTML_TAG(CODE): case HTML_TAG(SAMP): case HTML_TAG(TT): @@ -720,17 +731,6 @@ bool CHTMLReader::ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vectorOpen()) - { - bResult = ReadStream(oReader, arSelectors); - m_oTags.m_pStrike->Close(); - } - break; - } case HTML_TAG(FONT): { m_oTags.m_pFont->Apply(arSelectors.back(), arSelectors.size()); @@ -747,16 +747,6 @@ bool CHTMLReader::ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vectorReadSVG(arSelectors, oReader.GetOuterXml()); break; } - case HTML_TAG(INS): - case HTML_TAG(U): - { - if (m_oTags.m_pUnderline->Open()) - { - bResult = ReadStream(oReader, arSelectors); - m_oTags.m_pUnderline->Close(); - } - break; - } case HTML_TAG(INPUT): { m_oTags.m_pInput->Read(arSelectors); @@ -799,11 +789,26 @@ bool CHTMLReader::ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vectorOpen()) - { - bResult = ReadStream(oReader, arSelectors); - m_oTags.m_pItalic->Close(); - } - break; - } case HTML_TAG(H1): case HTML_TAG(H2): case HTML_TAG(H3): @@ -845,8 +841,11 @@ bool CHTMLReader::ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vectorRead(arSelectors.back()); - bResult = ReadStream(oReader, arSelectors); + if (m_oTags.m_pHeader->Open(arSelectors.back())) + { + bResult = ReadStream(oReader, arSelectors); + m_oTags.m_pHeader->Close(); + } break; } case HTML_TAG(ASIDE): @@ -917,6 +916,7 @@ bool CHTMLReader::ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors) { - if(oReader.IsEmptyNode()) + if(oReader.IsEmptyNode() || nullptr == m_pTableElement) return false; + m_pTableElement->Clear(); + XmlUtils::CXmlLiteReader oTableReader; if (!oTableReader.FromString(oReader.GetOuterXml()) || !oTableReader.ReadNextNode()) return false; - // TODO:: Возможно стоит сделать не CTableElement, а CTableConverter - // и перенести объявление в Init метод, чтобы не запрашивать тип райтера - // А после конвертация таблицы его очищать - CTableElement* pTableElement{nullptr}; - TExternalTableData oExternalData; - - oExternalData.ReadStream = [this](XmlUtils::CXmlLiteReader& oReader, - std::vector& arSelectors) - { return ReadStream(oReader, arSelectors, true); }; - - oExternalData.GetSubClass = [this](XmlUtils::CXmlLiteReader& oReader, - std::vector& arSelectors) - { GetSubClass(oReader, arSelectors, m_oCSSCalculator); }; - - oExternalData.m_pWriter = m_pWriter; - - switch (m_pWriter->GetType()) - { - case EWriterType::Markdown: pTableElement = new CMarkdownTable(&oExternalData); break; - case EWriterType::OOXML: pTableElement = new COOXMLTable(&oExternalData); break; - default: - return false; - } - - if (nullptr == pTableElement) - return false; - - if (!pTableElement->PreParse(oTableReader) || + if (!m_pTableElement->PreParse(oTableReader) || !oTableReader.MoveToStart() || !oTableReader.ReadNextNode()) - { - delete pTableElement; return false; - } - pTableElement->Normalize(); - pTableElement->Convert(oTableReader, arSelectors.back()); + m_pTableElement->Normalize(); + m_pTableElement->Convert(oTableReader, arSelectors.back()); - delete pTableElement; + m_pTableElement->Clear(); return true; } diff --git a/HtmlFile2/HTMLReader.h b/HtmlFile2/HTMLReader.h index f108e35b44..bb19abc1b2 100644 --- a/HtmlFile2/HTMLReader.h +++ b/HtmlFile2/HTMLReader.h @@ -30,6 +30,8 @@ class CHTMLReader IWriter *m_pWriter; + CTableElement* m_pTableElement; // Table Converter + THTMLTags m_oTags; public: CHTMLReader(); diff --git a/HtmlFile2/Table.cpp b/HtmlFile2/Table.cpp index c801f80968..f2506a7f17 100644 --- a/HtmlFile2/Table.cpp +++ b/HtmlFile2/Table.cpp @@ -152,6 +152,11 @@ bool CTableMatrix::Empty() const return m_arCells.empty(); } +void CTableMatrix::Clear() +{ + m_arCells.clear(); +} + bool CTableMatrix::SetCell(size_t unRowIndex, size_t unColumnIndex, ITableElementCell* pCell) { if (nullptr == pCell) @@ -240,16 +245,16 @@ const ITableElementCell* CTableMatrix::GetCell(size_t unRowIndex, size_t unColum return m_arCells[unRowIndex][unColumnIndex]; } -bool TExternalTableData::IsValid() const -{ - return true; -} - -CTableElement::CTableElement(TExternalTableData *pExternalData) - : m_pCaption(nullptr), m_pExternalData(pExternalData) +CTableElement::CTableElement(TExternalTableData &oExternalData) + : m_pCaption(nullptr), m_oExternalData(oExternalData) {} CTableElement::~CTableElement() +{ + Clear(); +} + +void CTableElement::Clear() { if (nullptr != m_pCaption) delete m_pCaption; @@ -257,6 +262,10 @@ CTableElement::~CTableElement() for (CTableColgroup* pColgroup : m_arColgroups) if (nullptr != pColgroup) delete pColgroup; + + m_oHeader.Clear(); + m_oBody.Clear(); + m_oFoother.Clear(); } ETableElement CTableElement::GetType() const diff --git a/HtmlFile2/Table.h b/HtmlFile2/Table.h index e2c7023b58..1fcf51e183 100644 --- a/HtmlFile2/Table.h +++ b/HtmlFile2/Table.h @@ -65,8 +65,6 @@ struct TExternalTableData FuncGetSubClass GetSubClass; IWriter* m_pWriter{nullptr}; - - bool IsValid() const; }; typedef std::vector Row; @@ -82,6 +80,8 @@ public: bool Empty() const; + void Clear(); + bool SetCell(size_t unRowIndex, size_t unColumnIndex, ITableElementCell* pCell); bool IsFillingCell(size_t unRowIndex, size_t unColumnIndex) const; @@ -132,10 +132,12 @@ private: class CTableElement : public ITableElementCell { protected: - CTableElement(TExternalTableData *pExternalData); + CTableElement(TExternalTableData &oExternalData); public: virtual ~CTableElement(); + void Clear(); + ETableElement GetType() const override; bool Empty() const; @@ -153,7 +155,7 @@ protected: std::vector m_arColgroups; - TExternalTableData *m_pExternalData; + TExternalTableData m_oExternalData; const NSCSS::CCompiledStyle* GetColStyle(size_t unColIndex) const; @@ -199,7 +201,7 @@ inline bool CTableElement::ParseMatrix(XmlUtils::CXmlLiteReader& oReader, CTable if (L"table" == wsElementName) { - T* pNewTable{new T(m_pExternalData)}; + T* pNewTable{new T(m_oExternalData)}; if (nullptr == pNewTable) return false; diff --git a/HtmlFile2/Tags/HTMLTags.h b/HtmlFile2/Tags/HTMLTags.h index 349cec5dd8..49d9458144 100644 --- a/HtmlFile2/Tags/HTMLTags.h +++ b/HtmlFile2/Tags/HTMLTags.h @@ -29,37 +29,18 @@ OPEN_INTERFACE_TAG(Abbr) ADD_VOID_INTERFACE_METHOD(Close); CLOSE_INTERFACE_TAG() -OPEN_INTERFACE_TAG(Bold) - ADD_BOOL_INTERFACE_METHOD(Open); - ADD_VOID_INTERFACE_METHOD(Close); -CLOSE_INTERFACE_TAG() - OPEN_INTERFACE_TAG(Break) ADD_BOOL_INTERFACE_METHOD(Read, const NSCSS::CNode& oTagNode); CLOSE_INTERFACE_TAG() -OPEN_INTERFACE_TAG(Italic) - ADD_BOOL_INTERFACE_METHOD(Open); - ADD_VOID_INTERFACE_METHOD(Close); -CLOSE_INTERFACE_TAG() - -OPEN_INTERFACE_TAG(Strike) - ADD_BOOL_INTERFACE_METHOD(Open); - ADD_VOID_INTERFACE_METHOD(Close); -CLOSE_INTERFACE_TAG() - OPEN_INTERFACE_TAG(Preformatted) ADD_BOOL_INTERFACE_METHOD(Open); ADD_VOID_INTERFACE_METHOD(Close, const std::vector& arSelectors); CLOSE_INTERFACE_TAG() -OPEN_INTERFACE_TAG(Underline) - ADD_BOOL_INTERFACE_METHOD(Open); - ADD_VOID_INTERFACE_METHOD(Close); -CLOSE_INTERFACE_TAG() - OPEN_INTERFACE_TAG(Header) - ADD_BOOL_INTERFACE_METHOD(Read, const NSCSS::CNode& oTagNode); + ADD_BOOL_INTERFACE_METHOD(Open, const NSCSS::CNode& oTagNode); + ADD_VOID_INTERFACE_METHOD(Close); CLOSE_INTERFACE_TAG() OPEN_INTERFACE_TAG(Division) @@ -154,37 +135,18 @@ OPEN_CLASS_TAG(Abbr) ADD_VOID_CLASS_METHOD(Close); CLOSE_CLASS_TAG() -OPEN_CLASS_TAG(Bold) - ADD_BOOL_CLASS_METHOD(Open); - ADD_VOID_CLASS_METHOD(Close); -CLOSE_CLASS_TAG() - OPEN_CLASS_TAG(Break) ADD_BOOL_CLASS_METHOD(Read, const NSCSS::CNode& oTagNode); CLOSE_CLASS_TAG() -OPEN_CLASS_TAG(Italic) - ADD_BOOL_CLASS_METHOD(Open); - ADD_VOID_CLASS_METHOD(Close); -CLOSE_CLASS_TAG() - -OPEN_CLASS_TAG(Strike) - ADD_BOOL_CLASS_METHOD(Open); - ADD_VOID_CLASS_METHOD(Close); -CLOSE_CLASS_TAG() - OPEN_CLASS_TAG(Preformatted) ADD_BOOL_CLASS_METHOD(Open); ADD_VOID_CLASS_METHOD(Close, const std::vector& arSelectors); CLOSE_CLASS_TAG() -OPEN_CLASS_TAG(Underline) - ADD_BOOL_CLASS_METHOD(Open); - ADD_VOID_CLASS_METHOD(Close); -CLOSE_CLASS_TAG() - OPEN_CLASS_TAG(Header) - ADD_BOOL_CLASS_METHOD(Read, const NSCSS::CNode& oTagNode); + ADD_BOOL_CLASS_METHOD(Open, const NSCSS::CNode& oTagNode); + ADD_VOID_CLASS_METHOD(Close); CLOSE_CLASS_TAG() OPEN_CLASS_TAG(Division) @@ -237,30 +199,26 @@ OPEN_CLASS_TAG(HTML) ADD_BOOL_CLASS_METHOD(Apply, const NSCSS::CNode& oTagNode); CLOSE_CLASS_TAG() -#define ADD_TAG(class_name) INTERFACE_TAGS::I ## class_name ## Tag *m_p##class_name{nullptr} +#define ADD_HTML_TAG(class_name) INTERFACE_TAGS::I ## class_name ## Tag *m_p##class_name{nullptr} struct THTMLTags { - ADD_TAG(Anchor); - ADD_TAG(Abbr); - ADD_TAG(Bold); - ADD_TAG(Break); - ADD_TAG(Italic); - ADD_TAG(Strike); - ADD_TAG(Preformatted); - ADD_TAG(Underline); - ADD_TAG(Header); - ADD_TAG(Division); - ADD_TAG(Image); - ADD_TAG(Font); - ADD_TAG(Input); - ADD_TAG(BaseFont); - ADD_TAG(Blockquote); - ADD_TAG(List); - ADD_TAG(HorizontalRule); - ADD_TAG(ListElement); - ADD_TAG(Code); - ADD_TAG(HTML); + ADD_HTML_TAG(Anchor); + ADD_HTML_TAG(Abbr); + ADD_HTML_TAG(Break); + ADD_HTML_TAG(Preformatted); + ADD_HTML_TAG(Header); + ADD_HTML_TAG(Division); + ADD_HTML_TAG(Image); + ADD_HTML_TAG(Font); + ADD_HTML_TAG(Input); + ADD_HTML_TAG(BaseFont); + ADD_HTML_TAG(Blockquote); + ADD_HTML_TAG(List); + ADD_HTML_TAG(HorizontalRule); + ADD_HTML_TAG(ListElement); + ADD_HTML_TAG(Code); + ADD_HTML_TAG(HTML); ~THTMLTags() { @@ -275,12 +233,8 @@ struct THTMLTags CLEAR_VARIABLE(Anchor); CLEAR_VARIABLE(Abbr); - CLEAR_VARIABLE(Bold); CLEAR_VARIABLE(Break); - CLEAR_VARIABLE(Italic); - CLEAR_VARIABLE(Strike); CLEAR_VARIABLE(Preformatted); - CLEAR_VARIABLE(Underline); CLEAR_VARIABLE(Header); CLEAR_VARIABLE(Division); CLEAR_VARIABLE(Image); @@ -307,12 +261,8 @@ struct THTMLTags INIT_VARIABLE(Anchor); INIT_VARIABLE(Abbr); - INIT_VARIABLE(Bold); INIT_VARIABLE(Break); - INIT_VARIABLE(Italic); - INIT_VARIABLE(Strike); INIT_VARIABLE(Preformatted); - INIT_VARIABLE(Underline); INIT_VARIABLE(Header); INIT_VARIABLE(Division); INIT_VARIABLE(Image); diff --git a/HtmlFile2/Tags/MDTags.cpp b/HtmlFile2/Tags/MDTags.cpp index ac8a2d666f..e0dc3c691b 100644 --- a/HtmlFile2/Tags/MDTags.cpp +++ b/HtmlFile2/Tags/MDTags.cpp @@ -50,31 +50,6 @@ void CAnchorTag::Close(const NSCSS::CNode& oTagNode) m_pWriter->WriteString(L")"); } -template<> -bool CBoldTag::Open() -{ - if (!Valid()) - return false; - - if (m_pWriter->IsBold()) - return true; - - m_pWriter->WriteOpenSpecialString(L"**"); - m_pWriter->EnteredBold(); - - return true; -} - -template<> -void CBoldTag::Close() -{ - if (!Valid() || !m_pWriter->IsBold()) - return; - - m_pWriter->WriteCloseSpecialString(L"**"); - m_pWriter->OutBold(); -} - template<> bool CBreakTag::Read(const NSCSS::CNode& oTagNode) { @@ -86,56 +61,6 @@ bool CBreakTag::Read(const NSCSS::CNode& oTagNode) return true; } -template<> -bool CItalicTag::Open() -{ - if (!Valid()) - return false; - - if (m_pWriter->IsItalic()) - return true; - - m_pWriter->WriteOpenSpecialString(L"*"); - m_pWriter->EnteredItalic(); - - return true; -} - -template<> -void CItalicTag::Close() -{ - if (!Valid()) - return; - - m_pWriter->WriteCloseSpecialString(L"*"); - m_pWriter->OutItalic(); -} - -template<> -bool CStrikeTag::Open() -{ - if (!Valid()) - return false; - - if (m_pWriter->IsStrike()) - return true; - - m_pWriter->WriteOpenSpecialString(L"~~"); - m_pWriter->EnteredStrike(); - - return true; -} - -template<> -void CStrikeTag::Close() -{ - if (!Valid()) - return; - - m_pWriter->WriteCloseSpecialString(L"~~"); - m_pWriter->OutStrike(); -} - template<> bool CPreformattedTag::Open() { @@ -176,7 +101,7 @@ void CPreformattedTag::Close(const std::vector& arSelec } template<> -bool CHeaderTag::Read(const NSCSS::CNode& oTagNode) +bool CHeaderTag::Open(const NSCSS::CNode& oTagNode) { if (!Valid()) return false; @@ -193,10 +118,16 @@ bool CHeaderTag::Read(const NSCSS::CNode& oTagNode) return false; } - return true; } +template<> +void CHeaderTag::Close() +{ + if (Valid()) + m_pWriter->WriteBreakLine(); +} + bool ConvertBufferToBase64(BYTE* pBuffer, size_t unSize, std::wstring& wsBase64) { if (nullptr == pBuffer || 0 == unSize) @@ -360,19 +291,21 @@ bool IsMetafileExtention(const std::wstring& wsExtention) bool ConvertFromBase64(const std::wstring& wsBase64, UINT unWidth, UINT unHeight, NSFonts::IApplicationFonts* pFonts, const std::wstring& wsTempDir, std::wstring& wsResultBase64) { - bool bResult{false}; - size_t nBase{wsBase64.find(L"/", 4)}; - nBase++; + const size_t unStartExtention{wsBase64.find(L"/", 4)}; + if (unStartExtention == std::wstring::npos) + return false; - const size_t nEndBase{wsBase64.find(L";", nBase)}; - if (nEndBase == std::wstring::npos) - return bResult; + const size_t unEndExtention{wsBase64.find(L";", unStartExtention)}; + if (unEndExtention == std::wstring::npos) + return false; - nBase = wsBase64.find(L"base64", nEndBase); + const size_t nBase = wsBase64.find(L"base64", unEndExtention); if (nBase == std::wstring::npos) - return bResult; + return false; - const int nOffset = nBase + 7; + bool bResult{false}; + + const int nOffset = nBase + 7; //Skip "base64," int nSrcLen = (int)(wsBase64.length() - nBase + 1); int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); @@ -383,9 +316,12 @@ bool ConvertFromBase64(const std::wstring& wsBase64, UINT unWidth, UINT unHeight if (!pImageData || FALSE == NSBase64::Base64Decode(wsBase64.c_str() + nOffset, nSrcLen, pImageData, &nDecodeLen)) return false; - if (IsSVGExtention(wsBase64.substr(nBase, nEndBase - nBase))) + if (IsSVGExtention(wsBase64.substr(unStartExtention + 1, unEndExtention - unStartExtention - 1))) { const std::wstring wsSvg(pImageData, pImageData + nDecodeLen); + + RELEASEARRAYOBJECTS(pImageData); + bResult = ConvertFromSVG(wsSvg, unWidth, unHeight, pFonts, wsTempDir, wsResultBase64); } else @@ -393,20 +329,17 @@ bool ConvertFromBase64(const std::wstring& wsBase64, UINT unWidth, UINT unHeight CBgraFrame oFrame; oFrame.Decode(pImageData, nDecodeLen); - if (oFrame.get_Width() != unWidth || oFrame.get_Height() != unHeight) - { - oFrame.Resize(unWidth, unHeight); + RELEASEARRAYOBJECTS(pImageData); - BYTE *pBuffer{nullptr}; - int nEncodeSize{0}; + oFrame.Resize(unWidth, unHeight); - oFrame.Encode(pBuffer, nEncodeSize, 4); + BYTE *pBuffer{nullptr}; + int nEncodeSize{0}; - bResult = ConvertBufferToBase64(pBuffer, nEncodeSize, wsResultBase64); - } + oFrame.Encode(pBuffer, nEncodeSize, 4); + + bResult = ConvertBufferToBase64(pBuffer, nEncodeSize, wsResultBase64); } - - RELEASEARRAYOBJECTS(pImageData); } return bResult; @@ -709,8 +642,8 @@ bool IsTable(const ITableElementCell* pCell) return nullptr != pCell && ETableElement::Table == pCell->GetType(); } -CMarkdownTable::CMarkdownTable(TExternalTableData* pExternalData) - : CTableElement(pExternalData) +CMarkdownTable::CMarkdownTable(TExternalTableData &oExternalData) + : CTableElement(oExternalData) {} CMarkdownTable::~CMarkdownTable() @@ -810,10 +743,10 @@ void ReadNestedCells(XmlUtils::CXmlLiteReader& oReader, std::vector(m_pExternalData->m_pWriter)}; + CMDWriter *pWriter{dynamic_cast(m_oExternalData.m_pWriter)}; if (nullptr == pWriter) return false; @@ -821,7 +754,9 @@ bool CMarkdownTable::Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNo std::vector arTableSelectors{oTableNode}; pWriter->WriteBreakLine(); - WriteToStringBuilder(*m_pCaption, *pWriter->GetCurrentDocument()); + + if (HaveCaption()) + WriteToStringBuilder(*m_pCaption, *pWriter->GetCurrentDocument()); //Open table pWriter->WriteBreakLine(); @@ -868,28 +803,28 @@ bool CMarkdownTable::Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNo //Close table pWriter->OutTable(); - pWriter->WriteBreakLine(); + pWriter->WriteBreakLine(false); return true; } bool CMarkdownTable::ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption) { - if (nullptr == m_pExternalData || nullptr == m_pExternalData->m_pWriter) + if (nullptr == m_oExternalData.m_pWriter) return false; if (nullptr == pCaption) pCaption = new XmlString(50); std::vector arSelectors; - m_pExternalData->GetSubClass(oReader, arSelectors); + m_oExternalData.GetSubClass(oReader, arSelectors); arSelectors.back().m_pCompiledStyle->m_oText.SetAlign(L"center", 0, true); - CMDWriter& oWriter{*(CMDWriter*)m_pExternalData->m_pWriter}; + CMDWriter& oWriter{*(CMDWriter*)m_oExternalData.m_pWriter}; oWriter.SetDataOutput(m_pCaption); - m_pExternalData->ReadStream(oReader, arSelectors); + m_oExternalData.ReadStream(oReader, arSelectors); oWriter.WriteBreakLine(); oWriter.RevertDataOutput(); @@ -925,26 +860,26 @@ bool CMarkdownTable::ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, std::vecto { if (nullptr != arNestedCells.front().second) { - m_pExternalData->m_pWriter->GetCurrentDocument()->Write(*arNestedCells.front().second); + m_oExternalData.m_pWriter->GetCurrentDocument()->Write(*arNestedCells.front().second); delete arNestedCells.front().second; } arNestedCells.pop(); } else { - MoveToNextTableCell(oReader, arSelectors, arDepths, m_pExternalData->GetSubClass); + MoveToNextTableCell(oReader, arSelectors, arDepths, m_oExternalData.GetSubClass); if (ETableElement::FlatTable == pTableCell->GetType()) { TCurentTablePosition oPosition{unRowIndex, unColumnIndex, unRowIndex, unColumnIndex}; std::vector arNestedSelectors; - ReadNestedCells(oReader, arNestedSelectors, oPosition, arNestedCells, oMatrix, pWriter, *m_pExternalData); + ReadNestedCells(oReader, arNestedSelectors, oPosition, arNestedCells, oMatrix, pWriter, m_oExternalData); --unColumnIndex; } else { - m_pExternalData->ReadStream(oReader, arSelectors); + m_oExternalData.ReadStream(oReader, arSelectors); if (oMatrix[unRowIndex].size() - 1 != unColumnIndex) WriteCellSeparator(*pWriter); } diff --git a/HtmlFile2/Tags/MDTags.h b/HtmlFile2/Tags/MDTags.h index 1361899188..0914db3072 100644 --- a/HtmlFile2/Tags/MDTags.h +++ b/HtmlFile2/Tags/MDTags.h @@ -12,31 +12,18 @@ bool CAnchorTag::Open(const std::vector& arSelectors); template<> void CAnchorTag::Close(const NSCSS::CNode& oTagNode); -template<> -bool CBoldTag::Open(); -template<> -void CBoldTag::Close(); - template<> bool CBreakTag::Read(const NSCSS::CNode& oTagNode); -template<> -bool CItalicTag::Open(); -template<> -void CItalicTag::Close(); - -template<> -bool CStrikeTag::Open(); -template<> -void CStrikeTag::Close(); - template<> bool CPreformattedTag::Open(); template<> void CPreformattedTag::Close(const std::vector& arSelectors); template<> -bool CHeaderTag::Read(const NSCSS::CNode& oTagNode); +bool CHeaderTag::Open(const NSCSS::CNode& oTagNode); +template<> +void CHeaderTag::Close(); template<> bool CImageTag::Read(const std::vector& arSelectors); @@ -75,7 +62,7 @@ struct TElementInfo class CMarkdownTable : public CTableElement { public: - CMarkdownTable(TExternalTableData* pExternalData); + CMarkdownTable(TExternalTableData &oExternalData); virtual ~CMarkdownTable(); bool PreParse(XmlUtils::CXmlLiteReader& oReader) override; diff --git a/HtmlFile2/Tags/OOXMLTags.cpp b/HtmlFile2/Tags/OOXMLTags.cpp index 329b02a26d..e0f2bf4c1f 100644 --- a/HtmlFile2/Tags/OOXMLTags.cpp +++ b/HtmlFile2/Tags/OOXMLTags.cpp @@ -1172,8 +1172,8 @@ bool CHTMLTag::Apply(const NSCSS::CNode& oTagNode) return true; } -COOXMLTable::COOXMLTable(TExternalTableData* pExternalData) - : CTableElement(pExternalData) +COOXMLTable::COOXMLTable(TExternalTableData& oExternalData) + : CTableElement(oExternalData) {} COOXMLTable::~COOXMLTable() @@ -1569,7 +1569,7 @@ void COOXMLTable::ConvertTable(XmlUtils::CXmlLiteReader& oReader, COOXMLWriter& while(oReader.ReadNextSiblingNode2(arDepths.top())) { const std::wstring sName = oReader.GetName(); - m_pExternalData->GetSubClass(oReader, arTableSelectors); + m_oExternalData.GetSubClass(oReader, arTableSelectors); if(sName == L"thead") CONVERT_MATRIX(Header) @@ -1606,7 +1606,7 @@ void COOXMLTable::ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, COOXMLWriter& if (nullptr != pTableCell) { - MoveToNextTableCell(oReader, arSelectors, arDepths, m_pExternalData->GetSubClass); + MoveToNextTableCell(oReader, arSelectors, arDepths, m_oExternalData.GetSubClass); if (ETableElement::Table == pTableCell->GetType()) { @@ -1620,7 +1620,7 @@ void COOXMLTable::ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, COOXMLWriter& else { arDepths.push(oReader.GetDepth()); - MoveToNextTableCell(oReader, arSelectors, arDepths, m_pExternalData->GetSubClass); + MoveToNextTableCell(oReader, arSelectors, arDepths, m_oExternalData.GetSubClass); ConvertTable(oReader, oWriter, *pTable, arSelectors.back()); } } @@ -1633,7 +1633,7 @@ void COOXMLTable::ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, COOXMLWriter& unMaxCellHeight = (std::max)(unMaxCellHeight, unCellHeight); - m_pExternalData->ReadStream(oReader, arSelectors); + m_oExternalData.ReadStream(oReader, arSelectors); } oWriter.CloseP(); @@ -1696,10 +1696,10 @@ void COOXMLTable::Normalize() bool COOXMLTable::Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& oTableNode) { - if (nullptr == m_pExternalData || Empty()) + if (Empty()) return false; - COOXMLWriter* pWriter{dynamic_cast(m_pExternalData->m_pWriter)}; + COOXMLWriter* pWriter{dynamic_cast(m_oExternalData.m_pWriter)}; if (nullptr == pWriter) return false; @@ -1711,22 +1711,22 @@ bool COOXMLTable::Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& bool COOXMLTable::ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption) { - if (nullptr == m_pExternalData || nullptr == m_pExternalData->m_pWriter) + if (nullptr == m_oExternalData.m_pWriter) return false; if (nullptr == pCaption) pCaption = new XmlString(200); std::vector arSelectors; - m_pExternalData->GetSubClass(oReader, arSelectors); + m_oExternalData.GetSubClass(oReader, arSelectors); arSelectors.back().m_pCompiledStyle->m_oText.SetAlign(L"center", 0, true); - COOXMLWriter& oWriter{*(COOXMLWriter*)m_pExternalData->m_pWriter}; + COOXMLWriter& oWriter{*(COOXMLWriter*)m_oExternalData.m_pWriter}; oWriter.SetDataOutput(m_pCaption); oWriter.WritePPr(arSelectors); - m_pExternalData->ReadStream(oReader, arSelectors); + m_oExternalData.ReadStream(oReader, arSelectors); oWriter.CloseP(); oWriter.RevertDataOutput(); @@ -1735,12 +1735,9 @@ bool COOXMLTable::ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pC bool COOXMLTable::ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vector& arColgroups) { - if (nullptr == m_pExternalData) - return false; - std::vector arNodes; - m_pExternalData->GetSubClass(oReader, arNodes); + m_oExternalData.GetSubClass(oReader, arNodes); CTableColgroup *pColgroup = new CTableColgroup(arNodes.back()); @@ -1755,7 +1752,7 @@ bool COOXMLTable::ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vectorGetSubClass(oReader, arNodes); + m_oExternalData.GetSubClass(oReader, arNodes); CTableCol *pCol = new CTableCol(arNodes.back()); diff --git a/HtmlFile2/Tags/OOXMLTags.h b/HtmlFile2/Tags/OOXMLTags.h index 1f16cfb342..9f93c57fa9 100644 --- a/HtmlFile2/Tags/OOXMLTags.h +++ b/HtmlFile2/Tags/OOXMLTags.h @@ -93,7 +93,7 @@ enum class ETableRules class COOXMLTable : public CTableElement { public: - COOXMLTable(TExternalTableData* pExternalData); + COOXMLTable(TExternalTableData &oExternalData); virtual ~COOXMLTable(); bool PreParse(XmlUtils::CXmlLiteReader& oReader) override; diff --git a/HtmlFile2/Writers/IWriter.h b/HtmlFile2/Writers/IWriter.h index 2a78f0755d..c2d5780dbf 100644 --- a/HtmlFile2/Writers/IWriter.h +++ b/HtmlFile2/Writers/IWriter.h @@ -8,12 +8,6 @@ namespace HTML { -enum class EWriterType -{ - OOXML, - Markdown -}; - class IWriter { protected: @@ -53,8 +47,6 @@ public: virtual XmlString* GetCurrentDocument() const = 0; - virtual EWriterType GetType() const = 0; - void SetSrcDirectory (const std::wstring& wsPath) { m_pSrcPath = &wsPath; diff --git a/HtmlFile2/Writers/MDWriter.cpp b/HtmlFile2/Writers/MDWriter.cpp index cba05a29ac..bd90281f58 100644 --- a/HtmlFile2/Writers/MDWriter.cpp +++ b/HtmlFile2/Writers/MDWriter.cpp @@ -162,47 +162,51 @@ bool CMDWriter::WriteText(std::wstring wsText, const std::vector& WriteString(L"> ", true); } + const bool bOnlySpaces{wsText.end() == std::find_if_not(wsText.begin(), wsText.end(), [](wchar_t wchChar){ return iswspace(wchChar);})}; + if (!bPreformatted && !InCode()) { ReplaceSpaces(wsText); ReplaceSpecialCharsInEdges(wsText); } - bool bNeedBold{false}, bNeedItalic{false}, bNeedStrike{false}; + bool bNeedBold {false}, + bNeedItalic{false}, + bNeedStrike{false}; - if (nullptr != pCompiledStyle) + if (nullptr != pCompiledStyle && !bOnlySpaces) { - if (!IsBold() && pCompiledStyle->m_oFont.Bold()) + if (pCompiledStyle->m_oFont.Bold()) bNeedBold = true; - if (!IsItalic() && pCompiledStyle->m_oFont.Italic()) + if (pCompiledStyle->m_oFont.Italic()) bNeedItalic = true; - if (!IsStrike() && pCompiledStyle->m_oText.LineThrough()) + if (pCompiledStyle->m_oText.LineThrough()) bNeedStrike = true; } if (bNeedBold) - WriteString(L"**"); + WriteOpenSpecialString(L"**"); if (bNeedItalic) - WriteString(L"*"); + WriteOpenSpecialString(L"*"); if (bNeedStrike) - WriteString(L"~~"); + WriteOpenSpecialString(L"~~"); ApplyAlternativeTags(pCompiledStyle); WriteString(wsText); ApplyAlternativeTags(pCompiledStyle, true); if (bNeedBold) - WriteString(L"**"); + WriteCloseSpecialString(L"**"); if (bNeedItalic) - WriteString(L"*"); + WriteCloseSpecialString(L"*"); if (bNeedStrike) - WriteString(L"~~"); + WriteCloseSpecialString(L"~~"); if (L'\n' == wsText.back()) m_arStates.top().m_bNeedBreakLine = false; @@ -252,22 +256,32 @@ void CMDWriter::WriteString(const std::wstring& wsString, bool bSpecialString) m_arStates.top().m_bEmptyLine = wsString.empty(); if (!bSpecialString) + { + if (!m_arStates.top().m_oSpecialString.m_wsLastSpecialString.empty() && + m_arStates.top().m_oSpecialString.m_bClosed) + m_arStates.top().m_oSpecialString.m_wsLastSpecialString.clear(); + m_arStates.top().m_bNeedBreakLine = true; + } } void CMDWriter::WriteOpenSpecialString(const std::wstring& wsString) { - if (m_arStates.top().m_wsLastSpecialString == wsString) + if (!m_arStates.top().m_oSpecialString.m_wsLastSpecialString.empty() && + (m_arStates.top().m_oSpecialString.m_wsLastSpecialString == wsString || + (L'*' == m_arStates.top().m_oSpecialString.m_wsLastSpecialString.front() && L'*' == wsString.front()))) GetCurrentDocument()->WriteString(L" "); - m_arStates.top().m_wsLastSpecialString.clear(); + m_arStates.top().m_oSpecialString.m_wsLastSpecialString.clear(); + m_arStates.top().m_oSpecialString.m_bClosed = false; WriteString(wsString, true); } void CMDWriter::WriteCloseSpecialString(const std::wstring& wsString) { - m_arStates.top().m_wsLastSpecialString = wsString; + m_arStates.top().m_oSpecialString.m_wsLastSpecialString = wsString; + m_arStates.top().m_oSpecialString.m_bClosed = true; WriteString(wsString, true); } @@ -277,11 +291,6 @@ XmlString* CMDWriter::GetCurrentDocument() const return m_arStates.top().m_pCurrentDocument; } -EWriterType CMDWriter::GetType() const -{ - return EWriterType::Markdown; -} - void CMDWriter::WriteBreakLine(bool bNeedChecked) { if (bNeedChecked && !m_arStates.top().m_bNeedBreakLine) @@ -306,52 +315,6 @@ void CMDWriter::WriteBreakLine(bool bNeedChecked) m_arStates.top().m_bEmptyLine = true; m_arStates.top().m_bNeedBreakLine = false; - m_arStates.top().m_wsLastSpecialString.clear(); -} - -void CMDWriter::EnteredBold() -{ - m_arStates.top().m_bBold = true; -} - -void CMDWriter::OutBold() -{ - m_arStates.top().m_bBold = false; -} - -bool CMDWriter::IsBold() -{ - return m_arStates.top().m_bBold; -} - -void CMDWriter::EnteredItalic() -{ - m_arStates.top().m_bItalic = true; -} - -void CMDWriter::OutItalic() -{ - m_arStates.top().m_bItalic = false; -} - -bool CMDWriter::IsItalic() -{ - return m_arStates.top().m_bItalic; -} - -void CMDWriter::EnteredStrike() -{ - m_arStates.top().m_bStrike = true; -} - -void CMDWriter::OutStrike() -{ - m_arStates.top().m_bStrike = false; -} - -bool CMDWriter::IsStrike() -{ - return m_arStates.top().m_bStrike; } void CMDWriter::EnteredBlockquote() diff --git a/HtmlFile2/Writers/MDWriter.h b/HtmlFile2/Writers/MDWriter.h index 3e3a79cbb2..81fbb4aa8a 100644 --- a/HtmlFile2/Writers/MDWriter.h +++ b/HtmlFile2/Writers/MDWriter.h @@ -21,10 +21,6 @@ class CMDWriter : public IWriter UINT m_unLevelBlockquote{0}; - bool m_bBold{false}; - bool m_bItalic{false}; - bool m_bStrike{false}; - bool m_bInTable{false}; bool m_bInPreformatted{false}; bool m_bInCode{false}; @@ -34,7 +30,11 @@ class CMDWriter : public IWriter UINT m_unLevelList{0}; UINT m_unIndexListElement{1}; - std::wstring m_wsLastSpecialString; + struct TSpecialString + { + std::wstring m_wsLastSpecialString; + bool m_bClosed{false}; + }m_oSpecialString; }; std::stack m_arStates; @@ -65,22 +65,8 @@ public: XmlString* GetCurrentDocument() const override; - EWriterType GetType() const override; - void WriteBreakLine(bool bNeedChecked = true); - void EnteredBold(); - void OutBold(); - bool IsBold(); - - void EnteredItalic(); - void OutItalic(); - bool IsItalic(); - - void EnteredStrike(); - void OutStrike(); - bool IsStrike(); - void EnteredBlockquote(); void OutBlockquote(); UINT GetLevelBlockquote(); diff --git a/HtmlFile2/Writers/OOXMLWriter.cpp b/HtmlFile2/Writers/OOXMLWriter.cpp index 662ea3e792..46ef0f2c9b 100644 --- a/HtmlFile2/Writers/OOXMLWriter.cpp +++ b/HtmlFile2/Writers/OOXMLWriter.cpp @@ -1231,11 +1231,6 @@ XmlString* COOXMLWriter::GetCurrentDocument() const return m_arStates.top().m_pCurrentDocument; } -EWriterType COOXMLWriter::GetType() const -{ - return EWriterType::OOXML; -} - const NSCSS::NSProperties::CPage* COOXMLWriter::GetPageData() const { return &m_oPageData; diff --git a/HtmlFile2/Writers/OOXMLWriter.h b/HtmlFile2/Writers/OOXMLWriter.h index b3156897fb..c3039546f3 100644 --- a/HtmlFile2/Writers/OOXMLWriter.h +++ b/HtmlFile2/Writers/OOXMLWriter.h @@ -21,7 +21,7 @@ struct TImageData std::wstring m_wsAlign; TImageData() - : m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left") + : m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left") {} bool ZeroSize() const @@ -188,8 +188,6 @@ public: XmlString& GetWebSettingsXml(); XmlString* GetCurrentDocument() const override; - EWriterType GetType() const override; - const NSCSS::NSProperties::CPage* GetPageData() const; std::wstring GetMediaDir() const;