WsParser_VS/WsNovelParser/main.cpp

254 lines
8.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <QtCore/QCoreApplication>
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfoList>
#include <ast_gen.h>
#include <ast_novel.h>
#include <libtoken.h>
#include <syntax_novel.h>
#include <tokens_novel.h>
#include <QDir>
#include <QTextStream>
#include <iostream>
#include <QTime>
#include "novelparser.h"
#include "htmlprint.h"
using namespace example_novel;
std::function<void(std::shared_ptr<const ast_gen::ElementAccess>, int)> tnode_print =
[&](std::shared_ptr<const ast_gen::ElementAccess> node, int intend) {
auto name = node->element()->signature();
auto text = QString(intend * 2, ' ') + name;
/*for (auto& t : node->tokens()) {
text += " " + t->token()->content();
}*/
qDebug() << text;
for (auto& c_n : node->children()) {
tnode_print(c_n, intend + 1);
}
};
/*
* nsc --help
* nsc [opts] --path path-to-dir
* opts:
* -p print-struct 输出整体结构
* -s service 常驻服务启动
*/
int main(int argc, char* argv[]) {
QCoreApplication a(argc, argv);
QStringList args;
for (int idx = 0; idx < argc; idx++) {
args += QString::fromLocal8Bit(argv[idx]);
}
// 帮助特殊用法
if (args.contains(u8"--help")) {
std::cout << "nsc(WsNovelStoryCompiler故事线编译器)" << std::endl;
std::cout << "版本V1.0.0" << std::endl;
std::cout << "nsc -path path-to-dir" << std::endl;
exit(0);
}
auto source_dir = QDir::current();
auto index = args.indexOf(u8"--path");
if (index < 0) {
std::cout << "参数错误:必须指定 --path 参数" << endl;
exit(1);
}
if (index + 1 >= args.size()) {
std::cout << "参数错误:--path 后面应该续接story文件的父文件夹路径。" << std::endl;
exit(1);
}
else {
auto tdir = QDir(args[index+1]);
if (tdir.exists()) {
source_dir = tdir;
}
else {
std::cout << "参数错误传入的story文件父文件夹路径无效。"<< std::endl;
exit(1);
}
}
auto files = source_dir.entryInfoList(QStringList() << "*.story");
if (files.size()) {
try {
auto parser = std::make_shared<NovelParser>();
auto novel_accesstree = parser->parse(files);
QTime time_stamp = QTime::currentTime();
printer::tools_printer tool;
tool.build_fragments(novel_accesstree);
tool.build_refers_network(novel_accesstree);
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<void(std::shared_ptr<const printer::Access>)> html_output =
[](std::shared_ptr<const printer::Access> inst) {
auto target_path = inst->pageRefers();
QFile tfile(target_path);
if (tfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QDomDocument doc_inst(QDomImplementation().createDocumentType(u8"html", QString(), QString()));
auto html = doc_inst.createElement(u8"html");
doc_inst.appendChild(html);
auto body = doc_inst.createElement(u8"body");
html.appendChild(body);
inst->buildPageHTML(body);
QTextStream tout(&tfile);
doc_inst.save(tout, 2);
tout.flush();
}
};
for (auto& node : tool.fragment_defines)
html_output(node);
for (auto& node : tool.storyline_defines)
html_output(node);
for (auto& node : tool.volume_defines)
html_output(node);
auto dot_src = tool.storylines_paint(tool.storyline_defines.values());
QFile dot_file(QDir::current().filePath(u8"relates.dot"));
if (dot_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream txt(&dot_file);
txt.setCodec(u8"UTF-8");
txt << dot_src;
txt.flush();
}
system("dot -Tsvg relates.dot -o relates.svg");
auto vols_src = tool.volumes_paint(tool.volume_defines.values(), tool.storyline_defines.values());
QFile vols_file(QDir::current().filePath(u8"volumes_group.dot"));
if (vols_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream txt(&vols_file);
txt.setCodec(u8"UTF-8");
txt << vols_src;
txt.flush();
}
system("fdp -Tsvg volumes_group.dot -o volumes_group.svg");
{
QFile tfile("./index.html");
if (tfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QDomDocument doc_inst(QDomImplementation().createDocumentType(u8"html", QString(), QString()));
auto html = doc_inst.createElement(u8"html");
doc_inst.appendChild(html);
auto body = doc_inst.createElement(u8"body");
html.appendChild(body);
auto dom_storyline = doc_inst.createElement("div");
auto dom_storyline_title = doc_inst.createElement("h2");
dom_storyline_title.appendChild(doc_inst.createTextNode(u8"故事脉络"));
dom_storyline.appendChild(dom_storyline_title);
body.appendChild(dom_storyline);
auto lines = tool.storyline_defines.values();
std::sort(lines.begin(), lines.end(), [](std::shared_ptr<printer::StoryLine> a, std::shared_ptr<printer::StoryLine> b)->bool {
auto a_elm = std::dynamic_pointer_cast<const example_novel::StoryDefine>(a->accessPeers()->element());
auto b_elm = std::dynamic_pointer_cast<const example_novel::StoryDefine>(b->accessPeers()->element());
return a_elm->sort() < b_elm->sort();
});
for (auto& inst_line : lines) {
auto dom_line = doc_inst.createElement("p");
dom_storyline.appendChild(dom_line);
auto line_href = doc_inst.createElement("a");
line_href.setAttribute(u8"href", u8"file:///" + inst_line->pageRefers());
auto a_elm = std::dynamic_pointer_cast<const example_novel::StoryDefine>(inst_line->accessPeers()->element());
line_href.appendChild(doc_inst.createTextNode(QString(u8"%1.%2").arg(a_elm->sort()).arg(a_elm->signature())));
dom_line.appendChild(line_href);
}
auto dom_volume = doc_inst.createElement("div");
auto dom_volume_title = doc_inst.createElement("h2");
dom_volume_title.appendChild(doc_inst.createTextNode(u8"分卷内容"));
dom_volume.appendChild(dom_volume_title);
body.appendChild(dom_volume);
for (auto& inst_volume : tool.volume_defines) {
auto dom_volume_ref = doc_inst.createElement("p");
dom_volume.appendChild(dom_volume_ref);
auto volume_href = doc_inst.createElement("a");
volume_href.setAttribute(u8"href", u8"file:///" + inst_volume->pageRefers());
volume_href.appendChild(doc_inst.createTextNode(inst_volume->accessPeers()->element()->signature()));
dom_volume_ref.appendChild(volume_href);
}
auto dom_fragment = doc_inst.createElement("div");
auto dom_fragment_title = doc_inst.createElement("h2");
dom_fragment_title.appendChild(doc_inst.createTextNode(u8"情节集合"));
dom_fragment.appendChild(dom_fragment_title);
body.appendChild(dom_fragment);
auto table_cube = doc_inst.createElement(u8"table");
dom_fragment.appendChild(table_cube);
int row_ctrl = 0;
QDomElement elm_row;
for (auto& inst_frag : tool.fragment_defines) {
if(row_ctrl++ % 4 == 0){
elm_row = doc_inst.createElement(u8"tr");
table_cube.appendChild(elm_row);
}
auto dom_fragment_ref = doc_inst.createElement("td");
elm_row.appendChild(dom_fragment_ref);
auto frag_href = doc_inst.createElement("a");
frag_href.setAttribute(u8"href", u8"file:///" + inst_frag->pageRefers());
frag_href.appendChild(doc_inst.createTextNode(inst_frag->accessPeers()->element()->signature()));
dom_fragment_ref.appendChild(frag_href);
}
auto dom_relate = doc_inst.createElement(u8"div");
auto dom_relate_title = doc_inst.createElement(u8"h2");
dom_relate_title.appendChild(doc_inst.createTextNode(u8"联系图"));
dom_relate.appendChild(dom_relate_title);
body.appendChild(dom_relate);
auto img = doc_inst.createElement(u8"img");
img.setAttribute(u8"src", u8"file:///" + QDir::current().filePath(u8"relates.svg"));
dom_relate.appendChild(img);
dom_relate.appendChild(doc_inst.createElement("br"));
img = doc_inst.createElement(u8"img");
img.setAttribute(u8"src", u8"file:///" + QDir::current().filePath(u8"volumes_group.svg"));
dom_relate.appendChild(img);
QTextStream tout(&tfile);
doc_inst.save(tout, 2);
tout.flush();
}
}
auto current_stamp = QTime::currentTime();
qDebug() << QString(u8"html构建消耗时间%1 ms。").arg(time_stamp.msecsTo(current_stamp));
//tnode_print(novel_accesstree, 0);
qDebug() << u8"编译成功:" << QDir::current().absoluteFilePath(u8"index.html");
}
catch (lib_syntax::SyntaxException* e) {
qDebug().noquote() << e->message();
delete e;
}
catch (lib_parse::CheckException* e) {
qDebug().noquote() << e->message();
delete e;
}
}
return 0;
//return a.exec();
}