mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Migrated most of the html conversion to the new architecture
This commit is contained in:
@ -521,6 +521,10 @@ namespace NSCSS
|
||||
{L"font-size", L"20pt"},
|
||||
{L"margin-top", L"0"},
|
||||
{L"margin-bottom", L"0"}});
|
||||
m_mDefaultStyleData[L"blockquote"] = new CElement(L"blockquote", {{L"margin", L"0px"}});
|
||||
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"}});
|
||||
}
|
||||
|
||||
CCssCalculator_Private::CCssCalculator_Private()
|
||||
@ -711,6 +715,12 @@ namespace NSCSS
|
||||
if (L"xmp" == wsNodeName || L"nobr" == wsNodeName)
|
||||
return L"pre";
|
||||
|
||||
if (L"ol" == wsNodeName)
|
||||
return L"ul";
|
||||
|
||||
if (L"fieldset" == wsNodeName)
|
||||
return L"textarea";
|
||||
|
||||
return wsNodeName;
|
||||
}
|
||||
|
||||
|
||||
@ -16,8 +16,9 @@ namespace HTML
|
||||
#define ADD_TAG(strName, enumName) {strName, HTML_TAG(enumName)}
|
||||
#define SKIP_TAG SCRIPT
|
||||
#define UNKNOWN_TAG GumboTag::GUMBO_TAG_UNKNOWN
|
||||
#define HtmlTag GumboTag
|
||||
|
||||
const std::map<std::wstring, HtmlTag> m_HTML_TAGS
|
||||
const static std::map<std::wstring, HtmlTag> m_HTML_TAGS
|
||||
{
|
||||
ADD_TAG(L"a", A),
|
||||
ADD_TAG(L"abbr", ABBR),
|
||||
@ -151,6 +152,7 @@ const std::map<std::wstring, HtmlTag> m_HTML_TAGS
|
||||
|
||||
ADD_TAG(L"svg", SVG)
|
||||
};
|
||||
|
||||
inline std::wstring GetArgumentValue(XmlUtils::CXmlLiteReader& oLiteReader, const std::wstring& wsArgumentName, const std::wstring& wsDefaultValue = L"");
|
||||
inline bool CheckArgumentMath(const std::wstring& wsNodeName, const std::wstring& wsStyleName);
|
||||
inline HtmlTag GetHtmlTag(const std::wstring& wsStrTag);
|
||||
@ -168,11 +170,18 @@ CHTMLReader::CHTMLReader()
|
||||
pInterpretator->SetCSSCalculator(&m_oCSSCalculator);
|
||||
m_pInterpretator = pInterpretator;
|
||||
|
||||
m_mTags[HTML_TAG(A)] = std::make_shared<TAnchor<COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(ABBR)] = std::make_shared<TAnchor<COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(BR)] = std::make_shared<TBreak<COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(DIV)] = std::make_shared<TDivision<COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(IMG)] = std::make_shared<TImage<COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(A)] = std::make_shared<TAnchor <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(ABBR)] = std::make_shared<TAnchor <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(BR)] = std::make_shared<TBreak <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(DIV)] = std::make_shared<TDivision <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(IMG)] = std::make_shared<TImage <COOXMLInterpretator>>(pInterpretator, &m_oLightReader);
|
||||
m_mTags[HTML_TAG(FONT)] = std::make_shared<TFont <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(INPUT)] = std::make_shared<TInput <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(BASEFONT)] = std::make_shared<TBaseFont <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(BLOCKQUOTE)] = std::make_shared<TBlockquote <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(HR)] = std::make_shared<THorizontalRule<COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(UL)] = std::make_shared<TList <COOXMLInterpretator>>(pInterpretator);
|
||||
m_mTags[HTML_TAG(LI)] = std::make_shared<TListElement <COOXMLInterpretator>>(pInterpretator);
|
||||
|
||||
std::shared_ptr<ITag> oIgnoredTag{std::make_shared<TEmptyTag>()};
|
||||
|
||||
@ -510,7 +519,7 @@ bool CHTMLReader::ReadInside(std::vector<NSCSS::CNode>& arSelectors)
|
||||
}
|
||||
case HTML_TAG(BR):
|
||||
{
|
||||
bResult = ReadBreak(arSelectors);
|
||||
bResult = ReadEmptyTag(HTML_TAG(BR), arSelectors);
|
||||
break;
|
||||
}
|
||||
case HTML_TAG(CENTER):
|
||||
@ -546,12 +555,13 @@ bool CHTMLReader::ReadInside(std::vector<NSCSS::CNode>& arSelectors)
|
||||
bResult = ReadDefaultTag(HTML_TAG(S), arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(FONT):
|
||||
// {
|
||||
// bResult = m_pInterpretator->ReadFont(oXml, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
case HTML_TAG(FONT):
|
||||
{
|
||||
bResult = ReadDefaultTag(HTML_TAG(FONT), arSelectors);
|
||||
break;
|
||||
}
|
||||
case HTML_TAG(IMG):
|
||||
case HTML_TAG(SVG):
|
||||
{
|
||||
bResult = ReadDefaultTag(HTML_TAG(IMG), arSelectors);
|
||||
break;
|
||||
@ -578,23 +588,11 @@ bool CHTMLReader::ReadInside(std::vector<NSCSS::CNode>& arSelectors)
|
||||
bResult = ReadDefaultTag(HTML_TAG(SUP), arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(SVG):
|
||||
// {
|
||||
// m_pInterpretator->readSVG(oXml, sSelectors, oTS);
|
||||
|
||||
// wrP(oXml, sSelectors, oTS);
|
||||
// bResult = readSVG(m_oLightReader.GetOuterXml());
|
||||
|
||||
// if (bResult)
|
||||
// ImageRels(oXml, -1, L"", L"png");
|
||||
|
||||
// break;
|
||||
// }
|
||||
// case HTML_TAG(INPUT):
|
||||
// {
|
||||
// bResult = readInput(oXml, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
case HTML_TAG(INPUT):
|
||||
{
|
||||
bResult = ReadDefaultTag(HTML_TAG(INPUT), arSelectors);
|
||||
break;
|
||||
}
|
||||
case HTML_TAG(CANVAS):
|
||||
case HTML_TAG(VIDEO):
|
||||
case HTML_TAG(MATH):
|
||||
@ -624,11 +622,11 @@ bool CHTMLReader::ReadInside(std::vector<NSCSS::CNode>& arSelectors)
|
||||
bResult = ReadDefaultTag(HTML_TAG(PRE), arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(BASEFONT):
|
||||
// {
|
||||
// bResult = ReadBasefont(oXml, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
case HTML_TAG(BASEFONT):
|
||||
{
|
||||
bResult = ReadDefaultTag(HTML_TAG(BASEFONT), arSelectors);
|
||||
break;
|
||||
}
|
||||
case HTML_TAG(BUTTON):
|
||||
case HTML_TAG(LABEL):
|
||||
case HTML_TAG(DATA):
|
||||
@ -678,11 +676,11 @@ bool CHTMLReader::ReadInside(std::vector<NSCSS::CNode>& arSelectors)
|
||||
bResult = ReadDefaultTag(HTML_TAG(DIV), arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(BLOCKQUOTE):
|
||||
// {
|
||||
// bResult = ReadBlockquote(&oXmlData, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
case HTML_TAG(BLOCKQUOTE):
|
||||
{
|
||||
bResult = ReadDefaultTag(HTML_TAG(BLOCKQUOTE), arSelectors);
|
||||
break;
|
||||
}
|
||||
case HTML_TAG(ARTICLE):
|
||||
case HTML_TAG(HEADER):
|
||||
case HTML_TAG(MAIN):
|
||||
@ -703,22 +701,22 @@ bool CHTMLReader::ReadInside(std::vector<NSCSS::CNode>& arSelectors)
|
||||
bResult = ReadStream(arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(HR):
|
||||
// {
|
||||
// bResult = ReadHr(&oXmlData, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
// case HTML_TAG(LI):
|
||||
// {
|
||||
// bResult = ReadListElement(&oXmlData, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
// case HTML_TAG(OL):
|
||||
// case HTML_TAG(UL):
|
||||
// {
|
||||
// bResult = ReadList(&oXmlData, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
case HTML_TAG(HR):
|
||||
{
|
||||
bResult = ReadEmptyTag(HTML_TAG(HR), arSelectors);
|
||||
break;
|
||||
}
|
||||
case HTML_TAG(LI):
|
||||
{
|
||||
bResult = ReadDefaultTag(HTML_TAG(LI), arSelectors);
|
||||
break;
|
||||
}
|
||||
case HTML_TAG(OL):
|
||||
case HTML_TAG(UL):
|
||||
{
|
||||
bResult = ReadDefaultTag(HTML_TAG(OL), arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(MENU):
|
||||
// case HTML_TAG(SELECT):
|
||||
// case HTML_TAG(DATALIST):
|
||||
@ -733,22 +731,22 @@ bool CHTMLReader::ReadInside(std::vector<NSCSS::CNode>& arSelectors)
|
||||
bResult = ReadDefaultTag(HTML_TAG(PRE), arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(TABLE):
|
||||
// {
|
||||
// bResult = ParseTable(&oXmlData, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
case HTML_TAG(TABLE):
|
||||
{
|
||||
bResult = ReadTable(arSelectors);
|
||||
break;
|
||||
}
|
||||
// case HTML_TAG(RUBY):
|
||||
// {
|
||||
// bResult = ParseRuby(&oXmlData, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
// case HTML_TAG(TEXTAREA):
|
||||
// case HTML_TAG(FIELDSET):
|
||||
// {
|
||||
// bResult = ReadTextarea(&oXmlData, sSelectors, oTS);
|
||||
// break;
|
||||
// }
|
||||
// case HTML_TAG(TEXTAREA):
|
||||
// case HTML_TAG(FIELDSET):
|
||||
// {
|
||||
// bResult = ReadStream(arSelectors);
|
||||
// break;
|
||||
// }
|
||||
// case HTML_TAG(DETAILS):
|
||||
// {
|
||||
// bResult = ReadDetails(&oXmlData, sSelectors, oTS);
|
||||
@ -805,12 +803,140 @@ bool CHTMLReader::ReadAnchor(std::vector<NSCSS::CNode>& arSelectors)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CHTMLReader::ReadBreak(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
bool CHTMLReader::ReadTable(std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!m_mTags[HTML_TAG(BR)]->Open(arSelectors))
|
||||
if(m_oLightReader.IsEmptyNode())
|
||||
return false;
|
||||
|
||||
m_mTags[HTML_TAG(BR)]->Close(arSelectors);
|
||||
// if (HTML_TAG(TABLE) == m_oState.m_eLastElement)
|
||||
// WriteEmptyParagraph(oXml, true);
|
||||
|
||||
CTable oTable;
|
||||
CTextSettings oTextSettings{oTS};
|
||||
oTextSettings.sPStyle.clear();
|
||||
|
||||
NSCSS::CCompiledStyle *pStyle = sSelectors.back().m_pCompiledStyle;
|
||||
|
||||
//Table styles
|
||||
std::wstring wsFrame;
|
||||
|
||||
for (const std::pair<std::wstring, std::wstring>& oArgument : sSelectors.back().m_mAttributes)
|
||||
{
|
||||
if (L"border" == oArgument.first)
|
||||
{
|
||||
const int nWidth = NSStringFinder::ToInt(oArgument.second);
|
||||
|
||||
if (0 < nWidth)
|
||||
{
|
||||
oTable.SetRules(L"all");
|
||||
|
||||
if (!pStyle->m_oBorder.Empty())
|
||||
continue;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
else if (L"cellpadding" == oArgument.first)
|
||||
pStyle->m_oPadding.SetValues(oArgument.second + L"px", 0, true);
|
||||
else if (L"rules" == oArgument.first)
|
||||
oTable.SetRules(oArgument.second);
|
||||
else if (L"frame" == oArgument.first)
|
||||
wsFrame = oArgument.second;
|
||||
}
|
||||
|
||||
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 (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellspacing"))
|
||||
oTable.SetCellSpacing(NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"cellspacing"]));
|
||||
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());
|
||||
//------
|
||||
|
||||
int nDeath = m_oLightReader.GetDepth();
|
||||
while(m_oLightReader.ReadNextSiblingNode(nDeath))
|
||||
{
|
||||
const std::wstring sName = m_oLightReader.GetName();
|
||||
GetSubClass(oXml, sSelectors);
|
||||
|
||||
if(sName == L"caption")
|
||||
ParseTableCaption(oTable, sSelectors, oTS);
|
||||
if(sName == L"thead")
|
||||
ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeHeader);
|
||||
if(sName == L"tbody")
|
||||
ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeBody);
|
||||
else if(sName == L"tfoot")
|
||||
ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeFoother);
|
||||
else if (sName == L"colgroup")
|
||||
ParseTableColspan(oTable);
|
||||
|
||||
arSelectors.pop_back();
|
||||
}
|
||||
|
||||
oTable.Shorten();
|
||||
oTable.CompleteTable();
|
||||
oTable.ConvertToOOXML(*oXml);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CHTMLReader::ReadEmptyTag(UINT unTag, const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!m_mTags[unTag]->Open(arSelectors))
|
||||
return false;
|
||||
|
||||
m_mTags[unTag]->Close(arSelectors);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -9,8 +9,6 @@
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
#define HtmlTag GumboTag
|
||||
|
||||
class CHTMLReader
|
||||
{
|
||||
XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader
|
||||
@ -53,8 +51,8 @@ private:
|
||||
bool ReadText(std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
bool ReadAnchor(std::vector<NSCSS::CNode>& arSelectors);
|
||||
bool ReadBreak(const std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
bool ReadTable(std::vector<NSCSS::CNode>& arSelectors);
|
||||
bool ReadEmptyTag(UINT unTag, const std::vector<NSCSS::CNode>& arSelectors);
|
||||
bool ReadDefaultTag(UINT unTag, std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
void GetSubClass(std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
@ -47,7 +47,7 @@ inline void replace_all(std::wstring& s, const std::wstring& s1, const std::wstr
|
||||
inline std::wstring EncodeXmlString(std::wstring wsString);
|
||||
|
||||
COOXMLInterpretator::COOXMLInterpretator()
|
||||
: m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1), m_nShapeId(1), m_pFonts(nullptr)
|
||||
: m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1), m_nShapeId(1), m_bWasDivs(false), m_pFonts(nullptr)
|
||||
{
|
||||
m_oPageData.SetWidth (DEFAULT_PAGE_WIDTH, NSCSS::UnitMeasure::Twips, 0, true);
|
||||
m_oPageData.SetHeight(DEFAULT_PAGE_HEIGHT, NSCSS::UnitMeasure::Twips, 0, true);
|
||||
@ -346,7 +346,7 @@ void COOXMLInterpretator::End(const std::wstring& wsDst)
|
||||
}
|
||||
|
||||
// webSettings.xml
|
||||
if (!m_mDivs.empty())
|
||||
if (!m_bWasDivs)
|
||||
m_oWebSettings.WriteString(L"</w:divs>");
|
||||
|
||||
m_oWebSettings.WriteString(L"</w:webSettings>");
|
||||
@ -587,7 +587,7 @@ std::wstring COOXMLInterpretator::WritePPr(const std::vector<NSCSS::CNode>& arSe
|
||||
if (sPStyle.empty() && !ElementInTable(arSelectors))
|
||||
sPStyle = L"normal-web";
|
||||
|
||||
if (sPStyle.empty() /*&& oTS.sPStyle.empty() && 0 > oTS.nLi*/)
|
||||
if (sPStyle.empty() && m_arDivId.empty() /*&& oTS.sPStyle.empty() && 0 > oTS.nLi*/)
|
||||
return L"";
|
||||
|
||||
// m_oXmlStyle.WriteLitePStyle(oTS.oAdditionalStyle);
|
||||
@ -622,6 +622,8 @@ std::wstring COOXMLInterpretator::WritePPr(const std::vector<NSCSS::CNode>& arSe
|
||||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:numPr><w:ilvl w:val=\"" + std::to_wstring(nLiLevel) + L"\"/><w:numId w:val=\"" +
|
||||
(bNumberingLi ? L"1" : std::to_wstring(m_nNumberingId)) + L"\"/></w:numPr>");
|
||||
|
||||
if (!m_arDivId.empty())
|
||||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:divId w:val=\"" + m_arDivId.top() + L"\"/>");
|
||||
// m_pCurrentDocument->WriteString(oTS.sPStyle + sPSettings);
|
||||
m_arStates.top().m_pCurrentDocument->WriteNodeEnd(L"w:pPr");
|
||||
m_arStates.top().m_bWasPStyle = true;
|
||||
@ -1036,6 +1038,24 @@ void COOXMLInterpretator::UpdatePageStyle(const std::vector<NSCSS::CNode>& arSel
|
||||
m_pStylesCalculator->CalculatePageStyle(m_oPageData, arSelectors);
|
||||
}
|
||||
|
||||
void COOXMLInterpretator::SetBaseFont(const std::wstring& wsFontStyles)
|
||||
{
|
||||
if (nullptr != m_pStylesCalculator)
|
||||
m_pStylesCalculator->AddStyles(wsFontStyles);
|
||||
}
|
||||
|
||||
void COOXMLInterpretator::SetDivId(const std::wstring& wsDivId)
|
||||
{
|
||||
m_arDivId.push(wsDivId);
|
||||
m_bWasDivs = true;
|
||||
}
|
||||
|
||||
void COOXMLInterpretator::RollBackDivId()
|
||||
{
|
||||
if (!m_arDivId.empty())
|
||||
m_arDivId.pop();
|
||||
}
|
||||
|
||||
std::wstring COOXMLInterpretator::FindFootnote(const std::wstring& wsId)
|
||||
{
|
||||
const std::map<std::wstring, std::wstring>::const_iterator itFound{m_mFootnotes.find(wsId)};
|
||||
@ -1094,6 +1114,11 @@ XmlString& COOXMLInterpretator::GetCurrentDocument()
|
||||
return *m_arStates.top().m_pCurrentDocument;
|
||||
}
|
||||
|
||||
const NSCSS::NSProperties::CPage* COOXMLInterpretator::GetPageData() const
|
||||
{
|
||||
return &m_oPageData;
|
||||
}
|
||||
|
||||
NSFonts::IApplicationFonts* COOXMLInterpretator::GetFonts()
|
||||
{
|
||||
if (nullptr == m_pFonts)
|
||||
|
||||
@ -107,11 +107,13 @@ class COOXMLInterpretator : public IHTMLInterpretator
|
||||
int m_nId; // ID остальные элементы
|
||||
int m_nShapeId; // Id shape's
|
||||
|
||||
std::stack<std::wstring> m_arDivId;
|
||||
bool m_bWasDivs;
|
||||
|
||||
std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски
|
||||
std::map<std::wstring, UINT> m_mBookmarks; // Закладки
|
||||
using anchors_map = std::map<std::wstring, std::wstring>;
|
||||
anchors_map m_mAnchors; // Map якорей с индивидуальными id
|
||||
std::map<std::wstring, UINT> m_mDivs; // Div элементы
|
||||
|
||||
NSFonts::IApplicationFonts* m_pFonts; // Необходимо для оптимизации работы со шрифтами
|
||||
public:
|
||||
@ -165,6 +167,9 @@ public:
|
||||
std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bParagraphStyle);
|
||||
|
||||
void UpdatePageStyle(const std::vector<NSCSS::CNode>& arSelectors);
|
||||
void SetBaseFont(const std::wstring& wsFontStyles);
|
||||
void SetDivId(const std::wstring& wsDivId);
|
||||
void RollBackDivId();
|
||||
|
||||
std::wstring FindFootnote(const std::wstring& wsId);
|
||||
void OpenFootnote(const std::wstring& wsFootnoteID);
|
||||
@ -179,6 +184,7 @@ public:
|
||||
XmlString& GetWebSettingsXml();
|
||||
XmlString& GetCurrentDocument();
|
||||
|
||||
const NSCSS::NSProperties::CPage* GetPageData() const;
|
||||
NSFonts::IApplicationFonts* GetFonts();
|
||||
|
||||
std::wstring GetMediaDir() const;
|
||||
|
||||
@ -67,6 +67,12 @@ CREATE_TAG(TPreformatted);
|
||||
CREATE_TAG(THeader);
|
||||
CREATE_TAG(TDivision);
|
||||
CREATE_TAG(TImage);
|
||||
|
||||
CREATE_TAG(TFont);
|
||||
CREATE_TAG(TInput);
|
||||
CREATE_TAG(TBaseFont);
|
||||
CREATE_TAG(TBlockquote);
|
||||
CREATE_TAG(THorizontalRule);
|
||||
CREATE_TAG(TList);
|
||||
CREATE_TAG(TListElement);
|
||||
}
|
||||
#endif // HTMLTAGS_H
|
||||
|
||||
@ -1,19 +1,817 @@
|
||||
#include "OOXMLTags.h"
|
||||
#include "../src/StringFinder.h"
|
||||
|
||||
#include "../../Common/Network/FileTransporter/include/FileTransporter.h"
|
||||
|
||||
#include "../../DesktopEditor/xml/include/xmlutils.h"
|
||||
#include "../../DesktopEditor/raster/BgraFrame.h"
|
||||
#include "../../DesktopEditor/graphics/pro/Graphics.h"
|
||||
#include "../../DesktopEditor/common/ProcessEnv.h"
|
||||
#include "../../DesktopEditor/common/Base64.h"
|
||||
#include "../../DesktopEditor/common/File.h"
|
||||
#include "../../DesktopEditor/common/ProcessEnv.h"
|
||||
#include "../../DesktopEditor/common/Path.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
bool IsSVG(const std::wstring& wsExtention)
|
||||
inline bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
inline bool NotValidExtension(const std::wstring& sExtention);
|
||||
inline bool IsSVG(const std::wstring& wsExtention);
|
||||
bool ReadSVG(const std::wstring& wsSvg, NSFonts::IApplicationFonts* pFonts, const std::wstring& wsTempDir, const std::wstring& wsImagePath);
|
||||
bool ReadBase64(const std::wstring& wsSrc, const std::wstring& wsImagePath, NSFonts::IApplicationFonts* pFonts, const std::wstring& wsTempDir, std::wstring& wsExtention);
|
||||
bool GetStatusUsingExternalLocalFiles();
|
||||
bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsSrcPath, const std::wstring& wsCorePath, bool bIsAllowExternalLocalFiles);
|
||||
|
||||
bool CopyImage(std::wstring wsImageSrc, const std::wstring& wsSrc, const std::wstring& wsDst, bool bIsAllowExternalLocalFiles);
|
||||
bool UpdateImageData(const std::wstring& wsImagePath, TImageData& oImageData);
|
||||
|
||||
const static double HTML_FONTS[7] = {7.5, 10, 12, 13.5, 18, 24, 36};
|
||||
|
||||
TAnchor<COOXMLInterpretator>::TAnchor(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TAnchor<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
return L"svg" == wsExtention || L"svg+xml" == wsExtention;
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
std::wstring wsRef, wsAlt, wsName;
|
||||
bool bCross = false;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"href", wsRef) && wsRef.find('#') != std::wstring::npos)
|
||||
bCross = true;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"name", wsName))
|
||||
m_pInterpretator->WriteBookmark(wsName);
|
||||
|
||||
arSelectors.back().GetAttributeValue(L"alt", wsAlt);
|
||||
|
||||
if (!m_pInterpretator->OpenP())
|
||||
m_pInterpretator->CloseR();
|
||||
else
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
|
||||
if (bCross)
|
||||
m_pInterpretator->OpenCrossHyperlink(wsRef, arSelectors);
|
||||
else
|
||||
{
|
||||
std::wstring wsTooltip(wsRef);
|
||||
arSelectors.back().GetAttributeValue(L"title", wsTooltip);
|
||||
|
||||
m_pInterpretator->OpenExternalHyperlink(wsRef, wsTooltip, arSelectors);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NotValidExtension(const std::wstring& sExtention)
|
||||
void TAnchor<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
|
||||
bool bCross = false;
|
||||
std::wstring wsFootnote;
|
||||
|
||||
if (arSelectors.back().m_wsStyle.find(L"mso-footnote-id") != std::wstring::npos)
|
||||
wsFootnote = arSelectors.back().m_wsStyle.substr(arSelectors.back().m_wsStyle.rfind(L':') + 1);
|
||||
else
|
||||
{
|
||||
if (arSelectors.back().GetAttributeValue(L"epub:type", wsFootnote) && wsFootnote.find(L"noteref"))
|
||||
wsFootnote = L"href";
|
||||
}
|
||||
|
||||
std::wstring wsRef;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"href", wsRef))
|
||||
{
|
||||
if(wsRef.find('#') != std::wstring::npos)
|
||||
bCross = true;
|
||||
}
|
||||
|
||||
if (bCross)
|
||||
{
|
||||
if (wsFootnote == L"href")
|
||||
wsFootnote = wsRef.substr(wsRef.find('#') + 1);
|
||||
|
||||
m_pInterpretator->CloseCrossHyperlink(arSelectors, wsFootnote, wsRef);
|
||||
}
|
||||
else
|
||||
m_pInterpretator->CloseExternalHyperlink();
|
||||
}
|
||||
|
||||
TAbbr<COOXMLInterpretator>::TAbbr(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TAbbr<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
std::wstring wsTitle;
|
||||
|
||||
if (!arSelectors.back().GetAttributeValue(L"title", wsTitle))
|
||||
return false;
|
||||
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
|
||||
XmlString* pCurrentDocument{&m_pInterpretator->GetCurrentDocument()};
|
||||
|
||||
pCurrentDocument->WriteString(L"<w:r><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:instrText>HYPERLINK \\l \"" + m_pInterpretator->AddLiteBookmark() + L"\" \\o \"");
|
||||
pCurrentDocument->WriteEncodeXmlString(wsTitle);
|
||||
pCurrentDocument->WriteString(L"\"</w:instrText></w:r>");
|
||||
pCurrentDocument->WriteString(L"<w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TAbbr<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
|
||||
m_pInterpretator->GetCurrentDocument().WriteString(L"<w:r><w:fldChar w:fldCharType=\"end\"/></w:r>");
|
||||
}
|
||||
|
||||
TBreak<COOXMLInterpretator>::TBreak(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TBreak<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
m_pInterpretator->Break(arSelectors);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TBreak<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
TDivision<COOXMLInterpretator>::TDivision(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TDivision<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
m_pInterpretator->UpdatePageStyle(arSelectors);
|
||||
|
||||
UINT unMsoFootnote = 0;
|
||||
|
||||
if (L"footnote" == arSelectors.back().GetAttributeValue(L"epub:type"))
|
||||
++unMsoFootnote;
|
||||
|
||||
if (std::wstring::npos != arSelectors.back().m_wsStyle.find(L"mso-element:footnote"))
|
||||
++unMsoFootnote;
|
||||
|
||||
std::wstring wsFootnoteID;
|
||||
|
||||
if (!arSelectors.back().m_wsId.empty())
|
||||
{
|
||||
wsFootnoteID = m_pInterpretator->FindFootnote(arSelectors.back().m_wsId);
|
||||
|
||||
if (!wsFootnoteID.empty())
|
||||
++unMsoFootnote;
|
||||
|
||||
if (unMsoFootnote >= 2 && !wsFootnoteID.empty())
|
||||
{
|
||||
m_pInterpretator->OpenFootnote(wsFootnoteID);
|
||||
m_pInterpretator->SetCurrentDocument(&m_pInterpretator->GetNotesXml());
|
||||
}
|
||||
}
|
||||
|
||||
m_arFootnoteIDs.push(unMsoFootnote);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TDivision<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator() || m_arFootnoteIDs.empty())
|
||||
return;
|
||||
|
||||
if (m_arFootnoteIDs.top() >= 2)
|
||||
{
|
||||
m_pInterpretator->CloseFootnote();
|
||||
m_pInterpretator->RollBackState();
|
||||
}
|
||||
|
||||
m_arFootnoteIDs.pop();
|
||||
}
|
||||
|
||||
TImage<COOXMLInterpretator>::TImage(COOXMLInterpretator* pInterpretator, XmlUtils::CXmlLiteReader* pXmlReader)
|
||||
: TTag(pInterpretator), m_pXmlReader(pXmlReader)
|
||||
{}
|
||||
|
||||
bool TImage<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
if (L"svg" == arSelectors.back().m_wsName)
|
||||
{
|
||||
if (nullptr == m_pXmlReader)
|
||||
return false;
|
||||
|
||||
const std::wstring wsImagePath{m_pInterpretator->GetMediaDir() + L'i' + std::to_wstring(m_arrImages.size()) + L".png"};
|
||||
|
||||
if (!ReadSVG(m_pXmlReader->GetOuterXml(), m_pInterpretator->GetFonts(), m_pInterpretator->GetTempDir(), wsImagePath))
|
||||
return false;
|
||||
|
||||
TImageData oNewImageData;
|
||||
if (!UpdateImageData(wsImagePath, oNewImageData))
|
||||
return false;
|
||||
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
m_pInterpretator->WriteImage(oNewImageData, std::to_wstring(m_arrImages.size()));
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::wstring wsAlt{arSelectors.back().GetAttributeValue(L"alt")};
|
||||
std::wstring wsSrc{arSelectors.back().GetAttributeValue(L"src")};
|
||||
|
||||
TImageData oImageData;
|
||||
|
||||
std::wstring wsTempValue;
|
||||
NSCSS::NSProperties::CDigit oTempDigit;
|
||||
|
||||
#define GET_UNIT_DATA(variable_data, data_variable)\
|
||||
if (NSCSS::UnitMeasure::None == data_variable.GetUnitMeasure())\
|
||||
variable_data = static_cast<UINT>(NSCSS::CUnitMeasureConverter::ConvertPx(data_variable.ToDouble(), NSCSS::Inch, 96) * 914400);\
|
||||
else\
|
||||
variable_data = static_cast<UINT>(data_variable.ToDouble(NSCSS::Inch) * 914400)
|
||||
|
||||
#define READ_IMAGE_DATA(name_data, variable_data)\
|
||||
if (arSelectors.back().GetAttributeValue(name_data, wsTempValue))\
|
||||
{\
|
||||
if (oTempDigit.SetValue(wsTempValue))\
|
||||
{\
|
||||
GET_UNIT_DATA(variable_data, oTempDigit);\
|
||||
}\
|
||||
}
|
||||
|
||||
READ_IMAGE_DATA(L"width", oImageData.m_unWidth);
|
||||
READ_IMAGE_DATA(L"height", oImageData.m_unHeight);
|
||||
READ_IMAGE_DATA(L"hspace", oImageData.m_nHSpace);
|
||||
READ_IMAGE_DATA(L"vspace", oImageData.m_nVSpace);
|
||||
|
||||
if (nullptr != arSelectors.back().m_pCompiledStyle)
|
||||
{
|
||||
oTempDigit = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetWidth();
|
||||
|
||||
if (0 == oImageData.m_unWidth && !oTempDigit.Empty())
|
||||
{
|
||||
GET_UNIT_DATA(oImageData.m_unWidth, oTempDigit);
|
||||
}
|
||||
|
||||
oTempDigit = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetHeight();
|
||||
|
||||
if (0 == oImageData.m_unHeight && !oTempDigit.Empty())
|
||||
{
|
||||
GET_UNIT_DATA(oImageData.m_unHeight, oTempDigit);
|
||||
}
|
||||
}
|
||||
|
||||
if (wsSrc.empty())
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bRes = false;
|
||||
std::wstring wsExtention;
|
||||
const std::wstring wsImagePath{m_pInterpretator->GetMediaDir() + L'i' + std::to_wstring(m_arrImages.size())};
|
||||
|
||||
// Предполагаем картинку в Base64
|
||||
if (wsSrc.length() > 4 && wsSrc.substr(0, 4) == L"data" && wsSrc.find(L"/", 4) != std::wstring::npos)
|
||||
bRes = ReadBase64(wsSrc, wsImagePath, m_pInterpretator->GetFonts(), m_pInterpretator->GetTempDir(), wsExtention);
|
||||
|
||||
const bool bIsAllowExternalLocalFiles = GetStatusUsingExternalLocalFiles();
|
||||
|
||||
if (!bRes && (wsSrc.length() <= 7 || L"http" != wsSrc.substr(0, 4)))
|
||||
{
|
||||
wsSrc = NSSystemPath::ShortenPath(wsSrc);
|
||||
|
||||
if (!CanUseThisPath(wsSrc, m_pInterpretator->GetSrcPath(), m_pInterpretator->GetCorePath(), bIsAllowExternalLocalFiles))
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверка расширения
|
||||
if (!bRes)
|
||||
{
|
||||
wsExtention = NSFile::GetFileExtention(wsSrc);
|
||||
std::transform(wsExtention.begin(), wsExtention.end(), wsExtention.begin(), tolower);
|
||||
|
||||
std::wstring::const_iterator itFound = std::find_if(wsExtention.cbegin(), wsExtention.cend(), [](wchar_t wChar){ return !iswalpha(wChar) && L'+' != wChar; });
|
||||
|
||||
if (wsExtention.cend() != itFound)
|
||||
wsExtention.erase(itFound, wsExtention.cend());
|
||||
}
|
||||
|
||||
const std::wstring wsBasePath{m_pInterpretator->GetBasePath()};
|
||||
|
||||
// Предполагаем картинку в сети
|
||||
if (!bRes &&
|
||||
((!wsBasePath.empty() && wsBasePath.length() > 4 && wsBasePath.substr(0, 4) == L"http") ||
|
||||
(wsSrc.length() > 4 && wsSrc.substr(0, 4) == L"http")))
|
||||
{
|
||||
const std::wstring wsDst = wsImagePath + L'.' + ((!wsExtention.empty()) ? wsExtention : L"png");
|
||||
|
||||
// Проверка gc_allowNetworkRequest предполагается в kernel_network
|
||||
NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(m_pInterpretator->GetBasePath() + wsSrc, false);
|
||||
oDownloadImg.SetFilePath(wsDst);
|
||||
bRes = oDownloadImg.DownloadSync();
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsSVG(wsExtention))
|
||||
{
|
||||
std::wstring wsFileData;
|
||||
|
||||
if (!NSFile::CFileBinary::ReadAllTextUtf8(wsDst, wsFileData) ||
|
||||
!ReadSVG(wsFileData, m_pInterpretator->GetFonts(), m_pInterpretator->GetTempDir(), wsImagePath))
|
||||
bRes = false;
|
||||
|
||||
NSFile::CFileBinary::Remove(wsDst);
|
||||
wsExtention = L"png";
|
||||
}
|
||||
else if (wsExtention.empty())
|
||||
{
|
||||
//TODO:: лучше узнавать формат изображения из содержимого
|
||||
wsExtention = L"png";
|
||||
}
|
||||
}
|
||||
|
||||
int nImageId = -1;
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
if (NotValidExtension(wsExtention))
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Проверка на повтор
|
||||
std::vector<std::wstring>::iterator nFind = std::find(m_arrImages.begin(), m_arrImages.end(), wsSrc);
|
||||
if (nFind != m_arrImages.end())
|
||||
{
|
||||
bRes = true;
|
||||
nImageId = nFind - m_arrImages.begin();
|
||||
}
|
||||
}
|
||||
|
||||
// Предполагаем картинку по локальному пути
|
||||
if (!bRes)
|
||||
{
|
||||
const std::wstring wsDst = wsImagePath + L'.' + wsExtention;
|
||||
|
||||
if (!m_pInterpretator->GetBasePath().empty())
|
||||
{
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_pInterpretator->GetBasePath(), wsSrc), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_pInterpretator->GetSrcPath(), NSSystemPath::Combine(m_pInterpretator->GetBasePath(), wsSrc)), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
if (!bRes)
|
||||
bRes = CopyImage(NSSystemPath::Combine(m_pInterpretator->GetSrcPath(), wsSrc), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(m_pInterpretator->GetSrcPath() + L"/" + NSFile::GetFileName(wsSrc), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(wsSrc, m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
|
||||
if (!bRes)
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
else
|
||||
{
|
||||
m_arrImages.push_back(wsSrc);
|
||||
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
|
||||
const std::wstring wsImageID{std::to_wstring(m_arrImages.size())};
|
||||
|
||||
if (nImageId < 0)
|
||||
{
|
||||
m_pInterpretator->WriteImageRels(wsImageID, wsImageID + L'.' + wsExtention);
|
||||
m_arrImages.push_back(wsSrc);
|
||||
}
|
||||
|
||||
if (!oImageData.ZeroSize())
|
||||
{
|
||||
m_pInterpretator->WriteImage(oImageData, wsImageID);
|
||||
return true;
|
||||
}
|
||||
|
||||
TImageData oNewImageData{oImageData};
|
||||
if (!UpdateImageData(wsImagePath + L'.' + wsExtention, oNewImageData))
|
||||
return false;
|
||||
|
||||
m_pInterpretator->WriteImage(oNewImageData, wsImageID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TImage<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
TFont<COOXMLInterpretator>::TFont(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TFont<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
std::wstring wsValue;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"color", wsValue))
|
||||
arSelectors.back().m_pCompiledStyle->m_oText.SetColor(wsValue, arSelectors.size());
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"face", wsValue))
|
||||
arSelectors.back().m_pCompiledStyle->m_oFont.SetFamily(wsValue, arSelectors.size());
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"size", wsValue))
|
||||
{
|
||||
int nSize = 3;
|
||||
if(!wsValue.empty())
|
||||
{
|
||||
// if(wsValue.front() == L'+')
|
||||
// nSize += NSStringFinder::ToInt(wsValue.substr(1));
|
||||
// else if(wsValue.front() == L'-')
|
||||
// nSize -= NSStringFinder::ToInt(wsValue.substr(1));
|
||||
// else
|
||||
// nSize = NSStringFinder::ToInt(wsValue);
|
||||
}
|
||||
|
||||
if (nSize < 1 || nSize > 7)
|
||||
nSize = 3;
|
||||
|
||||
arSelectors.back().m_pCompiledStyle->m_oFont.SetSize(HTML_FONTS[nSize - 1], NSCSS::UnitMeasure::Point, arSelectors.size());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TFont<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
TInput<COOXMLInterpretator>::TInput(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TInput<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
std::wstring wsValue{arSelectors.back().GetAttributeValue(L"value")};
|
||||
const std::wstring wsAlt{arSelectors.back().GetAttributeValue(L"alt")},
|
||||
wsType{arSelectors.back().GetAttributeValue(L"type")};
|
||||
|
||||
if(wsType == L"hidden")
|
||||
return false;
|
||||
|
||||
if(wsValue.empty())
|
||||
wsValue = wsAlt;
|
||||
|
||||
if(!wsValue.empty())
|
||||
{
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
m_pInterpretator->OpenR();
|
||||
m_pInterpretator->WriteRPr(m_pInterpretator->GetCurrentDocument(), arSelectors);
|
||||
m_pInterpretator->OpenT();
|
||||
m_pInterpretator->GetCurrentDocument().WriteEncodeXmlString(wsValue + L' ');
|
||||
m_pInterpretator->CloseT();
|
||||
m_pInterpretator->CloseR();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TInput<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
TBaseFont<COOXMLInterpretator>::TBaseFont(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TBaseFont<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
std::wstring wsFontStyles, wsValue;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"face", wsValue))
|
||||
wsFontStyles += L"font-family:" + wsValue + L';';
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"size", wsValue))
|
||||
{
|
||||
wsFontStyles += L"font-size:";
|
||||
|
||||
switch(NSStringFinder::ToInt(wsValue, 3))
|
||||
{
|
||||
case 1: wsFontStyles += L"7.5pt;"; break;
|
||||
case 2: wsFontStyles += L"10pt;"; break;
|
||||
default:
|
||||
case 3: wsFontStyles += L"12pt;"; break;
|
||||
case 4: wsFontStyles += L"13.5pt;"; break;
|
||||
case 5: wsFontStyles += L"18pt;"; break;
|
||||
case 6: wsFontStyles += L"24pt;"; break;
|
||||
case 7: wsFontStyles += L"36pt;"; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"color", wsValue))
|
||||
wsFontStyles += L"text-color:" + wsValue + L';';
|
||||
|
||||
if (wsFontStyles.empty())
|
||||
return false;
|
||||
|
||||
m_pInterpretator->SetBaseFont(L"*{" + wsFontStyles + L'}');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TBaseFont<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
TBlockquote<COOXMLInterpretator>::TBlockquote(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TBlockquote<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
const std::wstring wsKeyWord{arSelectors.back().m_wsName};
|
||||
|
||||
std::map<std::wstring, UINT>::const_iterator itFound = m_mDivs.find(wsKeyWord);
|
||||
|
||||
if (m_mDivs.end() != itFound)
|
||||
{
|
||||
m_pInterpretator->SetDivId(std::to_wstring(itFound->second));
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::wstring wsId{std::to_wstring(m_mDivs.size() + 1)};
|
||||
|
||||
XmlString &oWebSettings{m_pInterpretator->GetWebSettingsXml()};
|
||||
|
||||
if (m_mDivs.empty())
|
||||
oWebSettings.WriteString(L"<w:divs>");
|
||||
|
||||
NSCSS::CCompiledStyle *pStyle = arSelectors.back().m_pCompiledStyle;
|
||||
|
||||
const bool bInTable = ElementInTable(arSelectors);
|
||||
|
||||
INT nMarLeft = (!bInTable) ? 720 : 0;
|
||||
INT nMarRight = (!bInTable) ? 720 : 0;
|
||||
INT nMarTop = (!bInTable) ? 100 : 0;
|
||||
INT nMarBottom = (!bInTable) ? 100 : 0;
|
||||
|
||||
const NSCSS::NSProperties::CPage *pPageData{m_pInterpretator->GetPageData()};
|
||||
|
||||
if (!pStyle->m_oMargin.GetLeft().Empty() && !pStyle->m_oMargin.GetLeft().Zero())
|
||||
nMarLeft = pStyle->m_oMargin.GetLeft().ToInt(NSCSS::Twips, pPageData->GetWidth().ToInt(NSCSS::Twips));
|
||||
|
||||
if (!pStyle->m_oMargin.GetRight().Empty() && !pStyle->m_oMargin.GetRight().Zero())
|
||||
nMarRight = pStyle->m_oMargin.GetRight().ToInt(NSCSS::Twips, pPageData->GetWidth().ToInt(NSCSS::Twips));
|
||||
|
||||
if (!pStyle->m_oMargin.GetTop().Empty() && !pStyle->m_oMargin.GetTop().Zero())
|
||||
nMarTop = pStyle->m_oMargin.GetTop().ToInt(NSCSS::Twips, pPageData->GetHeight().ToInt(NSCSS::Twips));
|
||||
|
||||
if (!pStyle->m_oMargin.GetBottom().Empty() && !pStyle->m_oMargin.GetBottom().Zero())
|
||||
nMarBottom = pStyle->m_oMargin.GetBottom().ToInt(NSCSS::Twips, pPageData->GetHeight().ToInt(NSCSS::Twips));
|
||||
|
||||
if (L"blockquote" == wsKeyWord)
|
||||
{
|
||||
oWebSettings.WriteString(L"<w:div w:id=\"" + wsId + L"\">");
|
||||
oWebSettings.WriteString(L"<w:blockQuote w:val=\"1\"/>");
|
||||
oWebSettings.WriteString(L"<w:marLeft w:val=\"" + std::to_wstring(nMarLeft) + L"\"/>");
|
||||
oWebSettings.WriteString(L"<w:marRight w:val=\"" + std::to_wstring(nMarRight) + L"\"/>");
|
||||
oWebSettings.WriteString(L"<w:marTop w:val=\"" + std::to_wstring(nMarTop) + L"\"/>");
|
||||
oWebSettings.WriteString(L"<w:marBottom w:val=\"" + std::to_wstring(nMarBottom) + L"\"/>");
|
||||
oWebSettings.WriteString(L"<w:divBdr>");
|
||||
oWebSettings.WriteString(L"<w:top w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>");
|
||||
oWebSettings.WriteString(L"<w:left w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>");
|
||||
oWebSettings.WriteString(L"<w:bottom w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>");
|
||||
oWebSettings.WriteString(L"<w:right w:val=\"none\" w:sz=\"0\" w:space=\"0\" w:color=\"auto\"/>");
|
||||
oWebSettings.WriteString(L"</w:divBdr>");
|
||||
oWebSettings.WriteString(L"</w:div>");
|
||||
}
|
||||
|
||||
m_mDivs.insert(std::make_pair(wsKeyWord, m_mDivs.size() + 1));
|
||||
|
||||
m_pInterpretator->SetDivId(wsId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TBlockquote<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
|
||||
m_pInterpretator->RollBackDivId();
|
||||
}
|
||||
|
||||
THorizontalRule<COOXMLInterpretator>::THorizontalRule(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator), m_unShapeId(1)
|
||||
{}
|
||||
|
||||
bool THorizontalRule<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
for (const NSCSS::CNode& item : arSelectors)
|
||||
{
|
||||
if (item.m_wsName == L"div" && item.m_wsStyle == L"mso-element:footnote-list")
|
||||
return false;
|
||||
}
|
||||
|
||||
NSCSS::NSProperties::CDigit oSize, oWidth;
|
||||
NSCSS::NSProperties::CColor oColor;
|
||||
bool bShade = true;
|
||||
std::wstring wsAlign{L"center"};
|
||||
std::wstring wsValue;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"align", wsValue))
|
||||
{
|
||||
if (NSStringFinder::Equals(L"left", wsValue))
|
||||
wsAlign = L"left";
|
||||
else if (NSStringFinder::Equals(L"right", wsValue))
|
||||
wsAlign = L"right";
|
||||
else if (NSStringFinder::Equals(L"center", wsValue))
|
||||
wsAlign = L"center";
|
||||
}
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"color", wsValue))
|
||||
oColor.SetValue(wsValue);
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"noshade", wsValue))
|
||||
bShade = false;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"size", wsValue))
|
||||
oSize.SetValue(wsValue);
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"width", wsValue))
|
||||
oWidth.SetValue(wsValue);
|
||||
|
||||
XmlString& oCurrentDocument{m_pInterpretator->GetCurrentDocument()};
|
||||
|
||||
m_pInterpretator->OpenP();
|
||||
oCurrentDocument.WriteString(L"<w:pPr><w:jc w:val=\"" + wsAlign + L"\"/></w:pPr>");
|
||||
m_pInterpretator->OpenR();
|
||||
|
||||
const NSCSS::NSProperties::CPage *pPageData{m_pInterpretator->GetPageData()};
|
||||
|
||||
const unsigned int unPageWidth{static_cast<unsigned int>((pPageData->GetWidth().ToDouble(NSCSS::Inch) - pPageData->GetMargin().GetLeft().ToDouble(NSCSS::Inch) - pPageData->GetMargin().GetRight().ToDouble(NSCSS::Inch)) * 914400.)};
|
||||
|
||||
std::wstring wsWidth;
|
||||
|
||||
// width измеряется в px или %
|
||||
if (!oWidth.Empty())
|
||||
wsWidth = std::to_wstring(static_cast<int>((NSCSS::UnitMeasure::Percent != oWidth.GetUnitMeasure()) ? (NSCSS::CUnitMeasureConverter::ConvertPx(oWidth.ToDouble(), NSCSS::Inch, 96) * 914400.) : oWidth.ToDouble(NSCSS::Inch, unPageWidth)));
|
||||
else
|
||||
wsWidth = std::to_wstring(unPageWidth);
|
||||
|
||||
std::wstring wsHeight{L"14288"};
|
||||
|
||||
// size измеряется только в px
|
||||
if (!oSize.Empty())
|
||||
wsHeight = std::to_wstring(static_cast<int>(NSCSS::CUnitMeasureConverter::ConvertPx(oSize.ToDouble(), NSCSS::Inch, 96) * 914400.));
|
||||
|
||||
oCurrentDocument.WriteString(L"<w:rPr><w:noProof/></w:rPr>");
|
||||
oCurrentDocument.WriteString(L"<mc:AlternateContent><mc:Choice Requires=\"wps\"><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\">");
|
||||
oCurrentDocument.WriteString(L"<wp:extent cx=\"" + wsWidth + L"\" cy=\"0\"/>");
|
||||
oCurrentDocument.WriteString(L"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>");
|
||||
oCurrentDocument.WriteString(L"<wp:docPr id=\"" + std::to_wstring(m_unShapeId) + L"\" name=\"Line " + std::to_wstring(m_unShapeId) + L"\"/>"
|
||||
"<wp:cNvGraphicFramePr/>"
|
||||
"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
|
||||
"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">"
|
||||
"<wps:wsp>"
|
||||
"<wps:cNvSpPr/>"
|
||||
"<wps:spPr>");
|
||||
oCurrentDocument.WriteString(L"<a:xfrm>"
|
||||
"<a:off x=\"0\" y=\"0\"/>"
|
||||
"<a:ext cx=\"" + wsWidth + L"\" cy=\"0\"/>"
|
||||
"</a:xfrm>"
|
||||
"<a:custGeom><a:pathLst><a:path>"
|
||||
"<a:moveTo><a:pt x=\"0\" y=\"0\"/></a:moveTo>"
|
||||
"<a:lnTo><a:pt x=\"" + wsWidth + L"\" y=\"0\"/></a:lnTo>"
|
||||
"</a:path></a:pathLst></a:custGeom>"
|
||||
"<a:ln w=\"" + wsHeight + L"\"><a:solidFill><a:srgbClr val=\"" + ((!oColor.Empty()) ? oColor.ToHEX() : L"808080") + L"\"/></a:solidFill></a:ln>");
|
||||
|
||||
if (bShade)
|
||||
oCurrentDocument.WriteString(L"<a:scene3d><a:camera prst=\"orthographicFront\"/><a:lightRig rig=\"threePt\" dir=\"t\"/></a:scene3d><a:sp3d><a:bevelT prst=\"angle\"/></a:sp3d>");
|
||||
|
||||
oCurrentDocument.WriteString(L"</wps:spPr><wps:bodyPr/></wps:wsp></a:graphicData></a:graphic></wp:inline></w:drawing></mc:Choice></mc:AlternateContent>");
|
||||
|
||||
m_pInterpretator->CloseP();
|
||||
|
||||
++m_unShapeId;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void THorizontalRule<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
TList<COOXMLInterpretator>::TList(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator), m_unNumberingId(1)
|
||||
{}
|
||||
|
||||
bool TList<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
m_pInterpretator->CloseP();
|
||||
|
||||
//Нумерованный список
|
||||
if (L"ol" == arSelectors.back().m_wsName)
|
||||
{
|
||||
const int nStart{NSStringFinder::ToInt(arSelectors.back().GetAttributeValue(L"start"), 1)};
|
||||
|
||||
XmlString& oNumberXml{m_pInterpretator->GetNumberingXml()};
|
||||
|
||||
const std::wstring wsStart(std::to_wstring(nStart));
|
||||
oNumberXml.WriteString(L"<w:abstractNum w:abstractNumId=\"");
|
||||
oNumberXml.WriteString(std::to_wstring(m_unNumberingId++));
|
||||
oNumberXml.WriteString(L"\"><w:multiLevelType w:val=\"hybridMultilevel\"/><w:lvl w:ilvl=\"0\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"709\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"1\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%2.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1429\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"2\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%3.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"2149\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"3\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%4.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2869\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"4\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%5.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3589\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"5\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%6.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"4309\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"6\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%7.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5029\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"7\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%8.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5749\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"8\"><w:start w:val=\"");
|
||||
oNumberXml.WriteString(wsStart);
|
||||
oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%9.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"6469\" w:hanging=\"180\"/></w:pPr></w:lvl></w:abstractNum>");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TList<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
|
||||
m_pInterpretator->CloseP();
|
||||
}
|
||||
|
||||
TListElement<COOXMLInterpretator>::TListElement(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
bool TListElement<COOXMLInterpretator>::Open(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
return ValidInterpretator();
|
||||
}
|
||||
|
||||
void TListElement<COOXMLInterpretator>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
|
||||
m_pInterpretator->CloseP();
|
||||
}
|
||||
|
||||
inline bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; });
|
||||
}
|
||||
|
||||
inline bool NotValidExtension(const std::wstring& sExtention)
|
||||
{
|
||||
return sExtention != L"bmp" && sExtention != L"emf" && sExtention != L"emz" && sExtention != L"eps" && sExtention != L"fpx" && sExtention != L"gif" &&
|
||||
sExtention != L"jpe" && sExtention != L"jpeg" && sExtention != L"jpg" && sExtention != L"jfif" && sExtention != L"pct" && sExtention != L"pict" &&
|
||||
@ -21,11 +819,13 @@ bool NotValidExtension(const std::wstring& sExtention)
|
||||
sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && !IsSVG(sExtention);
|
||||
}
|
||||
|
||||
inline bool IsSVG(const std::wstring& wsExtention)
|
||||
{
|
||||
return L"svg" == wsExtention || L"svg+xml" == wsExtention;
|
||||
}
|
||||
|
||||
bool ReadSVG(const std::wstring& wsSvg, NSFonts::IApplicationFonts* pFonts, const std::wstring& wsTempDir, const std::wstring& wsImagePath)
|
||||
{
|
||||
if (wsSvg.empty())
|
||||
return false;
|
||||
|
||||
MetaFile::IMetaFile* pSvgReader = MetaFile::Create(pFonts);
|
||||
if (!pSvgReader->LoadFromString(wsSvg))
|
||||
{
|
||||
@ -96,7 +896,6 @@ bool ReadSVG(const std::wstring& wsSvg, NSFonts::IApplicationFonts* pFonts, cons
|
||||
pGrRenderer->put_Width(dWidth);
|
||||
pGrRenderer->put_Height(dHeight);
|
||||
|
||||
// TODO: src directory as tmp - it's not good idea
|
||||
pSvgReader->SetTempDirectory(wsTempDir);
|
||||
pSvgReader->DrawOnRenderer(pGrRenderer, 0, 0, dWidth, dHeight);
|
||||
|
||||
@ -121,7 +920,7 @@ bool ReadBase64(const std::wstring& wsSrc, const std::wstring& wsImagePath, NSFo
|
||||
|
||||
size_t nEndBase = wsSrc.find(L";", nBase);
|
||||
if (nEndBase == std::wstring::npos)
|
||||
return false;
|
||||
return bRes;
|
||||
|
||||
wsExtention = wsSrc.substr(nBase, nEndBase - nBase);
|
||||
|
||||
@ -129,11 +928,11 @@ bool ReadBase64(const std::wstring& wsSrc, const std::wstring& wsImagePath, NSFo
|
||||
wsExtention = L"jpg";
|
||||
|
||||
if (NotValidExtension(wsExtention))
|
||||
return false;
|
||||
return bRes;
|
||||
|
||||
nBase = wsSrc.find(L"base64", nEndBase);
|
||||
if (nBase == std::wstring::npos)
|
||||
return false;
|
||||
return bRes;
|
||||
|
||||
int nOffset = nBase + 7;
|
||||
int nSrcLen = (int)(wsSrc.length() - nBase + 1);
|
||||
@ -183,17 +982,7 @@ bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsSrcPath, c
|
||||
if (!wsCorePath.empty())
|
||||
{
|
||||
const std::wstring wsFullPath = NSSystemPath::ShortenPath(NSSystemPath::Combine(wsSrcPath, wsPath));
|
||||
|
||||
std::wstring::const_iterator itFirst{wsFullPath.cbegin()};
|
||||
std::wstring::const_iterator itSecond{wsCorePath.cbegin()};
|
||||
|
||||
for (;itFirst != wsFullPath.cend() && itSecond != wsCorePath.cend(); ++itFirst, ++itSecond)
|
||||
{
|
||||
if (*itFirst != *itSecond)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return boost::starts_with(wsFullPath, wsCorePath);
|
||||
}
|
||||
|
||||
if (wsPath.length() >= 3 && L"../" == wsPath.substr(0, 3))
|
||||
@ -202,43 +991,6 @@ bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsSrcPath, c
|
||||
return true;
|
||||
}
|
||||
|
||||
std::wstring NormalizePath(const std::wstring& wsPath)
|
||||
{
|
||||
return NSSystemPath::ShortenPath(wsPath);
|
||||
}
|
||||
|
||||
std::wstring GetFileExtention(const std::wstring& wsFilePath)
|
||||
{
|
||||
return NSFile::GetFileExtention(wsFilePath);
|
||||
}
|
||||
|
||||
std::wstring GetFileName(const std::wstring& wsFilePath)
|
||||
{
|
||||
return NSFile::GetFileName(wsFilePath);
|
||||
}
|
||||
|
||||
bool DownloadImage(const std::wstring& wsHref, const std::wstring& wsDst)
|
||||
{
|
||||
NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(wsHref, false);
|
||||
oDownloadImg.SetFilePath(wsDst);
|
||||
return oDownloadImg.DownloadSync();
|
||||
}
|
||||
|
||||
bool ReadAllTextUtf8(const std::wstring& wsFilePath, std::wstring& wsText)
|
||||
{
|
||||
return NSFile::CFileBinary::ReadAllTextUtf8(wsFilePath, wsText);
|
||||
}
|
||||
|
||||
bool RemoveFile(const std::wstring& wsFilePath)
|
||||
{
|
||||
return NSFile::CFileBinary::Remove(wsFilePath);
|
||||
}
|
||||
|
||||
std::wstring CombinePaths(const std::wstring& wsFirstPath, const std::wstring& wsSecondPath)
|
||||
{
|
||||
return NSSystemPath::Combine(wsFirstPath, wsSecondPath);
|
||||
}
|
||||
|
||||
bool CopyImage(std::wstring wsImageSrc, const std::wstring& wsSrc, const std::wstring& wsDst, bool bIsAllowExternalLocalFiles)
|
||||
{
|
||||
bool bRes = false;
|
||||
@ -247,11 +999,11 @@ bool CopyImage(std::wstring wsImageSrc, const std::wstring& wsSrc, const std::ws
|
||||
if (!bIsAllowExternalLocalFiles)
|
||||
{
|
||||
wsImageSrc = NSSystemPath::NormalizePath(wsImageSrc);
|
||||
std::wstring wsStartSrc = NSSystemPath::NormalizePath(wsSrc);
|
||||
const std::wstring wsStartSrc = NSSystemPath::NormalizePath(wsSrc);
|
||||
bAllow = wsImageSrc.substr(0, wsStartSrc.length()) == wsStartSrc;
|
||||
}
|
||||
if (bAllow)
|
||||
bRes = NSFile::CFileBinary::Copy(wsImageSrc, wsDst);
|
||||
bRes = NSFile::CFileBinary::Copy(wsSrc, wsDst);
|
||||
|
||||
return bRes;
|
||||
}
|
||||
@ -303,5 +1055,4 @@ bool UpdateImageData(const std::wstring& wsImagePath, TImageData& oImageData)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,145 +5,32 @@
|
||||
#include "../Interpretators/OOXMLInterpretator.h"
|
||||
#include <stack>
|
||||
|
||||
namespace XmlUtils { class CXmlLiteReader; }
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
template<>
|
||||
struct TAnchor<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
TAnchor(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
std::wstring wsRef, wsAlt, wsName;
|
||||
bool bCross = false;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"href", wsRef) && wsRef.find('#') != std::wstring::npos)
|
||||
bCross = true;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"name", wsName))
|
||||
m_pInterpretator->WriteBookmark(wsName);
|
||||
|
||||
arSelectors.back().GetAttributeValue(L"alt", wsAlt);
|
||||
|
||||
if (!m_pInterpretator->OpenP())
|
||||
m_pInterpretator->CloseR();
|
||||
else
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
|
||||
if (bCross)
|
||||
m_pInterpretator->OpenCrossHyperlink(wsRef, arSelectors);
|
||||
else
|
||||
{
|
||||
std::wstring wsTooltip(wsRef);
|
||||
arSelectors.back().GetAttributeValue(L"title", wsTooltip);
|
||||
|
||||
m_pInterpretator->OpenExternalHyperlink(wsRef, wsTooltip, arSelectors);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
|
||||
bool bCross = false;
|
||||
std::wstring wsFootnote;
|
||||
|
||||
if (arSelectors.back().m_wsStyle.find(L"mso-footnote-id") != std::wstring::npos)
|
||||
wsFootnote = arSelectors.back().m_wsStyle.substr(arSelectors.back().m_wsStyle.rfind(L':') + 1);
|
||||
else
|
||||
{
|
||||
if (arSelectors.back().GetAttributeValue(L"epub:type", wsFootnote) && wsFootnote.find(L"noteref"))
|
||||
wsFootnote = L"href";
|
||||
}
|
||||
|
||||
std::wstring wsRef;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"href", wsRef))
|
||||
{
|
||||
if(wsRef.find('#') != std::wstring::npos)
|
||||
bCross = true;
|
||||
}
|
||||
|
||||
if (bCross)
|
||||
{
|
||||
if (wsFootnote == L"href")
|
||||
wsFootnote = wsRef.substr(wsRef.find('#') + 1);
|
||||
|
||||
m_pInterpretator->CloseCrossHyperlink(arSelectors, wsFootnote, wsRef);
|
||||
}
|
||||
else
|
||||
m_pInterpretator->CloseExternalHyperlink();
|
||||
}
|
||||
TAnchor(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TAbbr<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
TAbbr(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
std::wstring wsTitle;
|
||||
|
||||
if (!arSelectors.back().GetAttributeValue(L"title", wsTitle))
|
||||
return false;
|
||||
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
|
||||
XmlString* pCurrentDocument{&m_pInterpretator->GetCurrentDocument()};
|
||||
|
||||
pCurrentDocument->WriteString(L"<w:r><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:instrText>HYPERLINK \\l \"" + m_pInterpretator->AddLiteBookmark() + L"\" \\o \"");
|
||||
pCurrentDocument->WriteEncodeXmlString(wsTitle);
|
||||
pCurrentDocument->WriteString(L"\"</w:instrText></w:r>");
|
||||
pCurrentDocument->WriteString(L"<w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
|
||||
m_pInterpretator->GetCurrentDocument().WriteString(L"<w:r><w:fldChar w:fldCharType=\"end\"/></w:r>");
|
||||
}
|
||||
TAbbr(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TBreak<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
TBreak(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
m_pInterpretator->Break(arSelectors);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
}
|
||||
TBreak(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -151,291 +38,82 @@ struct TDivision<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
std::stack<UINT> m_arFootnoteIDs;
|
||||
|
||||
TDivision(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
|
||||
m_pInterpretator->UpdatePageStyle(arSelectors);
|
||||
|
||||
UINT unMsoFootnote = 0;
|
||||
|
||||
if (L"footnote" == arSelectors.back().GetAttributeValue(L"epub:type"))
|
||||
++unMsoFootnote;
|
||||
|
||||
if (std::wstring::npos != arSelectors.back().m_wsStyle.find(L"mso-element:footnote"))
|
||||
++unMsoFootnote;
|
||||
|
||||
std::wstring wsFootnoteID;
|
||||
|
||||
if (!arSelectors.back().m_wsId.empty())
|
||||
{
|
||||
wsFootnoteID = m_pInterpretator->FindFootnote(arSelectors.back().m_wsId);
|
||||
|
||||
if (!wsFootnoteID.empty())
|
||||
++unMsoFootnote;
|
||||
|
||||
if (unMsoFootnote >= 2 && !wsFootnoteID.empty())
|
||||
{
|
||||
m_pInterpretator->OpenFootnote(wsFootnoteID);
|
||||
m_pInterpretator->SetCurrentDocument(&m_pInterpretator->GetNotesXml());
|
||||
}
|
||||
}
|
||||
|
||||
m_arFootnoteIDs.push(unMsoFootnote);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator() || m_arFootnoteIDs.empty())
|
||||
return;
|
||||
|
||||
if (m_arFootnoteIDs.top() >= 2)
|
||||
{
|
||||
m_pInterpretator->CloseFootnote();
|
||||
m_pInterpretator->RollBackState();
|
||||
}
|
||||
|
||||
m_arFootnoteIDs.pop();
|
||||
}
|
||||
TDivision(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
bool NotValidExtension(const std::wstring& sExtention);
|
||||
bool IsSVG(const std::wstring& wsExtention);
|
||||
bool ReadSVG(const std::wstring& wsSvg, NSFonts::IApplicationFonts* pFonts, const std::wstring& wsTempDir, const std::wstring& wsImagePath);
|
||||
bool ReadBase64(const std::wstring& wsSrc, const std::wstring& wsImagePath, NSFonts::IApplicationFonts* pFonts, const std::wstring& wsTempDir, std::wstring& wsExtention);
|
||||
bool GetStatusUsingExternalLocalFiles();
|
||||
bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsSrcPath, const std::wstring& wsCorePath, bool bIsAllowExternalLocalFiles);
|
||||
|
||||
std::wstring NormalizePath(const std::wstring& wsPath);
|
||||
std::wstring CombinePaths(const std::wstring& wsFirstPath, const std::wstring& wsSecondPath);
|
||||
|
||||
std::wstring GetFileExtention(const std::wstring& wsFilePath);
|
||||
std::wstring GetFileName(const std::wstring& wsFilePath);
|
||||
|
||||
bool DownloadImage(const std::wstring& wsHref, const std::wstring& wsDst);
|
||||
bool CopyImage(std::wstring wsImageSrc, const std::wstring& wsSrc, const std::wstring& wsDst, bool bIsAllowExternalLocalFiles);
|
||||
bool UpdateImageData(const std::wstring& wsImagePath, TImageData& oImageData);
|
||||
|
||||
bool ReadAllTextUtf8(const std::wstring& wsFilePath, std::wstring& wsText);
|
||||
bool RemoveFile(const std::wstring& wsFilePath);
|
||||
|
||||
template<>
|
||||
struct TImage<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
std::vector<std::wstring> m_arrImages;
|
||||
XmlUtils::CXmlLiteReader* m_pXmlReader; //TODO:: подумать как можно иначе получить текс в svg теге
|
||||
|
||||
TImage(COOXMLInterpretator* pInterpretator)
|
||||
: TTag(pInterpretator)
|
||||
{}
|
||||
TImage(COOXMLInterpretator* pInterpretator, XmlUtils::CXmlLiteReader* pXmlReader);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return false;
|
||||
template<>
|
||||
struct TFont<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
TFont(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
const std::wstring wsAlt{arSelectors.back().GetAttributeValue(L"alt")};
|
||||
std::wstring wsSrc{arSelectors.back().GetAttributeValue(L"src")};
|
||||
template<>
|
||||
struct TInput<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
TInput(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
TImageData oImageData;
|
||||
template<>
|
||||
struct TBaseFont<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
TBaseFont(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
std::wstring wsTempValue;
|
||||
NSCSS::NSProperties::CDigit oTempDigit;
|
||||
template<>
|
||||
struct TBlockquote<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
std::map<std::wstring, UINT> m_mDivs;
|
||||
|
||||
#define GET_UNIT_DATA(variable_data, data_variable)\
|
||||
if (NSCSS::UnitMeasure::None == data_variable.GetUnitMeasure())\
|
||||
variable_data = static_cast<UINT>(NSCSS::CUnitMeasureConverter::ConvertPx(data_variable.ToDouble(), NSCSS::Inch, 96) * 914400);\
|
||||
else\
|
||||
variable_data = static_cast<UINT>(data_variable.ToDouble(NSCSS::Inch) * 914400)
|
||||
TBlockquote(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
#define READ_IMAGE_DATA(name_data, variable_data)\
|
||||
if (arSelectors.back().GetAttributeValue(name_data, wsTempValue))\
|
||||
{\
|
||||
if (oTempDigit.SetValue(wsTempValue))\
|
||||
{\
|
||||
GET_UNIT_DATA(variable_data, oTempDigit);\
|
||||
}\
|
||||
}
|
||||
template<>
|
||||
struct THorizontalRule<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
UINT m_unShapeId;
|
||||
|
||||
READ_IMAGE_DATA(L"width", oImageData.m_unWidth);
|
||||
READ_IMAGE_DATA(L"height", oImageData.m_unHeight);
|
||||
READ_IMAGE_DATA(L"hspace", oImageData.m_nHSpace);
|
||||
READ_IMAGE_DATA(L"vspace", oImageData.m_nVSpace);
|
||||
THorizontalRule(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
if (nullptr != arSelectors.back().m_pCompiledStyle)
|
||||
{
|
||||
oTempDigit = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetWidth();
|
||||
template<>
|
||||
struct TList<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
UINT m_unNumberingId;
|
||||
|
||||
if (0 == oImageData.m_unWidth && !oTempDigit.Empty())
|
||||
{
|
||||
GET_UNIT_DATA(oImageData.m_unWidth, oTempDigit);
|
||||
}
|
||||
TList(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
oTempDigit = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetHeight();
|
||||
|
||||
if (0 == oImageData.m_unHeight && !oTempDigit.Empty())
|
||||
{
|
||||
GET_UNIT_DATA(oImageData.m_unHeight, oTempDigit);
|
||||
}
|
||||
}
|
||||
|
||||
if (wsSrc.empty())
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bRes = false;
|
||||
std::wstring wsExtention;
|
||||
const std::wstring wsImagePath{m_pInterpretator->GetMediaDir() + L'i' + std::to_wstring(m_arrImages.size())};
|
||||
|
||||
// Предполагаем картинку в Base64
|
||||
if (wsSrc.length() > 4 && wsSrc.substr(0, 4) == L"data" && wsSrc.find(L"/", 4) != std::wstring::npos)
|
||||
bRes = ReadBase64(wsSrc, wsImagePath, m_pInterpretator->GetFonts(), m_pInterpretator->GetTempDir(), wsExtention);
|
||||
|
||||
const bool bIsAllowExternalLocalFiles = GetStatusUsingExternalLocalFiles();
|
||||
|
||||
if (!bRes && (wsSrc.length() <= 7 || L"http" != wsSrc.substr(0, 4)))
|
||||
{
|
||||
wsSrc = NormalizePath(wsSrc);
|
||||
|
||||
if (!CanUseThisPath(wsSrc, m_pInterpretator->GetSrcPath(), m_pInterpretator->GetCorePath(), bIsAllowExternalLocalFiles))
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверка расширения
|
||||
if (!bRes)
|
||||
{
|
||||
wsExtention = GetFileExtention(wsSrc);
|
||||
std::transform(wsExtention.begin(), wsExtention.end(), wsExtention.begin(), tolower);
|
||||
|
||||
std::wstring::const_iterator itFound = std::find_if(wsExtention.cbegin(), wsExtention.cend(), [](wchar_t wChar){ return !iswalpha(wChar) && L'+' != wChar; });
|
||||
|
||||
if (wsExtention.cend() != itFound)
|
||||
wsExtention.erase(itFound, wsExtention.cend());
|
||||
}
|
||||
|
||||
const std::wstring wsBasePath{m_pInterpretator->GetBasePath()};
|
||||
|
||||
// Предполагаем картинку в сети
|
||||
if (!bRes &&
|
||||
((!wsBasePath.empty() && wsBasePath.length() > 4 && wsBasePath.substr(0, 4) == L"http") ||
|
||||
(wsSrc.length() > 4 && wsSrc.substr(0, 4) == L"http")))
|
||||
{
|
||||
const std::wstring wsDst = wsImagePath + L'.' + ((!wsExtention.empty()) ? wsExtention : L"png");
|
||||
|
||||
// Проверка gc_allowNetworkRequest предполагается в kernel_network
|
||||
bRes = DownloadImage(m_pInterpretator->GetBasePath() + wsSrc, wsDst);
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsSVG(wsExtention))
|
||||
{
|
||||
std::wstring wsFileData;
|
||||
|
||||
if (!ReadAllTextUtf8(wsDst, wsFileData) ||
|
||||
!ReadSVG(wsFileData, m_pInterpretator->GetFonts(), m_pInterpretator->GetTempDir(), wsImagePath))
|
||||
bRes = false;
|
||||
|
||||
RemoveFile(wsDst);
|
||||
wsExtention = L"png";
|
||||
}
|
||||
else if (wsExtention.empty())
|
||||
{
|
||||
//TODO:: лучше узнавать формат изображения из содержимого
|
||||
wsExtention = L"png";
|
||||
}
|
||||
}
|
||||
|
||||
int nImageId = -1;
|
||||
|
||||
if (!bRes)
|
||||
{
|
||||
if (NotValidExtension(wsExtention))
|
||||
{
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Проверка на повтор
|
||||
std::vector<std::wstring>::iterator nFind = std::find(m_arrImages.begin(), m_arrImages.end(), wsSrc);
|
||||
if (nFind != m_arrImages.end())
|
||||
{
|
||||
bRes = true;
|
||||
nImageId = nFind - m_arrImages.begin();
|
||||
}
|
||||
}
|
||||
|
||||
// Предполагаем картинку по локальному пути
|
||||
if (!bRes)
|
||||
{
|
||||
const std::wstring wsDst = wsImagePath + L'.' + wsExtention;
|
||||
|
||||
if (!m_pInterpretator->GetBasePath().empty())
|
||||
{
|
||||
if (!bRes)
|
||||
bRes = CopyImage(CombinePaths(m_pInterpretator->GetBasePath(), wsSrc), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(CombinePaths(m_pInterpretator->GetSrcPath(), CombinePaths(m_pInterpretator->GetBasePath(), wsSrc)), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
if (!bRes)
|
||||
bRes = CopyImage(CombinePaths(m_pInterpretator->GetSrcPath(), wsSrc), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(m_pInterpretator->GetSrcPath() + L"/" + GetFileName(wsSrc), m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
if (!bRes)
|
||||
bRes = CopyImage(wsSrc, m_pInterpretator->GetSrcPath(), wsDst, bIsAllowExternalLocalFiles);
|
||||
}
|
||||
|
||||
if (!bRes)
|
||||
m_pInterpretator->WriteAlternativeImage(wsAlt, wsSrc, oImageData);
|
||||
else
|
||||
{
|
||||
m_arrImages.push_back(wsSrc);
|
||||
|
||||
m_pInterpretator->WritePPr(arSelectors);
|
||||
|
||||
const std::wstring wsImageID{std::to_wstring(m_arrImages.size())};
|
||||
|
||||
if (nImageId < 0)
|
||||
{
|
||||
m_pInterpretator->WriteImageRels(wsImageID, wsImageID + L'.' + wsExtention);
|
||||
m_arrImages.push_back(wsSrc);
|
||||
}
|
||||
|
||||
if (!oImageData.ZeroSize())
|
||||
{
|
||||
m_pInterpretator->WriteImage(oImageData, wsImageID);
|
||||
return true;
|
||||
}
|
||||
|
||||
TImageData oNewImageData{oImageData};
|
||||
if (!UpdateImageData(wsImagePath + L'.' + wsExtention, oNewImageData))
|
||||
return false;
|
||||
|
||||
m_pInterpretator->WriteImage(oNewImageData, wsImageID);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override
|
||||
{
|
||||
if (!ValidInterpretator())
|
||||
return;
|
||||
}
|
||||
template<>
|
||||
struct TListElement<COOXMLInterpretator> : public TTag<COOXMLInterpretator>
|
||||
{
|
||||
TListElement(COOXMLInterpretator* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -5,9 +5,11 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "../Common/3dParty/html/htmltoxhtml.h"
|
||||
#include "htmlfile2.h"
|
||||
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
#include "../Common/3dParty/html/htmltoxhtml.h".
|
||||
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
|
||||
#include "../Common/3dParty/html/css/src/xhtml/CDocumentStyle.h"
|
||||
#include "../Common/Network/FileTransporter/include/FileTransporter.h"
|
||||
@ -23,13 +25,10 @@
|
||||
#include "../DesktopEditor/raster/BgraFrame.h"
|
||||
#include "../DesktopEditor/graphics/pro/Graphics.h"
|
||||
|
||||
#include "htmlfile2.h"
|
||||
#include "src/Languages.h"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include "HTMLReader.h"
|
||||
|
||||
#ifndef VALUE2STR
|
||||
#define VALUE_TO_STRING(x) #x
|
||||
#define VALUE2STR(x) VALUE_TO_STRING(x)
|
||||
@ -4082,71 +4081,7 @@ private:
|
||||
if(m_oLightReader.IsEmptyNode())
|
||||
return false;
|
||||
|
||||
CloseP(oXml, arSelectors);
|
||||
|
||||
CTextSettings oTSLi(oTS);
|
||||
|
||||
++oTSLi.nLi;
|
||||
|
||||
//Нумерованный список
|
||||
if (L"ol" == arSelectors.back().m_wsName)
|
||||
{
|
||||
int nStart = 1;
|
||||
while(m_oLightReader.MoveToNextAttribute())
|
||||
if(m_oLightReader.GetName() == L"start")
|
||||
nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1);
|
||||
m_oLightReader.MoveToElement();
|
||||
|
||||
oTSLi.bNumberingLi = true;
|
||||
|
||||
const std::wstring wsStart(std::to_wstring(nStart));
|
||||
m_oNumberXml.WriteString(L"<w:abstractNum w:abstractNumId=\"");
|
||||
m_oNumberXml.WriteString(std::to_wstring(m_nNumberingId++));
|
||||
m_oNumberXml.WriteString(L"\"><w:multiLevelType w:val=\"hybridMultilevel\"/><w:lvl w:ilvl=\"0\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"709\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"1\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%2.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1429\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"2\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%3.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"2149\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"3\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%4.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2869\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"4\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%5.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3589\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"5\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%6.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"4309\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"6\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%7.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5029\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"7\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%8.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5749\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"8\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%9.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"6469\" w:hanging=\"180\"/></w:pPr></w:lvl></w:abstractNum>");
|
||||
}
|
||||
else
|
||||
oTSLi.bNumberingLi = false;
|
||||
|
||||
CTextSettings oTSList{oTSLi};
|
||||
|
||||
oTSList.oAdditionalStyle.m_oMargin.SetTop (100, NSCSS::UnitMeasure::Twips, 0, true);
|
||||
oTSList.oAdditionalStyle.m_oMargin.SetBottom(100, NSCSS::UnitMeasure::Twips, 0, true);
|
||||
|
||||
int nDeath = m_oLightReader.GetDepth();
|
||||
while(m_oLightReader.ReadNextSiblingNode2(nDeath))
|
||||
{
|
||||
const std::wstring wsName = m_oLightReader.GetName();
|
||||
|
||||
if (L"li" == wsName)
|
||||
ReadListElement(oXml, arSelectors, oTSList);
|
||||
else
|
||||
{
|
||||
CloseP(oXml, arSelectors);
|
||||
readInside(oXml, arSelectors, oTSLi, wsName);
|
||||
}
|
||||
}
|
||||
|
||||
CloseP(oXml, arSelectors);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readLi (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, CTextSettings& oTS, bool bType)
|
||||
@ -5069,51 +5004,65 @@ private:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#else
|
||||
#include "HTMLReader.h"
|
||||
#endif
|
||||
|
||||
CHtmlFile2::CHtmlFile2()
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal = new CHtmlFile2_Private();
|
||||
#endif
|
||||
}
|
||||
|
||||
CHtmlFile2::~CHtmlFile2()
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
RELEASEOBJECT(m_internal);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CHtmlFile2::IsHtmlFile(const std::wstring& sFile)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
// Конвертируем в xhtml
|
||||
if(!m_internal->htmlXhtml(sFile))
|
||||
return false;
|
||||
// Читаем html
|
||||
return m_internal->isHtml();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CHtmlFile2::IsMhtFile(const std::wstring& sFile)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
// Конвертируем в xhtml
|
||||
if(!m_internal->mhtXhtml(sFile))
|
||||
return false;
|
||||
// Читаем html
|
||||
return m_internal->isHtml();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void CHtmlFile2::SetTmpDirectory(const std::wstring& sFolder)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal->m_sTmp = NSSystemPath::NormalizePath(sFolder);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CHtmlFile2::SetCoreDirectory(const std::wstring& wsFolder)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal->m_sCore = NSSystemPath::NormalizePath(wsFolder);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::OpenHtml(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
|
||||
{
|
||||
HTML::CHTMLReader oHTMLReader;
|
||||
|
||||
return oHTMLReader.ConvertFromTo(sSrc, sDst);
|
||||
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
if(!m_internal->m_oLightReader.IsValid())
|
||||
if(!IsHtmlFile(sSrc))
|
||||
return S_FALSE;
|
||||
@ -5132,10 +5081,15 @@ HRESULT CHtmlFile2::OpenHtml(const std::wstring& sSrc, const std::wstring& sDst,
|
||||
m_internal->readSrc();
|
||||
m_internal->write();
|
||||
return S_OK;
|
||||
#else
|
||||
HTML::CHTMLReader oHTMLReader;
|
||||
return oHTMLReader.ConvertFromTo(sSrc, sDst);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::OpenMht(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
if(!m_internal->m_oLightReader.IsValid())
|
||||
if(!IsMhtFile(sSrc))
|
||||
return S_FALSE;
|
||||
@ -5154,10 +5108,14 @@ HRESULT CHtmlFile2::OpenMht(const std::wstring& sSrc, const std::wstring& sDst,
|
||||
m_internal->readSrc();
|
||||
m_internal->write();
|
||||
return S_OK;
|
||||
#else
|
||||
return S_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::OpenBatchHtml(const std::vector<std::wstring>& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal->m_sDst = sDst;
|
||||
m_internal->CreateDocxEmpty(oParams);
|
||||
bool bFirst = true;
|
||||
@ -5194,8 +5152,11 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector<std::wstring>& sSrc, const s
|
||||
|
||||
m_internal->write();
|
||||
return S_OK;
|
||||
#endif
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
std::wstring CTableRow::ConvertToOOXML(const CTable& oTable, int nInstruction)
|
||||
{
|
||||
if (m_arCells.empty())
|
||||
@ -5351,3 +5312,4 @@ std::wstring CTableCell::ConvertToOOXML(const CTable& oTable, UINT unColumnNumbe
|
||||
|
||||
return oCell.GetData();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -76,7 +76,9 @@ class CHtmlFile2_Private;
|
||||
class HTMLFILE2_DECL_EXPORT CHtmlFile2
|
||||
{
|
||||
private:
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
CHtmlFile2_Private* m_internal;
|
||||
#endif
|
||||
public:
|
||||
CHtmlFile2();
|
||||
~CHtmlFile2();
|
||||
|
||||
Reference in New Issue
Block a user