cross reference

This commit is contained in:
Svetlana Kulikova
2020-07-21 18:12:52 +03:00
parent 10a970efb0
commit 95c4cf28e0
6 changed files with 4670 additions and 51 deletions

View File

@ -166,12 +166,13 @@ public:
SDocumentInfo m_oDocumentInfo; // Информация об fb2-документе
std::wstring m_sTmpFolder; // Рабочая папка
int m_nContentsId; // ID оглавления
int m_nContentsId; // ID содержания
int m_nCrossReferenceId; // ID перекрестной ссылки
STitleInfo* m_pSrcTitleInfo; // Данные об исходнике книги
SPublishInfo* m_pPublishInfo; // Сведения об издании книги
std::map<std::wstring, std::wstring> m_mFootnotes; // Ссылки
std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски
std::map<std::wstring, std::vector<std::wstring>> m_mImages; // Картинки
std::map<std::wstring, std::wstring> m_mCustomInfo; // Произвольная информация
@ -181,6 +182,7 @@ public:
m_pSrcTitleInfo = NULL;
m_pPublishInfo = NULL;
m_nContentsId = 1;
m_nCrossReferenceId = 1;
m_sTmpFolder = L"";
}
@ -251,14 +253,11 @@ public:
std::wstring sName = m_oLightReader.GetName();
size_t nLen = sName.length() - 4;
if(sName.substr(nLen > 0 ? nLen : 0) == L"href")
{
sImageName = m_oLightReader.GetText().substr(1);
break;
}
}
m_oLightReader.MoveToElement();
if(sImageName == L"")
return;
readCrossReference(oBuilder);
std::map<std::wstring, std::vector<std::wstring>>::iterator it = m_mImages.find(sImageName);
if(it != m_mImages.end())
@ -304,32 +303,34 @@ public:
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode(nDeath))
{
// Пишем title + sLevel
oBuilder += L"<w:p><w:pPr><w:pStyle w:val=\"";
oBuilder += sLevel;
oBuilder += L"\"/></w:pPr>";
// Пишем ссылку от оглавления
std::wstring sContentsId;
if(sLevel == L"title1")
{
sContentsId = std::to_wstring(m_nContentsId++);
oBuilder += L"<w:bookmarkStart w:id=\"";
oBuilder += sContentsId;
oBuilder += L"\" w:name=\"_Toc";
oBuilder += sContentsId;
oBuilder += L"\"/>";
}
// Пишем заголовок
if(m_oLightReader.GetName() == L"p")
readP(L"", oBuilder);
// Пишем ссылку от оглавления
if(sLevel == L"title1")
{
oBuilder += L"<w:bookmarkEnd w:id=\"";
oBuilder += sContentsId;
oBuilder += L"\"/>";
// Пишем title + sLevel
oBuilder += L"<w:p><w:pPr><w:pStyle w:val=\"";
oBuilder += sLevel;
oBuilder += L"\"/></w:pPr>";
// Пишем ссылку от оглавления
std::wstring sContentsId;
if(sLevel == L"title1")
{
sContentsId = std::to_wstring(m_nContentsId++);
oBuilder += L"<w:bookmarkStart w:id=\"";
oBuilder += sContentsId;
oBuilder += L"\" w:name=\"_Toc";
oBuilder += sContentsId;
oBuilder += L"\"/>";
}
readP(L"", oBuilder);
// Пишем ссылку от оглавления
if(sLevel == L"title1")
{
oBuilder += L"<w:bookmarkEnd w:id=\"";
oBuilder += sContentsId;
oBuilder += L"\"/>";
}
oBuilder += L"</w:p>";
}
oBuilder += L"</w:p>";
}
}
@ -337,6 +338,8 @@ public:
// имеет право писать p
void readEpigraph(NSStringUtils::CStringBuilder& oBuilder)
{
readCrossReference(oBuilder);
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode(nDeath))
{
@ -352,7 +355,7 @@ public:
else if(sName == L"cite")
readCite(oBuilder);
else if(sName == L"empty-line")
oBuilder += L"<w:p></w:p>";
oBuilder += L"<w:p><w:pPr><w:pStyle w:val=\"epigraph-p\"/></w:pPr></w:p>";
else if(sName == L"text-author")
{
oBuilder += L"<w:p><w:pPr><w:pStyle w:val=\"epigraph-p\"/></w:pPr>";
@ -367,6 +370,8 @@ public:
// sRStyle - накопленный стиль
void readP(std::wstring sRStyle, NSStringUtils::CStringBuilder& oBuilder)
{
readCrossReference(oBuilder);
int nDepth = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode2(nDepth))
{
@ -410,22 +415,29 @@ public:
}
}
m_oLightReader.MoveToElement();
// Пробел перед текстом внутри ссылки
oBuilder += L"<w:r><w:t xml:space=\"preserve\"> </w:t></w:r>";
// Читаем текст внутри ссылки
readP(sRStyle, oBuilder);
if(sFootnoteName == L"")
continue;
std::map<std::wstring, std::wstring>::iterator it = m_mFootnotes.find(sFootnoteName);
if(it != m_mFootnotes.end())
{
oBuilder += L"<w:r>";
// Стиль ссылки
oBuilder += L"<w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteReference w:id=\"";
// Пробел перед текстом внутри сноски
oBuilder += L"<w:r><w:t xml:space=\"preserve\"> </w:t></w:r>";
// Читаем текст внутри сноски
readP(sRStyle, oBuilder);
// Стиль сноски
oBuilder += L"<w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteReference w:id=\"";
oBuilder += it->second;
oBuilder += L"\"/></w:r>";
}
// Перекрестная ссылка
else
{
oBuilder += L"<w:hyperlink w:tooltip=\"Current Document\" w:anchor=\"";
oBuilder += sFootnoteName;
oBuilder += L"\">";
// Читаем текст внутри ссылки
readP(sRStyle + L"<w:rStyle w:val=\"cross\"/>", oBuilder);
oBuilder += L"</w:hyperlink>";
}
}
// Читаем вычеркнутый текст
else if(sName == L"strikethrough")
@ -449,6 +461,8 @@ public:
// имеет право писать p
void readPoem(NSStringUtils::CStringBuilder& oBuilder)
{
readCrossReference(oBuilder);
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode(nDeath))
{
@ -500,6 +514,8 @@ public:
// имеет право писать p
void readCite(NSStringUtils::CStringBuilder& oBuilder)
{
readCrossReference(oBuilder);
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode(nDeath))
{
@ -511,7 +527,7 @@ public:
oBuilder += L"</w:p>";
}
else if(sName == L"empty-line")
oBuilder += L"<w:p></w:p>";
oBuilder += L"<w:p><w:pPr><w:pStyle w:val=\"cite-p\"/></w:pPr></w:p>";
else if(sName == L"poem")
readPoem(oBuilder);
else if(sName == L"table")
@ -528,6 +544,8 @@ public:
// Читает table
void readTable(NSStringUtils::CStringBuilder& oBuilder)
{
readCrossReference(oBuilder);
// Стиль таблицы
oBuilder += L"<w:tbl><w:tblPr><w:tblStyle w:val=\"table-t\"/><w:tblW w:w=\"0\" w:type=\"auto\"/><w:tblLayout w:type=\"fixed\"/></w:tblPr>";
@ -589,6 +607,8 @@ public:
// имеет право писать p
void readAnnotation(NSStringUtils::CStringBuilder& oBuilder)
{
readCrossReference(oBuilder);
int nADeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode(nADeath))
{
@ -604,16 +624,40 @@ public:
else if(sAnName == L"cite")
readCite(oBuilder);
else if(sAnName == L"empty-line")
oBuilder += L"<w:p></w:p>";
oBuilder += L"<w:p><w:pPr><w:pStyle w:val=\"annotation\"/></w:pPr></w:p>";
else if(sAnName == L"table")
readTable(oBuilder);
}
}
// Читает перекрестные ссылки
void readCrossReference(NSStringUtils::CStringBuilder& oBuilder)
{
// id для перекрестных ссылок
while(m_oLightReader.MoveToNextAttribute())
{
if(m_oLightReader.GetName() == L"id")
{
std::wstring sCrossId = std::to_wstring(m_nCrossReferenceId++);
oBuilder += L"<w:bookmarkStart w:id=\"";
oBuilder += sCrossId;
oBuilder += L"\" w:name=\"";
oBuilder += m_oLightReader.GetText();
oBuilder += L"\"/><w:bookmarkEnd w:id=\"";
oBuilder += sCrossId;
oBuilder += L"\"/>";
break;
}
}
m_oLightReader.MoveToElement();
}
// Читает section
// имеет право писать p
void readSection(unsigned int nLevel, NSStringUtils::CStringBuilder& oBuilder)
{
readCrossReference(oBuilder);
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode(nDeath))
{
@ -662,7 +706,7 @@ public:
else if(sName == L"cite")
readCite(oBuilder);
else if(sName == L"empty-line")
oBuilder += L"<w:p></w:p>";
oBuilder += L"<w:p><w:pPr><w:pStyle w:val=\"section-p\"/></w:pPr></w:p>";
else if(sName == L"table")
readTable(oBuilder);
}
@ -1267,10 +1311,6 @@ void CFb2File::SetTmpDirectory(const std::wstring& sFolder)
// sPath - путь к файлу fb2, sDirectory - директория, где формируется и создается docx
HRESULT CFb2File::Open(const std::wstring& sPath, const std::wstring& sDirectory, CFb2Params* oParams)
{
// Чистим папку назначения
NSDirectory::DeleteDirectory(sDirectory);
NSDirectory::CreateDirectory(sDirectory);
// Копирование шаблона
if(!ExtractTemplate(sDirectory))
return S_FALSE;