WsParser_VS/StoryPresent/xast_parse.cpp

606 lines
17 KiB
C++
Raw Blame History

#include "xast_parse.h"
using namespace xast_parse;
using namespace std;
__SiblingImpl::__SiblingImpl(SliceType t, shared_ptr<IElementSlice> pnode)
: t_store(t), parent_store(pnode) { }
SliceType __SiblingImpl::type() const {
return t_store;
}
weak_ptr<IElementSlice> __SiblingImpl::parentSlice() const {
return this->parent_store;
}
void __SiblingImpl::setPrev(shared_ptr<IElementSlice> inst) {
this->prev_store = inst;
}
weak_ptr<IElementSlice> __SiblingImpl::prevSlice() const {
return this->prev_store;
}
void __SiblingImpl::setNext(shared_ptr<IElementSlice> next) {
if (this->next_store) {
this->next_store->setPrev(next);
next->setNext(this->next_store);
}
next->setPrev(this->shared_from_this());
this->next_store = next;
}
shared_ptr<IElementSlice> __SiblingImpl::nextSlice() const {
return this->next_store;
}
uint __SiblingImpl::index() const {
uint v_index = 0;
auto temp_node = this->prevSlice();
while (temp_node.lock()) {
v_index++;
temp_node = temp_node.lock()->prevSlice();
}
return v_index;
}
TextParagraph::TextParagraph(shared_ptr<IElementSlice> parent)
: __SiblingImpl(SliceType::TextPragraph, parent) { }
void TextParagraph::setLines(const QString& contents) {
this->lines = contents.split('\n');
}
QString TextParagraph::getLines() const {
return lines.join('\n');
}
void TextParagraph::addLine(const QString& line) {
this->lines << line;
}
QList<QString> TextParagraph::nameSet() const {
return parentSlice().lock()->nameSet() << "$$";
}
StoryDefine::StoryDefine(const QString& name, uint sort, const QString& path)
:__CollectionElement(SliceType::StoryDefines, nullptr),
name_store(name), sort_store(sort), file_path(path) { }
QString StoryDefine::name() const {
return this->name_store;
}
QString xast_parse::StoryDefine::bindPath() const
{
return file_path;
}
shared_ptr<IElementSlice> StoryDefine::getFragment(const QString& name) {
auto temp_node = this->firstChild();
while (temp_node) {
if (temp_node->type() == SliceType::FragmentDefines) {
if (dynamic_pointer_cast<FragmentDefine>(temp_node)->name() == name)
return temp_node;
}
temp_node = temp_node->nextSlice();
}
return nullptr;
}
QList<QString> StoryDefine::nameSet() const {
return QList<QString>() << name();
}
uint StoryDefine::index() const {
return this->sort_store;
}
FragmentDefine::FragmentDefine(const QString& name, shared_ptr<StoryDefine> pnode)
: __DesElement(SliceType::FragmentDefines, static_pointer_cast<IElementSlice>(pnode)), name_store(name) { }
QString FragmentDefine::name() const {
return name_store;
}
QList<shared_ptr<IElementSlice>> FragmentDefine::referSlices() const {
return this->refs_list;
}
void FragmentDefine::appendRefer(shared_ptr<IElementSlice> slice) {
if (this->refs_list.contains(slice))
return;
this->refs_list << slice;
}
QList<QString> FragmentDefine::nameSet() const {
return parentSlice().lock()->nameSet() << name();
}
__CollectionElement::__CollectionElement(SliceType t, shared_ptr<IElementSlice> pnode) :__SiblingImpl(t, pnode) { }
shared_ptr<IElementSlice> __CollectionElement::firstChild() const {
return this->first_head;
}
void __CollectionElement::setFirstChild(shared_ptr<IElementSlice> inst) {
this->first_head = inst;
}
__DesElement::__DesElement(SliceType t, shared_ptr<IElementSlice> pnode)
: __SiblingImpl(t, pnode) { }
shared_ptr<TextParagraph> __DesElement::getTextNode() const {
if (!text_store)
const_cast<__DesElement*>(this)->text_store = make_shared<TextParagraph>(
const_pointer_cast<__SiblingImpl>(this->shared_from_this()));
return text_store;
}
FragmentRefer::FragmentRefer(const QString& story, const QString& fragm, shared_ptr<IElementSlice> pnode)
: __DesElement(SliceType::PointRefers, pnode), story_refers(story), fragment_refers(fragm) { }
QString FragmentRefer::storyRefer() const {
return this->story_refers;
}
QString FragmentRefer::fragmentRefer() const {
return this->fragment_refers;
}
weak_ptr<FragmentDefine> FragmentRefer::referTarget() const {
return this->refer_targets;
}
void FragmentRefer::setReferTowards(shared_ptr<FragmentDefine> target) {
this->refer_targets = target;
}
QList<QString> FragmentRefer::nameSet() const {
return parentSlice().lock()->nameSet() << "@" + storyRefer() << fragmentRefer();
}
ArticleDefine::ArticleDefine(const QString& name, shared_ptr<IElementSlice> pnode)
: __CollectionElement(SliceType::ArticleDefines, pnode), name_store(name) { }
QString ArticleDefine::name() const {
return name_store;
}
QList<QString> ArticleDefine::nameSet() const {
return parentSlice().lock()->nameSet() << name();
}
VolumeDefine::VolumeDefine(const QString& name, const QString& path)
: __CollectionElement(SliceType::VolumeDefines, nullptr), name_store(name), file_path(path) { }
QString VolumeDefine::name() const {
return name_store;
}
QString VolumeDefine::bindPath() const {
return file_path;
}
QList<QString> VolumeDefine::getArticleNames() const {
QList<QString> names;
auto first_elm = this->firstChild();
while (first_elm) {
if (first_elm->type() == SliceType::ArticleDefines) {
names << static_pointer_cast<ArticleDefine>(first_elm)->name();
}
first_elm = first_elm->nextSlice();
}
return names;
}
shared_ptr<ArticleDefine> VolumeDefine::getArticleWith(const QString& name) const {
auto temp_elm = this->firstChild();
while (temp_elm) {
if (temp_elm->type() == SliceType::ArticleDefines) {
auto conv_elm = static_pointer_cast<ArticleDefine>(temp_elm);
if (conv_elm->name() == name) {
return conv_elm;
}
}
temp_elm = temp_elm->nextSlice();
}
return nullptr;
}
QList<QString> VolumeDefine::nameSet() const {
return QList<QString>() << name();
}
XAST_Parser::XAST_Parser(const QString& ast_path) {
QFile ast_file(ast_path);
if (!ast_file.open(QIODevice::Text | QIODevice::ReadOnly))
throw new exception("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>" + ast_path.toLocal8Bit());
this->dom_tree.setContent(&ast_file);
auto ranks = this->dom_tree.elementsByTagName(u8"rank");
for (auto idx = 0; idx < ranks.size(); ++idx) {
auto re = ranks.at(idx).toElement();
auto path = re.attribute(u8"doc-path");
auto rankv = re.attribute(u8"rank");
auto inst = std::make_shared<RankDecs>(path, rankv);
this->rank_coll.append(inst);
}
auto nodes = this->dom_tree.elementsByTagName(u8"story");
for (auto idx = 0; idx < nodes.size(); ++idx) {
auto nd = nodes.at(idx);
auto sinst = this->init_story_define(nd.toElement());
story_dict[sinst->name()] = sinst;
}
nodes = this->dom_tree.elementsByTagName(u8"volume");
for (auto idx = 0; idx < nodes.size(); ++idx) {
auto nd = nodes.at(idx);
auto vinst = this->init_volume_define(nd.toElement());
volume_dict[vinst->name()] = vinst;
}
for (auto sit : story_dict.values()) {
this->fragments_plait(story_dict, sit);
}
for (auto vit : volume_dict.values()) {
this->fragments_plait(story_dict, vit);
}
ast_file.close();
}
QList<shared_ptr<RankDecs>> XAST_Parser::rankList() const {
return rank_coll;
}
QHash<QString, shared_ptr<StoryDefine>> XAST_Parser::storyGraph() const {
return story_dict;
}
QHash<QString, shared_ptr<VolumeDefine>> XAST_Parser::volumeGraph() const {
return volume_dict;
}
void xast_parse::XAST_Parser::output(const QDir& dir) {
for (auto& r : this->rankList()) {
this->write_rank(r, dir);
}
for (auto& s : this->storyGraph()) {
this->write_story(s, dir);
}
for (auto& v : this->volumeGraph()) {
this->write_volume(v, dir);
}
}
shared_ptr<StoryDefine> XAST_Parser::init_story_define(const QDomElement& story_e) {
auto s_name = story_e.attribute(u8"name");
auto s_sort = story_e.attribute(u8"sort").toUInt();
auto s_path = story_e.attribute(u8"file-path");
auto inst = make_shared<StoryDefine>(s_name, s_sort, s_path);
QList<QDomElement> elms_list;
auto temp_elm = story_e.firstChildElement();
while (!temp_elm.isNull()) {
if (temp_elm.tagName() != u8"tokens")
elms_list << temp_elm;
temp_elm = temp_elm.nextSiblingElement();
}
shared_ptr<IElementSlice> temporary_ptr = nullptr;
while (elms_list.size()) {
shared_ptr<IElementSlice> current_ptr = nullptr;
auto text_count = this->text_sections_count(elms_list);
if (text_count) {
current_ptr = this->text_paragraph_build(inst, elms_list, text_count);
}
else if (elms_list.at(0).tagName() == u8"fragment") {
current_ptr = this->fragment_define_build(inst, elms_list.at(0));
elms_list.takeFirst();
}
else if (elms_list.at(0).tagName() == u8"refer") {
current_ptr = this->fragment_refer_build(inst, elms_list.at(0));
elms_list.takeFirst();
}
if (!temporary_ptr) {
inst->setFirstChild(current_ptr);
}
else {
temporary_ptr->setNext(current_ptr);
}
temporary_ptr = current_ptr;
}
return inst;
}
uint XAST_Parser::text_sections_count(const QList<QDomElement>& elms) {
uint count = 0;
for (auto enode : elms) {
if (enode.tagName() != u8"text-section")
break;
count++;
}
return count;
}
shared_ptr<TextParagraph> XAST_Parser::text_paragraph_build(shared_ptr<__CollectionElement> pnode, QList<QDomElement>& elms, uint count) {
auto inst = make_shared<TextParagraph>(pnode);
for (uint idx = 0; idx < count; ++idx) {
auto telm = elms.takeAt(0);
auto line = telm.attribute(u8"text");
inst->addLine(line);
}
return inst;
}
shared_ptr<FragmentDefine> XAST_Parser::fragment_define_build(shared_ptr<StoryDefine> pnode, const QDomElement& e) {
auto fname = e.attribute(u8"name");
auto fragm = make_shared<FragmentDefine>(fname, pnode);
auto temp_elm = e.firstChildElement();
while (!temp_elm.isNull()) {
if (temp_elm.tagName() == u8"text-section") {
auto line = temp_elm.attribute(u8"text");
fragm->getTextNode()->addLine(line);
}
temp_elm = temp_elm.nextSiblingElement();
}
return fragm;
}
shared_ptr<FragmentRefer> XAST_Parser::fragment_refer_build(shared_ptr<__CollectionElement> pnode, const QDomElement& e) {
auto story_ref = e.attribute(u8"story");
auto fragm_ref = e.attribute(u8"fragment");
auto fragmemt_refi = make_shared<FragmentRefer>(story_ref, fragm_ref, pnode);
auto temp_node = e.firstChildElement();
while (!temp_node.isNull()) {
if (temp_node.tagName() == u8"text-section") {
auto line = temp_node.attribute(u8"text");
fragmemt_refi->getTextNode()->addLine(line);
}
temp_node = temp_node.nextSiblingElement();
}
return fragmemt_refi;
}
void XAST_Parser::fragments_plait(QHash<QString, shared_ptr<StoryDefine>> story_map, shared_ptr<ICollection> reflist) {
auto slice = reflist->firstChild();
while (slice) {
if (slice->type() == SliceType::PointRefers) {
auto refer_inst = static_pointer_cast<FragmentRefer>(slice);
auto story_target = story_map[refer_inst->storyRefer()];
auto fragm_target = story_target->getFragment(refer_inst->fragmentRefer());
auto fragm_cast = static_pointer_cast<FragmentDefine>(fragm_target);
fragm_cast->appendRefer(refer_inst);
refer_inst->setReferTowards(fragm_cast);
}
switch (slice->type()) {
case SliceType::StoryDefines:
case SliceType::VolumeDefines:
case SliceType::ArticleDefines:
this->fragments_plait(story_map, static_pointer_cast<__CollectionElement>(slice));
break;
default:
break;
}
slice = slice->nextSlice();
}
}
shared_ptr<VolumeDefine> XAST_Parser::init_volume_define(const QDomElement& volume_e) {
auto v_name = volume_e.attribute(u8"name");
auto v_path = volume_e.attribute(u8"file-path");
auto inst = make_shared<VolumeDefine>(v_name, v_path);
QList<QDomElement> node_list;
auto temp_node = volume_e.firstChildElement();
while (!temp_node.isNull()) {
if (temp_node.tagName() != u8"tokens")
node_list << temp_node;
temp_node = temp_node.nextSiblingElement();
}
shared_ptr<IElementSlice> temporary_ptr = nullptr;
while (node_list.size()) {
shared_ptr<IElementSlice> current_ptr = nullptr;
auto text_count = this->text_sections_count(node_list);
if (text_count) {
current_ptr = this->text_paragraph_build(inst, node_list, text_count);
}
else if (node_list.at(0).tagName() == u8"article") {
current_ptr = this->init_article_define(inst, node_list.at(0));
node_list.takeFirst();
}
if (!temporary_ptr) {
inst->setFirstChild(current_ptr);
}
else {
temporary_ptr->setNext(current_ptr);
}
temporary_ptr = current_ptr;
}
return inst;
}
shared_ptr<ArticleDefine> XAST_Parser::init_article_define(shared_ptr<VolumeDefine> pnode, const QDomElement& article_e) {
auto a_name = article_e.attribute(u8"name");
auto inst = make_shared<ArticleDefine>(a_name, pnode);
QList<QDomElement> node_list;
auto temp_node = article_e.firstChildElement();
while (!temp_node.isNull()) {
if (temp_node.tagName() != u8"tokens")
node_list << temp_node;
temp_node = temp_node.nextSiblingElement();
}
shared_ptr<IElementSlice> temporary_ptr = nullptr;
while (node_list.size()) {
shared_ptr<IElementSlice> current_ptr = nullptr;
auto text_count = this->text_sections_count(node_list);
if (text_count) {
current_ptr = this->text_paragraph_build(inst, node_list, text_count);
}
else if (node_list.at(0).tagName() == u8"refer") {
current_ptr = this->fragment_refer_build(inst, node_list.at(0));
node_list.takeFirst();
}
if (!temporary_ptr) {
inst->setFirstChild(current_ptr);
}
else {
temporary_ptr->setNext(current_ptr);
}
temporary_ptr = current_ptr;
}
return inst;
}
#include <QMessageBox>
#include <QCoreApplication>
#include <QTextStream>
void xast_parse::XAST_Parser::write_rank(std::shared_ptr<RankDecs> inst, const QDir& odir) {
auto fname = inst->bindPath();
QFile target_file(odir.filePath(fname));
if (!target_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::critical(nullptr, "<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", odir.filePath(fname) + "<EFBFBD>޷<EFBFBD><EFBFBD>򿪣<EFBFBD>");
QCoreApplication::exit(0);
return;
}
QTextStream o(&target_file);
o.setCodec("UTF-8");
o << QString(u8"#<23><><EFBFBD><EFBFBD> ") << inst->rank() << endl;
}
void xast_parse::XAST_Parser::write_story(std::shared_ptr<StoryDefine> inst, const QDir& odir)
{
auto fname = inst->bindPath();
QFile target_file(odir.filePath(fname));
if (!target_file.open(QIODevice::Append | QIODevice::Text)) {
QMessageBox::critical(nullptr, "<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", odir.filePath(fname) + "<EFBFBD>޷<EFBFBD><EFBFBD>򿪣<EFBFBD>");
QCoreApplication::exit(0);
return;
}
QTextStream o(&target_file);
o.setCodec("UTF-8");
o << QString(u8"{<7B><><EFBFBD><EFBFBD> ") << inst->name() << "\n";
auto temp = inst->firstChild();
while (temp) {
switch (temp->type()) {
case SliceType::TextPragraph:
this->write_text(1, std::dynamic_pointer_cast<TextParagraph>(temp), o);
break;
case SliceType::FragmentDefines:
this->write_fragmdef(1, std::dynamic_pointer_cast<FragmentDefine>(temp), o);
break;
case SliceType::PointRefers:
this->write_fragmref(1, std::dynamic_pointer_cast<FragmentRefer>(temp), o);
break;
default:
break;
}
temp = temp->nextSlice();
}
o << QString(u8"}\n");
}
void xast_parse::XAST_Parser::write_text(int dep, std::shared_ptr<TextParagraph> inst, QTextStream& out)
{
auto text = inst->getLines();
text.replace("\n", "\n" + QString(dep * 2, ' '));
out << QString(dep * 2, ' ') << text << "\n";
}
void xast_parse::XAST_Parser::write_fragmdef(int dep, std::shared_ptr<FragmentDefine> inst, QTextStream& out)
{
out << QString(dep * 2, ' ') << QString(u8"{<7B><><EFBFBD><EFBFBD> %1\n").arg(inst->name());
this->write_text(dep + 1, inst->getTextNode(), out);
out << QString(dep * 2, ' ') << QString(u8"}\n");
}
void xast_parse::XAST_Parser::write_fragmref(int dep, std::shared_ptr<FragmentRefer> inst, QTextStream& out)
{
out << QString(dep * 2, ' ') << QString(u8"{@<40><><EFBFBD><EFBFBD> %1&%2\n").arg(inst->fragmentRefer(), inst->storyRefer());
this->write_text(dep + 1, inst->getTextNode(), out);
out << QString(dep * 2, ' ') << QString(u8"}\n");
}
void xast_parse::XAST_Parser::write_volume(std::shared_ptr<VolumeDefine> inst, const QDir& odir)
{
auto fname = inst->bindPath();
QFile target_file(odir.filePath(fname));
if (!target_file.open(QIODevice::Append | QIODevice::Text)) {
QMessageBox::critical(nullptr, "<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", odir.filePath(fname) + "<EFBFBD>޷<EFBFBD><EFBFBD>򿪣<EFBFBD>");
QCoreApplication::exit(0);
return;
}
QTextStream o(&target_file);
o.setCodec("UTF-8");
o << QString(u8"{<7B>־<EFBFBD> %1\n").arg(inst->name());
auto temp = inst->firstChild();
while (temp) {
switch (temp->type()) {
case SliceType::TextPragraph:
this->write_text(1, std::dynamic_pointer_cast<TextParagraph>(temp), o);
break;
case SliceType::ArticleDefines:
this->write_article(1, std::dynamic_pointer_cast<ArticleDefine>(temp), o);
break;
default:
break;
}
temp = temp->nextSlice();
}
o << QString(u8"}\n");
}
void xast_parse::XAST_Parser::write_article(int dep, std::shared_ptr<ArticleDefine> inst, QTextStream& out)
{
out << QString(u8"%1{<7B>½<EFBFBD> %2\n").arg(QString(dep * 2, ' '), inst->name());
auto temp = inst->firstChild();
while (temp) {
switch (temp->type()) {
case SliceType::TextPragraph:
this->write_text(dep + 1, std::dynamic_pointer_cast<TextParagraph>(temp), out);
break;
case SliceType::PointRefers:
this->write_fragmref(dep + 1, std::dynamic_pointer_cast<FragmentRefer>(temp), out);
break;
default:
break;
}
temp = temp->nextSlice();
}
out << QString(u8"%1}\n").arg(QString(dep * 2, ' '));
}
RankDecs::RankDecs(const QString& path, const QString& rank)
:fpath(path), rank_v(rank) { }
QString RankDecs::bindPath() const {
return fpath;
}
QString RankDecs::rank() const {
return rank_v;
}