diff --git a/WsNovelParser/WsNovelParser.vcxproj.user b/WsNovelParser/WsNovelParser.vcxproj.user
index 79d638e..737f5df 100644
--- a/WsNovelParser/WsNovelParser.vcxproj.user
+++ b/WsNovelParser/WsNovelParser.vcxproj.user
@@ -5,9 +5,9 @@
WindowsLocalDebugger
- 2024-03-31T05:42:51.9907375Z
+ 2024-03-31T14:11:49.6878635Z
- 2024-03-31T05:42:52.0532400Z
+ 2024-03-31T14:11:50.2019950Z
\ No newline at end of file
diff --git a/WsNovelParser/htmlprint.cpp b/WsNovelParser/htmlprint.cpp
index 18dae35..cc33dbd 100644
--- a/WsNovelParser/htmlprint.cpp
+++ b/WsNovelParser/htmlprint.cpp
@@ -1,19 +1,29 @@
#include "htmlprint.h"
#include
+#include
using namespace example_novel;
using namespace printer;
-Access::Access(std::shared_ptr handle) :access_handle(handle) {}
+Access::Access(std::shared_ptr handle)
+ :access_handle(handle) {}
std::shared_ptr Access::accessPeers() const { return access_handle; }
-void Access::setHtmlRefer(const QString& href) { this->refers_store = href; }
+void Access::setPageRefers(const QString& href) { this->summary_refer_store = href; }
-QString Access::htmlRefer() const { return this->refers_store; }
+QString Access::pageRefers() const { return this->summary_refer_store; }
Element::Element(std::shared_ptr 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 handle) : Access(handle) {}
void Group::append(std::shared_ptr elm)
@@ -26,29 +36,131 @@ 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) {}
-QString StoryLine::toHTML() const
-{
+QString StoryLine::getPageHTML(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->getPieceHTML(dom_storyline);
+ }break;
+ default:
+ break;
+ }
+ }
+
return QString();
}
StoryVolume::StoryVolume(std::shared_ptr handle) : Group(handle) {}
-QString StoryVolume::toHTML() const
+QString StoryVolume::getPageHTML(QDomElement& doc) const
{
return QString();
}
FragmentRef::FragmentRef(std::shared_ptr handle) : Element(handle) {}
-QString FragmentRef::toOutsideHTML() const
+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();
+}
+
+QString FragmentRef::getPieceHTML(QDomElement& dom_parent) const {
+ auto syntax_element = this->accessPeers()->element();
+ auto refer_element = std::dynamic_pointer_cast(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(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::toDefinitionHTML() const
-{
+QString FragmentRef::getPageHTML(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", this->pieceRefers());
+ 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());
return QString();
}
@@ -56,26 +168,77 @@ Fragment::Fragment(std::shared_ptr handle) : Eleme
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;
}
-QString Fragment::toOutsideHTML() const
-{
+QString Fragment::getPieceHTML(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("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(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::toDefinitionHTML() const
-{
+QString Fragment::getPageHTML(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", 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);
+ }
+ }
+
+ for (auto& it : this->additionals()) {
+ it->getPageHTML(dom_fragment);
+ }
+
return QString();
}
#include
void tools_printer::build_fragments(std::shared_ptr novel_root)
{
- if (novel_root->element()->typeMark() == (int)example_novel::NovelNode::FragmentDefine) {
+ if (novel_root->element()->typeMark() == (int)NovelNode::FragmentDefine) {
auto inst = std::make_shared(novel_root);
this->fragment_defines[novel_root->element()->signature()] = inst;
}
@@ -87,13 +250,13 @@ void tools_printer::build_fragments(std::shared_ptr novel_node)
{
- switch ((example_novel::NovelNode)novel_node->element()->typeMark()) {
- case example_novel::NovelNode::StoryDefine: {
+ 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 example_novel::NovelNode::VolumeDefine: {
+ case NovelNode::VolumeDefine: {
auto volumeinst = std::make_shared(novel_node);
this->volume_defines[novel_node->element()->signature()] = volumeinst;
build_volumeline(volumeinst);
@@ -112,14 +275,14 @@ void tools_printer::build_storyline(std::shared_ptr line, std::shared
}
}
else {
- switch ((example_novel::NovelNode)novel_node->element()->typeMark())
+ switch ((NovelNode)novel_node->element()->typeMark())
{
- case example_novel::NovelNode::FragmentDefine: {
+ case NovelNode::FragmentDefine: {
auto inst = this->fragment_defines[novel_node->element()->signature()];
line->append(inst);
}return;
- case example_novel::NovelNode::FragmentRefer: {
- auto refer_node = std::dynamic_pointer_cast(novel_node->element());
+ 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);
@@ -139,8 +302,8 @@ void tools_printer::build_volumeline(std::shared_ptr volume, std::s
build_volumeline(volume, inst_c);
}
else {
- if (example_novel::NovelNode::FragmentRefer == (example_novel::NovelNode)novel_node->element()->typeMark()) {
- auto refer_node = std::dynamic_pointer_cast(novel_node->element());
+ 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);
@@ -153,36 +316,50 @@ void tools_printer::build_volumeline(std::shared_ptr volume, std::s
}
}
-void printer::tools_printer::fragments_anchors_define(const QList>& list, const QDir & destdir) {
- for (auto &it : list) {
+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->setHtmlRefer(destdir.absoluteFilePath(QString("%1.html").arg(address_x)));
+ it->setPageRefers(target_dir.absoluteFilePath(QString("%1.html").arg(address_x)));
}
}
-std::function>&, const QDir &)> refers_refresh =
- [&](const QList> &items, const QDir &destdir){
- for (auto &item : items) {
- auto refer = std::dynamic_pointer_cast(item);
- if (refer) {
- auto address_x = QString::number((qulonglong)refer->accessPeers()->element().get());
- refer->setHtmlRefer(destdir.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->setPieceRefer(summary_href + u8"#" + element_addr);
}
-};
+ };
-void printer::tools_printer::storylines_anchors_define(const QList>& list, const QDir & destdir) {
- for (auto &it : list) {
+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());
- it->setHtmlRefer(destdir.absoluteFilePath(QString("%1.html").arg(address_x)));
- refers_refresh(it->elements(), destdir);
+ auto page_address = target_dir.absoluteFilePath(QString("%1.html").arg(address_x));
+ it->setPageRefers(page_address);
+ refers_refresh(it->elements(), page_address);
}
}
-void printer::tools_printer::volumes_anchors_define(const QList>& list, const QDir & destdir) {
- for (auto &it : list) {
+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());
- it->setHtmlRefer(destdir.absoluteFilePath(QString("%1.html").arg(address_x)));
- refers_refresh(it->elements(), destdir);
+ auto page_address = target_dir.absoluteFilePath(QString("%1.html").arg(address_x));
+ it->setPageRefers(page_address);
+ refers_refresh(it->elements(), page_address);
}
}
diff --git a/WsNovelParser/htmlprint.h b/WsNovelParser/htmlprint.h
index 8066360..1bc976f 100644
--- a/WsNovelParser/htmlprint.h
+++ b/WsNovelParser/htmlprint.h
@@ -1,6 +1,7 @@
#pragma once
#include
#include
+#include
#include
#include
@@ -14,14 +15,27 @@ namespace printer {
Access(std::shared_ptr handle);
virtual ~Access() = default;
+ /*
+ * @brief 获取绑定的语法元素
+ * @return 元素内存指针
+ */
std::shared_ptr accessPeers() const;
- void setHtmlRefer(const QString& href);
- QString htmlRefer() const;
+ /*
+ * @brief 设置汇总页面路径
+ * @param href 页面路径
+ */
+ void setPageRefers(const QString& href);
+ QString pageRefers() const;
+
+ /*
+ * @brief 获取汇总页面的HTML
+ */
+ virtual QString getPageHTML(QDomElement& doc) const = 0;
private:
std::shared_ptr access_handle;
- QString refers_store;
+ QString summary_refer_store;
};
/*
@@ -32,8 +46,19 @@ namespace printer {
Element(std::shared_ptr handle);
virtual ~Element() = default;
- virtual QString toOutsideHTML() const = 0;
- virtual QString toDefinitionHTML() const = 0;
+ /*
+ * @brief 设置片段URL,从故事汇总页面跳转回出处页面
+ */
+ virtual void setPieceRefer(const QString& href);
+ virtual QString pieceRefers() const;
+
+ /*
+ * @brief 获取故事片段出处的节点HTML
+ */
+ virtual QString getPieceHTML(QDomElement &doc) const = 0;
+
+ private:
+ QString refer_store;
};
/*
@@ -44,10 +69,9 @@ namespace printer {
Group(std::shared_ptr handle);
virtual ~Group() = default;
- virtual QString toHTML() const = 0;
-
void append(std::shared_ptr elm);
QList> elements() const;
+ std::shared_ptr getElement(const QString& signature) const;
private:
QList> element_store;
@@ -58,7 +82,7 @@ namespace printer {
StoryLine(std::shared_ptr handle);
// 通过 Group 继承
- QString toHTML() const override;
+ QString getPageHTML(QDomElement& doc) const override;
};
@@ -67,10 +91,10 @@ namespace printer {
StoryVolume(std::shared_ptr handle);
// 通过 Group 继承
- QString toHTML() const override;
+ QString getPageHTML(QDomElement& doc) const override;
};
-
+ class Fragment;
/*
* @brief 情节片段引用定义
*/
@@ -78,9 +102,17 @@ namespace printer {
public:
FragmentRef(std::shared_ptr handle);
+ void setHost(std::shared_ptr frag_inst);
+ std::shared_ptr hostFragment() const;
+
+ // 通过 Access 继承
+ QString getPageHTML(QDomElement& doc) const override;
+
// 通过 Element 继承
- QString toOutsideHTML() const override;
- QString toDefinitionHTML() const override;
+ QString getPieceHTML(QDomElement& doc) const override;
+
+ private:
+ std::weak_ptr host_inst;
};
/*
@@ -96,10 +128,11 @@ namespace printer {
void appendRefers(std::shared_ptr inst);
QList> additionals() const;
+ // 通过 Access 继承
+ QString getPageHTML(QDomElement& doc) const override;
// 通过 Element 继承
- QString toOutsideHTML() const override;
- QString toDefinitionHTML() const override;
+ QString getPieceHTML(QDomElement& doc) const override;
};
diff --git a/WsNovelParser/main.cpp b/WsNovelParser/main.cpp
index d003ea2..27077dd 100644
--- a/WsNovelParser/main.cpp
+++ b/WsNovelParser/main.cpp
@@ -27,15 +27,10 @@ int main(int argc, char* argv[]) {
printer::tools_printer tool;
tool.build_fragments(novel_accesstree);
tool.build_refers_network(novel_accesstree);
-
- auto dest = QDir::current();
- dest.mkdir("storylines");
- dest.mkdir("volumes");
- dest.mkdir("fragments");
- tool.fragments_anchors_define(tool.fragment_defines.values(), QDir(dest.filePath("fragments")));
- tool.storylines_anchors_define(tool.storyline_defines.values(), QDir(dest.filePath("storylines")));
- tool.volumes_anchors_define(tool.volume_defines.values(), QDir(dest.filePath("volumes")));
+ tool.fragments_anchors_define(tool.fragment_defines.values(), QDir::current());
+ tool.storylines_anchors_define(tool.storyline_defines.values(), QDir::current());
+ tool.volumes_anchors_define(tool.volume_defines.values(), QDir::current());
std::function, int)> tnode_print =
[&](std::shared_ptr node, int intend) {
diff --git a/libParse/libParse.vcxproj.user b/libParse/libParse.vcxproj.user
index 59cfff3..57e7254 100644
--- a/libParse/libParse.vcxproj.user
+++ b/libParse/libParse.vcxproj.user
@@ -5,9 +5,9 @@
WindowsLocalDebugger
- 2024-03-31T05:42:52.1001219Z
+ 2024-03-31T14:11:50.6102543Z
- 2024-03-31T05:42:52.1782463Z
+ 2024-03-31T14:11:50.7328441Z
\ No newline at end of file
diff --git a/libSyntax/libSyntax.vcxproj.user b/libSyntax/libSyntax.vcxproj.user
index d396399..3545fe8 100644
--- a/libSyntax/libSyntax.vcxproj.user
+++ b/libSyntax/libSyntax.vcxproj.user
@@ -5,9 +5,9 @@
WindowsLocalDebugger
- 2024-03-31T05:42:52.3344976Z
+ 2024-03-31T14:11:50.4238856Z
- 2024-03-31T05:42:52.5226570Z
+ 2024-03-31T14:11:50.5434786Z
\ No newline at end of file
diff --git a/libToken/libToken.vcxproj.user b/libToken/libToken.vcxproj.user
index 26e5b18..5e874a7 100644
--- a/libToken/libToken.vcxproj.user
+++ b/libToken/libToken.vcxproj.user
@@ -2,9 +2,9 @@
- 2024-03-31T05:42:52.2094883Z
+ 2024-03-31T14:11:50.7936395Z
- 2024-03-31T05:42:52.3032378Z
+ 2024-03-31T14:11:50.9152358Z
\ No newline at end of file