mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
1378 lines
66 KiB
C++
1378 lines
66 KiB
C++
#include "OOXMLWriter.h"
|
||
|
||
#include <cwctype>
|
||
|
||
#include "../../DesktopEditor/common/File.h"
|
||
#include "../../DesktopEditor/common/Directory.h"
|
||
#include "../../DesktopEditor/common/SystemUtils.h"
|
||
|
||
#include "../../DesktopEditor/graphics/pro/Fonts.h"
|
||
|
||
#include "../src/Languages.h"
|
||
|
||
namespace HTML
|
||
{
|
||
#ifndef VALUE2STR
|
||
#define VALUE_TO_STRING(x) #x
|
||
#define VALUE2STR(x) VALUE_TO_STRING(x)
|
||
#endif
|
||
|
||
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
|
||
|
||
#define MAXCOLUMNSINTABLE 63
|
||
#define MAXROWSINTABLE 32767
|
||
|
||
#define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips
|
||
#define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips
|
||
|
||
#define DEFAULT_LANGUAGE std::wstring(L"en-US")
|
||
#define DEFAULT_FONT_FAMILY std::wstring(L"Times New Roman")
|
||
#define DEFAULT_FONT_SIZE 24
|
||
|
||
#define DEFAULT_IMAGE_WIDTH 304800
|
||
#define DEFAULT_IMAGE_HEIGHT 304800
|
||
|
||
inline bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors);
|
||
inline bool ElementInHeader(const std::vector<NSCSS::CNode> arSelsectors);
|
||
inline std::wstring StandardizeHeaderId(const std::wstring& wsHeader);
|
||
inline int CalculateFontChange(const std::vector<NSCSS::CNode>& arSelectors);
|
||
inline UINT GetFontSizeLevel(UINT unFontSize);
|
||
inline UINT GetFontSizeByLevel(UINT unLevel);
|
||
inline void ReplaceSpaces(std::wstring& wsValue);
|
||
|
||
COOXMLWriter::COOXMLWriter()
|
||
: m_pDstPath(nullptr), m_pTempDir(nullptr), m_pSrcPath(nullptr),
|
||
m_pBasePath(nullptr), m_pCorePath(nullptr), m_pHTMLParameters(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);
|
||
m_oPageData.SetMargin(1440, NSCSS::UnitMeasure::Twips, 0, true);
|
||
m_oPageData.SetFooter(720, NSCSS::UnitMeasure::Twips, 0, true);
|
||
m_oPageData.SetHeader(720, NSCSS::UnitMeasure::Twips, 0, true);
|
||
|
||
m_arStates.push(TState());
|
||
m_arStates.top().m_pCurrentDocument = &m_oDocXml;
|
||
}
|
||
|
||
void COOXMLWriter::SetCSSCalculator(NSCSS::CCssCalculator* pCSSCalculator)
|
||
{
|
||
m_pStylesCalculator = pCSSCalculator;
|
||
}
|
||
|
||
void COOXMLWriter::SetHTMLParameters(THTMLParameters* pHTMLParameters)
|
||
{
|
||
m_pHTMLParameters = pHTMLParameters;
|
||
}
|
||
|
||
void COOXMLWriter::SetSrcDirectory(const std::wstring& wsPath)
|
||
{
|
||
m_pSrcPath = &wsPath;
|
||
}
|
||
|
||
void COOXMLWriter::SetDstDirectory(const std::wstring& wsPath)
|
||
{
|
||
m_pDstPath = &wsPath;
|
||
}
|
||
|
||
void COOXMLWriter::SetTempDirectory(const std::wstring& wsPath)
|
||
{
|
||
m_pTempDir = &wsPath;
|
||
}
|
||
|
||
void COOXMLWriter::SetBaseDirectory(const std::wstring& wsPath)
|
||
{
|
||
m_pBasePath = &wsPath;
|
||
}
|
||
|
||
void COOXMLWriter::SetCoreDirectory(const std::wstring& wsPath)
|
||
{
|
||
m_pCorePath = &wsPath;
|
||
}
|
||
|
||
void COOXMLWriter::Begin(const std::wstring& wsDst)
|
||
{
|
||
// Создаем пустые папки
|
||
NSDirectory::CreateDirectory(wsDst + L"/_rels");
|
||
NSDirectory::CreateDirectory(wsDst + L"/docProps");
|
||
NSDirectory::CreateDirectory(wsDst + L"/word");
|
||
NSDirectory::CreateDirectory(wsDst + L"/word/_rels");
|
||
NSDirectory::CreateDirectory(wsDst + L"/word/media");
|
||
NSDirectory::CreateDirectory(wsDst + L"/word/theme");
|
||
|
||
// theme1.xml
|
||
std::wstring sTheme = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" name=\"Office Theme\"><a:themeElements><a:clrScheme name=\"Office\"><a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1><a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1><a:dk2><a:srgbClr val=\"44546A\"/></a:dk2><a:lt2><a:srgbClr val=\"E7E6E6\"/></a:lt2><a:accent1><a:srgbClr val=\"5B9BD5\"/></a:accent1><a:accent2><a:srgbClr val=\"ED7D31\"/></a:accent2><a:accent3><a:srgbClr val=\"A5A5A5\"/></a:accent3><a:accent4><a:srgbClr val=\"FFC000\"/></a:accent4><a:accent5><a:srgbClr val=\"4472C4\"/></a:accent5><a:accent6><a:srgbClr val=\"70AD47\"/></a:accent6><a:hlink><a:srgbClr val=\"0563C1\"/></a:hlink><a:folHlink><a:srgbClr val=\"954F72\"/></a:folHlink></a:clrScheme><a:fontScheme name=\"Office Classic 2\"><a:majorFont><a:latin typeface=\"Times New Roman\"/><a:ea typeface=\"Times New Roman\"/><a:cs typeface=\"Times New Roman\"/></a:majorFont><a:minorFont><a:latin typeface=\"Times New Roman\"/><a:ea typeface=\"Times New Roman\"/><a:cs typeface=\"Times New Roman\"/></a:minorFont></a:fontScheme><a:fmtScheme name=\"Office\"><a:fillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"50000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"35000\"><a:schemeClr val=\"phClr\"><a:tint val=\"37000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:tint val=\"15000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:shade val=\"51000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"80000\"><a:schemeClr val=\"phClr\"><a:shade val=\"93000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"94000\"/><a:satMod val=\"135000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"0\"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=\"6350\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"><a:shade val=\"95000\"/><a:satMod val=\"105000\"/></a:schemeClr></a:solidFill></a:ln><a:ln w=\"12700\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln><a:ln w=\"19050\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"38000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"40000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"40000\"><a:schemeClr val=\"phClr\"><a:tint val=\"45000\"/><a:shade val=\"99000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"20000\"/><a:satMod val=\"255000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"/></a:gradFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"80000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"30000\"/><a:satMod val=\"200000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/></a:theme>";
|
||
NSFile::CFileBinary oThemeWriter;
|
||
if (oThemeWriter.CreateFileW(wsDst + L"/word/theme/theme1.xml"))
|
||
{
|
||
oThemeWriter.WriteStringUTF8(sTheme);
|
||
oThemeWriter.CloseFile();
|
||
}
|
||
|
||
// app.xml
|
||
std::wstring sApplication = NSSystemUtils::GetEnvVariable(NSSystemUtils::gc_EnvApplicationName);
|
||
if (sApplication.empty())
|
||
sApplication = NSSystemUtils::gc_EnvApplicationNameDefault;
|
||
#if defined(INTVER)
|
||
const std::string sVersion = VALUE2STR(INTVER);
|
||
#else
|
||
const std::string sVersion{L"1.0"};
|
||
#endif
|
||
std::wstring sApp = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\"><Application>";
|
||
sApp += sApplication + L"/" + UTF8_TO_U(sVersion);
|
||
sApp += L"</Application><DocSecurity>0</DocSecurity><HyperlinksChanged>false</HyperlinksChanged><LinksUpToDate>false</LinksUpToDate><ScaleCrop>false</ScaleCrop><SharedDoc>false</SharedDoc></Properties>";
|
||
NSFile::CFileBinary oAppWriter;
|
||
if (oAppWriter.CreateFileW(wsDst + L"/docProps/app.xml"))
|
||
{
|
||
oAppWriter.WriteStringUTF8(sApp);
|
||
oAppWriter.CloseFile();
|
||
}
|
||
|
||
// .rels
|
||
std::wstring sRels = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/></Relationships>";
|
||
NSFile::CFileBinary oRelsWriter;
|
||
if (oRelsWriter.CreateFileW(wsDst + L"/_rels/.rels"))
|
||
{
|
||
oRelsWriter.WriteStringUTF8(sRels);
|
||
oRelsWriter.CloseFile();
|
||
}
|
||
|
||
// [Content_Types].xml
|
||
std::wstring sContent = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"bmp\" ContentType=\"image/bmp\"/><Default Extension=\"svg\" ContentType=\"image/svg+xml\"/><Default Extension=\"jfif\" ContentType=\"image/jpeg\"/><Default Extension=\"wmf\" ContentType=\"image/x-wmf\"/><Default Extension=\"gif\" ContentType=\"image/gif\"/><Default Extension=\"jpe\" ContentType=\"image/jpeg\"/><Default Extension=\"png\" ContentType=\"image/png\"/><Default Extension=\"jpg\" ContentType=\"image/jpeg\"/><Default Extension=\"jpeg\" ContentType=\"image/jpeg\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"bin\" ContentType=\"application/vnd.openxmlformats-officedocument.oleObject\"/><Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/><Override PartName=\"/word/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/><Override PartName=\"/word/fontTable.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml\"/><Override PartName=\"/word/webSettings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml\"/><Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/><Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/><Override PartName=\"/word/footnotes.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml\"/><Override PartName=\"/word/settings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/><Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/><Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/></Types>";
|
||
NSFile::CFileBinary oContentWriter;
|
||
if (oContentWriter.CreateFileW(wsDst + L"/[Content_Types].xml"))
|
||
{
|
||
oContentWriter.WriteStringUTF8(sContent);
|
||
oContentWriter.CloseFile();
|
||
}
|
||
|
||
// fontTable.xml
|
||
std::wstring sFontTable = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:fonts xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" mc:Ignorable=\"w14 w15\"><w:font w:name=\"Wingdings\"><w:panose1 w:val=\"05000000000000000000\"/></w:font><w:font w:name=\"Courier New\"><w:panose1 w:val=\"02070309020205020404\"/></w:font><w:font w:name=\"Symbol\"><w:panose1 w:val=\"05050102010706020507\"/></w:font><w:font w:name=\"Times New Roman\"><w:panose1 w:val=\"020B0604020202020204\"/></w:font><w:font w:name=\"Calibri\"><w:panose1 w:val=\"020F0502020204030204\"/></w:font><w:font w:name=\"Times New Roman\"><w:panose1 w:val=\"02020603050405020304\"/></w:font><w:font w:name=\"Cambria\"><w:panose1 w:val=\"02040503050406030204\"/></w:font></w:fonts>";
|
||
NSFile::CFileBinary oFontTableWriter;
|
||
if (oFontTableWriter.CreateFileW(wsDst + L"/word/fontTable.xml"))
|
||
{
|
||
oFontTableWriter.WriteStringUTF8(sFontTable);
|
||
oFontTableWriter.CloseFile();
|
||
}
|
||
|
||
// settings.xml
|
||
std::wstring sSettings = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"><w:displayBackgroundShape/><w:clrSchemeMapping w:accent1=\"accent1\" w:accent2=\"accent2\" w:accent3=\"accent3\" w:accent4=\"accent4\" w:accent5=\"accent5\" w:accent6=\"accent6\" w:bg1=\"light1\" w:bg2=\"light2\" w:followedHyperlink=\"followedHyperlink\" w:hyperlink=\"hyperlink\" w:t1=\"dark1\" w:t2=\"dark2\"/><w:defaultTabStop w:val=\"708\"/><m:mathPr/><w:trackRevisions w:val=\"false\"/><w:footnotePr><w:footnote w:id=\"-1\"/><w:footnote w:id=\"0\"/><w:numFmt w:val=\"decimal\"/><w:numRestart w:val=\"continuous\"/><w:numStart w:val=\"1\"/><w:pos w:val=\"pageBottom\"/></w:footnotePr><w:decimalSymbol w:val=\".\"/><w:listSeparator w:val=\",\"/><w:compat><w:compatSetting w:name=\"compatibilityMode\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"15\"/><w:compatSetting w:name=\"overrideTableStyleFontSizeAndJustification\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"enableOpenTypeFeatures\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"doNotFlipMirrorIndents\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"useWord2013TrackBottomHyphenation\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"0\"/></w:compat><w:zoom w:percent=\"100\"/><w:characterSpacingControl w:val=\"doNotCompress\"/><w:themeFontLang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/><w:shapeDefaults><o:shapedefaults v:ext=\"edit\" spidmax=\"1026\"/><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/></o:shapelayout></w:shapeDefaults></w:settings>";
|
||
NSFile::CFileBinary oSettingsWriter;
|
||
if (oSettingsWriter.CreateFileW(wsDst + L"/word/settings.xml"))
|
||
{
|
||
oSettingsWriter.WriteStringUTF8(sSettings);
|
||
oSettingsWriter.CloseFile();
|
||
}
|
||
|
||
// numbering.xml
|
||
// Маркированный список
|
||
m_oNumberXml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:numbering xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 wp14\"><w:abstractNum w:abstractNumId=\"0\"><w:multiLevelType w:val=\"hybridMultilevel\"/><w:lvl w:ilvl=\"0\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"";
|
||
m_oNumberXml.AddCharSafe(183);
|
||
m_oNumberXml += L"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Symbol\" w:hAnsi=\"Symbol\" w:cs=\"Symbol\" w:eastAsia=\"Symbol\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"o\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\" w:cs=\"Courier New\" w:eastAsia=\"Courier New\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"2\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"";
|
||
m_oNumberXml.AddCharSafe(167);
|
||
m_oNumberXml += L"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Wingdings\" w:hAnsi=\"Wingdings\" w:cs=\"Wingdings\" w:eastAsia=\"Wingdings\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"3\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"";
|
||
m_oNumberXml.AddCharSafe(183);
|
||
m_oNumberXml += L"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2880\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Symbol\" w:hAnsi=\"Symbol\" w:cs=\"Symbol\" w:eastAsia=\"Symbol\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"4\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"o\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3600\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\" w:cs=\"Courier New\" w:eastAsia=\"Courier New\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"5\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"";
|
||
m_oNumberXml.AddCharSafe(167);
|
||
m_oNumberXml += L"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"4320\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Wingdings\" w:hAnsi=\"Wingdings\" w:cs=\"Wingdings\" w:eastAsia=\"Wingdings\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"6\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"";
|
||
m_oNumberXml.AddCharSafe(183);
|
||
m_oNumberXml += L"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5040\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Symbol\" w:hAnsi=\"Symbol\" w:cs=\"Symbol\" w:eastAsia=\"Symbol\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"7\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"o\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5760\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\" w:cs=\"Courier New\" w:eastAsia=\"Courier New\"/></w:rPr></w:lvl><w:lvl w:ilvl=\"8\"><w:start w:val=\"1\"/><w:numFmt w:val=\"bullet\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"";
|
||
m_oNumberXml.AddCharSafe(167);
|
||
m_oNumberXml += L"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"6480\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Wingdings\" w:hAnsi=\"Wingdings\" w:cs=\"Wingdings\" w:eastAsia=\"Wingdings\"/></w:rPr></w:lvl></w:abstractNum>";
|
||
|
||
std::wstring wsCurrentLanguage;
|
||
|
||
// core.xml
|
||
std::wstring sCore = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">";
|
||
if(nullptr != m_pHTMLParameters)
|
||
{
|
||
if(!m_pHTMLParameters->m_sBookTitle.empty())
|
||
{
|
||
sCore += L"<dc:title>";
|
||
sCore += EncodeXmlString(m_pHTMLParameters->m_sBookTitle);
|
||
sCore += L"</dc:title>";
|
||
}
|
||
if(!m_pHTMLParameters->m_sAuthors.empty())
|
||
{
|
||
sCore += L"<dc:creator>";
|
||
sCore += EncodeXmlString(m_pHTMLParameters->m_sAuthors);
|
||
sCore += L"</dc:creator>";
|
||
}
|
||
if(!m_pHTMLParameters->m_sGenres.empty())
|
||
{
|
||
sCore += L"<dc:subject>";
|
||
sCore += EncodeXmlString(m_pHTMLParameters->m_sGenres);
|
||
sCore += L"</dc:subject>";
|
||
}
|
||
if(!m_pHTMLParameters->m_sDate.empty())
|
||
{
|
||
sCore += L"<dcterms:created xsi:type=\"dcterms:W3CDTF\">";
|
||
sCore += EncodeXmlString(m_pHTMLParameters->m_sDate);
|
||
sCore += L"</dcterms:created>";
|
||
}
|
||
if(!m_pHTMLParameters->m_sDescription.empty())
|
||
{
|
||
sCore += L"<dc:description>";
|
||
sCore += EncodeXmlString(m_pHTMLParameters->m_sDescription);
|
||
sCore += L"</dc:description>";
|
||
}
|
||
if (!m_pHTMLParameters->m_sLanguage.empty())
|
||
{
|
||
wsCurrentLanguage = IndentifyLanguage(m_pHTMLParameters->m_sLanguage);
|
||
|
||
sCore += L"<dc:language>";
|
||
sCore += wsCurrentLanguage;
|
||
sCore += L"</dc:language>";
|
||
}
|
||
}
|
||
sCore += L"<cp:lastModifiedBy/></cp:coreProperties>";
|
||
NSFile::CFileBinary oCoreWriter;
|
||
if (oCoreWriter.CreateFileW(wsDst + L"/docProps/core.xml"))
|
||
{
|
||
oCoreWriter.WriteStringUTF8(sCore);
|
||
oCoreWriter.CloseFile();
|
||
}
|
||
|
||
// Начала файлов
|
||
m_oDocXmlRels += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
|
||
m_oDocXmlRels += L"<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>";
|
||
m_oDocXmlRels += L"<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>";
|
||
m_oDocXmlRels += L"<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings\" Target=\"webSettings.xml\"/>";
|
||
m_oDocXmlRels += L"<Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/>";
|
||
m_oDocXmlRels += L"<Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme1.xml\"/>";
|
||
m_oDocXmlRels += L"<Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" Target=\"footnotes.xml\"/>";
|
||
m_oDocXmlRels += L"<Relationship Id=\"rId7\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>";
|
||
m_oNoteXmlRels += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
|
||
m_oDocXml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:document xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 wp14\"><w:body>";
|
||
m_oNoteXml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:footnotes xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" mc:Ignorable=\"w14 w15 wp14\">";
|
||
m_oNoteXml += L"<w:footnote w:type=\"separator\" w:id=\"-1\"><w:p><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:type=\"continuationSeparator\" w:id=\"0\"><w:p><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>";
|
||
m_oStylesXml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:styles xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" mc:Ignorable=\"w14 w15\">";
|
||
m_oWebSettings += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:webSettings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:optimizeForBrowser/>";
|
||
|
||
m_nId += 7;
|
||
|
||
// docDefaults по умолчанию
|
||
if(m_pHTMLParameters && !m_pHTMLParameters->m_sdocDefaults.empty())
|
||
m_oStylesXml += m_pHTMLParameters->m_sdocDefaults;
|
||
else
|
||
{
|
||
m_oStylesXml += L"<w:rPrDefault><w:rPr>";
|
||
m_oStylesXml += L"<w:rFonts w:ascii=\"" + DEFAULT_FONT_FAMILY + L"\" w:eastAsia=\"" + DEFAULT_FONT_FAMILY + L"\" w:hAnsi=\"" + DEFAULT_FONT_FAMILY + L"\" w:cs=\"" + DEFAULT_FONT_FAMILY + L"\"/>";
|
||
m_oStylesXml += L"<w:sz w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/><w:szCs w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/>";
|
||
m_oStylesXml += L"<w:lang w:val=\"" + ((!wsCurrentLanguage.empty()) ? wsCurrentLanguage : DEFAULT_LANGUAGE) + L"\" w:eastAsia=\"en-US\" w:bidi=\"ar-SA\"/>";
|
||
m_oStylesXml += L"</w:rPr></w:rPrDefault><w:pPrDefault/>";
|
||
|
||
// m_oStylesXml += L"<w:pPrDefault><w:pPr><w:spacing w:after=\"200\" w:line=\"276\" w:lineRule=\"auto\"/></w:pPr></w:pPrDefault>";
|
||
}
|
||
|
||
// normal по умолчанию
|
||
if(m_pHTMLParameters && !m_pHTMLParameters->m_sNormal.empty())
|
||
m_oStylesXml += m_pHTMLParameters->m_sNormal;
|
||
else
|
||
{
|
||
m_oStylesXml += L"<w:style w:type=\"paragraph\" w:styleId=\"normal\" w:default=\"1\"><w:name w:val=\"Normal\"/><w:qFormat/><w:rPr><w:rFonts w:eastAsiaTheme=\"minorEastAsia\"/>";
|
||
m_oStylesXml += L"<w:sz w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/><w:szCs w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/>";
|
||
m_oStylesXml += L"</w:rPr></w:style>";
|
||
}
|
||
|
||
// Маркированный список
|
||
m_oStylesXml += L"<w:style w:type=\"paragraph\" w:styleId=\"li\"><w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"normal\"/><w:qFormat/><w:uiPriority w:val=\"34\"/><w:pPr><w:contextualSpacing w:val=\"true\"/><w:ind w:left=\"720\"/></w:pPr></w:style>";
|
||
// Ссылки
|
||
m_oStylesXml += L"<w:style w:type=\"character\" w:styleId=\"a\"><w:name w:val=\"Hyperlink\"/><w:uiPriority w:val=\"99\"/><w:unhideWhenUsed/><w:rPr><w:color w:val=\"0000FF\" w:themeColor=\"hyperlink\"/><w:u w:val=\"single\"/></w:rPr></w:style>";
|
||
// Таблицы
|
||
// m_oStylesXml += L"<w:style w:type=\"table\" w:default=\"1\" w:styleId=\"table-based\"><w:name w:val=\"Normal Table\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w=\"0\" w:type=\"dxa\"/><w:tblCellMar><w:top w:w=\"0\" w:type=\"dxa\"/><w:left w:w=\"108\" w:type=\"dxa\"/><w:bottom w:w=\"0\" w:type=\"dxa\"/><w:right w:w=\"108\" w:type=\"dxa\"/></w:tblCellMar></w:tblPr></w:style><w:style w:type=\"table\" w:styleId=\"table\"><w:name w:val=\"Table Grid\"/><w:basedOn w:val=\"table-based\"/><w:uiPriority w:val=\"59\"/><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:tblPr><w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/></w:tblBorders></w:tblPr></w:style>";
|
||
// Сноски
|
||
m_oStylesXml += L"<w:style w:type=\"character\" w:styleId=\"footnote\"><w:name w:val=\"footnote reference\"/><w:uiPriority w:val=\"99\"/><w:unhideWhenUsed/><w:rPr><w:vertAlign w:val=\"superscript\"/></w:rPr></w:style><w:style w:type=\"paragraph\" w:styleId=\"footnote-p\"><w:name w:val=\"footnote text\"/><w:basedOn w:val=\"normal\"/><w:link w:val=\"footnote-c\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:rPr><w:sz w:val=\"18\"/></w:rPr><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"40\"/></w:pPr></w:style><w:style w:type=\"character\" w:styleId=\"footnote-c\" w:customStyle=\"1\"><w:name w:val=\"footnote text character\"/><w:link w:val=\"footnote-p\"/><w:uiPriority w:val=\"99\"/><w:rPr><w:sz w:val=\"18\"/></w:rPr></w:style>";
|
||
// Web стиль по-умолчанию
|
||
m_oStylesXml += L"<w:style w:type=\"paragraph\" w:styleId=\"normal-web\"><w:name w:val=\"Normal (Web)\"/><w:basedOn w:val=\"normal\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:pPr><w:spacing w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"/></w:pPr></w:style>";
|
||
}
|
||
|
||
void COOXMLWriter::End(const std::wstring& wsDst)
|
||
{
|
||
m_oDocXmlRels.WriteString(L"</Relationships>");
|
||
NSFile::CFileBinary oRelsWriter;
|
||
if (oRelsWriter.CreateFileW(wsDst + L"/word/_rels/document.xml.rels"))
|
||
{
|
||
oRelsWriter.WriteStringUTF8(m_oDocXmlRels.GetData());
|
||
oRelsWriter.CloseFile();
|
||
}
|
||
|
||
for (const std::pair<std::wstring, std::wstring>& oFootnote : m_mFootnotes)
|
||
{
|
||
m_oNoteXml.WriteString(L"<w:footnote w:id=\"");
|
||
m_oNoteXml.WriteString(oFootnote.second);
|
||
m_oNoteXml.WriteString(L"\"><w:p><w:pPr><w:pStyle w:val=\"footnote-p\"/></w:pPr><w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr></w:r><w:r><w:t xml:space=\"preserve\">");
|
||
m_oNoteXml.WriteEncodeXmlString(oFootnote.first);
|
||
m_oNoteXml.WriteString(L"</w:t></w:r></w:p></w:footnote>");
|
||
}
|
||
|
||
m_oNoteXmlRels.WriteString(L"</Relationships>");
|
||
if (oRelsWriter.CreateFileW(wsDst + L"/word/_rels/footnotes.xml.rels"))
|
||
{
|
||
oRelsWriter.WriteStringUTF8(m_oNoteXmlRels.GetData());
|
||
oRelsWriter.CloseFile();
|
||
}
|
||
|
||
if (m_arStates.top().m_bInP)
|
||
m_oDocXml.WriteString(L"</w:p>");
|
||
|
||
m_oDocXml.WriteString(L"<w:sectPr w:rsidR=\"0007083F\" w:rsidRPr=\"0007083F\" w:rsidSect=\"0007612E\">");
|
||
m_oDocXml.WriteString(L"<w:pgSz w:w=\"" + std::to_wstring(m_oPageData.GetWidth().ToInt(NSCSS::Twips)) + L"\" ");
|
||
m_oDocXml.WriteString(L" w:h=\"" + std::to_wstring(m_oPageData.GetHeight().ToInt(NSCSS::Twips)) + L"\"/>");
|
||
m_oDocXml.WriteString(L"<w:pgMar w:top=\"" + std::to_wstring(m_oPageData.GetMargin().GetTop().ToInt(NSCSS::Twips)) + L"\" ");
|
||
m_oDocXml.WriteString(L"w:right=\"" + std::to_wstring(m_oPageData.GetMargin().GetRight().ToInt(NSCSS::Twips)) + L"\" ");
|
||
m_oDocXml.WriteString(L"w:bottom=\"" + std::to_wstring(m_oPageData.GetMargin().GetBottom().ToInt(NSCSS::Twips)) + L"\" ");
|
||
m_oDocXml.WriteString(L"w:left=\"" + std::to_wstring(m_oPageData.GetMargin().GetLeft().ToInt(NSCSS::Twips)) + L"\" ");
|
||
m_oDocXml.WriteString(L"w:header=\"" + std::to_wstring(m_oPageData.GetHeader().ToInt(NSCSS::Twips)) + L"\" ");
|
||
m_oDocXml.WriteString(L"w:footer=\"" + std::to_wstring(m_oPageData.GetFooter().ToInt(NSCSS::Twips)) + L"\" ");
|
||
m_oDocXml.WriteString(L"w:gutter=\"0\"/><w:cols w:space=\"720\"/><w:docGrid w:linePitch=\"360\"/></w:sectPr></w:body></w:document>");
|
||
|
||
NSFile::CFileBinary oDocumentWriter;
|
||
if (oDocumentWriter.CreateFileW(wsDst + L"/word/document.xml"))
|
||
{
|
||
oDocumentWriter.WriteStringUTF8(m_oDocXml.GetData());
|
||
oDocumentWriter.CloseFile();
|
||
}
|
||
|
||
m_oNoteXml.WriteString(L"</w:footnotes>");
|
||
NSFile::CFileBinary oFootnotesWriter;
|
||
if (oFootnotesWriter.CreateFileW(wsDst + L"/word/footnotes.xml"))
|
||
{
|
||
oFootnotesWriter.WriteStringUTF8(m_oNoteXml.GetData());
|
||
oFootnotesWriter.CloseFile();
|
||
}
|
||
|
||
// styles.xml
|
||
m_oStylesXml.WriteString(L"</w:styles>");
|
||
NSFile::CFileBinary oStylesWriter;
|
||
if (oStylesWriter.CreateFileW(wsDst + L"/word/styles.xml"))
|
||
{
|
||
oStylesWriter.WriteStringUTF8(m_oStylesXml.GetData());
|
||
oStylesWriter.CloseFile();
|
||
}
|
||
|
||
// numbering.xml
|
||
// Маркированный список
|
||
m_oNumberXml.WriteString(L"<w:num w:numId=\"1\"><w:abstractNumId w:val=\"0\"/></w:num>");
|
||
// Нумерованный список
|
||
for(int i = 1; i < m_nNumberingId; i++)
|
||
{
|
||
m_oNumberXml.WriteString(L"<w:num w:numId=\"");
|
||
m_oNumberXml.WriteString(std::to_wstring(i + 1));
|
||
m_oNumberXml.WriteString(L"\"><w:abstractNumId w:val=\"");
|
||
m_oNumberXml.WriteString(std::to_wstring(i));
|
||
m_oNumberXml.WriteString(L"\"/></w:num>");
|
||
}
|
||
m_oNumberXml.WriteString(L"</w:numbering>");
|
||
NSFile::CFileBinary oNumberingWriter;
|
||
if (oNumberingWriter.CreateFileW(wsDst + L"/word/numbering.xml"))
|
||
{
|
||
oNumberingWriter.WriteStringUTF8(m_oNumberXml.GetData());
|
||
oNumberingWriter.CloseFile();
|
||
}
|
||
|
||
// webSettings.xml
|
||
if (m_bWasDivs)
|
||
m_oWebSettings.WriteString(L"</w:divs>");
|
||
|
||
m_oWebSettings.WriteString(L"</w:webSettings>");
|
||
NSFile::CFileBinary oWebSettingsWriter;
|
||
if (oWebSettingsWriter.CreateFileW(wsDst + L"/word/webSettings.xml"))
|
||
{
|
||
oWebSettingsWriter.WriteStringUTF8(m_oWebSettings.GetData());
|
||
oWebSettingsWriter.CloseFile();
|
||
}
|
||
}
|
||
|
||
bool COOXMLWriter::OpenP()
|
||
{
|
||
if (m_arStates.top().m_bInP)
|
||
return false;
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:p>");
|
||
m_arStates.top().m_bInP = true;
|
||
m_arStates.top().m_bWasPStyle = false;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool COOXMLWriter::OpenR()
|
||
{
|
||
if (m_arStates.top().m_bInR)
|
||
return false;
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:r>");
|
||
m_arStates.top().m_bInR = true;
|
||
return true;
|
||
}
|
||
|
||
bool COOXMLWriter::OpenT()
|
||
{
|
||
if (m_arStates.top().m_bInT)
|
||
return false;
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:t xml:space=\"preserve\">");
|
||
m_arStates.top().m_bInT = true;
|
||
return true;
|
||
}
|
||
|
||
void COOXMLWriter::CloseP()
|
||
{
|
||
m_arStates.top().m_bWasSpace = true;
|
||
|
||
if (!m_arStates.top().m_bInP)
|
||
return;
|
||
|
||
CloseT();
|
||
CloseR();
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"</w:p>");
|
||
m_arStates.top().m_bInP = false;
|
||
}
|
||
|
||
void COOXMLWriter::CloseR()
|
||
{
|
||
if (!m_arStates.top().m_bInR)
|
||
return;
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"</w:r>");
|
||
m_arStates.top().m_bInR = false;
|
||
}
|
||
|
||
void COOXMLWriter::CloseT()
|
||
{
|
||
if (!m_arStates.top().m_bInT)
|
||
return;
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"</w:t>");
|
||
m_arStates.top().m_bInT = false;
|
||
}
|
||
|
||
void COOXMLWriter::BeginBlock()
|
||
{
|
||
SaveState();
|
||
m_arStates.top().CreateNewCurrentDocument();
|
||
|
||
CloseP();
|
||
}
|
||
|
||
void COOXMLWriter::EndBlock(bool bAddBlock)
|
||
{
|
||
if (m_arStates.top().m_pCurrentDocument == &m_oDocXml)
|
||
return;
|
||
|
||
// readNote(&oXmlData, sSelectors, sNote);
|
||
|
||
CloseP();
|
||
|
||
if (bAddBlock)
|
||
WriteToStringBuilder(*m_arStates.top().m_pCurrentDocument, m_oDocXml);
|
||
// else
|
||
// m_oState = oCurentState;
|
||
|
||
RollBackState();
|
||
}
|
||
|
||
void COOXMLWriter::SetDataOutput(XmlString* pOutputData)
|
||
{
|
||
SaveState();
|
||
m_arStates.top().m_pCurrentDocument = pOutputData;
|
||
m_arStates.top().m_bRemoveCurrentDocument = false;
|
||
}
|
||
|
||
void COOXMLWriter::RevertDataOutput()
|
||
{
|
||
CloseP();
|
||
RollBackState();
|
||
}
|
||
|
||
void COOXMLWriter::SaveState()
|
||
{
|
||
m_arStates.push(m_arStates.top());
|
||
}
|
||
|
||
void COOXMLWriter::RollBackState()
|
||
{
|
||
if(m_arStates.size() > 1)
|
||
m_arStates.pop();
|
||
}
|
||
|
||
void COOXMLWriter::SetCurrentDocument(XmlString* pNewDocument)
|
||
{
|
||
SaveState();
|
||
|
||
m_arStates.top().m_pCurrentDocument = pNewDocument;
|
||
m_arStates.top().m_bRemoveCurrentDocument = false;
|
||
}
|
||
|
||
void COOXMLWriter::Break(const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
if (m_arStates.top().m_bInP)
|
||
{
|
||
OpenR();
|
||
if(arSelectors.back().m_pCompiledStyle->m_oText.GetAlign() == L"both")
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:tab/>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:br/>");
|
||
CloseR();
|
||
}
|
||
else
|
||
WriteEmptyParagraph();
|
||
|
||
m_arStates.top().m_bWasSpace = true;
|
||
}
|
||
|
||
void COOXMLWriter::OpenCrossHyperlink(const std::wstring& wsRef, const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:hyperlink w:anchor=\"");
|
||
const size_t nSharp = wsRef.find('#');
|
||
|
||
std::wstring wsAnchorValue;
|
||
|
||
if(nSharp == std::wstring::npos)
|
||
wsAnchorValue = NSFile::GetFileName(wsRef);
|
||
else
|
||
wsAnchorValue = (wsRef.c_str() + nSharp + 1);
|
||
|
||
if (!wsAnchorValue.empty())
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(AddAnchor(wsAnchorValue));
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\">");
|
||
}
|
||
|
||
void COOXMLWriter::OpenExternalHyperlink(const std::wstring& wsRef, const std::wstring& wsTooltip, const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
XmlString& oRelationshipXml(m_oDocXmlRels);
|
||
|
||
if (*&m_arStates.top().m_pCurrentDocument == &m_oNoteXml)
|
||
oRelationshipXml = m_oNoteXmlRels;
|
||
|
||
oRelationshipXml.WriteString(L"<Relationship Id=\"rHyp");
|
||
oRelationshipXml.WriteString(std::to_wstring(m_nHyperlinkId));
|
||
oRelationshipXml.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\" Target=\"");
|
||
oRelationshipXml.WriteEncodeXmlString(wsRef);
|
||
oRelationshipXml.WriteString(L"\" TargetMode=\"External\"/>");
|
||
|
||
m_arStates.top().m_bInHyperlink = true;
|
||
// Пишем в document.xml
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:hyperlink w:tooltip=\"");
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(wsTooltip);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\" r:id=\"rHyp");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(std::to_wstring(m_nHyperlinkId++));
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\">");
|
||
}
|
||
|
||
void COOXMLWriter::CloseCrossHyperlink(const std::vector<NSCSS::CNode>& arSelectors, std::wstring wsFootnote, const std::wstring& wsRef)
|
||
{
|
||
if (!m_arStates.top().m_bInP)
|
||
return;
|
||
|
||
CloseExternalHyperlink();
|
||
|
||
if (wsFootnote == L"href")
|
||
wsFootnote = wsRef.substr(wsRef.find('#') + 1);
|
||
|
||
bool bFootnote = false;
|
||
if (arSelectors.size() > 1)
|
||
{
|
||
const NSCSS::CNode& oNode = arSelectors[arSelectors.size() - 2];
|
||
bFootnote = oNode.m_wsName == L"p" && oNode.m_wsClass == L"MsoFootnoteText";
|
||
}
|
||
|
||
// Сноска
|
||
if (!wsFootnote.empty())
|
||
{
|
||
if (!bFootnote)
|
||
{
|
||
std::wstring sFootnoteID = std::to_wstring(m_nFootnoteId++);
|
||
OpenR();
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteReference w:id=\"");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(sFootnoteID);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\"/>");
|
||
CloseR();
|
||
m_mFootnotes.insert(std::make_pair(wsFootnote, sFootnoteID));
|
||
}
|
||
else
|
||
{
|
||
OpenR();
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteRef/>");
|
||
CloseR();
|
||
}
|
||
}
|
||
}
|
||
|
||
void COOXMLWriter::CloseExternalHyperlink()
|
||
{
|
||
if (!m_arStates.top().m_bInP && !m_arStates.top().m_bInHyperlink)
|
||
return;
|
||
|
||
CloseT();
|
||
CloseR();
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"</w:hyperlink>");
|
||
m_arStates.top().m_bInHyperlink = false;
|
||
}
|
||
|
||
std::wstring COOXMLWriter::WritePPr(const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
OpenP();
|
||
|
||
if (m_arStates.top().m_bWasPStyle)
|
||
return L"";
|
||
|
||
std::wstring sPStyle = GetStyle(*arSelectors.back().m_pCompiledStyle, true);
|
||
|
||
if (sPStyle.empty() && !ElementInTable(arSelectors))
|
||
sPStyle = L"normal-web";
|
||
|
||
if (sPStyle.empty() && m_arDivId.empty() /*&& oTS.sPStyle.empty() && 0 > oTS.nLi*/)
|
||
return L"";
|
||
|
||
// m_oXmlStyle.WriteLitePStyle(oTS.oAdditionalStyle);
|
||
// const std::wstring sPSettings = m_oXmlStyle.GetStyle();
|
||
// m_oXmlStyle.Clear();
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteNodeBegin(L"w:pPr");
|
||
|
||
if (!sPStyle.empty())
|
||
{
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:pStyle w:val=\"");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(sPStyle);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\"/>");
|
||
}
|
||
|
||
int nLiLevel{-1};
|
||
bool bNumberingLi{false};
|
||
|
||
for (const NSCSS::CNode& oNode : arSelectors)
|
||
{
|
||
if (L"ol" == oNode.m_wsName)
|
||
bNumberingLi = true;
|
||
else if (L"li" == oNode.m_wsName)
|
||
bNumberingLi = false;
|
||
else
|
||
continue;
|
||
|
||
++nLiLevel;
|
||
}
|
||
|
||
if (nLiLevel >= 0)
|
||
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;
|
||
|
||
return sPStyle;
|
||
}
|
||
|
||
std::wstring COOXMLWriter::WriteRPr(XmlString& oXml, const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
if (!m_arStates.top().m_bInP)
|
||
return L"";
|
||
|
||
NSCSS::CCompiledStyle *pMainStyle{arSelectors.back().m_pCompiledStyle};
|
||
std::wstring sRSettings;
|
||
|
||
std::wstring sRStyle = GetStyle(*pMainStyle, false);
|
||
|
||
// if (!oTS.oAdditionalStyle.Empty())
|
||
// {
|
||
// NSCSS::CCompiledStyle oSettingStyle{oTS.oAdditionalStyle};
|
||
|
||
// NSCSS::CCompiledStyle::StyleEquation(oMainStyle, oSettingStyle);
|
||
|
||
// m_oXmlStyle.WriteLiteRStyle(oSettingStyle);
|
||
// sRSettings = m_oXmlStyle.GetStyle();
|
||
// m_oXmlStyle.Clear();
|
||
// }
|
||
|
||
std::wstring wsFontSize;
|
||
|
||
const int nCalculatedFontChange{CalculateFontChange(arSelectors)};
|
||
|
||
if (0 != nCalculatedFontChange)
|
||
{
|
||
int nFontSizeLevel{static_cast<int>((pMainStyle->m_oFont.Empty()) ? 3 : GetFontSizeLevel(pMainStyle->m_oFont.GetSize().ToInt(NSCSS::Point) * 2))};
|
||
|
||
nFontSizeLevel += nCalculatedFontChange;
|
||
|
||
const UINT unFontSize{GetFontSizeByLevel(nFontSizeLevel)};
|
||
|
||
wsFontSize += L"<w:sz w:val=\"" + std::to_wstring(unFontSize) + L"\"/><w:szCs w:val=\"" + std::to_wstring(unFontSize) + L"\"/>";
|
||
}
|
||
|
||
const std::wstring wsTextMode{pMainStyle->m_oDisplay.GetVAlign().ToWString()};
|
||
|
||
if (!sRStyle.empty() || L"normal" != wsTextMode || !wsFontSize.empty() || !sRSettings.empty())
|
||
{
|
||
oXml.WriteString(L"<w:rPr>");
|
||
if (!sRStyle.empty())
|
||
{
|
||
oXml.WriteString(L"<w:rStyle w:val=\"");
|
||
oXml.WriteString(sRStyle);
|
||
oXml.WriteString(L"\"/>");
|
||
}
|
||
|
||
if (L"sub" == wsTextMode)
|
||
oXml.WriteString(L"<w:vertAlign w:val=\"subscript\"/>");
|
||
else if (L"super" == wsTextMode)
|
||
oXml.WriteString(L"<w:vertAlign w:val=\"superscript\"/>");
|
||
|
||
oXml.WriteString(sRSettings + wsFontSize);
|
||
oXml.WriteString(L"</w:rPr>");
|
||
}
|
||
return sRStyle;
|
||
}
|
||
|
||
bool COOXMLWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
if (wsText.empty())
|
||
return false;
|
||
|
||
bool bBidirectional{false}, bPreformatted{false}, bQuotation{false}, bAddSpaces{true}, bMergedText{false};
|
||
|
||
for (const NSCSS::CNode& oNode : arSelectors)
|
||
{
|
||
if (L"bdo" == oNode.m_wsName && L"rtl" == oNode.GetAttributeValue(L"dir"))
|
||
bBidirectional = true;
|
||
else if (L"bdi" == oNode.m_wsName)
|
||
bBidirectional = false;
|
||
else if (L"pre" == oNode.m_wsName || L"nobr" == oNode.m_wsName || L"xmp" == oNode.m_wsName)
|
||
bPreformatted = true;
|
||
else if (L"q" == oNode.m_wsName)
|
||
bQuotation = true;
|
||
else if (L"span" == oNode.m_wsName)
|
||
bAddSpaces = false;
|
||
}
|
||
|
||
const NSCSS::CCompiledStyle* pCompiledStyle{arSelectors.back().m_pCompiledStyle};
|
||
|
||
if (!bPreformatted && nullptr != arSelectors.back().m_pCompiledStyle)
|
||
{
|
||
// TODO::поведение должно быть немного разное (реализовать)
|
||
switch(pCompiledStyle->m_oDisplay.GetWhiteSpace().ToInt())
|
||
{
|
||
case NSCSS::NSProperties::EWhiteSpace::Pre:
|
||
case NSCSS::NSProperties::EWhiteSpace::Pre_Wrap:
|
||
case NSCSS::NSProperties::EWhiteSpace::Pre_Line:
|
||
bPreformatted = true;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!bPreformatted && wsText.end() == std::find_if_not(wsText.begin(), wsText.end(), [](wchar_t wchChar){ return iswspace(wchChar) && 0xa0 != wchChar;}))
|
||
return false;
|
||
|
||
std::wstring wsHeaderId;
|
||
|
||
if (ElementInHeader(arSelectors))
|
||
wsHeaderId = StandardizeHeaderId(wsText);
|
||
|
||
if(bBidirectional)
|
||
std::reverse(wsText.begin(), wsText.end());
|
||
|
||
const bool bInT = m_arStates.top().m_bInT;
|
||
|
||
//TODO:: сделать так, чтобы параграф (со своими стилями) открывался при чтении сооответствующей ноды, а не при чтении текста
|
||
OpenP();
|
||
|
||
WritePPr(arSelectors);
|
||
|
||
std::wstring wsCrossId;
|
||
|
||
if (!wsHeaderId.empty())
|
||
WriteEmptyBookmark(wsHeaderId);
|
||
|
||
NSStringUtils::CStringBuilder oRPr;
|
||
std::wstring sRStyle;
|
||
|
||
if (OpenR())
|
||
{
|
||
sRStyle = WriteRPr(oRPr, arSelectors);
|
||
WriteToStringBuilder(oRPr, *m_arStates.top().m_pCurrentDocument);
|
||
}
|
||
|
||
if (bQuotation)
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:t xml:space=\"preserve\">"</w:t>");
|
||
|
||
if (!bPreformatted && bAddSpaces && m_arStates.top().m_bInP && !m_arStates.top().m_bInR && !iswspace(wsText.front()) && !iswpunct(wsText.front()) && !m_arStates.top().m_bWasSpace)
|
||
{
|
||
if (pCompiledStyle->m_oDisplay.GetVAlign().Empty() || L"normal" == pCompiledStyle->m_oDisplay.GetVAlign().ToWString())
|
||
WriteSpace();
|
||
}
|
||
|
||
if(bPreformatted)
|
||
{
|
||
size_t unBegin = 0, unEnd = wsText.find_first_of(L"\n\r\t");
|
||
|
||
while (std::wstring::npos != unBegin)
|
||
{
|
||
if (OpenR())
|
||
WriteToStringBuilder(oRPr, *m_arStates.top().m_pCurrentDocument);
|
||
|
||
OpenT();
|
||
if (unEnd == std::wstring::npos)
|
||
{
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(wsText.c_str() + unBegin, wsText.length() - unBegin);
|
||
break;
|
||
}
|
||
|
||
if (unBegin != unEnd)
|
||
{
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(wsText.c_str() + unBegin, unEnd - unBegin);
|
||
CloseT();
|
||
}
|
||
|
||
if (L'\n' == wsText[unEnd])
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:br/>");
|
||
else if (L'\t' == wsText[unEnd])
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:tab/>");
|
||
|
||
unBegin = unEnd + 1;
|
||
unEnd = wsText.find_first_of(L"\n\r\t", unBegin);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ReplaceSpaces(wsText);
|
||
|
||
if (!wsText.empty() && L'\t' == wsText[0])
|
||
{
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:tab/>");
|
||
wsText.erase(0, 1);
|
||
}
|
||
|
||
if (!wsText.empty() && std::iswspace(wsText.front()) && m_arStates.top().m_bWasSpace)
|
||
wsText.erase(0, 1);
|
||
|
||
OpenT();
|
||
|
||
if (bMergedText && !m_arStates.top().m_bWasSpace && bInT && !bPreformatted)
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(L" ");
|
||
|
||
if (!wsText.empty())
|
||
{
|
||
m_arStates.top().m_bWasSpace = std::iswspace(wsText.back());
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(wsText);
|
||
}
|
||
}
|
||
|
||
if (bQuotation)
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:t xml:space=\"preserve\">"</w:t>");
|
||
|
||
CloseT();
|
||
|
||
if (!bMergedText)
|
||
CloseR();
|
||
|
||
return true;
|
||
}
|
||
|
||
void COOXMLWriter::WriteEmptyParagraph(bool bVahish, bool bInP)
|
||
{
|
||
if (!bInP)
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:p><w:pPr>");
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:rPr><w:rFonts w:eastAsia=\"Times New Roman\"/>");
|
||
|
||
if (bVahish)
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:sz w:val=\"2\"/><w:szCs w:val=\"2\"/><w:vanish/>");
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"</w:rPr>");
|
||
|
||
if (!bInP)
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"</w:pPr></w:p>");
|
||
}
|
||
|
||
void COOXMLWriter::WriteSpace()
|
||
{
|
||
OpenR();
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:rPr><w:rFonts w:eastAsia=\"Times New Roman\"/></w:rPr><w:t xml:space=\"preserve\"> </w:t>");
|
||
CloseR();
|
||
m_arStates.top().m_bWasSpace = true;
|
||
}
|
||
|
||
void COOXMLWriter::WriteEmptyBookmark(const std::wstring& wsId)
|
||
{
|
||
const std::wstring wsCrossId{WriteBookmark(wsId)};
|
||
|
||
if (wsCrossId.empty())
|
||
return;
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:bookmarkEnd w:id=\"");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(wsCrossId);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\"/>");
|
||
}
|
||
|
||
std::wstring COOXMLWriter::AddLiteBookmark()
|
||
{
|
||
return m_mBookmarks.insert(std::make_pair(L"Bookmark" + std::to_wstring(m_mBookmarks.size() + 1), m_mBookmarks.size() + 1)).first->first;
|
||
}
|
||
|
||
std::wstring COOXMLWriter::WriteBookmark(const std::wstring& wsId)
|
||
{
|
||
const std::wstring sCrossId = std::to_wstring(m_mBookmarks.size() + 1);
|
||
std::wstring sName;
|
||
|
||
if (m_mBookmarks.end() != m_mBookmarks.find(wsId))
|
||
sName = wsId + L"_" + std::to_wstring(++m_mBookmarks[wsId]);
|
||
else
|
||
{
|
||
const anchors_map::const_iterator itFound{m_mAnchors.find(wsId)};
|
||
|
||
if (m_mAnchors.end() != itFound)
|
||
sName = itFound->second;
|
||
else
|
||
sName = AddAnchor(wsId);
|
||
|
||
m_mBookmarks.insert({wsId, 1});
|
||
}
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:bookmarkStart w:id=\"");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(sCrossId);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\" w:name=\"");
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(sName);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\"/>");
|
||
|
||
return sCrossId;
|
||
}
|
||
|
||
std::wstring COOXMLWriter::AddAnchor(const std::wstring& wsAnchorValue)
|
||
{
|
||
const anchors_map::iterator itFound = m_mAnchors.find(wsAnchorValue);
|
||
|
||
if (m_mAnchors.end() != itFound)
|
||
return itFound->second;
|
||
|
||
const std::wstring wsAnchorId{L"anchor-" + std::to_wstring(m_mAnchors.size() + 1)};
|
||
m_mAnchors[wsAnchorValue] = wsAnchorId;
|
||
|
||
return wsAnchorId;
|
||
}
|
||
|
||
void COOXMLWriter::WriteImage(const TImageData& oImageData, const std::wstring& wsId)
|
||
{
|
||
OpenR();
|
||
|
||
XmlString* pCurrentDocument{m_arStates.top().m_pCurrentDocument};
|
||
|
||
// Пишем в document.xml
|
||
if (oImageData.ZeroSpaces())
|
||
{
|
||
pCurrentDocument->WriteString(L"<w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\"");
|
||
pCurrentDocument->WriteString(std::to_wstring(oImageData.m_unWidth));
|
||
pCurrentDocument->WriteString(L"\" cy=\"");
|
||
pCurrentDocument->WriteString(std::to_wstring(oImageData.m_unHeight));
|
||
pCurrentDocument->WriteString(L"\"/><wp:docPr id=\"");
|
||
pCurrentDocument->WriteString(wsId);
|
||
pCurrentDocument->WriteString(L"\" name=\"Picture " + wsId + L"\"/><a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:nvPicPr><pic:cNvPr id=\"");
|
||
pCurrentDocument->WriteString(wsId);
|
||
pCurrentDocument->WriteString(L"\" name=\"Picture " + wsId + L"\"/><pic:cNvPicPr></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"rPic");
|
||
pCurrentDocument->WriteString(wsId);
|
||
pCurrentDocument->WriteString(L"\"/><a:stretch/></pic:blipFill><pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"");
|
||
pCurrentDocument->WriteString(std::to_wstring(oImageData.m_unWidth));
|
||
pCurrentDocument->WriteString(L"\" cy=\"");
|
||
pCurrentDocument->WriteString(std::to_wstring(oImageData.m_unHeight));
|
||
pCurrentDocument->WriteString(L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing>");
|
||
}
|
||
else
|
||
{
|
||
pCurrentDocument->WriteString(L"<w:rPr><w:noProof/></w:rPr><w:drawing>");
|
||
pCurrentDocument->WriteString(L"<wp:anchor distT=\"" + std::to_wstring(oImageData.m_nHSpace) + L"\" distB=\"" + std::to_wstring(oImageData.m_nHSpace) + L"\" distL=\"" + std::to_wstring(oImageData.m_nVSpace) + L"\" distR=\"" + std::to_wstring(oImageData.m_nVSpace) + L"\" simplePos=\"0\" relativeHeight=\"251658240\" behindDoc=\"0\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"0\">");
|
||
pCurrentDocument->WriteString(L"<wp:simplePos x=\"0\" y=\"0\"/>");
|
||
pCurrentDocument->WriteString(L"<wp:positionH relativeFrom=\"column\"><wp:align>" + oImageData.m_wsAlign + L"</wp:align></wp:positionH>");
|
||
pCurrentDocument->WriteString(L"<wp:positionV relativeFrom=\"line\"><wp:posOffset>0</wp:posOffset></wp:positionV>");
|
||
pCurrentDocument->WriteString(L"<wp:extent cx=\"" + std::to_wstring(oImageData.m_unWidth) + L"\" cy=\"" + std::to_wstring(oImageData.m_unHeight) + L"\"/>");
|
||
pCurrentDocument->WriteString(L"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>");
|
||
pCurrentDocument->WriteString(L"<wp:wrapSquare wrapText=\"bothSides\"/>");
|
||
pCurrentDocument->WriteString(L"<wp:docPr id=\"" + wsId + L"\" name=\"Picture " + wsId + L"\"/>");
|
||
pCurrentDocument->WriteString(L"<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></wp:cNvGraphicFramePr>");
|
||
pCurrentDocument->WriteString(L"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">");
|
||
pCurrentDocument->WriteString(L"<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">");
|
||
pCurrentDocument->WriteString(L"<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">");
|
||
pCurrentDocument->WriteString(L"<pic:nvPicPr><pic:cNvPr id=\"" + wsId + L"\" name=\"Picture " + wsId + L"\"/>");
|
||
pCurrentDocument->WriteString(L"<pic:cNvPicPr><a:picLocks noChangeAspect=\"1\" noChangeArrowheads=\"1\"/></pic:cNvPicPr></pic:nvPicPr>");
|
||
pCurrentDocument->WriteString(L"<pic:blipFill><a:blip r:link=\"rPic" + wsId + L"\"><a:extLst><a:ext uri=\"{28A0092B-C50C-407E-A947-70E740481C1C}\"><a14:useLocalDpi xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\" val=\"0\"/></a:ext></a:extLst></a:blip><a:srcRect/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>");
|
||
pCurrentDocument->WriteString(L"<pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"" + std::to_wstring(oImageData.m_unWidth) + L"\" cy=\"" + std::to_wstring(oImageData.m_unHeight) + L"\"/></a:xfrm>");
|
||
pCurrentDocument->WriteString(L"<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln></pic:spPr></pic:pic></a:graphicData></a:graphic>");
|
||
pCurrentDocument->WriteString(L"<wp14:sizeRelH relativeFrom=\"page\"><wp14:pctWidth>0</wp14:pctWidth></wp14:sizeRelH><wp14:sizeRelV relativeFrom=\"page\"><wp14:pctHeight>0</wp14:pctHeight></wp14:sizeRelV>");
|
||
pCurrentDocument->WriteString(L"</wp:anchor></w:drawing>");
|
||
}
|
||
|
||
CloseR();
|
||
}
|
||
|
||
void COOXMLWriter::WriteAlternativeImage(const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData)
|
||
{
|
||
m_oDocXmlRels.WriteString(L"<Relationship Id=\"rId");
|
||
m_oDocXmlRels.WriteString(std::to_wstring(m_nId));
|
||
m_oDocXmlRels.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"");
|
||
m_oDocXmlRels.WriteEncodeXmlString(wsSrc);
|
||
m_oDocXmlRels.WriteString(L"\" TargetMode=\"External\"/>");
|
||
|
||
const bool bOpenedP{OpenP()};
|
||
|
||
WriteEmptyImage((0 != oImageData.m_unWidth) ? oImageData.m_unWidth : DEFAULT_IMAGE_WIDTH, (0 != oImageData.m_unHeight) ? oImageData.m_unHeight : DEFAULT_IMAGE_HEIGHT, L"", wsAlt);
|
||
|
||
if (bOpenedP)
|
||
CloseP();
|
||
}
|
||
void COOXMLWriter::WriteEmptyImage(int nWidth, int nHeight, const std::wstring& wsName, const std::wstring& wsDescr)
|
||
{
|
||
OpenR();
|
||
|
||
#define WRITE_ENCODE_ARGUMENT(argumentName, argumentValue) \
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L" " + std::wstring(argumentName) + L"=\""); \
|
||
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(argumentValue); \
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"\"")
|
||
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:rPr><w:noProof/></w:rPr><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\"" + std::to_wstring(nWidth) + L"\" cy=\"" + std::to_wstring(nHeight) + L"\"/><wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<wp:docPr id=\"" + std::to_wstring(m_nId - 7) + L"\"");
|
||
WRITE_ENCODE_ARGUMENT(L"name", wsName);
|
||
WRITE_ENCODE_ARGUMENT(L"descr", wsDescr);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"/>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></wp:cNvGraphicFramePr>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<pic:nvPicPr><pic:cNvPr id=\"0\"");
|
||
WRITE_ENCODE_ARGUMENT(L"name", wsName);
|
||
WRITE_ENCODE_ARGUMENT(L"descr", wsDescr);
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"/>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<pic:cNvPicPr><a:picLocks noChangeAspect=\"1\" noChangeArrowheads=\"1\"/></pic:cNvPicPr></pic:nvPicPr>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<pic:blipFill><a:blip r:link=\"rId" + std::to_wstring(m_nId++) + L"\"><a:extLst><a:ext uri=\"{28A0092B-C50C-407E-A947-70E740481C1C}\"><a14:useLocalDpi xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\" val=\"0\"/></a:ext></a:extLst></a:blip><a:srcRect/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"<pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"" + std::to_wstring(nWidth) + L"\" cy=\"" + std::to_wstring(nHeight) + L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln></pic:spPr>");
|
||
m_arStates.top().m_pCurrentDocument->WriteString(L"</pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing>");
|
||
|
||
CloseR();
|
||
}
|
||
|
||
void COOXMLWriter::WriteImageRels(const std::wstring& wsImageId, const std::wstring& wsImageName)
|
||
{
|
||
m_oDocXmlRels.WriteString(L"<Relationship Id=\"rPic");
|
||
m_oDocXmlRels.WriteString(wsImageId);
|
||
m_oDocXmlRels.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/i");
|
||
m_oDocXmlRels.WriteEncodeXmlString(wsImageName);
|
||
m_oDocXmlRels.WriteString(L"\"/>");
|
||
}
|
||
|
||
std::wstring COOXMLWriter::GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bParagraphStyle)
|
||
{
|
||
if ((bParagraphStyle && !m_oXmlStyle.WritePStyle(oStyle)) || (!bParagraphStyle && !m_oXmlStyle.WriteRStyle(oStyle)))
|
||
return L"";
|
||
|
||
m_oStylesXml.WriteString(m_oXmlStyle.GetStyle());
|
||
return m_oXmlStyle.GetIdAndClear();
|
||
}
|
||
|
||
void COOXMLWriter::UpdatePageStyle(const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
if (nullptr != m_pStylesCalculator)
|
||
m_pStylesCalculator->CalculatePageStyle(m_oPageData, arSelectors);
|
||
}
|
||
|
||
void COOXMLWriter::SetBaseFont(const std::wstring& wsFontStyles)
|
||
{
|
||
if (nullptr != m_pStylesCalculator)
|
||
m_pStylesCalculator->AddStyles(wsFontStyles);
|
||
}
|
||
|
||
void COOXMLWriter::SetDivId(const std::wstring& wsDivId)
|
||
{
|
||
m_arDivId.push(wsDivId);
|
||
m_bWasDivs = true;
|
||
}
|
||
|
||
void COOXMLWriter::RollBackDivId()
|
||
{
|
||
if (!m_arDivId.empty())
|
||
m_arDivId.pop();
|
||
}
|
||
|
||
std::wstring COOXMLWriter::FindFootnote(const std::wstring& wsId)
|
||
{
|
||
const std::map<std::wstring, std::wstring>::const_iterator itFound{m_mFootnotes.find(wsId)};
|
||
return (itFound != m_mFootnotes.cend()) ? itFound->second : std::wstring();
|
||
}
|
||
|
||
void COOXMLWriter::OpenFootnote(const std::wstring& wsFootnoteID)
|
||
{
|
||
m_oNoteXml.WriteString(L"<w:footnote w:id=\"");
|
||
m_oNoteXml.WriteString(wsFootnoteID);
|
||
m_oNoteXml.WriteString(L"\">");
|
||
}
|
||
|
||
void COOXMLWriter::CloseFootnote()
|
||
{
|
||
m_oNoteXml.WriteString(L"</w:footnote>");
|
||
}
|
||
|
||
XmlString& COOXMLWriter::GetStylesXml()
|
||
{
|
||
return m_oStylesXml;
|
||
}
|
||
|
||
XmlString& COOXMLWriter::GetDocRelsXml()
|
||
{
|
||
return m_oDocXmlRels;
|
||
}
|
||
|
||
XmlString& COOXMLWriter::GetNotesRelsXml()
|
||
{
|
||
return m_oNoteXmlRels;
|
||
}
|
||
|
||
XmlString& COOXMLWriter::GetDocumentXml()
|
||
{
|
||
return m_oDocXml;
|
||
}
|
||
|
||
XmlString& COOXMLWriter::GetNotesXml()
|
||
{
|
||
return m_oNoteXml;
|
||
}
|
||
|
||
XmlString& COOXMLWriter::GetNumberingXml()
|
||
{
|
||
return m_oNumberXml;
|
||
}
|
||
|
||
XmlString& COOXMLWriter::GetWebSettingsXml()
|
||
{
|
||
return m_oWebSettings;
|
||
}
|
||
|
||
XmlString* COOXMLWriter::GetCurrentDocument() const
|
||
{
|
||
return m_arStates.top().m_pCurrentDocument;
|
||
}
|
||
|
||
const NSCSS::NSProperties::CPage* COOXMLWriter::GetPageData() const
|
||
{
|
||
return &m_oPageData;
|
||
}
|
||
|
||
NSFonts::IApplicationFonts* COOXMLWriter::GetFonts()
|
||
{
|
||
if (nullptr == m_pFonts)
|
||
{
|
||
m_pFonts = NSFonts::NSApplication::Create();
|
||
|
||
if (NULL != m_pFonts)
|
||
m_pFonts->Initialize();
|
||
}
|
||
|
||
return m_pFonts;
|
||
}
|
||
|
||
std::wstring COOXMLWriter::GetMediaDir() const
|
||
{
|
||
return ((nullptr != m_pDstPath) ? *m_pDstPath : std::wstring()) + L"/word/media/";
|
||
}
|
||
|
||
std::wstring COOXMLWriter::GetTempDir() const
|
||
{
|
||
return (nullptr != m_pTempDir) ? *m_pTempDir : std::wstring();
|
||
}
|
||
|
||
std::wstring COOXMLWriter::GetSrcPath() const
|
||
{
|
||
return (nullptr != m_pSrcPath) ? *m_pSrcPath : std::wstring();
|
||
}
|
||
|
||
std::wstring COOXMLWriter::GetBasePath() const
|
||
{
|
||
return (nullptr != m_pBasePath) ? *m_pBasePath : std::wstring();
|
||
}
|
||
|
||
std::wstring COOXMLWriter::GetCorePath() const
|
||
{
|
||
return (nullptr != m_pCorePath) ? *m_pCorePath : std::wstring();
|
||
}
|
||
|
||
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 ElementInHeader(const std::vector<NSCSS::CNode> arSelsectors)
|
||
{
|
||
for (const NSCSS::CNode& oNode : arSelsectors)
|
||
{
|
||
if (2 == oNode.m_wsName.length() && L'h' != oNode.m_wsName[0] &&
|
||
(L'1' == oNode.m_wsName[1] || L'2' == oNode.m_wsName[1] ||
|
||
L'3' == oNode.m_wsName[1] || L'4' == oNode.m_wsName[1] ||
|
||
L'5' == oNode.m_wsName[1] || L'6' == oNode.m_wsName[1]))
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
std::wstring StandardizeHeaderId(const std::wstring& wsHeader)
|
||
{
|
||
if (wsHeader.empty())
|
||
return std::wstring();
|
||
|
||
std::wstring result;
|
||
result.reserve(wsHeader.size());
|
||
|
||
// Флаг, указывающий, был ли предыдущий символ дефисом
|
||
bool prevWasHyphen = false;
|
||
bool inWhitespaceSequence = false;
|
||
wchar_t lowerC;
|
||
|
||
for (wchar_t c : wsHeader)
|
||
{
|
||
// Приведение к нижнему регистру
|
||
lowerC = std::tolower(c);
|
||
|
||
// Проверяем, является ли символ буквой или цифрой
|
||
if (std::iswalnum(lowerC))
|
||
{
|
||
result.push_back(lowerC);
|
||
prevWasHyphen = false;
|
||
inWhitespaceSequence = false;
|
||
}
|
||
// Проверяем, является ли символ пробельным (пробел, табуляция и т.д.)
|
||
else if (std::iswspace(lowerC))
|
||
{
|
||
// Заменяем последовательности пробельных символов на один дефис
|
||
if (!inWhitespaceSequence && !result.empty())
|
||
{
|
||
result.push_back(L'-');
|
||
inWhitespaceSequence = true;
|
||
}
|
||
}
|
||
// Проверяем, является ли символ дефисом или подчеркиванием
|
||
else if (c == L'-' || c == L'_')
|
||
{
|
||
// Добавляем дефис, если предыдущий символ не был дефисом
|
||
if (!prevWasHyphen && !result.empty())
|
||
{
|
||
result.push_back(L'-');
|
||
prevWasHyphen = true;
|
||
}
|
||
inWhitespaceSequence = false;
|
||
}
|
||
// Все остальные символы (знаки препинания) пропускаем
|
||
// Но если это буква в Unicode, мы можем её обработать
|
||
else if (std::iswalpha(lowerC))
|
||
{
|
||
// Для Unicode-символов, которые являются буквами
|
||
result.push_back(lowerC);
|
||
prevWasHyphen = false;
|
||
inWhitespaceSequence = false;
|
||
}
|
||
// Остальные символы игнорируем
|
||
}
|
||
|
||
// Удаляем дефисы в начале и конце
|
||
size_t start = 0;
|
||
size_t end = result.length();
|
||
|
||
while (start < end && result[start] == L'-')
|
||
++start;
|
||
|
||
while (end > start && result[end - 1] == L'-')
|
||
--end;
|
||
|
||
// Удаляем последовательные дефисы
|
||
std::wstring finalResult;
|
||
finalResult.reserve(end - start);
|
||
|
||
bool lastWasHyphen = false;
|
||
for (size_t i = start; i < end; i++)
|
||
{
|
||
if (result[i] == L'-')
|
||
{
|
||
if (!lastWasHyphen)
|
||
{
|
||
finalResult.push_back(L'-');
|
||
lastWasHyphen = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
finalResult.push_back(result[i]);
|
||
lastWasHyphen = false;
|
||
}
|
||
}
|
||
|
||
return finalResult;
|
||
}
|
||
|
||
inline int CalculateFontChange(const std::vector<NSCSS::CNode>& arSelectors)
|
||
{
|
||
int nFontChange = 0;
|
||
|
||
for (const NSCSS::CNode& oNode : arSelectors)
|
||
{
|
||
if (L"big" == oNode.m_wsName)
|
||
++nFontChange;
|
||
else if (L"small" == oNode.m_wsName)
|
||
--nFontChange;
|
||
}
|
||
|
||
return nFontChange;
|
||
}
|
||
|
||
inline UINT GetFontSizeLevel(UINT unFontSize)
|
||
{
|
||
if (unFontSize <= 18)
|
||
return 1;
|
||
else if (unFontSize <= 22)
|
||
return 2;
|
||
else if (unFontSize <= 26)
|
||
return 3;
|
||
else if (unFontSize <= 30)
|
||
return 4;
|
||
else if (unFontSize <= 40)
|
||
return 5;
|
||
else if (unFontSize <= 59)
|
||
return 6;
|
||
else
|
||
return 7;
|
||
}
|
||
|
||
inline UINT GetFontSizeByLevel(UINT unLevel)
|
||
{
|
||
if (0 == unLevel)
|
||
return 15;
|
||
else if (unLevel > 7)
|
||
return 72;
|
||
|
||
switch (unLevel)
|
||
{
|
||
case 1: return 15;
|
||
case 2: return 20;
|
||
case 3: return 24;
|
||
case 4: return 27;
|
||
case 5: return 36;
|
||
case 6: return 48;
|
||
case 7: return 72;
|
||
}
|
||
return 24;
|
||
}
|
||
|
||
inline void ReplaceSpaces(std::wstring& wsValue)
|
||
{
|
||
// boost::wregex oRegex(L"\\s+");
|
||
// wsValue = boost::regex_replace(wsValue, oRegex, L" ");
|
||
|
||
std::wstring::const_iterator itBegin = std::find_if(wsValue.cbegin(), wsValue.cend(), [](wchar_t wchValue){ return std::iswspace(wchValue) && 0xa0 != wchValue; });
|
||
std::wstring::const_iterator itEnd;
|
||
|
||
while (wsValue.cend() != itBegin)
|
||
{
|
||
itEnd = std::find_if(itBegin, wsValue.cend(), [](wchar_t wchValue){ return !std::iswspace(wchValue) || 0xa0 == wchValue; });
|
||
|
||
wsValue.replace(itBegin, itEnd, L" ");
|
||
|
||
itBegin = std::find_if(itBegin + 1, wsValue.cend(), [](wchar_t wchValue){ return std::iswspace(wchValue) && 0xa0 != wchValue; });
|
||
}
|
||
}
|
||
}
|