366 lines
12 KiB
C++
366 lines
12 KiB
C++
#include "htmlprint.h"
|
|
#include <QDir>
|
|
#include <QDomElement>
|
|
|
|
using namespace example_novel;
|
|
using namespace printer;
|
|
|
|
Access::Access(std::shared_ptr<const ast_gen::ElementAccess> handle)
|
|
:access_handle(handle) {}
|
|
|
|
std::shared_ptr<const ast_gen::ElementAccess> Access::accessPeers() const { return access_handle; }
|
|
|
|
void Access::setPageRefers(const QString& href) { this->summary_refer_store = href; }
|
|
|
|
QString Access::pageRefers() const { return this->summary_refer_store; }
|
|
|
|
Element::Element(std::shared_ptr<const ast_gen::ElementAccess> handle) :Access(handle) {}
|
|
|
|
void printer::Element::setPieceRefer(const QString& href) {
|
|
this->refer_store = href;
|
|
}
|
|
|
|
QString printer::Element::pieceRefers() const {
|
|
return refer_store;
|
|
}
|
|
|
|
Group::Group(std::shared_ptr<const ast_gen::ElementAccess> handle) : Access(handle) {}
|
|
|
|
void Group::append(std::shared_ptr<Element> elm)
|
|
{
|
|
element_store.append(elm);
|
|
}
|
|
|
|
QList<std::shared_ptr<Element>> Group::elements() const
|
|
{
|
|
return this->element_store;
|
|
}
|
|
|
|
std::shared_ptr<Element> printer::Group::getElement(const QString& signature) const
|
|
{
|
|
for (auto& it : elements()) {
|
|
if (it->accessPeers()->element()->signature() == signature)
|
|
return it;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
StoryLine::StoryLine(std::shared_ptr<const ast_gen::ElementAccess> handle) :Group(handle) {}
|
|
|
|
QString StoryLine::getPageHTML(QDomElement& parent) const {
|
|
auto syntax_access = this->accessPeers();
|
|
auto storyline_inst = std::dynamic_pointer_cast<const StoryDefine>(syntax_access->element());
|
|
|
|
auto doc = parent.ownerDocument();
|
|
auto dom_storyline = doc.createElement("div");
|
|
parent.appendChild(dom_storyline);
|
|
|
|
auto dom_title = doc.createElement("h1");
|
|
dom_title.appendChild(doc.createTextNode(storyline_inst->name()));
|
|
dom_storyline.appendChild(dom_title);
|
|
|
|
for (auto& inst_c : syntax_access->children()) {
|
|
switch ((NovelNode)inst_c->element()->typeMark()) {
|
|
case NovelNode::TextSection: {
|
|
auto text_inst = std::dynamic_pointer_cast<const TextSection>(inst_c->element());
|
|
auto dom_p = doc.createElement("p");
|
|
dom_p.appendChild(doc.createTextNode(text_inst->content()));
|
|
dom_storyline.appendChild(dom_p);
|
|
}break;
|
|
case NovelNode::FragmentRefer:
|
|
case NovelNode::FragmentDefine: {
|
|
auto element_inst = this->getElement(inst_c->element()->signature());
|
|
element_inst->getPieceHTML(dom_storyline);
|
|
}break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
StoryVolume::StoryVolume(std::shared_ptr<const ast_gen::ElementAccess> handle) : Group(handle) {}
|
|
|
|
QString StoryVolume::getPageHTML(QDomElement& doc) const
|
|
{
|
|
return QString();
|
|
}
|
|
|
|
FragmentRef::FragmentRef(std::shared_ptr<const ast_gen::ElementAccess> handle) : Element(handle) {}
|
|
|
|
void printer::FragmentRef::setHost(std::shared_ptr<Fragment> frag_inst)
|
|
{
|
|
this->host_inst = frag_inst;
|
|
}
|
|
|
|
std::shared_ptr<Fragment> printer::FragmentRef::hostFragment() const
|
|
{
|
|
return this->host_inst.lock();
|
|
}
|
|
|
|
QString FragmentRef::getPieceHTML(QDomElement& dom_parent) const {
|
|
auto syntax_element = this->accessPeers()->element();
|
|
auto refer_element = std::dynamic_pointer_cast<const FragmentRefers>(syntax_element);
|
|
|
|
auto jump_to_host = this->hostFragment()->pageRefers();
|
|
auto doc = dom_parent.ownerDocument();
|
|
|
|
auto dom_reference = doc.createElement(u8"div");
|
|
dom_parent.appendChild(dom_reference);
|
|
|
|
auto dom_title = doc.createElement(u8"h2");
|
|
dom_reference.appendChild(dom_title);
|
|
|
|
auto dom_href = doc.createElement(u8"a");
|
|
dom_href.appendChild(doc.createTextNode(refer_element->referSignature()));
|
|
dom_href.setAttribute("href", jump_to_host);
|
|
dom_title.appendChild(dom_href);
|
|
|
|
for (auto child : this->accessPeers()->children()) {
|
|
if (child->element()->typeMark() == (int)NovelNode::TextSection) {
|
|
auto text_inst = std::dynamic_pointer_cast<const TextSection>(child->element());
|
|
auto dom_p = doc.createElement("p");
|
|
dom_p.appendChild(doc.createTextNode(text_inst->content()));
|
|
dom_reference.appendChild(dom_p);
|
|
}
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
QString FragmentRef::getPageHTML(QDomElement& parent) const {
|
|
auto syntax_access = this->accessPeers();
|
|
auto refer_element = std::dynamic_pointer_cast<const FragmentRefers>(syntax_access->element());
|
|
|
|
auto doc = parent.ownerDocument();
|
|
|
|
auto refers_dom = doc.createElement(u8"div");
|
|
parent.appendChild(refers_dom);
|
|
|
|
auto title_block = doc.createElement(u8"h2");
|
|
refers_dom.appendChild(title_block);
|
|
auto title_refer = doc.createElement(u8"a");
|
|
title_refer.appendChild(doc.createTextNode(refer_element->signature()));
|
|
title_refer.setAttribute("href", this->pieceRefers());
|
|
title_block.appendChild(title_refer);
|
|
|
|
std::function<void(QList<std::shared_ptr<const ast_gen::ElementAccess>>)> build_cascade =
|
|
[&](QList<std::shared_ptr<const ast_gen::ElementAccess>> children_items) {
|
|
for (auto child : children_items) {
|
|
if (child->element()->typeMark() == (int)NovelNode::TextSection) {
|
|
auto text_inst = std::dynamic_pointer_cast<const TextSection>(child->element());
|
|
auto p = doc.createElement("p");
|
|
p.appendChild(doc.createTextNode(text_inst->content()));
|
|
refers_dom.appendChild(p);
|
|
}
|
|
else {
|
|
build_cascade(child->children());
|
|
}
|
|
}
|
|
};
|
|
|
|
build_cascade(syntax_access->children());
|
|
return QString();
|
|
}
|
|
|
|
Fragment::Fragment(std::shared_ptr<const ast_gen::ElementAccess> handle) : Element(handle) {}
|
|
|
|
void Fragment::appendRefers(std::shared_ptr<FragmentRef> inst) {
|
|
this->additionals_store.append(inst);
|
|
inst->setHost(std::static_pointer_cast<Fragment>(this->shared_from_this()));
|
|
}
|
|
|
|
QList<std::shared_ptr<FragmentRef>> Fragment::additionals() const {
|
|
return this->additionals_store;
|
|
}
|
|
|
|
QString Fragment::getPieceHTML(QDomElement& parent) const {
|
|
auto syntax_access = this->accessPeers();
|
|
auto fragment_inst = std::dynamic_pointer_cast<const FragmentDefine>(syntax_access->element());
|
|
|
|
auto doc = parent.ownerDocument();
|
|
auto dom_fragment = doc.createElement("div");
|
|
parent.appendChild(dom_fragment);
|
|
|
|
auto dom_title = doc.createElement("h2");
|
|
dom_fragment.appendChild(dom_title);
|
|
|
|
auto dom_href = doc.createElement("a");
|
|
dom_href.appendChild(doc.createTextNode(fragment_inst->name()));
|
|
dom_href.setAttribute("href", this->pageRefers());
|
|
dom_title.appendChild(dom_href);
|
|
|
|
for (auto& inst_c : syntax_access->children()) {
|
|
if (NovelNode::TextSection == (NovelNode)inst_c->element()->typeMark()) {
|
|
auto text_inst = std::dynamic_pointer_cast<const TextSection>(inst_c->element());
|
|
auto dom_p = doc.createElement("p");
|
|
dom_p.appendChild(doc.createTextNode(text_inst->content()));
|
|
dom_fragment.appendChild(dom_p);
|
|
}
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
QString Fragment::getPageHTML(QDomElement& parent) const {
|
|
auto syntax_access = this->accessPeers();
|
|
auto fragment_inst = std::dynamic_pointer_cast<const FragmentDefine>(syntax_access->element());
|
|
|
|
auto doc = parent.ownerDocument();
|
|
auto dom_fragment = doc.createElement("div");
|
|
parent.appendChild(dom_fragment);
|
|
|
|
auto dom_title = doc.createElement("h1");
|
|
dom_fragment.appendChild(dom_title);
|
|
|
|
auto dom_href = doc.createElement("a");
|
|
dom_href.appendChild(doc.createTextNode(fragment_inst->signature()));
|
|
dom_href.setAttribute("href", this->pageRefers());
|
|
dom_title.appendChild(dom_href);
|
|
|
|
for (auto& inst_c : syntax_access->children()) {
|
|
if (NovelNode::TextSection == (NovelNode)inst_c->element()->typeMark()) {
|
|
auto text_inst = std::dynamic_pointer_cast<const TextSection>(inst_c->element());
|
|
auto dom_p = doc.createElement("p");
|
|
dom_p.appendChild(doc.createTextNode(text_inst->content()));
|
|
dom_fragment.appendChild(dom_p);
|
|
}
|
|
}
|
|
|
|
for (auto& it : this->additionals()) {
|
|
it->getPageHTML(dom_fragment);
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
#include <ast_novel.h>
|
|
void tools_printer::build_fragments(std::shared_ptr<const ast_gen::ElementAccess> novel_root)
|
|
{
|
|
if (novel_root->element()->typeMark() == (int)NovelNode::FragmentDefine) {
|
|
auto inst = std::make_shared<Fragment>(novel_root);
|
|
this->fragment_defines[novel_root->element()->signature()] = inst;
|
|
}
|
|
|
|
for (auto& inst_c : novel_root->children()) {
|
|
build_fragments(inst_c);
|
|
}
|
|
}
|
|
|
|
void tools_printer::build_refers_network(std::shared_ptr<const ast_gen::ElementAccess> novel_node)
|
|
{
|
|
switch ((NovelNode)novel_node->element()->typeMark()) {
|
|
case NovelNode::StoryDefine: {
|
|
auto storyinst = std::make_shared<StoryLine>(novel_node);
|
|
this->storyline_defines[novel_node->element()->signature()] = storyinst;
|
|
build_storyline(storyinst);
|
|
}return;
|
|
case NovelNode::VolumeDefine: {
|
|
auto volumeinst = std::make_shared<StoryVolume>(novel_node);
|
|
this->volume_defines[novel_node->element()->signature()] = volumeinst;
|
|
build_volumeline(volumeinst);
|
|
}return;
|
|
}
|
|
|
|
for (auto& inst_c : novel_node->children())
|
|
build_refers_network(inst_c);
|
|
}
|
|
|
|
void tools_printer::build_storyline(std::shared_ptr<StoryLine> line, std::shared_ptr<const ast_gen::ElementAccess> novel_node)
|
|
{
|
|
if (!novel_node) {
|
|
for (auto& inst_c : line->accessPeers()->children()) {
|
|
build_storyline(line, inst_c);
|
|
}
|
|
}
|
|
else {
|
|
switch ((NovelNode)novel_node->element()->typeMark())
|
|
{
|
|
case NovelNode::FragmentDefine: {
|
|
auto inst = this->fragment_defines[novel_node->element()->signature()];
|
|
line->append(inst);
|
|
}return;
|
|
case NovelNode::FragmentRefer: {
|
|
auto refer_node = std::dynamic_pointer_cast<const FragmentRefers>(novel_node->element());
|
|
auto refer_fragment = this->fragment_defines[refer_node->referSignature()];
|
|
auto inst = std::make_shared<FragmentRef>(novel_node);
|
|
refer_fragment->appendRefers(inst);
|
|
line->append(inst);
|
|
}return;
|
|
}
|
|
|
|
for (auto& inst_c : novel_node->children())
|
|
build_storyline(line, inst_c);
|
|
}
|
|
}
|
|
|
|
void tools_printer::build_volumeline(std::shared_ptr<StoryVolume> volume, std::shared_ptr<const ast_gen::ElementAccess> novel_node)
|
|
{
|
|
if (!novel_node) {
|
|
for (auto& inst_c : volume->accessPeers()->children())
|
|
build_volumeline(volume, inst_c);
|
|
}
|
|
else {
|
|
if (NovelNode::FragmentRefer == (NovelNode)novel_node->element()->typeMark()) {
|
|
auto refer_node = std::dynamic_pointer_cast<const FragmentRefers>(novel_node->element());
|
|
auto refer_fragment = this->fragment_defines[refer_node->referSignature()];
|
|
auto inst = std::make_shared<FragmentRef>(novel_node);
|
|
refer_fragment->appendRefers(inst);
|
|
volume->append(inst);
|
|
return;
|
|
}
|
|
|
|
for (auto& inst_c : novel_node->children())
|
|
build_volumeline(volume, inst_c);
|
|
}
|
|
}
|
|
|
|
void tools_printer::fragments_anchors_define(const QList<std::shared_ptr<Fragment>>& list, const QDir& root_dir) {
|
|
auto path = root_dir.filePath("fragments");
|
|
if (!QDir(path).exists())
|
|
root_dir.mkdir("fragments");
|
|
QDir target_dir(path);
|
|
|
|
for (auto& it : list) {
|
|
auto address_x = QString::number((qulonglong)it->accessPeers()->element().get());
|
|
it->setPageRefers(target_dir.absoluteFilePath(QString("%1.html").arg(address_x)));
|
|
}
|
|
}
|
|
|
|
std::function<void(const QList<std::shared_ptr<Element>>&, const QString&)> refers_refresh =
|
|
[&](const QList<std::shared_ptr<Element>>& items, const QString& summary_href) {
|
|
for (auto& item : items) {
|
|
auto element_addr = QString::number((qulonglong)item->accessPeers()->element().get());
|
|
item->setPieceRefer(summary_href + u8"#" + element_addr);
|
|
}
|
|
};
|
|
|
|
void tools_printer::storylines_anchors_define(const QList<std::shared_ptr<StoryLine>>& list, const QDir& root_dir) {
|
|
auto path = root_dir.filePath("storylines");
|
|
if (!QDir(path).exists())
|
|
root_dir.mkdir("storylines");
|
|
QDir target_dir(path);
|
|
|
|
for (auto& it : list) {
|
|
auto address_x = QString::number((qulonglong)it->accessPeers()->element().get());
|
|
auto page_address = target_dir.absoluteFilePath(QString("%1.html").arg(address_x));
|
|
it->setPageRefers(page_address);
|
|
refers_refresh(it->elements(), page_address);
|
|
}
|
|
}
|
|
|
|
void tools_printer::volumes_anchors_define(const QList<std::shared_ptr<StoryVolume>>& list, const QDir& root_dir) {
|
|
auto path = root_dir.filePath("volumes");
|
|
if (!QDir(path).exists())
|
|
root_dir.mkdir("volumes");
|
|
QDir target_dir(path);
|
|
|
|
for (auto& it : list) {
|
|
auto address_x = QString::number((qulonglong)it->accessPeers()->element().get());
|
|
auto page_address = target_dir.absoluteFilePath(QString("%1.html").arg(address_x));
|
|
it->setPageRefers(page_address);
|
|
refers_refresh(it->elements(), page_address);
|
|
}
|
|
}
|