diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp
index 49d4d29bf2..5cb274feeb 100644
--- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp
+++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp
@@ -525,6 +525,7 @@ namespace NSCSS
m_mDefaultStyleData[L"ul"] = new CElement(L"ul", {{L"margin-top", L"100tw"},
{L"margin-bottom", L"100tw"}});
m_mDefaultStyleData[L"textarea"] = new CElement(L"textarea", {{L"border", L"1px solid black"}});
+ m_mDefaultStyleData[L"th"] = new CElement(L"b", {{L"font-weight", L"bold"}});
}
CCssCalculator_Private::CCssCalculator_Private()
diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h
index 8d62be17b6..30b573f937 100644
--- a/Common/3dParty/html/css/src/StyleProperties.h
+++ b/Common/3dParty/html/css/src/StyleProperties.h
@@ -118,6 +118,11 @@ namespace NSCSS
return *this;
}
+
+ bool LessSignificantThen(const CValueBase& oValue) const
+ {
+ return oValue.m_unLevel >= m_unLevel && (!m_bImportant || oValue.m_bImportant) && !oValue.Empty();
+ }
};
template
diff --git a/HtmlFile2/HTMLReader.cpp b/HtmlFile2/HTMLReader.cpp
index ee082e3800..5b8382de5d 100644
--- a/HtmlFile2/HTMLReader.cpp
+++ b/HtmlFile2/HTMLReader.cpp
@@ -261,6 +261,7 @@ inline bool CheckArgumentMath(const std::wstring& wsNodeName, const std::wstring
inline HtmlTag GetHtmlTag(const std::wstring& wsStrTag);
inline bool UnreadableNode(const std::wstring& wsNodeName);
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)
@@ -375,9 +376,6 @@ void CHTMLReader::InitOOXMLTags(THTMLParameters* pParametrs)
m_mTags[HTML_TAG(OL)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(LI)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(CAPTION)] = std::make_shared>(pWriter);
- m_mTags[HTML_TAG(TABLE)] = std::make_shared>(pWriter);
- m_mTags[HTML_TAG(TR)] = std::make_shared>(pWriter);
- m_mTags[HTML_TAG(TD)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(HTML)] = std::make_shared>(pWriter);
std::shared_ptr oIgnoredTag{std::make_shared()};
@@ -424,9 +422,6 @@ void CHTMLReader::InitMDTags(TMarkdownParameters* pParametrs)
m_mTags[HTML_TAG(IMG)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(HR)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(BLOCKQUOTE)] = std::make_shared>(pWriter);
- m_mTags[HTML_TAG(TABLE)] = std::make_shared>(pWriter);
- m_mTags[HTML_TAG(TR)] = std::make_shared>(pWriter);
- m_mTags[HTML_TAG(TD)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(OL)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(LI)] = std::make_shared>(pWriter);
m_mTags[HTML_TAG(PRE)] = std::make_shared>(pWriter);
@@ -454,9 +449,9 @@ void CHTMLReader::InitMDTags(TMarkdownParameters* pParametrs)
m_mTags[HTML_TAG(HTML)] = oIgnoredTag;
}
-bool CHTMLReader::IsHTML()
+bool CHTMLReader::IsHTML(XmlUtils::CXmlLiteReader& oReader)
{
- return ((m_oLightReader.MoveToStart() && m_oLightReader.ReadNextNode()) ? m_oLightReader.GetName() == L"html" : false);
+ return ((oReader.MoveToStart() && oReader.ReadNextNode()) ? oReader.GetName() == L"html" : false);
}
HRESULT CHTMLReader::InitAndConvert2OOXML(const std::vector& arPaths, const std::wstring& wsDirectory, Convert_Func Convertation, THTMLParameters* pParameters)
@@ -505,7 +500,9 @@ HRESULT CHTMLReader::InitAndConvert2Markdown(const std::vector& ar
bool CHTMLReader::Convert(const std::wstring& wsPath, Convert_Func Convertation)
{
- if (nullptr == m_pWriter || !Convertation(wsPath, m_oLightReader) || !m_oLightReader.IsValid() || !IsHTML())
+ XmlUtils::CXmlLiteReader oReader;
+
+ if (nullptr == m_pWriter || !Convertation(wsPath, oReader) || !oReader.IsValid() || !IsHTML(oReader))
return false;
if (m_wsTempDirectory.empty())
@@ -515,79 +512,79 @@ bool CHTMLReader::Convert(const std::wstring& wsPath, Convert_Func Convertation)
m_wsSrcDirectory = NSSystemPath::GetDirectoryName(wsPath);
- m_oLightReader.MoveToStart();
- m_oLightReader.ReadNextNode();
- ReadStyle();
+ oReader.MoveToStart();
+ oReader.ReadNextNode();
+ ReadStyle(oReader);
// Переходим в начало
- if(!m_oLightReader.MoveToStart())
+ if(!oReader.MoveToStart())
return S_FALSE;
- ReadDocument();
+ ReadDocument(oReader);
return true;
}
-void CHTMLReader::ReadStyle()
+void CHTMLReader::ReadStyle(XmlUtils::CXmlLiteReader& oReader)
{
- if(m_oLightReader.IsEmptyNode())
+ if(oReader.IsEmptyNode())
return;
- const int nDeath = m_oLightReader.GetDepth();
+ const int nDeath = oReader.GetDepth();
std::wstring sName;
- while(m_oLightReader.ReadNextSiblingNode(nDeath))
+ while(oReader.ReadNextSiblingNode(nDeath))
{
- sName = m_oLightReader.GetName();
+ sName = oReader.GetName();
if(sName == L"body")
- ReadStyle2();
+ ReadStyle2(oReader);
else
{
// Стиль по ссылке
if(sName == L"link")
{
- while(m_oLightReader.MoveToNextAttribute())
- ReadStyleFromNetwork();
+ while(oReader.MoveToNextAttribute())
+ ReadStyleFromNetwork(oReader);
- m_oLightReader.MoveToElement();
+ oReader.MoveToElement();
}
// тэг style содержит стили для styles.xml
else if(sName == L"style")
- m_oCSSCalculator.AddStyles(m_oLightReader.GetText2());
+ m_oCSSCalculator.AddStyles(oReader.GetText2());
else
- ReadStyle();
+ ReadStyle(oReader);
}
}
}
-void CHTMLReader::ReadStyle2()
+void CHTMLReader::ReadStyle2(XmlUtils::CXmlLiteReader& oReader)
{
- const std::wstring wsName = m_oLightReader.GetName();
+ const std::wstring wsName = oReader.GetName();
// Стиль по ссылке
if(wsName == L"link")
{
- while(m_oLightReader.MoveToNextAttribute())
- ReadStyleFromNetwork();
- m_oLightReader.MoveToElement();
+ while(oReader.MoveToNextAttribute())
+ ReadStyleFromNetwork(oReader);
+ oReader.MoveToElement();
}
// тэг style содержит стили для styles.xml
else if(wsName == L"style")
- m_oCSSCalculator.AddStyles(m_oLightReader.GetText2());
+ m_oCSSCalculator.AddStyles(oReader.GetText2());
- const int nDeath = m_oLightReader.GetDepth();
- while(m_oLightReader.ReadNextSiblingNode(nDeath))
+ const int nDeath = oReader.GetDepth();
+ while(oReader.ReadNextSiblingNode(nDeath))
{
- if(!m_oLightReader.IsEmptyNode())
- ReadStyle2();
+ if(!oReader.IsEmptyNode())
+ ReadStyle2(oReader);
}
}
-void CHTMLReader::ReadStyleFromNetwork()
+void CHTMLReader::ReadStyleFromNetwork(XmlUtils::CXmlLiteReader& oReader)
{
- if(m_oLightReader.GetName() != L"href")
+ if(oReader.GetName() != L"href")
return;
- std::wstring sRef = m_oLightReader.GetText();
+ std::wstring sRef = oReader.GetText();
if(NSFile::GetFileExtention(sRef) != L"css")
return;
std::wstring sFName = NSFile::GetFileName(sRef);
@@ -610,44 +607,44 @@ void CHTMLReader::ReadStyleFromNetwork()
}
}
-void CHTMLReader::ReadDocument()
+void CHTMLReader::ReadDocument(XmlUtils::CXmlLiteReader& oReader)
{
- m_oLightReader.ReadNextNode();
+ oReader.ReadNextNode();
- int nDeath = m_oLightReader.GetDepth();
- while(m_oLightReader.ReadNextSiblingNode(nDeath))
+ int nDeath = oReader.GetDepth();
+ while(oReader.ReadNextSiblingNode(nDeath))
{
- const std::wstring wsName = m_oLightReader.GetName();
+ const std::wstring wsName = oReader.GetName();
if(wsName == L"head")
- ReadHead();
+ ReadHead(oReader);
else if(wsName == L"body")
- ReadBody();
+ ReadBody(oReader);
}
}
-void CHTMLReader::ReadHead()
+void CHTMLReader::ReadHead(XmlUtils::CXmlLiteReader& oReader)
{
- if(m_oLightReader.IsEmptyNode())
+ if(oReader.IsEmptyNode())
return;
- int nDeath = m_oLightReader.GetDepth();
- while (m_oLightReader.ReadNextSiblingNode(nDeath))
+ int nDeath = oReader.GetDepth();
+ while (oReader.ReadNextSiblingNode(nDeath))
{
- const std::wstring wsName = m_oLightReader.GetName();
+ const std::wstring wsName = oReader.GetName();
// Базовый адрес
if (L"base" == wsName)
- m_wsBaseDirectory = GetArgumentValue(m_oLightReader, L"href");
+ m_wsBaseDirectory = GetArgumentValue(oReader, L"href");
}
- m_oLightReader.MoveToElement();
+ oReader.MoveToElement();
}
-void CHTMLReader::ReadBody()
+void CHTMLReader::ReadBody(XmlUtils::CXmlLiteReader& oReader)
{
std::vector arSelectors;
arSelectors.push_back(NSCSS::CNode(L"html", L"", L""));
- GetSubClass(arSelectors);
+ GetSubClass(oReader, arSelectors, m_oCSSCalculator);
if (!m_mTags[HTML_TAG(HTML)]->Open(arSelectors))
return;
@@ -657,22 +654,22 @@ void CHTMLReader::ReadBody()
if (arSelectors.back().m_mAttributes.end() != itFound)
arSelectors.back().m_mAttributes.erase(itFound);
- m_oLightReader.MoveToElement();
+ oReader.MoveToElement();
- ReadStream(arSelectors);
+ ReadStream(oReader, arSelectors);
m_mTags[HTML_TAG(HTML)]->Close(arSelectors);
}
-bool CHTMLReader::ReadStream(std::vector& arSelectors, bool bInsertEmptyP)
+bool CHTMLReader::ReadStream(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, bool bInsertEmptyP)
{
if (nullptr == m_pWriter)
return false;
bool bResult{false};
- const int nDeath = m_oLightReader.GetDepth();
- if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode2(nDeath))
+ const int nDeath = oReader.GetDepth();
+ if(oReader.IsEmptyNode() || !oReader.ReadNextSiblingNode2(nDeath))
{
if (!bInsertEmptyP)
return false;
@@ -683,9 +680,9 @@ bool CHTMLReader::ReadStream(std::vector& arSelectors, bool bInser
do
{
- if (ReadInside(arSelectors))
+ if (ReadInside(oReader, arSelectors))
bResult = true;
- } while(m_oLightReader.ReadNextSiblingNode2(nDeath));
+ } while(oReader.ReadNextSiblingNode2(nDeath));
if (!bResult && bInsertEmptyP)
m_pWriter->WriteEmptyParagraph();
@@ -693,18 +690,18 @@ bool CHTMLReader::ReadStream(std::vector& arSelectors, bool bInser
return bResult;
}
-bool CHTMLReader::ReadInside(std::vector& arSelectors)
+bool CHTMLReader::ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors)
{
- const std::wstring wsName{m_oLightReader.GetName()};
+ const std::wstring wsName{oReader.GetName()};
if(wsName == L"#text")
- return ReadText(arSelectors);
+ return ReadText(oReader, arSelectors);
//TODO:: обработать все варианты return'а
if (UnreadableNode(wsName) || TagIsUnprocessed(wsName))
return false;
- GetSubClass(arSelectors);
+ GetSubClass(oReader, arSelectors, m_oCSSCalculator);
bool bResult = true;
@@ -715,24 +712,24 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
case HTML_TAG(A):
case HTML_TAG(AREA):
{
- bResult = ReadDefaultTag(HTML_TAG(A), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(A), arSelectors);
break;
}
case HTML_TAG(ABBR):
{
- bResult = ReadDefaultTag(HTML_TAG(ABBR), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(ABBR), arSelectors);
break;
}
case HTML_TAG(B):
case HTML_TAG(STRONG):
{
- bResult = ReadDefaultTag(HTML_TAG(B), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(B), arSelectors);
break;
}
case HTML_TAG(BDO):
case HTML_TAG(BDI):
{
- bResult = ReadDefaultTag(HTML_TAG(BDO), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(BDO), arSelectors);
break;
}
case HTML_TAG(BR):
@@ -742,7 +739,7 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
}
case HTML_TAG(CENTER):
{
- bResult = ReadDefaultTag(HTML_TAG(CENTER), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(CENTER), arSelectors);
break;
}
case HTML_TAG(CITE):
@@ -751,7 +748,7 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
case HTML_TAG(I):
case HTML_TAG(VAR):
{
- bResult = ReadDefaultTag(HTML_TAG(I), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(I), arSelectors);
break;
}
case HTML_TAG(CODE):
@@ -759,62 +756,61 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
case HTML_TAG(TT):
case HTML_TAG(OUTPUT):
{
- bResult = ReadDefaultTag(HTML_TAG(CODE), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(CODE), arSelectors);
break;
}
case HTML_TAG(KBD):
{
- bResult = ReadDefaultTag(HTML_TAG(KBD), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(KBD), arSelectors);
break;
}
case HTML_TAG(DEL):
case HTML_TAG(S):
case HTML_TAG(STRIKE):
{
- bResult = ReadDefaultTag(HTML_TAG(S), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(S), arSelectors);
break;
}
case HTML_TAG(FONT):
{
- bResult = ReadDefaultTag(HTML_TAG(FONT), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(FONT), arSelectors);
break;
}
case HTML_TAG(IMG):
-
{
bResult = ReadEmptyTag(HTML_TAG(IMG), arSelectors);
break;
}
case HTML_TAG(SVG):
{
- bResult = ReadSVG(arSelectors);
+ bResult = ReadSVG(oReader, arSelectors);
break;
}
case HTML_TAG(INS):
case HTML_TAG(U):
{
- bResult = ReadDefaultTag(HTML_TAG(U), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(U), arSelectors);
break;
}
case HTML_TAG(MARK):
{
- bResult = ReadDefaultTag(HTML_TAG(MARK), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(MARK), arSelectors);
break;
}
case HTML_TAG(Q):
{
- bResult = ReadDefaultTag(HTML_TAG(Q), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(Q), arSelectors);
break;
}
case HTML_TAG(SUP):
case HTML_TAG(SUB):
{
- bResult = ReadDefaultTag(HTML_TAG(SUP), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(SUP), arSelectors);
break;
}
case HTML_TAG(INPUT):
{
- bResult = ReadDefaultTag(HTML_TAG(INPUT), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(INPUT), arSelectors);
break;
}
case HTML_TAG(CANVAS):
@@ -838,17 +834,17 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
}
case HTML_TAG(SPAN):
{
- bResult = ReadDefaultTag(HTML_TAG(SPAN), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(SPAN), arSelectors);
break;
}
case HTML_TAG(NOBR):
{
- bResult = ReadDefaultTag(HTML_TAG(PRE), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(PRE), arSelectors);
break;
}
case HTML_TAG(BASEFONT):
{
- bResult = ReadDefaultTag(HTML_TAG(BASEFONT), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(BASEFONT), arSelectors);
break;
}
case HTML_TAG(BUTTON):
@@ -864,7 +860,7 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
case HTML_TAG(ACRONYM):
case HTML_TAG(BIG):
{
- bResult = ReadStream(arSelectors);
+ bResult = ReadStream(oReader, arSelectors);
break;
}
default:
@@ -875,12 +871,12 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
{
case HTML_TAG(ADDRESS):
{
- bResult = ReadDefaultTag(HTML_TAG(I), arSelectors);;
+ bResult = ReadDefaultTag(oReader, HTML_TAG(I), arSelectors);;
break;
}
case HTML_TAG(DD):
{
- bResult = ReadDefaultTag(HTML_TAG(DD), arSelectors);;
+ bResult = ReadDefaultTag(oReader, HTML_TAG(DD), arSelectors);;
break;
}
case HTML_TAG(H1):
@@ -890,18 +886,18 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
case HTML_TAG(H5):
case HTML_TAG(H6):
{
- bResult = ReadDefaultTag(HTML_TAG(H1), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(H1), arSelectors);
break;
}
case HTML_TAG(ASIDE):
case HTML_TAG(DIV):
{
- bResult = ReadDefaultTag(HTML_TAG(DIV), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(DIV), arSelectors);
break;
}
case HTML_TAG(BLOCKQUOTE):
{
- bResult = ReadDefaultTag(HTML_TAG(BLOCKQUOTE), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(BLOCKQUOTE), arSelectors);
break;
}
case HTML_TAG(ARTICLE):
@@ -921,7 +917,7 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
case HTML_TAG(LEGEND):
case HTML_TAG(MAP):
{
- bResult = ReadStream(arSelectors);
+ bResult = ReadStream(oReader, arSelectors);
break;
}
case HTML_TAG(HR):
@@ -931,13 +927,13 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
}
case HTML_TAG(LI):
{
- bResult = ReadDefaultTag(HTML_TAG(LI), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(LI), arSelectors);
break;
}
case HTML_TAG(OL):
case HTML_TAG(UL):
{
- bResult = ReadDefaultTag(HTML_TAG(OL), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(OL), arSelectors);
break;
}
// case HTML_TAG(MENU):
@@ -951,12 +947,12 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
case HTML_TAG(PRE):
case HTML_TAG(XMP):
{
- bResult = ReadDefaultTag(HTML_TAG(PRE), arSelectors);
+ bResult = ReadDefaultTag(oReader, HTML_TAG(PRE), arSelectors);
break;
}
case HTML_TAG(TABLE):
{
- bResult = ReadTable(arSelectors);
+ bResult = ReadTable(oReader, arSelectors);
break;
}
// case HTML_TAG(RUBY):
@@ -977,7 +973,7 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
// }
default:
{
- bResult = ReadStream(arSelectors);
+ bResult = ReadStream(oReader, arSelectors);
break;
}
}
@@ -990,23 +986,23 @@ bool CHTMLReader::ReadInside(std::vector& arSelectors)
return bResult;
}
-bool CHTMLReader::ReadText(std::vector& arSelectors)
+bool CHTMLReader::ReadText(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors)
{
if (nullptr == m_pWriter)
return false;
- GetSubClass(arSelectors);
+ GetSubClass(oReader, arSelectors, m_oCSSCalculator);
- const bool bResult{m_pWriter->WriteText(m_oLightReader.GetText(), arSelectors)};
+ const bool bResult{m_pWriter->WriteText(oReader.GetText(), arSelectors)};
arSelectors.pop_back();
return bResult;
}
-bool CHTMLReader::ReadSVG(const std::vector& arSelectors)
+bool CHTMLReader::ReadSVG(XmlUtils::CXmlLiteReader& oReader, const std::vector& arSelectors)
{
- if (!m_mTags[HTML_TAG(IMG)]->Open(arSelectors, m_oLightReader.GetOuterXml()))
+ if (!m_mTags[HTML_TAG(IMG)]->Open(arSelectors, oReader.GetOuterXml()))
return false;
m_mTags[HTML_TAG(IMG)]->Close(arSelectors);
@@ -1014,406 +1010,54 @@ bool CHTMLReader::ReadSVG(const std::vector& arSelectors)
return true;
}
-bool CHTMLReader::ReadTable(std::vector& arSelectors)
+bool CHTMLReader::ReadTable(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors)
{
- if(m_oLightReader.IsEmptyNode())
+ if(oReader.IsEmptyNode())
return false;
- if (nullptr != m_pWriter && !m_pWriter->SupportNestedTables())
- {
- //Временно разруливаем это тут, так как по текущей логике мы сначала
- //читаем всю таблицу и её вложенные элементы, а потом приступаем к конвертации,
- //поэтому конвертору уже приходят вложенные таблицы, что в MD запрещено
- for (std::vector::const_reverse_iterator itElement{arSelectors.crbegin() + 1}; itElement < arSelectors.crend(); ++itElement)
- if (L"table" == itElement->m_wsName)
- return false;
+ XmlUtils::CXmlLiteReader oTableReader;
- if (nullptr != dynamic_cast(m_pWriter))
- ((CMDWriter*)m_pWriter)->EnteredTable();
- }
-
- CStorageTable oTable;
-
- NSCSS::CCompiledStyle *pStyle = arSelectors.back().m_pCompiledStyle;
-
- //Table styles
- std::wstring wsFrame;
- std::wstring wsValue;
-
- if (arSelectors.back().GetAttributeValue(L"border", wsValue))
- {
- const int nWidth = NSStringFinder::ToInt(wsValue);
-
- if (0 < nWidth)
- {
- oTable.SetRules(L"all");
-
- if (pStyle->m_oBorder.Empty())
- {
- pStyle->m_oBorder.SetStyle(L"outset", 0, true);
- pStyle->m_oBorder.SetWidth(nWidth, NSCSS::UnitMeasure::Point, 0, true);
- pStyle->m_oBorder.SetColor(L"auto", 0, true);
- }
- }
- else if (pStyle->m_oBorder.Empty())
- {
- pStyle->m_oBorder.SetNone(0, true);
- oTable.SetRules(L"none");
- }
- }
-
- if (arSelectors.back().GetAttributeValue(L"cellpadding", wsValue))
- pStyle->m_oPadding.SetValues(wsValue + L"px", 0, true);
-
- if (arSelectors.back().GetAttributeValue(L"rules", wsValue))
- oTable.SetRules(wsValue);
-
- arSelectors.back().GetAttributeValue(L"frame", wsFrame);
-
- if (!wsFrame.empty() && pStyle->m_oBorder.Empty())
- {
- #define SetDefaultBorderSide(side) \
- pStyle->m_oBorder.SetStyle##side(L"solid", 0, true); \
- pStyle->m_oBorder.SetWidth##side(1, NSCSS::UnitMeasure::Point, 0, true); \
- pStyle->m_oBorder.SetColor##side(L"black", 0, true)
-
- if (NSStringFinder::Equals(L"border", wsFrame))
- {
- SetDefaultBorderSide();
- }
- else if (NSStringFinder::Equals(L"above", wsFrame))
- {
- SetDefaultBorderSide(TopSide);
- }
- else if (NSStringFinder::Equals(L"below", wsFrame))
- {
- SetDefaultBorderSide(BottomSide);
- }
- else if (NSStringFinder::Equals(L"hsides", wsFrame))
- {
- SetDefaultBorderSide(TopSide);
- SetDefaultBorderSide(BottomSide);
- }
- else if (NSStringFinder::Equals(L"vsides", wsFrame))
- {
- SetDefaultBorderSide(LeftSide);
- SetDefaultBorderSide(RightSide);
- }
- else if (NSStringFinder::Equals(L"rhs", wsFrame))
- {
- SetDefaultBorderSide(RightSide);
- }
- else if (NSStringFinder::Equals(L"lhs", wsFrame))
- {
- SetDefaultBorderSide(LeftSide);
- }
- }
-
- if (pStyle->m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Collapse)
- oTable.SetCellSpacing(0);
- else if (arSelectors.back().GetAttributeValue(L"cellspacing", wsValue))
- oTable.SetCellSpacing(NSStringFinder::ToInt(wsValue));
- else if (pStyle->m_oBorder.GetCollapse() == NSCSS::NSProperties::BorderCollapse::Separate)
- oTable.SetCellSpacing(15);
-
- oTable.SetWidth(pStyle->m_oDisplay.GetWidth());
- oTable.SetBorder(pStyle->m_oBorder);
- oTable.SetPadding(pStyle->m_oPadding);
- oTable.SetMargin(pStyle->m_oMargin);
- oTable.SetAlign(pStyle->m_oDisplay.GetHAlign().ToWString());
- //------
-
- //TODO:: переписать работу с таблицами без предварительной конвертации ячеек и хранения их внутренних данных
- //Читаем содержимое таблицы -> считаем ячейки -> нормализуем таблицу -> конвертим таблицу
-
- int nDeath = m_oLightReader.GetDepth();
- while(m_oLightReader.ReadNextSiblingNode(nDeath))
- {
- const std::wstring sName = m_oLightReader.GetName();
- GetSubClass(arSelectors);
-
- if(sName == L"caption")
- ReadTableCaption(oTable, arSelectors);
- if(sName == L"thead")
- ReadTableRows(oTable, arSelectors, ERowParseMode::Header);
- if(sName == L"tbody")
- ReadTableRows(oTable, arSelectors, ERowParseMode::Body);
- else if(sName == L"tfoot")
- ReadTableRows(oTable, arSelectors, ERowParseMode::Foother);
- else if (sName == L"colgroup")
- ReadTableColspan(oTable);
-
- arSelectors.pop_back();
- }
-
- oTable.Shorten();
- oTable.CompleteTable();
-
- #define CONVERT_ROWS(rows, parse_mode)\
- {\
- const std::vector arRows{rows};\
- \
- for (UINT unRow = 0; unRow < arRows.size(); ++unRow)\
- {\
- ERowPosition eRowPosition{ERowPosition::Middle};\
- \
- if (0 == unRow)\
- eRowPosition = ERowPosition::First;\
- else if (arRows.size() - 1 == unRow)\
- eRowPosition = ERowPosition::Last;\
- \
- if (!m_mTags[HTML_TAG(TR)]->Open(arSelectors, boost::tuple(&arRows[unRow]->GetStyles(), oTable, parse_mode, eRowPosition)))\
- continue;\
- \
- const std::vector& arCells{arRows[unRow]->GetCells()};\
- \
- for (UINT unCol = 0; unCol < arCells.size(); ++unCol)\
- {\
- m_mTags[HTML_TAG(TD)]->Open(arSelectors, boost::tuple(*arCells[unCol], oTable, unCol, parse_mode, eRowPosition));\
- \
- if (0 != arCells[unCol]->GetData()->GetCurSize())\
- {\
- WriteToStringBuilder(*(arCells[unCol]->GetData()), *(m_pWriter->GetCurrentDocument()));\
- arCells[unCol]->GetData()->Clear();\
- }\
- else\
- m_pWriter->WriteEmptyParagraph();\
- \
- m_mTags[HTML_TAG(TD)]->Close(arSelectors);\
- }\
- \
- m_mTags[HTML_TAG(TR)]->Close(arSelectors);\
- }}
-
- if (!m_mTags[HTML_TAG(TABLE)]->Open(arSelectors, &oTable))
+ if (!oTableReader.FromString(oReader.GetOuterXml()) || !oTableReader.ReadNextNode())
return false;
- if (!oTable.HaveHeader())
+ 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())
{
- if (m_mTags[HTML_TAG(TR)]->Open(arSelectors, boost::tuple(nullptr, oTable, ERowParseMode::Header, ERowPosition::First)))
- m_mTags[HTML_TAG(TR)]->Close(arSelectors);
- }
- else
- {
- for (const std::vector& arHeader : oTable.GetHeaders())
- CONVERT_ROWS(arHeader, ERowParseMode::Header)
+ case EWriterType::Markdown: pTableElement = new CMarkdownTable(&oExternalData); break;
+ case EWriterType::OOXML: pTableElement = new COOXMLTable(&oExternalData); break;
+ default:
+ return false;
}
- CONVERT_ROWS(oTable.GetRows(), ERowParseMode::Body)
- CONVERT_ROWS(oTable.GetFoothers(), ERowParseMode::Foother)
+ if (nullptr == pTableElement)
+ return false;
- m_mTags[HTML_TAG(TABLE)]->Close(arSelectors);
+ if (!pTableElement->PreParse(oTableReader) ||
+ !oTableReader.MoveToStart() || !oTableReader.ReadNextNode())
+ {
+ delete pTableElement;
+ return false;
+ }
+ pTableElement->Normalize();
+ pTableElement->Convert(oTableReader, arSelectors.back());
+
+ delete pTableElement;
return true;
}
-void CHTMLReader::ReadTableCaption(CStorageTable& oTable, std::vector& arSelectors)
-{
- if (nullptr == m_pWriter)
- return;
-
- GetSubClass(arSelectors);
- m_pWriter->SetDataOutput(oTable.GetCaptionData());
-
- arSelectors.back().m_pCompiledStyle->m_oDisplay.SetVAlign(L"center", arSelectors.size());
-
- ReadDefaultTag(HTML_TAG(CAPTION), arSelectors);
-
- m_pWriter->RevertDataOutput();
- arSelectors.pop_back();
-}
-
-void CalculateCellStyles(TTableCellStyle* pCellStyle, std::vector& arSelectors)
-{
- if (NULL == pCellStyle)
- return;
-
- pCellStyle->m_wsVAlign = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetVAlign().ToWString();
- pCellStyle->m_wsHAlign = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetHAlign().ToWString();
- pCellStyle->m_oBackground = arSelectors.back().m_pCompiledStyle->m_oBackground.GetColor();
- pCellStyle->m_oHeight = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetHeight();
- pCellStyle->m_oWidth = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetWidth();
- pCellStyle->m_oPadding = arSelectors.back().m_pCompiledStyle->m_oPadding;
- pCellStyle->m_oBorder = arSelectors.back().m_pCompiledStyle->m_oBorder;
-
- if (pCellStyle->m_wsHAlign.empty())
- pCellStyle->m_wsHAlign = arSelectors.back().m_pCompiledStyle->m_oText.GetAlign().ToWString();
-}
-
-struct TRowspanElement
-{
- UINT m_unRowSpan;
- UINT m_unColumnIndex;
- const CStorageTableCell* m_pCell;
-
- TRowspanElement(UINT unRowSpan, UINT unColumnIndex, const CStorageTableCell* pCell)
- : m_unRowSpan(unRowSpan), m_unColumnIndex(unColumnIndex), m_pCell(pCell)
- {}
-};
-
-void CHTMLReader::ReadTableRows(CStorageTable& oTable, std::vector& arSelectors, ERowParseMode eMode)
-{
- if (nullptr == m_pWriter)
- return;
-
- std::vector arRowspanElements;
- std::vector arRows;
-
- int nDeath = m_oLightReader.GetDepth();
- while (m_oLightReader.ReadNextSiblingNode(nDeath))
- {
- if (L"tr" != m_oLightReader.GetName())
- continue;
-
- GetSubClass(arSelectors);
-
- CStorageTableRow *pRow = new CStorageTableRow();
-
- for (std::vector::iterator itElement = arRowspanElements.begin(); itElement < arRowspanElements.end();)
- {
- pRow->InsertCell(CStorageTableCell::CreateEmpty(itElement->m_pCell->GetColspan(), true, itElement->m_pCell->GetStyles()), itElement->m_unColumnIndex);
-
- itElement->m_unRowSpan--;
- if (1 == itElement->m_unRowSpan)
- itElement = arRowspanElements.erase(itElement);
- else
- ++itElement;
- }
-
- UINT unColumnIndex = 0;
- int nTrDepth = m_oLightReader.GetDepth();
- while (m_oLightReader.ReadNextSiblingNode(nTrDepth))
- {
- CStorageTableCell *pCell = new CStorageTableCell();
-
- if (NULL == pCell)
- continue;
-
- GetSubClass(arSelectors);
-
- std::vector arNewSelectors{(std::vector::const_iterator)std::find_if(arSelectors.begin(), arSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), arSelectors.cend()};
-
- CalculateCellStyles(pCell->GetStyles(), arNewSelectors);
-
- std::wstring wsValue;
-
- if (arSelectors.back().GetAttributeValue(L"colspan", wsValue))
- pCell->SetColspan(NSStringFinder::ToInt(wsValue, 1), pRow->GetIndex());
-
- if (arSelectors.back().GetAttributeValue(L"rowspan", wsValue))
- {
- pCell->SetRowspan(NSStringFinder::ToInt(wsValue, 1));
-
- if (1 != pCell->GetRowspan())
- arRowspanElements.push_back({pCell->GetRowspan(), unColumnIndex, pCell});
- }
-
- // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным
- if(m_oLightReader.GetName() == L"th")
- {
- if (pCell->GetStyles()->m_wsHAlign.empty())
- arSelectors.back().m_pCompiledStyle->m_oText.SetAlign(L"center", arSelectors.size());
-
- arSelectors.back().m_pCompiledStyle->m_oFont.SetWeight(L"bold", arSelectors.size());
-
- m_pWriter->SetDataOutput(pCell->GetData());
- ReadStream(arSelectors, true);
- m_pWriter->RevertDataOutput();
- }
- // Читаем td. Ячейка таблицы
- else if(m_oLightReader.GetName() == L"td")
- {
- m_pWriter->SetDataOutput(pCell->GetData());
- ReadStream(arSelectors, true);
- m_pWriter->RevertDataOutput();
- }
-
- if (pRow->GetIndex() == MAXCOLUMNSINTABLE - 1)
- {
- while (m_oLightReader.ReadNextSiblingNode(nTrDepth))
- {
- if (L"td" != m_oLightReader.GetName() && L"th" != m_oLightReader.GetName())
- continue;
-
- GetSubClass(arSelectors);
- m_pWriter->SetDataOutput(pCell->GetData());
- ReadStream(arSelectors);
- m_pWriter->RevertDataOutput();
- arSelectors.pop_back();
- }
- }
-
- pRow->AddCell(pCell);
- arSelectors.pop_back();
-
- ++unColumnIndex;
-
- if (pRow->GetIndex() == MAXCOLUMNSINTABLE)
- break;
- }
-
- arSelectors.pop_back();
- arRows.push_back(pRow);
- }
-
- oTable.AddRows(arRows, eMode);
-}
-
-void CHTMLReader::ReadTableColspan(CStorageTable& oTable)
-{
- std::vector arNodes;
- GetSubClass(arNodes);
-
- CTableColgroup *pColgroup = new CTableColgroup(arNodes.back());
-
- if (NULL == pColgroup)
- return;
-
- oTable.AddColgroup(pColgroup);
-
- const int nDeath = m_oLightReader.GetDepth();
- if (!m_oLightReader.IsEmptyNode() && m_oLightReader.ReadNextSiblingNode2(nDeath))
- {
- do
- {
- if (L"col" != m_oLightReader.GetName())
- continue;
-
- GetSubClass(arNodes);
-
- CTableCol *pCol = new CTableCol(arNodes.back());
-
- if (NULL == pCol)
- {
- arNodes.pop_back();
- continue;
- }
-
- CalculateCellStyles(pCol->GetStyle(), arNodes);
- arNodes.pop_back();
-
- if (NULL == pCol)
- continue;
-
- pColgroup->AddCol(pCol);
- } while(m_oLightReader.ReadNextSiblingNode2(nDeath));
- }
-
- if(pColgroup->Empty())
- {
- std::map::const_iterator itFound = arNodes.begin()->m_mAttributes.find(L"span");
-
- CTableCol *pCol = new CTableCol((arNodes.begin()->m_mAttributes.cend() != itFound) ? NSStringFinder::ToInt(itFound->second, 1) : 1);
-
- if (NULL == pCol)
- return;
-
- CalculateCellStyles(pCol->GetStyle(), arNodes);
-
- pColgroup->AddCol(pCol);
- }
-}
-
bool CHTMLReader::ReadEmptyTag(UINT unTag, const std::vector& arSelectors)
{
if (!m_mTags[unTag]->Open(arSelectors))
@@ -1424,57 +1068,18 @@ bool CHTMLReader::ReadEmptyTag(UINT unTag, const std::vector& arSe
return true;
}
-bool CHTMLReader::ReadDefaultTag(UINT unTag, std::vector& arSelectors)
+bool CHTMLReader::ReadDefaultTag(XmlUtils::CXmlLiteReader& oReader, UINT unTag, std::vector& arSelectors)
{
if (!m_mTags[unTag]->Open(arSelectors))
return false;
- const bool bResult{ReadStream(arSelectors)};
+ const bool bResult{ReadStream(oReader, arSelectors)};
m_mTags[unTag]->Close(arSelectors);
return bResult;
}
-void CHTMLReader::GetSubClass(std::vector& arSelectors)
-{
- NSCSS::CNode oNode;
-
- oNode.m_wsName = m_oLightReader.GetName();
- // Стиль по атрибуту
- std::wstring wsAttributeName;
-
- if (m_oLightReader.MoveToFirstAttribute())
- {
- do
- {
- 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_oCSSCalculator.CalculateCompiledStyle(arSelectors);
-}
-
inline std::wstring GetArgumentValue(XmlUtils::CXmlLiteReader& oLiteReader, const std::wstring& wsArgumentName, const std::wstring& wsDefaultValue)
{
if (!oLiteReader.MoveToFirstAttribute())
@@ -1530,4 +1135,43 @@ inline bool TagIsUnprocessed(const std::wstring& wsTagName)
{
return L"xml" == wsTagName;
}
+
+inline void GetSubClass(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, NSCSS::CCssCalculator& oCSSCalculator)
+{
+ NSCSS::CNode oNode;
+
+ oNode.m_wsName = oReader.GetName();
+ // Стиль по атрибуту
+ std::wstring wsAttributeName;
+
+ if (oReader.MoveToFirstAttribute())
+ {
+ do
+ {
+ wsAttributeName = oReader.GetName();
+ if(wsAttributeName == L"class")
+ oNode.m_wsClass = EncodeXmlString(oReader.GetText());
+ else if(wsAttributeName == L"id")
+ {
+ oNode.m_wsId = EncodeXmlString(oReader.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 += oReader.GetText();
+ else
+ {
+ if (CheckArgumentMath(oNode.m_wsName, wsAttributeName))
+ oNode.m_mAttributes[wsAttributeName] = oReader.GetText();
+ }
+ }while(oReader.MoveToNextAttribute());
+ }
+
+ oReader.MoveToElement();
+ arSelectors.push_back(oNode);
+
+ oCSSCalculator.CalculateCompiledStyle(arSelectors);
+}
}
diff --git a/HtmlFile2/HTMLReader.h b/HtmlFile2/HTMLReader.h
index dce2cc1b85..4ccef4917e 100644
--- a/HtmlFile2/HTMLReader.h
+++ b/HtmlFile2/HTMLReader.h
@@ -1,6 +1,7 @@
#ifndef HTMLREADER_H
#define HTMLREADER_H
+#include
#include
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
@@ -17,7 +18,7 @@ namespace HTML
{
class CHTMLReader
{
- XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader
+ // XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader
NSCSS::CCssCalculator m_oCSSCalculator; // Css калькулятор
bool m_bIsTempDirOwner;
@@ -55,7 +56,7 @@ private:
void InitOOXMLTags(THTMLParameters* pParametrs = nullptr);
void InitMDTags(TMarkdownParameters* pParametrs = nullptr);
- bool IsHTML();
+ bool IsHTML(XmlUtils::CXmlLiteReader& oReader);
typedef std::function Convert_Func;
@@ -64,29 +65,24 @@ private:
bool Convert(const std::wstring& wsPath, Convert_Func Convertation);
- void ReadStyle();
- void ReadStyle2();
- void ReadStyleFromNetwork();
+ void ReadStyle(XmlUtils::CXmlLiteReader& oReader);
+ void ReadStyle2(XmlUtils::CXmlLiteReader& oReader);
+ void ReadStyleFromNetwork(XmlUtils::CXmlLiteReader& oReader);
- void ReadDocument();
- void ReadHead();
- void ReadBody();
+ void ReadDocument(XmlUtils::CXmlLiteReader& oReader);
+ void ReadHead(XmlUtils::CXmlLiteReader& oReader);
+ void ReadBody(XmlUtils::CXmlLiteReader& oReader);
- bool ReadStream(std::vector& arSelectors, bool bInsertEmptyP = false);
- bool ReadInside(std::vector& arSelectors);
+ bool ReadStream(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, bool bInsertEmptyP = false);
+ bool ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors);
- bool ReadText(std::vector& arSelectors);
+ bool ReadText(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors);
- bool ReadSVG(const std::vector& arSelectors);
+ bool ReadSVG(XmlUtils::CXmlLiteReader& oReader, const std::vector& arSelectors);
bool ReadEmptyTag(UINT unTag, const std::vector& arSelectors);
- bool ReadDefaultTag(UINT unTag, std::vector& arSelectors);
+ bool ReadDefaultTag(XmlUtils::CXmlLiteReader& oReader, UINT unTag, std::vector& arSelectors);
- bool ReadTable(std::vector& arSelectors);
- void ReadTableCaption(CStorageTable& oTable, std::vector& arSelectors);
- void ReadTableRows(CStorageTable& oTable, std::vector& arSelectors, ERowParseMode eMode);
- void ReadTableColspan(CStorageTable& oTable);
-
- void GetSubClass(std::vector& arSelectors);
+ bool ReadTable(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors);
};
}
diff --git a/HtmlFile2/Table.cpp b/HtmlFile2/Table.cpp
index 7d3f3d260d..c801f80968 100644
--- a/HtmlFile2/Table.cpp
+++ b/HtmlFile2/Table.cpp
@@ -1,16 +1,12 @@
#include "Table.h"
#include "Common.h"
-#include "src/StringFinder.h"
+#include "src/CCompiledStyle.h"
namespace HTML
{
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
-#define RELEASE_VECTOR_PTR(vector_object, object_type) \
- for (object_type* pElement : vector_object) \
- RELEASEOBJECT(pElement)
-
#define FIRST_ELEMENT 0x00000001
#define LAST_ELEMENT 0x00000002
#define MID_ELEMENT 0x00000004
@@ -26,342 +22,323 @@ namespace HTML
#define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips
#define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips
-TTableRowStyle::TTableRowStyle()
- : m_unMaxIndex(0), m_unMaxHeight(0), m_bIsHeader(false)
+// const TTableCellStyle* CStorageTable::GetColStyle(UINT unColumnNumber) const
+// {
+// if (m_arColgroups.empty())
+// return NULL;
+
+// UINT unCurrentNumber = 0;
+
+// for (const CTableColgroup* pColgroup : m_arColgroups)
+// {
+// for (const CTableCol* pCol : pColgroup->GetCols())
+// {
+// unCurrentNumber += pCol->GetSpan();
+
+// if (unCurrentNumber >= unColumnNumber)
+// return pCol->GetStyle();
+// }
+// }
+
+// return NULL;
+// }
+
+// void CStorageTable::AddColgroup(CTableColgroup* pElement)
+// {
+// if (NULL != pElement)
+// m_arColgroups.push_back(pElement);
+// }
+
+// void CStorageTable::RecalculateMaxColumns()
+// {
+// for (const std::vector& arHeaders : m_arHeaders)
+// for (const CStorageTableRow* pHeader : arHeaders)
+// m_unMaxColumns = std::max(m_unMaxColumns, pHeader->GetIndex());
+
+// for (const CStorageTableRow* pRow : m_arRows)
+// m_unMaxColumns = std::max(m_unMaxColumns, pRow->GetIndex());
+
+// for (const CStorageTableRow* pFoother : m_arFoother)
+// m_unMaxColumns = std::max(m_unMaxColumns, pFoother->GetIndex());
+// }
+
+// void CStorageTable::Shorten()
+// {
+// UINT unIndex = 0;
+// CStorageTableCell* pCell = NULL;
+
+// UINT unMaxIndex = 0; //Максимальный индекс без учета строк, где имеется только 1 ячейка
+
+// for (const CStorageTableRow* pRow : m_arRows)
+// {
+// if (1 < pRow->GetCount())
+// unMaxIndex = std::max(unMaxIndex, pRow->GetIndex());
+// }
+
+// while (unIndex < m_arMinColspan.size())
+// {
+// for (CStorageTableRow* pRow : m_arRows)
+// {
+// if (0 != unMaxIndex && 1 == pRow->GetCount() && pRow->GetIndex() > unMaxIndex)
+// {
+// pCell = (*pRow)[unIndex];
+
+// if (NULL == pCell)
+// continue;
+
+// pCell->SetColspan(unMaxIndex, MAXCOLUMNSINTABLE);
+// continue;
+// }
+
+// if (1 == m_arMinColspan[unIndex])
+// break;
+
+// pCell = (*pRow)[unIndex];
+
+// if (NULL == pCell)
+// continue;
+
+// if (1 < pCell->GetColspan() && pCell->GetColspan() > m_arMinColspan[unIndex])
+// {
+// pCell->SetColspan(m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
+// continue;
+// }
+
+// if ((*pRow)[unIndex]->GetColspan() == m_arMinColspan[unIndex] + 1)
+// (*pRow)[unIndex]->SetColspan(2, MAXCOLUMNSINTABLE);
+// else if ((*pRow)[unIndex]->GetColspan() > m_arMinColspan[unIndex])
+// (*pRow)[unIndex]->SetColspan((*pRow)[unIndex]->GetColspan() - m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
+// }
+
+// ++unIndex;
+// }
+// }
+
+
+CTableElementCell::CTableElementCell(bool bIsFilling)
+ : m_eType{(bIsFilling) ? ETableElement::FillingCell : ETableElement::Cell}
{}
-bool TTableRowStyle::Empty() const
-{
- return 0 == m_unMaxHeight && false == m_bIsHeader;
-}
-
-TTableCellStyle::TTableCellStyle()
+CTableElementCell::~CTableElementCell()
{}
-bool TTableCellStyle::Empty()
+ETableElement CTableElementCell::GetType() const
{
- return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsVAlign.empty() && m_wsVAlign.empty();
+ return m_eType;
}
-void TTableCellStyle::Copy(const TTableCellStyle* pTableCellStyle)
+void CTableElementCell::IsFlatTable()
{
- if (NULL == pTableCellStyle)
- return;
-
- m_oWidth = pTableCellStyle->m_oWidth;
- m_oHeight = pTableCellStyle->m_oHeight;
- m_oBorder = pTableCellStyle->m_oBorder;
- m_oPadding = pTableCellStyle->m_oPadding;
- m_oBackground = pTableCellStyle->m_oBackground;
-
- m_wsHAlign = pTableCellStyle->m_wsHAlign;
- m_wsVAlign = pTableCellStyle->m_wsVAlign;
+ m_eType = ETableElement::FlatTable;
}
-TTableCellStyle& TTableCellStyle::operator+=(const TTableCellStyle* pCellStyle)
-{
- if (NULL == pCellStyle)
- return *this;
-
- m_oWidth += pCellStyle->m_oWidth;
- m_oHeight += pCellStyle->m_oHeight;
- m_oBorder += pCellStyle->m_oBorder;
- m_oPadding += pCellStyle->m_oPadding;
- m_oBackground += pCellStyle->m_oBackground;
-
- if (m_wsHAlign.empty())
- m_wsHAlign = pCellStyle->m_wsHAlign;
-
- if (m_wsVAlign.empty())
- m_wsVAlign = pCellStyle->m_wsVAlign;
-
- return *this;
-}
-
-CStorageTableCell::CStorageTableCell()
- : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false), m_oData(30)
+CTableMatrix::CTableMatrix()
{}
-CStorageTableCell::CStorageTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty)
- : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged),
- m_bIsEmpty(bIsEmpty)
-{}
-
-CStorageTableCell::CStorageTableCell(CStorageTableCell& oCell)
- : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged),
- m_bIsEmpty(oCell.m_bIsEmpty), m_oStyles(oCell.m_oStyles)
+CTableMatrix::~CTableMatrix()
{
- WriteToStringBuilder(oCell.m_oData, m_oData);
-}
-
-bool CStorageTableCell::Empty() const
-{
- return m_bIsEmpty;
-}
-
-bool CStorageTableCell::Merged() const
-{
- return m_bIsMerged;
-}
-
-CStorageTableCell* CStorageTableCell::Copy()
-{
- return new CStorageTableCell(*this);
-}
-
-CStorageTableCell* CStorageTableCell::CreateEmpty(UINT unColspan, bool m_bIsMerged, const TTableCellStyle* pStyle)
-{
- CStorageTableCell *pCell = new CStorageTableCell(unColspan, 1, m_bIsMerged, true);
-
- pCell->m_oStyles.Copy(pStyle);
-
- return pCell;
-}
-
-CStorageTableCell* CStorageTableCell::CreateEmpty(const TTableCellStyle* pStyle)
-{
- CStorageTableCell *pCell = new CStorageTableCell(1, 1, false, true);
-
- pCell->m_oStyles.Copy(pStyle);
-
- return pCell;
-}
-
-void CStorageTableCell::SetColspan(UINT unColspan, UINT unCurrentIndex)
-{
- if (MAXCOLUMNSINTABLE - 1 != unCurrentIndex)
- m_unColspan = std::min(MAXCOLUMNSINTABLE - 1 - unCurrentIndex, unColspan);
- else
- m_unColspan = 1;
-}
-
-UINT CStorageTableCell::GetColspan() const
-{
- return m_unColspan;
-}
-
-void CStorageTableCell::SetRowspan(UINT unRowspan)
-{
- m_unRowSpan = unRowspan;
-}
-
-UINT CStorageTableCell::GetRowspan() const
-{
- return m_unRowSpan;
-}
-
-NSStringUtils::CStringBuilder* CStorageTableCell::GetData()
-{
- return &m_oData;
-}
-
-const TTableCellStyle* CStorageTableCell::GetStyles() const
-{
- return &m_oStyles;
-}
-
-TTableCellStyle* CStorageTableCell::GetStyles()
-{
- return &m_oStyles;
-}
-
-void CStorageTableCell::SetWidth(const NSCSS::NSProperties::CDigit& oWidth)
-{
- m_oStyles.m_oWidth = oWidth;
-}
-
-void CStorageTableCell::SetHeight(const NSCSS::NSProperties::CDigit& oHeight)
-{
- m_oStyles.m_oHeight = oHeight;
-}
-
-UINT CStorageTableCell::GetWidth() const
-{
- return m_oStyles.m_oWidth.ToInt(NSCSS::Twips, DEFAULT_PAGE_WIDTH);
-}
-
-UINT CStorageTableCell::GetHeight() const
-{
- return m_oStyles.m_oHeight.ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT);
-}
-
-void CStorageTableCell::SetBorder(const NSCSS::NSProperties::CBorder& oBorder)
-{
- m_oStyles.m_oBorder = oBorder;
-}
-
-void CStorageTableCell::ClearTopBorder()
-{
- m_oStyles.m_oBorder.SetTopSide(L"none", 0, true);
-}
-
-void CStorageTableCell::ClearLeftBorder()
-{
- m_oStyles.m_oBorder.SetLeftSide(L"none", 0, true);
-}
-
-void CStorageTableCell::ClearBottomBorder()
-{
- m_oStyles.m_oBorder.SetBottomSide(L"none", 0, true);
-}
-
-void CStorageTableCell::ClearRightBorder()
-{
- m_oStyles.m_oBorder.SetRightSide(L"none", 0, true);
-}
-
-void CStorageTableCell::SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
-{
- m_oStyles.m_oPadding = oPadding;
-}
-
-void CStorageTableCell::SetHAlign(const std::wstring& wsAlign)
-{
- m_oStyles.m_wsHAlign = wsAlign;
-}
-
-void CStorageTableCell::SetVAlign(const std::wstring& wsAlign)
-{
- m_oStyles.m_wsVAlign = wsAlign;
-}
-
-void CStorageTableCell::SetBackground(const NSCSS::NSProperties::CColor& oColor)
-{
- m_oStyles.m_oBackground = oColor;
-}
-
-CStorageTableRow::CStorageTableRow()
-{}
-
-CStorageTableRow::~CStorageTableRow()
-{
- for (CStorageTableCell* pCell : m_arCells)
- RELEASEOBJECT(pCell);
-}
-
-void CStorageTableRow::AddCell(CStorageTableCell* pCell)
-{
- InsertCell(pCell, -1);
-}
-
-void CStorageTableRow::InsertCell(CStorageTableCell* pCell, int nPosition)
-{
- if (NULL == pCell)
- return;
-
- if (nPosition < 0)
+ for (Row& oRow : m_arCells)
{
- std::vector::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CStorageTableCell* pCell) { return pCell->Empty() && !pCell->Merged(); });
-
- if (m_arCells.end() != itFoundEmpty)
+ for (ITableElementCell* pCell : oRow)
{
- --m_oStyles.m_unMaxIndex;
- delete *itFoundEmpty;
- *itFoundEmpty = pCell;
-
- if (1 != pCell->GetColspan())
- {
- ++itFoundEmpty;
- UINT unColspan = pCell->GetColspan() - 1;
-
- while (m_arCells.end() != itFoundEmpty && (*itFoundEmpty)->Empty() && unColspan > 0)
- {
- --m_oStyles.m_unMaxIndex;
- --unColspan;
- delete (*itFoundEmpty);
- itFoundEmpty = m_arCells.erase(itFoundEmpty);
- }
-
- if (unColspan != 0)
- pCell->SetColspan(pCell->GetColspan() - unColspan, MAXCOLUMNSINTABLE);
- }
- }
- else
- m_arCells.push_back(pCell);
- }
- else if (nPosition >= m_arCells.size())
- {
- const UINT unMissingCount = nPosition - m_arCells.size();
-
- for (UINT unIndex = 0; unIndex < unMissingCount; ++unIndex)
- m_arCells.push_back(CStorageTableCell::CreateEmpty());
-
- m_oStyles.m_unMaxIndex += unMissingCount;
-
- m_arCells.push_back(pCell);
- }
- else if (m_arCells[nPosition]->Empty())
- {
- delete m_arCells[nPosition];
- --m_oStyles.m_unMaxIndex;
- m_arCells[nPosition] = pCell;
-
- if (1 != pCell->GetColspan())
- {
- ++nPosition;
- UINT unDeleteCount = pCell->GetColspan() - 1;
- while (nPosition < m_arCells.size() && m_arCells[nPosition]->Empty() && !m_arCells[nPosition]->Merged() && unDeleteCount > 0)
- {
- delete m_arCells[nPosition];
- --m_oStyles.m_unMaxIndex;
- m_arCells.erase(m_arCells.begin() + nPosition);
- --unDeleteCount;
- }
-
- if (0 != unDeleteCount)
- pCell->SetColspan(pCell->GetColspan() - unDeleteCount, MAXCOLUMNSINTABLE);
+ if (nullptr != pCell)
+ delete pCell;
}
}
- else
- m_arCells.insert(m_arCells.begin() + nPosition, pCell);
-
- m_oStyles.m_unMaxIndex += pCell->GetColspan();
-
- if (1 == pCell->GetColspan() && 1 == pCell->GetRowspan())
- m_oStyles.m_unMaxHeight = std::max(m_oStyles.m_unMaxHeight, pCell->GetHeight());
}
-UINT CStorageTableRow::GetIndex() const
-{
- return m_oStyles.m_unMaxIndex;
-}
-
-UINT CStorageTableRow::GetCount() const
-{
- return m_arCells.size();
-}
-
-CStorageTableCell* CStorageTableRow::operator[](UINT unIndex)
-{
- if (unIndex >= m_arCells.size())
- return NULL;
-
- return m_arCells[unIndex];
-}
-
-bool CStorageTableRow::Empty() const
+bool CTableMatrix::Empty() const
{
return m_arCells.empty();
}
-const TTableRowStyle& CStorageTableRow::GetStyles() const
+bool CTableMatrix::SetCell(size_t unRowIndex, size_t unColumnIndex, ITableElementCell* pCell)
{
- return m_oStyles;
+ if (nullptr == pCell)
+ return false;
+
+ if (m_arCells.size() <= unRowIndex)
+ {
+ if (!m_arCells.empty())
+ {
+ const size_t unMaxColumn{m_arCells.back().size()};
+ const size_t unOldSize{m_arCells.size()};
+ m_arCells.resize(unRowIndex + 1);
+
+ for (size_t unIndex = unOldSize; unIndex < m_arCells.size(); ++unIndex)
+ m_arCells[unIndex].resize(unMaxColumn);
+ }
+ else
+ m_arCells.resize(unRowIndex + 1);
+ }
+
+ if (m_arCells[unRowIndex].size() <= unColumnIndex)
+ {
+ m_arCells[unRowIndex].resize(unColumnIndex + 1);
+ m_arCells[unRowIndex][unColumnIndex] = pCell;
+ return true;
+ }
+
+ if (nullptr != m_arCells[unRowIndex][unColumnIndex])
+ delete m_arCells[unRowIndex][unColumnIndex];
+
+ m_arCells[unRowIndex][unColumnIndex] = pCell;
+
+ return true;
}
-const std::vector& CStorageTableRow::GetCells() const
+bool CTableMatrix::IsFillingCell(size_t unRowIndex, size_t unColumnIndex) const
+{
+ if (unRowIndex >= m_arCells.size())
+ return false;
+
+ if (unColumnIndex >= m_arCells[unRowIndex].size())
+ return false;
+
+ return (nullptr != m_arCells[unRowIndex][unColumnIndex]) ? ETableElement::FillingCell == m_arCells[unRowIndex][unColumnIndex]->GetType() : false;
+}
+
+bool CTableMatrix::IsNotNullCell(size_t unRowIndex, size_t unColumnIndex) const
+{
+ if (unRowIndex >= m_arCells.size())
+ return false;
+
+ if (unColumnIndex >= m_arCells[unRowIndex].size())
+ return false;
+
+ return nullptr != m_arCells[unRowIndex][unColumnIndex];
+}
+
+size_t CTableMatrix::GetRowSize() const
+{
+ return m_arCells.size();
+}
+
+size_t CTableMatrix::GetColumnSize() const
+{
+ return (m_arCells.empty()) ? 0 : m_arCells.front().size();
+}
+
+Table& CTableMatrix::GetMatrixCells()
{
return m_arCells;
}
-CTableCol::CTableCol(UINT unSpan)
- : m_unSpan(unSpan)
+const Table& CTableMatrix::GetMatrixCells() const
+{
+ return m_arCells;
+}
+
+const ITableElementCell* CTableMatrix::GetCell(size_t unRowIndex, size_t unColumnIndex) const
+{
+ if (unRowIndex >= m_arCells.size())
+ return nullptr;
+
+ if (unColumnIndex >= m_arCells[unRowIndex].size())
+ return nullptr;
+
+ return m_arCells[unRowIndex][unColumnIndex];
+}
+
+bool TExternalTableData::IsValid() const
+{
+ return true;
+}
+
+CTableElement::CTableElement(TExternalTableData *pExternalData)
+ : m_pCaption(nullptr), m_pExternalData(pExternalData)
{}
-CTableCol::CTableCol(const NSCSS::CNode& oTableColNode)
- : m_unSpan(1)
+CTableElement::~CTableElement()
{
- m_unSpan = NSStringFinder::ToInt(oTableColNode.GetAttributeValue(L"span"));
+ if (nullptr != m_pCaption)
+ delete m_pCaption;
+
+ for (CTableColgroup* pColgroup : m_arColgroups)
+ if (nullptr != pColgroup)
+ delete pColgroup;
+}
+
+ETableElement CTableElement::GetType() const
+{
+ return ETableElement::Table;
+}
+
+bool CTableElement::Empty() const
+{
+ return m_oHeader.Empty() && m_oBody.Empty() && m_oFoother.Empty();
+}
+
+bool CTableElement::HaveCaption() const
+{
+ return nullptr != m_pCaption && 0 != m_pCaption->GetCurSize();
+}
+
+const NSCSS::CCompiledStyle* CTableElement::GetColStyle(size_t unColIndex) const
+{
+ if (m_arColgroups.empty())
+ return nullptr;
+
+ const NSCSS::CCompiledStyle* pColStyle{nullptr};
+ size_t unSkipSpans{0};
+
+ for (const CTableColgroup* pColgroup : m_arColgroups)
+ {
+ pColStyle = pColgroup->GetColStyle(unColIndex - unSkipSpans);
+
+ if (nullptr != pColStyle)
+ return pColStyle;
+
+ unSkipSpans += pColgroup->GetTotalSpans();
+ }
+
+ return nullptr;
+}
+
+bool MoveToNextTableCell(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, std::stack& arDepths, TExternalTableData::FuncGetSubClass& GetSubClass)
+{
+ while (!arDepths.empty() && !oReader.ReadNextSiblingNode2(arDepths.top()))
+ {
+ arDepths.pop();
+ arSelectors.pop_back();
+ }
+
+ if (arDepths.empty())
+ return false;
+
+ do
+ {
+ const std::wstring wsName = oReader.GetName();
+
+ if (L"#text" == wsName || L"colgroup" == wsName || L"caption" == wsName)
+ return MoveToNextTableCell(oReader, arSelectors, arDepths, GetSubClass);
+
+ GetSubClass(oReader, arSelectors);
+
+ if (L"td" == wsName || L"th" == wsName)
+ return true;
+ else if (L"table" == wsName)
+ return false;
+
+ arDepths.push(oReader.GetDepth());
+
+ return MoveToNextTableCell(oReader, arSelectors, arDepths, GetSubClass);
+ }while(oReader.ReadNextSiblingNode2(arDepths.top()));
+
+ return false;
+}
+
+CTableCol::CTableCol(NSCSS::CNode& oTableColNode)
+ : m_pStyle(oTableColNode.m_pCompiledStyle)
+{
+ oTableColNode.m_pCompiledStyle = nullptr;
+ m_unSpan = NSStringFinder::ToInt(oTableColNode.GetAttributeValue(L"span"), 1);
+}
+
+CTableCol::~CTableCol()
+{
+ if (nullptr != m_pStyle)
+ delete m_pStyle;
}
UINT CTableCol::GetSpan() const
@@ -369,25 +346,22 @@ UINT CTableCol::GetSpan() const
return m_unSpan;
}
-TTableCellStyle* CTableCol::GetStyle()
+const NSCSS::CCompiledStyle* CTableCol::GetStyle() const
{
- return &m_oStyle;
+ return m_pStyle;
}
-const TTableCellStyle* CTableCol::GetStyle() const
-{
- return &m_oStyle;
-}
-
-CTableColgroup::CTableColgroup(NSCSS::CNode& oTableColgroupNode)
- : m_unWidth(0)
+CTableColgroup::CTableColgroup(const NSCSS::CNode& oTableColgroupNode)
+ : m_unTotalSpans(0)
{
m_unWidth = NSStringFinder::ToInt(oTableColgroupNode.GetAttributeValue(L"width"), 0);
}
CTableColgroup::~CTableColgroup()
{
- RELEASE_VECTOR_PTR(m_arCols, CTableCol)
+ for (CTableCol* pCol : m_arCols)
+ if (nullptr != pCol)
+ delete pCol;
}
bool CTableColgroup::Empty() const
@@ -397,8 +371,16 @@ bool CTableColgroup::Empty() const
void CTableColgroup::AddCol(CTableCol* pCol)
{
- if (NULL != pCol)
- m_arCols.push_back(pCol);
+ if (nullptr == pCol)
+ return;
+
+ m_arCols.push_back(pCol);
+ m_unTotalSpans += pCol->GetSpan();
+}
+
+UINT CTableColgroup::GetTotalSpans() const
+{
+ return m_unTotalSpans;
}
const std::vector& CTableColgroup::GetCols() const
@@ -406,310 +388,20 @@ const std::vector& CTableColgroup::GetCols() const
return m_arCols;
}
-TTableStyles::TTableStyles()
- : m_nCellSpacing(-1), m_enRules(None)
-{}
-
-bool TTableStyles::Empty() const
+const NSCSS::CCompiledStyle* CTableColgroup::GetColStyle(size_t unIndex) const
{
- return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && m_wsAlign.empty();
-}
+ if (m_arCols.empty())
+ return nullptr;
-CStorageTable::CStorageTable()
- : m_unMaxColumns(0)
-{}
-
-CStorageTable::~CStorageTable()
-{
- for (std::vector& arHeaders : m_arHeaders)
- RELEASE_VECTOR_PTR(arHeaders, CStorageTableRow)
-
- RELEASE_VECTOR_PTR(m_arFoother, CStorageTableRow)
- RELEASE_VECTOR_PTR(m_arRows, CStorageTableRow)
- RELEASE_VECTOR_PTR(m_arColgroups, CTableColgroup)
-}
-
-CStorageTableRow* CStorageTable::operator[](UINT unIndex)
-{
- if (unIndex < m_arRows.size())
- return m_arRows[unIndex];
-
- return NULL;
-}
-
-bool CStorageTable::Empty() const
-{
- return m_arHeaders.empty() && m_arRows.empty() && m_arFoother.empty();
-}
-
-bool CStorageTable::HaveCaption()
-{
- return 0 != m_oCaption.GetCurSize();
-}
-
-bool CStorageTable::HaveColgroups() const
-{
- return !m_arColgroups.empty();
-}
-
-bool CStorageTable::HaveHeader() const
-{
- return !m_arHeaders.empty();
-}
-
-UINT CStorageTable::GetRowCount() const
-{
- return m_arRows.size();
-}
-
-const TTableStyles& CStorageTable::GetTableStyles() const
-{
- return m_oStyles;
-}
-
-const TTableCellStyle* CStorageTable::GetColStyle(UINT unColumnNumber) const
-{
- if (m_arColgroups.empty())
- return NULL;
-
- UINT unCurrentNumber = 0;
-
- for (const CTableColgroup* pColgroup : m_arColgroups)
+ size_t unCurrentIndex{0};
+ for (const CTableCol* pCol : m_arCols)
{
- for (const CTableCol* pCol : pColgroup->GetCols())
- {
- unCurrentNumber += pCol->GetSpan();
+ if (unCurrentIndex <= unIndex && (unCurrentIndex + pCol->GetSpan()) > unIndex)
+ return pCol->GetStyle();
- if (unCurrentNumber >= unColumnNumber)
- return pCol->GetStyle();
- }
+ unCurrentIndex += pCol->GetSpan();
}
- return NULL;
+ return nullptr;
}
-
-void CStorageTable::AddRows(std::vector& arRows, ERowParseMode eParseMode)
-{
- if (arRows.empty())
- return;
-
- if (ERowParseMode::Foother == eParseMode && !m_arFoother.empty())
- eParseMode = ERowParseMode::Header;
-
- if (ERowParseMode::Header == eParseMode)
- m_arHeaders.push_back({});
-
- for (CStorageTableRow* pRow : arRows)
- AddRow(pRow, eParseMode);
-}
-
-void CStorageTable::AddRow(CStorageTableRow* pRow, ERowParseMode eParseMode)
-{
- if (NULL == pRow)
- return;
-
- for (UINT unIndex = 0; unIndex < pRow->GetCount(); ++unIndex)
- {
- if (unIndex >= m_arMinColspan.size())
- m_arMinColspan.push_back((*pRow)[unIndex]->GetColspan());
- else if ((*pRow)[unIndex]->GetColspan() < m_arMinColspan[unIndex])
- m_arMinColspan[unIndex] = (*pRow)[unIndex]->GetColspan();
- }
-
- switch (eParseMode)
- {
- default:
- case ERowParseMode::Body:
- {
- m_arRows.push_back(pRow);
- break;
- }
- case ERowParseMode::Header:
- {
- if (m_arHeaders.empty())
- m_arHeaders.push_back({});
-
- m_arHeaders.back().push_back(pRow);
- break;
- }
- case ERowParseMode::Foother:
- {
- m_arFoother.push_back(pRow);
- break;
- }
- }
-}
-
-NSStringUtils::CStringBuilder* CStorageTable::GetCaptionData()
-{
- return &m_oCaption;
-}
-
-void CStorageTable::SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
-{
- m_oStyles.m_oPadding = oPadding;
-}
-
-const NSCSS::NSProperties::CIndent& CStorageTable::GetPadding() const
-{
- return m_oStyles.m_oPadding;
-}
-
-void CStorageTable::SetMargin(const NSCSS::NSProperties::CIndent& oMargin)
-{
- m_oStyles.m_oMargin = oMargin;
-}
-
-void CStorageTable::SetBorder(const NSCSS::NSProperties::CBorder& oBorder)
-{
- m_oStyles.m_oBorder = oBorder;
-}
-
-void CStorageTable::SetWidth(const NSCSS::NSProperties::CDigit& oWidth)
-{
- m_oStyles.m_oWidth = oWidth;
-}
-
-void CStorageTable::SetCellSpacing(int nCellSpacing)
-{
- m_oStyles.m_nCellSpacing = nCellSpacing;
-}
-
-void CStorageTable::SetAlign(const std::wstring& wsValue)
-{
- m_oStyles.m_wsAlign = wsValue;
-}
-
-void CStorageTable::SetRules(const std::wstring& wsValue)
-{
- if (wsValue.empty())
- return;
-
- if (NSStringFinder::Equals(wsValue, L"all"))
- m_oStyles.m_enRules = TTableStyles::ETableRules::All;
- else if (NSStringFinder::Equals(wsValue, L"groups"))
- m_oStyles.m_enRules = TTableStyles::ETableRules::Groups;
- else if (NSStringFinder::Equals(wsValue, L"cols"))
- m_oStyles.m_enRules = TTableStyles::ETableRules::Cols;
- else if (NSStringFinder::Equals(wsValue, L"none"))
- m_oStyles.m_enRules = TTableStyles::ETableRules::None;
- else if (NSStringFinder::Equals(wsValue, L"rows"))
- m_oStyles.m_enRules = TTableStyles::ETableRules::Rows;
-}
-
-void CStorageTable::AddColgroup(CTableColgroup* pElement)
-{
- if (NULL != pElement)
- m_arColgroups.push_back(pElement);
-}
-
-void CStorageTable::RecalculateMaxColumns()
-{
- for (const std::vector& arHeaders : m_arHeaders)
- for (const CStorageTableRow* pHeader : arHeaders)
- m_unMaxColumns = std::max(m_unMaxColumns, pHeader->GetIndex());
-
- for (const CStorageTableRow* pRow : m_arRows)
- m_unMaxColumns = std::max(m_unMaxColumns, pRow->GetIndex());
-
- for (const CStorageTableRow* pFoother : m_arFoother)
- m_unMaxColumns = std::max(m_unMaxColumns, pFoother->GetIndex());
-}
-
-void CStorageTable::Shorten()
-{
- UINT unIndex = 0;
- CStorageTableCell* pCell = NULL;
-
- UINT unMaxIndex = 0; //Максимальный индекс без учета строк, где имеется только 1 ячейка
-
- for (const CStorageTableRow* pRow : m_arRows)
- {
- if (1 < pRow->GetCount())
- unMaxIndex = std::max(unMaxIndex, pRow->GetIndex());
- }
-
- while (unIndex < m_arMinColspan.size())
- {
- for (CStorageTableRow* pRow : m_arRows)
- {
- if (0 != unMaxIndex && 1 == pRow->GetCount() && pRow->GetIndex() > unMaxIndex)
- {
- pCell = (*pRow)[unIndex];
-
- if (NULL == pCell)
- continue;
-
- pCell->SetColspan(unMaxIndex, MAXCOLUMNSINTABLE);
- continue;
- }
-
- if (1 == m_arMinColspan[unIndex])
- break;
-
- pCell = (*pRow)[unIndex];
-
- if (NULL == pCell)
- continue;
-
- if (1 < pCell->GetColspan() && pCell->GetColspan() > m_arMinColspan[unIndex])
- {
- pCell->SetColspan(m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
- continue;
- }
-
- if ((*pRow)[unIndex]->GetColspan() == m_arMinColspan[unIndex] + 1)
- (*pRow)[unIndex]->SetColspan(2, MAXCOLUMNSINTABLE);
- else if ((*pRow)[unIndex]->GetColspan() > m_arMinColspan[unIndex])
- (*pRow)[unIndex]->SetColspan((*pRow)[unIndex]->GetColspan() - m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
- }
-
- ++unIndex;
- }
-}
-
-void CStorageTable::CompleteTable()
-{
- UINT unMaxIndex = 0;
-
- for (CStorageTableRow* pRow : m_arRows)
- unMaxIndex = std::max(unMaxIndex, pRow->GetIndex());
-
- for (CStorageTableRow* pRow : m_arRows)
- {
- if (NULL == pRow || 0 == pRow->GetCount())
- continue;
-
- for (UINT unIndex = pRow->GetIndex(); unIndex < unMaxIndex; ++unIndex)
- pRow->InsertCell(CStorageTableCell::CreateEmpty(), unIndex);
- }
-
- RecalculateMaxColumns();
-}
-
-const std::vector>& CStorageTable::GetHeaders() const
-{
- return m_arHeaders;
-}
-
-const std::vector& CStorageTable::GetFoothers() const
-{
- return m_arFoother;
-}
-
-const std::vector& CStorageTable::GetRows() const
-{
- return m_arRows;
-}
-
-const std::vector CStorageTable::GetColgroups() const
-{
- return m_arColgroups;
-}
-
-UINT CStorageTable::GetMaxColumns() const
-{
- return m_unMaxColumns;
-}
-
}
diff --git a/HtmlFile2/Table.h b/HtmlFile2/Table.h
index b3c828ece6..b8b6f51c50 100644
--- a/HtmlFile2/Table.h
+++ b/HtmlFile2/Table.h
@@ -2,9 +2,13 @@
#define TABLE_H
#include "../DesktopEditor/common/StringBuilder.h"
-#include "../Common/3dParty/html/css/src/StyleProperties.h"
-#include "../Common/3dParty/html/css/src/CNode.h"
+#include "../DesktopEditor/xml/include/xmlutils.h"
+#include "../Common/3dParty/html/css/src/CCssCalculator.h"
+#include "Writers/IWriter.h"
+#include "src/StringFinder.h"
+
+#include
#include
namespace HTML
@@ -12,244 +16,260 @@ namespace HTML
#define MAXCOLUMNSINTABLE 63
#define MAXROWSINTABLE 32767
-enum class ERowParseMode
+struct TCurentTablePosition
{
- Header,
- Body,
- Foother
+ size_t m_unRowIndex{0};
+ size_t m_unColumnIndex{0};
+
+ size_t m_unStartRowIndex{0};
+ size_t m_unStartColumnIndex{0};
};
-enum class ERowPosition
+
+enum class ETableElement
{
- First,
- Middle,
- Last
+ FillingCell,
+ Cell,
+ FlatTable,
+ Table
};
-struct TTableRowStyle
-{
- UINT m_unMaxIndex;
- UINT m_unMaxHeight;
- bool m_bIsHeader;
-
- TTableRowStyle();
-
- bool Empty() const;
-};
-
-struct TTableCellStyle
-{
- NSCSS::NSProperties::CDigit m_oWidth;
- NSCSS::NSProperties::CDigit m_oHeight;
- NSCSS::NSProperties::CBorder m_oBorder;
- NSCSS::NSProperties::CIndent m_oPadding;
- NSCSS::NSProperties::CColor m_oBackground;
-
- std::wstring m_wsHAlign;
- std::wstring m_wsVAlign;
-
- TTableCellStyle();
-
- bool Empty();
- void Copy(const TTableCellStyle* pTableCellStyle);
-
- TTableCellStyle& operator+=(const TTableCellStyle* pCellStyle);
-};
-
-class CStorageTable;
-
-class CStorageTableCell
+class ITableElementCell
{
public:
- CStorageTableCell();
- CStorageTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty);
- CStorageTableCell(CStorageTableCell& oCell);
+ ITableElementCell() = default;
+ virtual ~ITableElementCell() = default;
- bool Empty() const;
- bool Merged() const;
-
- CStorageTableCell* Copy();
-
- static CStorageTableCell* CreateEmpty(UINT unColspan = 1, bool m_bIsMerged = false, const TTableCellStyle* pStyle = NULL);
- static CStorageTableCell* CreateEmpty(const TTableCellStyle* pStyle);
-
- void SetColspan(UINT unColspan, UINT unCurrentIndex);
- UINT GetColspan() const;
-
- void SetRowspan(UINT unRowspan);
- UINT GetRowspan() const;
-
- NSStringUtils::CStringBuilder* GetData();
-
- const TTableCellStyle* GetStyles() const;
- TTableCellStyle* GetStyles();
-
- void SetWidth(const NSCSS::NSProperties::CDigit& oWidth);
- void SetHeight(const NSCSS::NSProperties::CDigit& oHeight);
-
- UINT GetWidth() const;
- UINT GetHeight() const;
-
- void SetBorder(const NSCSS::NSProperties::CBorder& oBorder);
-
- void ClearTopBorder();
- void ClearLeftBorder();
- void ClearBottomBorder();
- void ClearRightBorder();
-
- void SetPadding(const NSCSS::NSProperties::CIndent& oPadding);
- void SetHAlign(const std::wstring& wsAlign);
- void SetVAlign(const std::wstring& wsAlign);
- void SetBackground(const NSCSS::NSProperties::CColor& oColor);
-private:
- UINT m_unColspan;
- UINT m_unRowSpan;
-
- bool m_bIsMerged;
- bool m_bIsEmpty;
-
- TTableCellStyle m_oStyles;
- NSStringUtils::CStringBuilder m_oData;
+ virtual ETableElement GetType() const = 0;
};
-class CStorageTableRow
+class CTableElementCell : public ITableElementCell
+{
+ ETableElement m_eType;
+public:
+ CTableElementCell(bool bIsFilling = false);
+ virtual ~CTableElementCell();
+
+ ETableElement GetType() const override;
+
+ void IsFlatTable();
+};
+
+class ITag;
+class IWriter;
+
+struct TExternalTableData
+{
+ typedef std::function& arSelectors)> FuncReadStream;
+ typedef std::function& arSelectors)> FuncGetSubClass;
+
+ FuncReadStream ReadStream;
+ FuncGetSubClass GetSubClass;
+
+ IWriter* m_pWriter{nullptr};
+
+ bool IsValid() const;
+};
+
+typedef std::vector Row;
+typedef std::vector Table;
+
+class IWriter;
+
+class CTableMatrix
{
public:
- CStorageTableRow();
- ~CStorageTableRow();
-
- void AddCell(CStorageTableCell* pCell);
- void InsertCell(CStorageTableCell *pCell, int nPosition);
-
- UINT GetIndex() const;
- UINT GetCount() const;
-
- CStorageTableCell* operator[](UINT unIndex);
+ CTableMatrix();
+ virtual ~CTableMatrix();
bool Empty() const;
- const TTableRowStyle& GetStyles() const;
- const std::vector& GetCells() const;
-private:
- TTableRowStyle m_oStyles;
- std::vector m_arCells;
+
+ bool SetCell(size_t unRowIndex, size_t unColumnIndex, ITableElementCell* pCell);
+
+ bool IsFillingCell(size_t unRowIndex, size_t unColumnIndex) const;
+ bool IsNotNullCell(size_t unRowIndex, size_t unColumnIndex) const;
+
+ size_t GetRowSize() const;
+ size_t GetColumnSize() const;
+
+ const Table& GetMatrixCells() const;
+ Table& GetMatrixCells();
+ const ITableElementCell* GetCell(size_t unRowIndex, size_t unColumnIndex) const;
+protected:
+ Table m_arCells;
};
class CTableCol
{
public:
- CTableCol(UINT unSpan);
- CTableCol(const NSCSS::CNode& oTableColNode);
+ CTableCol(NSCSS::CNode& oTableColNode);
+ ~CTableCol();
UINT GetSpan() const;
- TTableCellStyle* GetStyle();
- const TTableCellStyle* GetStyle() const;
+ const NSCSS::CCompiledStyle* GetStyle() const;
private:
UINT m_unSpan;
- TTableCellStyle m_oStyle;
+ NSCSS::CCompiledStyle* m_pStyle;
};
class CTableColgroup
{
public:
- CTableColgroup(NSCSS::CNode& oTableColgroupNode);
+ CTableColgroup(const NSCSS::CNode& oTableColgroupNode);
~CTableColgroup();
bool Empty() const;
void AddCol(CTableCol* pCol);
+ UINT GetTotalSpans() const;
const std::vector& GetCols() const;
+ const NSCSS::CCompiledStyle* GetColStyle(size_t unIndex) const;
private:
std::vector m_arCols;
UINT m_unWidth;
+ UINT m_unTotalSpans;
};
-//Необходимые стили таблицы
-struct TTableStyles
-{
- NSCSS::NSProperties::CIndent m_oPadding;
- NSCSS::NSProperties::CIndent m_oMargin;
- NSCSS::NSProperties::CBorder m_oBorder;
- NSCSS::NSProperties::CDigit m_oWidth;
-
- int m_nCellSpacing;
-
- std::wstring m_wsAlign;
-
- enum ETableRules
- {
- All,
- Groups,
- Cols,
- None,
- Rows
- } m_enRules;
-
- TTableStyles();
-
- bool Empty() const;
-};
-
-class CStorageTable
+class CTableElement : public ITableElementCell
{
+protected:
+ CTableElement(TExternalTableData *pExternalData);
public:
- CStorageTable();
- ~CStorageTable();
+ virtual ~CTableElement();
- CStorageTableRow* operator[](UINT unIndex);
+ ETableElement GetType() const override;
bool Empty() const;
- bool HaveCaption();
- bool HaveColgroups() const;
- bool HaveHeader() const;
- UINT GetRowCount() const;
- const TTableStyles& GetTableStyles() const;
- const TTableCellStyle* GetColStyle(UINT unColumnNumber) const;
+ bool HaveCaption() const;
- void AddRows(std::vector& m_arRows, ERowParseMode eParseMode = ERowParseMode::Body);
- void AddRow(CStorageTableRow* pRow, ERowParseMode eParseMode = ERowParseMode::Body);
+ virtual bool PreParse(XmlUtils::CXmlLiteReader& oReader) = 0;
+ virtual void Normalize() = 0;
+ virtual bool Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& oTableNode) = 0;
+protected:
+ CTableMatrix m_oHeader;
+ CTableMatrix m_oBody;
+ CTableMatrix m_oFoother;
- NSStringUtils::CStringBuilder* GetCaptionData();
-
- void SetPadding(const NSCSS::NSProperties::CIndent& oPadding);
- const NSCSS::NSProperties::CIndent& GetPadding() const;
-
- void SetMargin(const NSCSS::NSProperties::CIndent& oMargin);
- void SetBorder(const NSCSS::NSProperties::CBorder& oBorder);
-
- void SetWidth(const NSCSS::NSProperties::CDigit& oWidth);
- void SetCellSpacing(int nCellSpacing);
- void SetAlign(const std::wstring& wsValue);
- void SetRules(const std::wstring& wsValue);
-
- void AddColgroup(CTableColgroup* pElement);
-
- void RecalculateMaxColumns();
- void Shorten();
- void CompleteTable();
-
- //TODO:: переделать на const std::vector Get...() const;
- const std::vector>& GetHeaders() const;
- const std::vector& GetFoothers() const;
- const std::vector& GetRows() const;
- const std::vector GetColgroups() const;
-
- UINT GetMaxColumns() const;
-private:
- std::vector> m_arHeaders;
- std::vector m_arFoother;
- std::vector m_arRows;
-
- std::vector m_arMinColspan;
-
- NSStringUtils::CStringBuilder m_oCaption;
+ XmlString *m_pCaption;
std::vector m_arColgroups;
- TTableStyles m_oStyles;
+ TExternalTableData *m_pExternalData;
- UINT m_unMaxColumns;
+ const NSCSS::CCompiledStyle* GetColStyle(size_t unColIndex) const;
+
+ virtual bool ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption) = 0;
+ virtual bool ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vector& arColgroups) = 0;
+ template
+ inline bool ParseTable(XmlUtils::CXmlLiteReader& oReader, T* pTable);
+ template
+ inline bool ParseMatrix(XmlUtils::CXmlLiteReader& oReader, CTableMatrix* pMatrix, size_t& unRowIndex, size_t& unColumnIndex, size_t& unMaxColumns);
};
+
+template
+inline bool CTableElement::ParseTable(XmlUtils::CXmlLiteReader& oReader, T* pTable)
+{
+ const int nDeath{oReader.GetDepth()};
+ std::wstring wsName;
+
+ while(oReader.ReadNextSiblingNode(nDeath))
+ {
+ wsName = oReader.GetName();
+
+ size_t unRowIndex{0}, unColumnIndex{0}, unMaxColumnIndex{0};
+
+ if(L"thead" == wsName)
+ ParseMatrix(oReader, &pTable->m_oHeader, unRowIndex, unColumnIndex, unMaxColumnIndex);
+ if(L"tbody" == wsName)
+ ParseMatrix(oReader, &pTable->m_oBody, unRowIndex, unColumnIndex, unMaxColumnIndex);
+ else if(L"tfoot" == wsName)
+ ParseMatrix(oReader, &pTable->m_oFoother, unRowIndex, unColumnIndex, unMaxColumnIndex);
+ else if (L"caption" == wsName)
+ ParseCaption(oReader, pTable->m_pCaption);
+ else if (L"colgroup" == wsName)
+ ParseColgroup(oReader, pTable->m_arColgroups);
+ }
+
+ return true;
+}
+
+template
+inline bool CTableElement::ParseMatrix(XmlUtils::CXmlLiteReader& oReader, CTableMatrix* pMatrix, size_t& unRowIndex, size_t& unColumnIndex, size_t& unMaxColumns)
+{
+ const std::wstring wsElementName{oReader.GetName()};
+
+ if (L"table" == wsElementName)
+ {
+ T* pNewTable{new T(m_pExternalData)};
+
+ if (nullptr == pNewTable)
+ return false;
+
+ pMatrix->SetCell(unRowIndex - 1, unColumnIndex - 1, pNewTable);
+
+ ParseTable(oReader, pNewTable);
+ }
+ else if (L"tr" == wsElementName)
+ {
+ const int nDepth{oReader.GetDepth()};
+ ++unRowIndex;
+ unColumnIndex = 0;
+
+ while (oReader.ReadNextSiblingNode(nDepth))
+ {
+ if (L"td" != oReader.GetName() && L"th" != oReader.GetName())
+ continue;
+
+ ParseMatrix(oReader, pMatrix, unRowIndex, unColumnIndex, unMaxColumns);
+ }
+ }
+ else if (L"td" == wsElementName || L"th" == wsElementName)
+ {
+ ++unColumnIndex;
+
+ while (pMatrix->IsFillingCell(unRowIndex - 1, unColumnIndex - 1))
+ ++unColumnIndex;
+
+ unMaxColumns = (std::max)(unMaxColumns, unColumnIndex);
+
+ if (!pMatrix->SetCell(unRowIndex - 1, unColumnIndex - 1, new CTableElementCell()))
+ return false;
+
+ if (oReader.MoveToFirstAttribute())
+ {
+ do
+ {
+ if (L"rowspan" == oReader.GetName())
+ {
+ const int nRowSpan{NSStringFinder::ToInt(oReader.GetText(), 1)};
+
+ for (int nRow = 1; nRow < nRowSpan; ++nRow)
+ pMatrix->SetCell(unRowIndex + nRow - 1, unColumnIndex - 1, new CTableElementCell(true));
+ }
+ else if (L"colspan" == oReader.GetName())
+ unColumnIndex += NSStringFinder::ToInt(oReader.GetText(), 1) - 1;
+ }while (oReader.MoveToNextAttribute());
+ oReader.MoveToElement();
+ }
+
+ const int nDepth{oReader.GetDepth()};
+ while (oReader.ReadNextSiblingNode(nDepth))
+ ParseMatrix(oReader, pMatrix, unRowIndex, unColumnIndex, unMaxColumns);
+ }
+ else if (oReader.IsEmptyNode())
+ return false;
+ else
+ {
+ const int nDepth{oReader.GetDepth()};
+ while (oReader.ReadNextSiblingNode(nDepth))
+ ParseMatrix(oReader, pMatrix, unRowIndex, unColumnIndex, unMaxColumns);
+ }
+
+ return true;
+}
+
+bool MoveToNextTableCell(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, std::stack& arDepths, TExternalTableData::FuncGetSubClass& GetSubClass);
}
#endif // TABLE_H
diff --git a/HtmlFile2/Tags/HTMLTags.h b/HtmlFile2/Tags/HTMLTags.h
index a7a1a48e2f..7d4b80c469 100644
--- a/HtmlFile2/Tags/HTMLTags.h
+++ b/HtmlFile2/Tags/HTMLTags.h
@@ -6,6 +6,13 @@
namespace HTML
{
+// TODO:: думаю лучше перейти на интерфейсы к каждой ноде
+// ISVGTag -> CMarkdownSVGTag
+// -> COOXMLSVGTag
+// Либо
+// template CSVGTag -> template<> class CSVGTag
+// -> template<> class CSVGTag
+
class ITag
{
public:
@@ -80,9 +87,6 @@ CREATE_TAG(CHorizontalRule);
CREATE_TAG(CList);
CREATE_TAG(CListElement);
CREATE_TAG(CCaption);
-CREATE_TAG(CTable);
-CREATE_TAG(CTableRow);
-CREATE_TAG(CTableCell);
CREATE_TAG(CCode);
CREATE_TAG(CHTML);
diff --git a/HtmlFile2/Tags/MDTags.cpp b/HtmlFile2/Tags/MDTags.cpp
index 7352656702..61e1777566 100644
--- a/HtmlFile2/Tags/MDTags.cpp
+++ b/HtmlFile2/Tags/MDTags.cpp
@@ -1,9 +1,13 @@
#include "MDTags.h"
+#include "../DesktopEditor/xml/include/xmlutils.h"
+
#include "../src/StringFinder.h"
#include "../Table.h"
+#include "../Common/3dParty/html/css/src/CCompiledStyle.h"
#include
+#include
namespace HTML
{
@@ -301,126 +305,6 @@ void CBlockquote::Close(const std::vector& arSelectors)
m_pWriter->WriteBreakLine(false);
}
-CTable::CTable(CMDWriter* pWriter)
- : CTag(pWriter)
-{}
-
-bool CTable::Open(const std::vector& arSelectors, const boost::any& oExtraData)
-{
- if (!ValidWriter() /*|| m_pWriter->InTable()*/) //В MD не поддерживаются вложенные таблицы (пока разруливаем в парсере)
- return false;
-
- m_pWriter->WriteBreakLine();
- m_pWriter->EnteredTable();
-
- if (m_pWriter->InCode())
- {
- if (!m_pWriter->InPreformatted())
- m_pWriter->WriteCloseSpecialString(L"`");
-
- m_pWriter->OutCode();
- }
-
- if (m_pWriter->InPreformatted())
- {
- m_pWriter->WriteBreakLine();
- m_pWriter->WriteCloseSpecialString(L"```");
- m_pWriter->WriteBreakLine(false);
- m_pWriter->OutPreformatted();
- }
-
- return true;
-}
-
-void CTable::Close(const std::vector& arSelectors)
-{
- if (!ValidWriter())
- return;
-
- m_pWriter->OutTable();
- m_pWriter->WriteBreakLine();
-}
-
-CTableRow::CTableRow(CMDWriter* pWriter)
- : CTag(pWriter), m_unLastRowType(static_cast(ERowParseMode::Foother))
-{}
-
-bool CTableRow::Open(const std::vector& arSelectors, const boost::any& oExtraData)
-{
- using DataForRow = boost::tuple;
-
- if (!ValidWriter() || oExtraData.empty() || typeid(DataForRow) != oExtraData.type())
- return false;
-
- m_pWriter->EnteredTable();
-
- const DataForRow& oDataForRow(boost::any_cast(oExtraData));
- const CStorageTable& oStorageTable{boost::get<1>(oDataForRow)};
-
- if (nullptr == boost::get<0>(oDataForRow) && ERowParseMode::Header == boost::get<2>(oDataForRow))
- {
- for (UINT unIndex = 0; unIndex < oStorageTable.GetMaxColumns(); ++unIndex)
- m_pWriter->WriteOpenSpecialString(L"| ");
-
- m_pWriter->WriteOpenSpecialString(L"|");
- m_pWriter->WriteBreakLine();
- m_unLastRowType = static_cast(ERowParseMode::Header);
- return true;
- }
-
- if (m_unLastRowType == static_cast(ERowParseMode::Header))
- {
- for (UINT unIndex = 0; unIndex < oStorageTable.GetMaxColumns(); ++unIndex)
- m_pWriter->WriteString(L"|-");
-
- m_pWriter->WriteOpenSpecialString(L"|");
- m_pWriter->WriteBreakLine(false);
- }
-
- m_pWriter->WriteOpenSpecialString(L"| ");
- m_unLastRowType = static_cast(boost::get<2>(oDataForRow));
-
- return true;
-}
-
-void CTableRow::Close(const std::vector& arSelectors)
-{
- if (!ValidWriter())
- return;
-
- m_pWriter->WriteBreakLine(false);
-}
-
-CTableCell::CTableCell(CMDWriter* pWriter)
- : CTag(pWriter), m_unNeedEmptyCells(0)
-{}
-
-bool CTableCell::Open(const std::vector& arSelectors, const boost::any& oExtraData)
-{
- using DataForCell = boost::tuple;
-
- if (!ValidWriter() || oExtraData.empty() || typeid(DataForCell) != oExtraData.type())
- return false;
-
- const DataForCell& oDataForCell{boost::any_cast(oExtraData)};
-
- m_unNeedEmptyCells = boost::get<0>(oDataForCell).GetColspan() - 1;
-
- return true;
-}
-
-void CTableCell::Close(const std::vector& arSelectors)
-{
- if (!ValidWriter())
- return;
-
- for (UINT unIndex = 0; unIndex < m_unNeedEmptyCells; ++unIndex)
- m_pWriter->WriteOpenSpecialString(L" |");
-
- m_unNeedEmptyCells = 0;
- m_pWriter->WriteOpenSpecialString(L" | ");
-}
-
CList::CList(CMDWriter* pWriter)
: CTag(pWriter)
{}
@@ -515,4 +399,391 @@ void CCode::Close(const std::vector& arSelectors)
m_pWriter->OutCode();
}
+
+bool IsTable(const ITableElementCell* pCell)
+{
+ return nullptr != pCell && ETableElement::Table == pCell->GetType();
+}
+
+CMarkdownTable::CMarkdownTable(TExternalTableData* pExternalData)
+ : CTableElement(pExternalData)
+{}
+
+CMarkdownTable::~CMarkdownTable()
+{}
+
+bool CMarkdownTable::PreParse(XmlUtils::CXmlLiteReader& oReader)
+{
+ return ParseTable(oReader, this);
+}
+
+void CMarkdownTable::Normalize()
+{
+ m_oHeader .GetMatrixCells() = Flatten(std::move(m_oHeader .GetMatrixCells()));
+ m_oBody .GetMatrixCells() = Flatten(std::move(m_oBody .GetMatrixCells()));
+ m_oFoother.GetMatrixCells() = Flatten(std::move(m_oFoother.GetMatrixCells()));
+}
+
+typedef std::queue, NSStringUtils::CStringBuilder*>> NestedCells;
+
+inline void WriteRowStart(CMDWriter& oWriter)
+{
+ oWriter.WriteOpenSpecialString(L"| ");
+}
+
+inline void WriteRowEnd(CMDWriter& oWriter)
+{
+ oWriter.WriteOpenSpecialString(L" |");
+ oWriter.WriteBreakLine(false);
+}
+
+inline void WriteCellSeparator(CMDWriter& oWriter)
+{
+ oWriter.WriteOpenSpecialString(L" | ");
+}
+
+void ReadNestedCells(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, TCurentTablePosition& oPosition, NestedCells& arNestedCells, const Table& oCells, CMDWriter* pWriter, const TExternalTableData& oExternalTableData)
+{
+ const int nDepth{oReader.GetDepth()};
+
+ while(oReader.ReadNextSiblingNode(nDepth))
+ {
+ const std::wstring wsName = oReader.GetName();
+ oExternalTableData.GetSubClass(oReader, arSelectors);
+
+ if (L"td" == wsName || L"th" == wsName)
+ {
+ if ((oPosition.m_unRowIndex != oPosition.m_unStartRowIndex || oPosition.m_unColumnIndex != oPosition.m_unStartColumnIndex) &&
+ ETableElement::FlatTable == oCells[oPosition.m_unRowIndex][oPosition.m_unColumnIndex]->GetType())
+ {
+ ReadNestedCells(oReader, arSelectors, oPosition, arNestedCells, oCells, pWriter, oExternalTableData);
+ continue;
+ }
+
+ NSStringUtils::CStringBuilder *pCellData = new NSStringUtils::CStringBuilder(20);
+
+ if (nullptr != pCellData)
+ {
+ pWriter->SetDataOutput(pCellData);
+ oExternalTableData.ReadStream(oReader, arSelectors);
+ if (oPosition.m_unColumnIndex != oCells[oPosition.m_unRowIndex].size() - 1)
+ WriteCellSeparator(*pWriter);
+ pWriter->RevertDataOutput();
+ }
+
+ arNestedCells.push(std::make_pair(std::make_pair(oPosition.m_unRowIndex, oPosition.m_unColumnIndex), pCellData));
+
+ //READ and add to nested cells
+ ++oPosition.m_unColumnIndex;
+ }
+ else if (L"tr" == wsName)
+ {
+ oPosition.m_unColumnIndex = oPosition.m_unStartColumnIndex;
+
+ ReadNestedCells(oReader, arSelectors, oPosition, arNestedCells, oCells, pWriter, oExternalTableData);
+
+ ++oPosition.m_unRowIndex;
+ }
+ else if (L"table" == wsName)
+ {
+ TCurentTablePosition oNestedPosition{oPosition};
+
+ oNestedPosition.m_unStartRowIndex = oPosition.m_unRowIndex;
+ oNestedPosition.m_unStartColumnIndex = oPosition.m_unColumnIndex;
+
+ std::vector arNestedSelectors{arSelectors.back()};
+
+ ReadNestedCells(oReader, arNestedSelectors, oNestedPosition, arNestedCells, oCells, pWriter, oExternalTableData);
+
+ oPosition.m_unRowIndex = oNestedPosition.m_unRowIndex;
+ }
+ else
+ ReadNestedCells(oReader, arSelectors, oPosition, arNestedCells, oCells, pWriter, oExternalTableData);
+
+ arSelectors.pop_back();
+ }
+}
+
+bool CMarkdownTable::Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& oTableNode)
+{
+ if (nullptr == m_pExternalData || Empty())
+ return false;
+
+ CMDWriter *pWriter{dynamic_cast(m_pExternalData->m_pWriter)};
+
+ if (nullptr == pWriter)
+ return false;
+
+ std::vector arTableSelectors{oTableNode};
+
+ pWriter->WriteBreakLine();
+ WriteToStringBuilder(*m_pCaption, *pWriter->GetCurrentDocument());
+
+ //Open table
+ pWriter->WriteBreakLine();
+ pWriter->EnteredTable();
+
+ if (pWriter->InCode())
+ {
+ if (!pWriter->InPreformatted())
+ pWriter->WriteCloseSpecialString(L"`");
+
+ pWriter->OutCode();
+ }
+
+ if (pWriter->InPreformatted())
+ {
+ pWriter->WriteBreakLine();
+ pWriter->WriteCloseSpecialString(L"```");
+ pWriter->WriteBreakLine(false);
+ pWriter->OutPreformatted();
+ }
+ //-----
+
+ //Convert header
+ if (!ConvertMatrix(oReader, arTableSelectors, m_oHeader.GetMatrixCells(), pWriter))
+ {
+ WriteRowStart(*pWriter);
+
+ for (size_t unColumnIndex = 0; unColumnIndex < m_oBody.GetColumnSize() - 1; ++unColumnIndex)
+ WriteCellSeparator(*pWriter);
+
+ WriteRowEnd(*pWriter);
+ }
+
+ WriteRowStart(*pWriter);
+ for (size_t unColumnIndex = 0; unColumnIndex < m_oBody.GetColumnSize() - 1; ++unColumnIndex)
+ pWriter->WriteString(L"-|-", true);
+ WriteRowEnd(*pWriter);
+ //----
+
+ //Convert body
+ ConvertMatrix(oReader, arTableSelectors, m_oBody.GetMatrixCells(), pWriter);
+ //Convert foother
+ ConvertMatrix(oReader, arTableSelectors, m_oFoother.GetMatrixCells(), pWriter);
+
+ //Close table
+ pWriter->OutTable();
+ pWriter->WriteBreakLine();
+
+ return true;
+}
+
+bool CMarkdownTable::ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption)
+{
+ if (nullptr == m_pExternalData || nullptr == m_pExternalData->m_pWriter)
+ return false;
+
+ if (nullptr == pCaption)
+ pCaption = new XmlString(50);
+
+ std::vector arSelectors;
+ m_pExternalData->GetSubClass(oReader, arSelectors);
+
+ arSelectors.back().m_pCompiledStyle->m_oText.SetAlign(L"center", 0, true);
+
+ CMDWriter& oWriter{*(CMDWriter*)m_pExternalData->m_pWriter};
+
+ oWriter.SetDataOutput(m_pCaption);
+ m_pExternalData->ReadStream(oReader, arSelectors);
+ oWriter.WriteBreakLine();
+ oWriter.RevertDataOutput();
+
+ return true;
+}
+
+bool CMarkdownTable::ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vector& arColgroups)
+{
+ return true;
+}
+
+bool CMarkdownTable::ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, const Table& oMatrix, CMDWriter* pWriter)
+{
+ if (oMatrix.empty() || nullptr == pWriter)
+ return false;
+
+ std::stack arDepths({0});
+
+ NestedCells arNestedCells;
+ ITableElementCell* pTableCell{nullptr};
+
+ for (size_t unRowIndex = 0; unRowIndex < oMatrix.size(); ++unRowIndex)
+ {
+ WriteRowStart(*pWriter);
+
+ for (size_t unColumnIndex = 0; unColumnIndex < oMatrix[unRowIndex].size(); ++unColumnIndex)
+ {
+ pTableCell = oMatrix[unRowIndex][unColumnIndex];
+
+ if (nullptr != pTableCell && ETableElement::FillingCell != pTableCell->GetType())
+ {
+ if (!arNestedCells.empty() && arNestedCells.front().first == std::make_pair(unRowIndex, unColumnIndex))
+ {
+ if (nullptr != arNestedCells.front().second)
+ {
+ m_pExternalData->m_pWriter->GetCurrentDocument()->Write(*arNestedCells.front().second);
+ delete arNestedCells.front().second;
+ }
+ arNestedCells.pop();
+ }
+ else
+ {
+ MoveToNextTableCell(oReader, arSelectors, arDepths, m_pExternalData->GetSubClass);
+
+ if (ETableElement::FlatTable == pTableCell->GetType())
+ {
+ TCurentTablePosition oPosition{unRowIndex, unColumnIndex, unRowIndex, unColumnIndex};
+ std::vector arNestedSelectors;
+
+ ReadNestedCells(oReader, arNestedSelectors, oPosition, arNestedCells, oMatrix, pWriter, *m_pExternalData);
+ --unColumnIndex;
+ }
+ else
+ {
+ m_pExternalData->ReadStream(oReader, arSelectors);
+ if (oMatrix[unRowIndex].size() - 1 != unColumnIndex)
+ WriteCellSeparator(*pWriter);
+ }
+ arSelectors.pop_back();
+ }
+ }
+ else
+ {
+ if (oMatrix[unRowIndex].size() - 1 != unColumnIndex)
+ WriteCellSeparator(*pWriter);
+ }
+ }
+
+ WriteRowEnd(*pWriter);
+ }
+
+ return true;
+}
+
+Table CMarkdownTable::Flatten(Table&& srcTable)
+{
+ if (srcTable.empty())
+ return {};
+
+ const size_t unRows{srcTable.size()};
+ const size_t unColumns{srcTable[0].size()};
+
+ std::vector> oInfos{unRows, std::vector{unColumns}};
+
+ for (size_t unRowIndex = 0; unRowIndex < unRows; ++unRowIndex)
+ for (size_t unColumnIndex = 0; unColumnIndex < unColumns; ++unColumnIndex)
+ oInfos[unRowIndex][unColumnIndex] = ComputeInfo(srcTable[unRowIndex][unColumnIndex]);
+
+ std::vector arRowHeights(unRows, 1);
+ std::vector arColumnWidths(unColumns, 1);
+
+ for (size_t unRowIndex = 0; unRowIndex < unRows; ++unRowIndex)
+ {
+ for (size_t unColumnIndex = 0; unColumnIndex < unColumns; ++unColumnIndex)
+ {
+ arRowHeights[unRowIndex] = (std::max)(arRowHeights[unRowIndex], oInfos[unRowIndex][unColumnIndex].unRows);
+ arColumnWidths[unColumnIndex] = (std::max)(arColumnWidths[unColumnIndex], oInfos[unRowIndex][unColumnIndex].unColumns);
+ }
+ }
+
+ std::vector arRowStart (unRows + 1, 0);
+ std::vector arColumnStart(unColumns + 1, 0);
+
+ for (size_t unRowIndex = 0; unRowIndex < unRows; ++unRowIndex)
+ arRowStart[unRowIndex + 1] = arRowStart[unRowIndex] + arRowHeights[unRowIndex];
+
+ for (size_t unColumnIndex = 0; unColumnIndex < unColumns; ++unColumnIndex)
+ arColumnStart[unColumnIndex + 1] = arColumnStart[unColumnIndex] + arColumnWidths[unColumnIndex];
+
+ const size_t unTotalRows {arRowStart[unRows]};
+ const size_t unTotalColumns{arColumnStart[unColumns]};
+
+ Table oResult{unTotalRows, Row{unTotalColumns, nullptr}};
+
+ size_t unBaseRow, unBaseColumn;
+
+ for (size_t unRowIndex = 0; unRowIndex < unRows; ++unRowIndex)
+ {
+ for (size_t unColumnIndex = 0; unColumnIndex < unColumns; ++unColumnIndex)
+ {
+ ITableElementCell*& pCell{srcTable[unRowIndex][unColumnIndex]};
+
+ if (nullptr == pCell)
+ continue;
+
+ const TElementInfo oInfo{oInfos[unRowIndex][unColumnIndex]};
+
+ unBaseRow = arRowStart[unRowIndex];
+ unBaseColumn = arColumnStart[unColumnIndex];
+
+ if (!IsTable(pCell))
+ {
+ oResult[unBaseRow][unBaseColumn] = pCell;
+ pCell = nullptr;
+ continue;
+ }
+
+ CMarkdownTable *pTable{dynamic_cast(pCell)};
+ pCell = nullptr;
+
+ Table& oChild{pTable->m_oBody.GetMatrixCells()};
+ Table oFlatChild{Flatten(std::move(oChild))};
+
+ for (size_t unChildRowIndex = 0; unChildRowIndex < oInfo.unRows; ++unChildRowIndex)
+ for (size_t unChildColumnIndex = 0; unChildColumnIndex < oInfo.unColumns; ++unChildColumnIndex)
+ oResult[unBaseRow + unChildRowIndex][unBaseColumn + unChildColumnIndex] = oFlatChild[unChildRowIndex][unChildColumnIndex];
+
+ CTableElementCell* pFlatCell{dynamic_cast(oResult[unBaseRow][unBaseColumn])};
+
+ if(nullptr != pFlatCell)
+ pFlatCell->IsFlatTable();
+
+ delete pTable;
+ }
+ }
+
+ return oResult;
+}
+
+TElementInfo CMarkdownTable::ComputeInfo(const ITableElementCell* pCell)
+{
+ if (!IsTable(pCell))
+ return {1, 1};
+
+ const CMarkdownTable *pMarkdownTable{dynamic_cast(pCell)};
+
+ if (nullptr == pMarkdownTable)
+ return {1, 1};
+
+ const CTableMatrix *pTable{&pMarkdownTable->m_oBody};
+
+ const size_t unRows{pTable->GetRowSize()};
+ const size_t unColumns{pTable->GetColumnSize()};
+
+ std::vector arRowHeights(unRows, 1);
+ std::vector arColumnWidths(unColumns, 1);
+
+ const Table& arCells{pTable->GetMatrixCells()};
+
+ for (size_t unRowIndex = 0; unRowIndex < unRows; ++unRowIndex)
+ {
+ for (size_t unColumnIndex = 0; unColumnIndex < unColumns; ++unColumnIndex)
+ {
+ TElementInfo oInfo{ComputeInfo(arCells[unRowIndex][unColumnIndex])};
+
+ arRowHeights[unRowIndex] = (std::max)(arRowHeights[unRowIndex], oInfo.unRows);
+ arColumnWidths[unColumnIndex] = (std::max)(arColumnWidths[unColumnIndex], oInfo.unColumns);
+ }
+ }
+
+ size_t unTotalRows{0}, unTotalColumns{0};
+
+ for (size_t unHeight : arRowHeights)
+ unTotalRows += unHeight;
+
+ for (size_t unWidth : arColumnWidths)
+ unTotalColumns += unWidth;
+
+ return {unTotalRows, unTotalColumns};
+}
}
diff --git a/HtmlFile2/Tags/MDTags.h b/HtmlFile2/Tags/MDTags.h
index 5849c47f7f..65452f867a 100644
--- a/HtmlFile2/Tags/MDTags.h
+++ b/HtmlFile2/Tags/MDTags.h
@@ -3,6 +3,7 @@
#include "HTMLTags.h"
#include "../Writers/MDWriter.h"
+#include "../Table.h"
namespace HTML
{
@@ -105,35 +106,6 @@ public:
virtual void Close(const std::vector& arSelectors) override;
};
-template<>
-class CTable : public CTag
-{
-public:
- CTable(CMDWriter* pWriter);
- virtual bool Open(const std::vector& arSelectors, const boost::any& oExtraData = boost::any()) override;
- virtual void Close(const std::vector& arSelectors) override;
-};
-
-template<>
-class CTableRow : public CTag
-{
- UINT m_unLastRowType;
-public:
- CTableRow(CMDWriter* pWriter);
- virtual bool Open(const std::vector& arSelectors, const boost::any& oExtraData = boost::any()) override;
- virtual void Close(const std::vector& arSelectors) override;
-};
-
-template<>
-class CTableCell : public CTag
-{
- UINT m_unNeedEmptyCells;
-public:
- CTableCell(CMDWriter* pWriter);
- virtual bool Open(const std::vector& arSelectors, const boost::any& oExtraData = boost::any()) override;
- virtual void Close(const std::vector& arSelectors) override;
-};
-
template<>
class CList : public CTag
{
@@ -160,6 +132,31 @@ public:
virtual bool Open(const std::vector& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector& arSelectors) override;
};
+
+struct TElementInfo
+{
+ size_t unRows;
+ size_t unColumns;
+};
+
+class CMarkdownTable : public CTableElement
+{
+public:
+ CMarkdownTable(TExternalTableData* pExternalData);
+ virtual ~CMarkdownTable();
+
+ bool PreParse(XmlUtils::CXmlLiteReader& oReader) override;
+ void Normalize() override;
+ bool Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& oTableNode) override;
+private:
+ bool ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption) override;
+ bool ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vector& arColgroups) override;
+
+ bool ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, std::vector& arSelectors, const Table& oMatrix, CMDWriter* pWriter);
+
+ static Table Flatten(Table&& srcTable);
+ static TElementInfo ComputeInfo(const ITableElementCell* pCell);
+};
}
#endif // MDTAGS_H
diff --git a/HtmlFile2/Tags/OOXMLTags.cpp b/HtmlFile2/Tags/OOXMLTags.cpp
index c29c32b9bb..1bbdb32e7c 100644
--- a/HtmlFile2/Tags/OOXMLTags.cpp
+++ b/HtmlFile2/Tags/OOXMLTags.cpp
@@ -675,10 +675,10 @@ bool CHorizontalRule::Open(const std::vector& arSele
if (arSelectors.back().GetAttributeValue(L"width", wsValue))
oWidth.SetValue(wsValue);
- XmlString& oCurrentDocument{*m_pWriter->GetCurrentDocument()};
+ XmlString& oXmlString{*m_pWriter->GetCurrentDocument()};
m_pWriter->OpenP();
- oCurrentDocument.WriteString(L"");
+ oXmlString.WriteString(L"");
m_pWriter->OpenR();
const NSCSS::NSProperties::CPage *pPageData{m_pWriter->GetPageData()};
@@ -699,18 +699,18 @@ bool CHorizontalRule::Open(const std::vector& arSele
if (!oSize.Empty())
wsHeight = std::to_wstring(static_cast(NSCSS::CUnitMeasureConverter::ConvertPx(oSize.ToDouble(), NSCSS::Inch, 96) * 914400.));
- oCurrentDocument.WriteString(L"");
- oCurrentDocument.WriteString(L"");
- oCurrentDocument.WriteString(L"");
- oCurrentDocument.WriteString(L"");
- oCurrentDocument.WriteString(L""
+ oXmlString.WriteString(L"");
+ oXmlString.WriteString(L"");
+ oXmlString.WriteString(L"");
+ oXmlString.WriteString(L"");
+ oXmlString.WriteString(L""
""
""
""
""
""
"");
- oCurrentDocument.WriteString(L""
+ oXmlString.WriteString(L""
""
""
""
@@ -721,9 +721,9 @@ bool CHorizontalRule::Open(const std::vector& arSele
"");
if (bShade)
- oCurrentDocument.WriteString(L"");
+ oXmlString.WriteString(L"");
- oCurrentDocument.WriteString(L"");
+ oXmlString.WriteString(L"");
m_pWriter->CloseP();
@@ -1079,7 +1079,7 @@ void CCaption::Close(const std::vector& arSelectors)
m_pWriter->CloseP();
}
-std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL, bool bAddIntermediateLines = false, TTableStyles::ETableRules enTableRule = TTableStyles::ETableRules::None)
+std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL, bool bAddIntermediateLines = false, ETableRules enTableRule = ETableRules::None)
{
std::wstring wsTable;
@@ -1108,7 +1108,7 @@ std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NS
if (!bAddIntermediateLines)
return wsTable;
- if (TTableStyles::ETableRules::Rows == enTableRule || TTableStyles::ETableRules::All == enTableRule)
+ if (ETableRules::Rows == enTableRule || ETableRules::All == enTableRule)
{
NSCSS::NSProperties::CBorderSide oNewSide(oBorder.GetBottomBorder());
oNewSide.SetWidth(L"1pt", 0, true);
@@ -1116,7 +1116,7 @@ std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NS
wsTable += L"";
}
- if (TTableStyles::ETableRules::Cols == enTableRule || TTableStyles::ETableRules::All == enTableRule)
+ if (ETableRules::Cols == enTableRule || ETableRules::All == enTableRule)
{
NSCSS::NSProperties::CBorderSide oNewSide(oBorder.GetRightBorder());
oNewSide.SetWidth(L"1pt", 0, true);
@@ -1145,165 +1145,6 @@ std::wstring CreateDefaultBorder(std::wstring wsSideName)
return L"";
}
-CTable::CTable(COOXMLWriter* pWriter)
- : CTag(pWriter)
-{}
-
-bool CTable::Open(const std::vector& arSelectors, const boost::any& oExtraData)
-{
- if (!ValidWriter() || oExtraData.empty() || typeid(CStorageTable*) != oExtraData.type())
- return false;
-
- CStorageTable* pStorageTable{boost::any_cast(oExtraData)};
-
- if (pStorageTable->Empty())
- return false;
-
- XmlString& oCurrentDocument{*m_pWriter->GetCurrentDocument()};
-
- oCurrentDocument.WriteNodeBegin(L"w:tbl");
- oCurrentDocument.WriteNodeBegin(L"w:tblPr");
-
- const TTableStyles& oTableStyles{pStorageTable->GetTableStyles()};
-
- if (!oTableStyles.m_oWidth.Empty() && !oTableStyles.m_oWidth.Zero())
- {
- if (NSCSS::UnitMeasure::Percent == oTableStyles.m_oWidth.GetUnitMeasure())
- oCurrentDocument += L"";
- else
- oCurrentDocument += L"";
- }
- else
- oCurrentDocument += L"";
-
- if (!oTableStyles.m_oMargin.GetLeft().Empty() && !oTableStyles.m_oMargin.GetLeft().Zero())
- {
- if (NSCSS::UnitMeasure::Percent == oTableStyles.m_oMargin.GetLeft().GetUnitMeasure())
- oCurrentDocument += L"";
- else
- oCurrentDocument += L"";
- }
-
- if (!oTableStyles.m_wsAlign.empty())
- oCurrentDocument += L"";
-
- if (0 < oTableStyles.m_nCellSpacing && oTableStyles.m_oBorder.GetCollapse() != NSCSS::NSProperties::BorderCollapse::Collapse)
- oCurrentDocument += L"";
-
- if (!oTableStyles.m_oBorder.Empty() && !oTableStyles.m_oBorder.Zero())
- oCurrentDocument += L"" + CreateBorders(oTableStyles.m_oBorder, NULL, true, (TTableStyles::ETableRules::Groups == oTableStyles.m_enRules && !pStorageTable->GetColgroups().empty()) ? TTableStyles::ETableRules::Cols : oTableStyles.m_enRules) + L"";
-
- if (!oTableStyles.m_oPadding.Empty() && !oTableStyles.m_oPadding.Zero())
- {
- const int nTopPadding = std::max(0, oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT));
- const int nLeftPadding = std::max(0, oTableStyles.m_oPadding.GetLeft() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ));
- const int nBottomPadding = std::max(0, oTableStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT));
- const int nRightPadding = std::max(0, oTableStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ));
-
- oCurrentDocument.WriteNodeBegin(L"w:tblCellMar");
-
- if (0 != nTopPadding)
- oCurrentDocument += L"";
-
- if (0 != nLeftPadding)
- oCurrentDocument += L"";
-
- if (0 != nBottomPadding)
- oCurrentDocument += L"";
-
- if (0 != nRightPadding)
- oCurrentDocument += L"";
-
- oCurrentDocument.WriteNodeEnd(L"w:tblCellMar");
- }
- else
- oCurrentDocument += L"";
-
- oCurrentDocument += L"";
- oCurrentDocument.WriteNodeEnd(L"w:tblPr");
-
- if (pStorageTable->HaveCaption())
- {
- oCurrentDocument.WriteNodeBegin(L"w:tr");
- oCurrentDocument.WriteNodeBegin(L"w:tc");
- oCurrentDocument.WriteNodeBegin(L"w:tcPr");
- oCurrentDocument += L"";
- oCurrentDocument += L"GetMaxColumns()) + L"\"/>";
- oCurrentDocument += L"";
- oCurrentDocument += L"";
- oCurrentDocument += L"";
- oCurrentDocument.WriteNodeEnd(L"w:tcPr");
- WriteToStringBuilder(*(pStorageTable->GetCaptionData()), oCurrentDocument);
- oCurrentDocument.WriteNodeEnd(L"w:tc");
- oCurrentDocument.WriteNodeEnd(L"w:tr");
- }
-
- return true;
-}
-
-void CTable::Close(const std::vector& arSelectors)
-{
- if (!ValidWriter())
- return;
-
- m_pWriter->GetCurrentDocument()->WriteNodeEnd(L"w:tbl");
- m_pWriter->WriteEmptyParagraph(true);
-}
-
-CTableRow::CTableRow(COOXMLWriter* pWriter)
- : CTag(pWriter)
-{}
-
-bool CTableRow::Open(const std::vector& arSelectors, const boost::any& oExtraData)
-{
- using DataForRow = boost::tuple;
-
- if (!ValidWriter() || oExtraData.empty() || typeid(DataForRow) != oExtraData.type())
- return false;
-
- const DataForRow& oDataForRow(boost::any_cast(oExtraData));
- const TTableRowStyle* pTableRowStyles{boost::get<0>(oDataForRow)};
-
- if (nullptr == pTableRowStyles)
- return false;
-
- XmlString& oCurrentDocument{*m_pWriter->GetCurrentDocument()};
-
- oCurrentDocument.WriteNodeBegin(L"w:tr");
-
- const TTableStyles& oTableStyles{boost::get<1>(oDataForRow).GetTableStyles()};
-
- if (!pTableRowStyles->Empty() || 0 < oTableStyles.m_nCellSpacing)
- {
- oCurrentDocument.WriteNodeBegin(L"w:trPr");
-
- if (pTableRowStyles->m_bIsHeader)
- oCurrentDocument += L"";
-
- if (0 < pTableRowStyles->m_unMaxHeight)
- oCurrentDocument += L"m_unMaxHeight) + L"\"/>";
-
- if (0 < oTableStyles.m_nCellSpacing)
- oCurrentDocument += L"";
-
- oCurrentDocument.WriteNodeEnd(L"w:trPr");
- }
-
- return true;
-}
-
-void HTML::CTableRow::Close(const std::vector& arSelectors)
-{
- if (!ValidWriter())
- return;
-
- m_pWriter->GetCurrentDocument()->WriteNodeEnd(L"w:tr");
-}
-
-CTableCell::CTableCell(COOXMLWriter* pInterpretator)
- : CTag(pInterpretator)
-{}
-
std::wstring CalculateSidesToClean(UINT unColumnNumber, const std::vector