#include "htmlprint.h"
#include
#include
using namespace example_novel;
using namespace printer;
Access::Access(std::shared_ptr handle)
:access_handle(handle) {}
std::shared_ptr 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 handle) :Access(handle) {}
void printer::Element::setSliceRefer(const QString& href) {
this->refer_store = href;
}
QString printer::Element::sliceRefers() const {
return refer_store;
}
Group::Group(std::shared_ptr handle) : Access(handle) {}
void Group::append(std::shared_ptr elm)
{
element_store.append(elm);
}
QList> Group::elements() const
{
return this->element_store;
}
std::shared_ptr 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 handle) :Group(handle) {}
void StoryLine::buildPageHTML(QDomElement& parent) const {
auto syntax_access = this->accessPeers();
auto storyline_inst = std::dynamic_pointer_cast(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(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->buildSliceHTML(dom_storyline);
}break;
default:
break;
}
}
}
StoryVolume::StoryVolume(std::shared_ptr handle) : Group(handle) {}
void StoryVolume::buildPageHTML(QDomElement& parent) const {
auto syntax_access = this->accessPeers();
auto volume_inst = std::dynamic_pointer_cast(syntax_access->element());
auto doc_inst = parent.ownerDocument();
auto dom_volume = doc_inst.createElement("div");
parent.appendChild(dom_volume);
auto dom_title = doc_inst.createElement("h1");
dom_title.appendChild(doc_inst.createTextNode(volume_inst->name()));
dom_volume.appendChild(dom_title);
std::function>&)> rich_refer_build =
[&](QDomElement& parent_element, const QList> children) {
for (auto& child : children) {
auto doc_ins = parent_element.ownerDocument();
switch ((NovelNode)child->element()->typeMark())
{
case NovelNode::TextSection: {
auto text_inst = std::dynamic_pointer_cast(child->element());
auto dom_p = doc_ins.createElement("p");
dom_p.appendChild(doc_ins.createTextNode(text_inst->content()));
parent_element.appendChild(dom_p);
}break;
case NovelNode::ArticleDefine: {
auto article_inst = std::dynamic_pointer_cast(child->element());
auto article_group = doc_ins.createElement("div");
auto article_head = doc_ins.createElement("h2");
article_head.appendChild(doc_ins.createTextNode(article_inst->name() + u8"{"));
article_group.appendChild(article_head);
rich_refer_build(article_group, child->children());
article_group.appendChild(doc_ins.createTextNode(u8"}"));
parent_element.appendChild(article_group);
}break;
case NovelNode::FragmentRefer:{
auto fragment_inst = std::dynamic_pointer_cast(child->element());
auto refer_inst = this->getElement(fragment_inst->signature());
refer_inst->buildSliceHTML(parent_element);
}break;
default:
break;
}
}
};
rich_refer_build(dom_volume, syntax_access->children());
}
FragmentRef::FragmentRef(std::shared_ptr handle) : Element(handle) {}
void printer::FragmentRef::setHost(std::shared_ptr frag_inst)
{
this->host_inst = frag_inst;
}
std::shared_ptr printer::FragmentRef::hostFragment() const
{
return this->host_inst.lock();
}
void FragmentRef::buildSliceHTML(QDomElement& dom_parent) const {
auto syntax_access = this->accessPeers();
auto refer_element = std::dynamic_pointer_cast(syntax_access->element());
auto jump_to_host = this->hostFragment()->pageRefers();
auto doc = dom_parent.ownerDocument();
auto dom_reference = doc.createElement(u8"div");
dom_reference.setAttribute("id", QString::number((qulonglong)refer_element.get()));
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", u8"file:///"+jump_to_host);
dom_title.appendChild(dom_href);
std::function>&)> rich_refer_build =
[&](QDomElement& parent_element, const QList> children) {
for (auto& child : children) {
auto doc_ins = parent_element.ownerDocument();
switch ((NovelNode)child->element()->typeMark())
{
case NovelNode::TextSection: {
auto text_inst = std::dynamic_pointer_cast(child->element());
auto dom_p = doc_ins.createElement("p");
dom_p.appendChild(doc_ins.createTextNode(text_inst->content()));
parent_element.appendChild(dom_p);
}break;
case NovelNode::ArticleDefine: {
auto article_inst = std::dynamic_pointer_cast(child->element());
auto article_group = doc_ins.createElement("div");
auto article_head = doc_ins.createElement("h2");
article_head.appendChild(doc_ins.createTextNode(article_inst->name() + u8"{"));
article_group.appendChild(article_head);
rich_refer_build(article_group, child->children());
article_group.appendChild(doc_ins.createTextNode(u8"}"));
parent_element.appendChild(article_group);
}break;
default:
break;
}
}
};
rich_refer_build(dom_reference, syntax_access->children());
}
void FragmentRef::buildPageHTML(QDomElement& parent) const {
auto syntax_access = this->accessPeers();
auto refer_element = std::dynamic_pointer_cast(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", u8"file:///"+this->sliceRefers());
title_block.appendChild(title_refer);
std::function>)> build_cascade =
[&](QList> children_items) {
for (auto child : children_items) {
if (child->element()->typeMark() == (int)NovelNode::TextSection) {
auto text_inst = std::dynamic_pointer_cast(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());
}
Fragment::Fragment(std::shared_ptr handle) : Element(handle) {}
void Fragment::appendRefers(std::shared_ptr inst) {
this->additionals_store.append(inst);
inst->setHost(std::static_pointer_cast(this->shared_from_this()));
}
QList> Fragment::additionals() const {
return this->additionals_store;
}
void Fragment::buildSliceHTML(QDomElement& parent) const {
auto syntax_access = this->accessPeers();
auto fragment_inst = std::dynamic_pointer_cast(syntax_access->element());
auto doc = parent.ownerDocument();
auto dom_fragment = doc.createElement("div");
dom_fragment.setAttribute("id", QString::number((qulonglong)fragment_inst.get()));
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", u8"file:///"+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(inst_c->element());
auto dom_p = doc.createElement("p");
dom_p.appendChild(doc.createTextNode(text_inst->content()));
dom_fragment.appendChild(dom_p);
}
}
}
void Fragment::buildPageHTML(QDomElement& parent) const {
auto syntax_access = this->accessPeers();
auto fragment_inst = std::dynamic_pointer_cast(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", u8"file:///" + this->sliceRefers());
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(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->buildPageHTML(dom_fragment);
}
}
#include
void tools_printer::build_fragments(std::shared_ptr novel_root)
{
if (novel_root->element()->typeMark() == (int)NovelNode::FragmentDefine) {
auto inst = std::make_shared(novel_root);
auto name = novel_root->element()->signature();
this->fragment_defines[name] = inst;
}
for (auto& inst_c : novel_root->children()) {
build_fragments(inst_c);
}
}
void tools_printer::build_refers_network(std::shared_ptr novel_node)
{
switch ((NovelNode)novel_node->element()->typeMark()) {
case NovelNode::StoryDefine: {
auto storyinst = std::make_shared(novel_node);
this->storyline_defines[novel_node->element()->signature()] = storyinst;
build_storyline(storyinst);
}return;
case NovelNode::VolumeDefine: {
auto volumeinst = std::make_shared(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 line, std::shared_ptr 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(novel_node->element());
auto refer_fragment = this->fragment_defines[refer_node->referSignature()];
auto inst = std::make_shared(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 volume, std::shared_ptr 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(novel_node->element());
auto refer_fragment = this->fragment_defines[refer_node->referSignature()];
auto inst = std::make_shared(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>& 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>&, const QString&)> refers_refresh =
[&](const QList>& items, const QString& summary_href) {
for (auto& item : items) {
auto element_addr = QString::number((qulonglong)item->accessPeers()->element().get());
item->setSliceRefer(summary_href + u8"#" + element_addr);
}
};
void tools_printer::storylines_anchors_define(const QList>& 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>& 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);
}
}
auto get_node_name = [](const std::shared_ptr item){
return u8"node_" + QString::number((qulonglong)item->accessPeers()->element().get());
};
QString printer::tools_printer::storylines_paint(const QList> &lines) {
QHash> node_records;
QString nodes_description;
for (auto& story : lines) {
auto story_elem = std::dynamic_pointer_cast(story->accessPeers()->element());
node_records[story_elem->signature()] = story;
nodes_description += get_node_name(story) + QString(u8"[label=\"%1\",shape=\"cds\"]\n").arg(story_elem->name());
for (auto &frag : story->elements()) {
auto fragment_peers = frag->accessPeers()->element();
if (fragment_peers->typeMark() == (int)example_novel::NovelNode::FragmentDefine) {
auto fragment_elem = std::dynamic_pointer_cast(fragment_peers);
auto node_name = fragment_elem->signature();
node_records[node_name] = frag;
nodes_description += get_node_name(frag) + QString(u8"[label=\"%1\",shape=\"rect\"]\n").arg(fragment_elem->name());
}
}
}
QString arrows_link;
for (auto &story : lines) {
auto story_elem = std::dynamic_pointer_cast(story->accessPeers()->element());
QString previous_node = get_node_name(story);
for (auto &frag : story->elements()) {
if (example_novel::NovelNode::FragmentDefine == (example_novel::NovelNode) frag->accessPeers()->element()->typeMark()) {
arrows_link += previous_node + u8"->" + get_node_name(frag) + QString(u8"[label=\"%1\"]\n").arg(story_elem->name());
previous_node = get_node_name(frag);
}
else if (example_novel::NovelNode::FragmentRefer == (example_novel::NovelNode)frag->accessPeers()->element()->typeMark()) {
auto frag_refer = std::dynamic_pointer_cast(frag->accessPeers()->element());
auto frag_src = node_records[frag_refer->referSignature()];
arrows_link += previous_node + u8"->" + get_node_name(frag_src) + QString(u8"[label=\"%1\"]\n").arg(story_elem->name());
previous_node = get_node_name(frag_src);
}
}
}
return QString(u8"digraph{ rankdir = LR \n %1\n %2 }").arg(nodes_description).arg(arrows_link);
}
QString printer::tools_printer::volumes_paint(const QList>& vols, const QList>& lines) {
QHash> node_records;
QString clusters_description;
for (auto& story : lines) {
QString nodes_description;
for (auto &frag : story->elements()) {
auto fragment_peers = frag->accessPeers()->element();
if (fragment_peers->typeMark() == (int)example_novel::NovelNode::FragmentDefine) {
auto fragment_elem = std::dynamic_pointer_cast(fragment_peers);
node_records[fragment_elem->signature()] = frag;
nodes_description += get_node_name(frag) + QString(u8"[label=\"%1\",shape=\"ellipse\"]\n").arg(fragment_elem->name());
}
}
auto story_elem = std::dynamic_pointer_cast(story->accessPeers()->element());
clusters_description += QString(u8"subgraph cluster_%1 { label=%3 \n %2 }")
.arg((qulonglong)story_elem.get()).arg(nodes_description).arg(story_elem->name());
}
auto article_cluster = [&node_records](
const std::shared_ptr article_access, QList &arrows_out)->QString {
QString nodes_description;
for (auto& fragment_access : article_access->children()) {
if (fragment_access->element()->typeMark() == (int)example_novel::NovelNode::FragmentRefer) {
auto refer_fragment = std::dynamic_pointer_cast(fragment_access->element());
nodes_description += QString(u8"fragment_%1[label=\"%2\",shape=\"plaintext\"]\n")
.arg((qulonglong)refer_fragment.get()).arg(refer_fragment->fragmentRefer());
auto symbo_refer = node_records[refer_fragment->referSignature()];
arrows_out << QString(u8"fragment_%1 -- %2[color=\"red\"]\n").arg((qulonglong)refer_fragment.get()).arg(get_node_name(symbo_refer));
}
}
auto article_define = std::dynamic_pointer_cast(article_access->element());
return QString(u8"subgraph cluster_%1{ label=%2 \n %3 }\n").arg((qulonglong)article_access->element().get())
.arg(article_define->name()).arg(nodes_description);
};
QString arrows_link;
for (auto &vol : vols) {
QString members_description;
for (auto& eref : vol->accessPeers()->children()) {
QList arrows_temp;
switch ((example_novel::NovelNode)eref->element()->typeMark()){
case example_novel::NovelNode::ArticleDefine:
members_description += article_cluster(eref, arrows_temp);
break;
default:
break;
}
for (auto& arrow : arrows_temp) {
arrows_link += arrow;
}
}
auto volume_elem = std::dynamic_pointer_cast(vol->accessPeers()->element());
clusters_description += QString(u8"subgraph cluster_%1 { label=%3 \n %2 }")
.arg((qulonglong)volume_elem.get()).arg(members_description).arg(volume_elem->name());
}
return QString("graph scale{ %1 \n %2}").arg(clusters_description).arg(arrows_link);
}