2024-03-17 07:58:28 +00:00
|
|
|
|
#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>
|
2024-03-31 05:59:17 +00:00
|
|
|
|
#include <QDir>
|
2024-04-04 05:18:44 +00:00
|
|
|
|
#include <QTextStream>
|
2024-04-20 03:34:33 +00:00
|
|
|
|
#include <iostream>
|
2024-06-15 01:18:33 +00:00
|
|
|
|
#include <QTime>
|
2024-06-22 10:53:51 +00:00
|
|
|
|
#include <argsparser.h>
|
2024-03-17 07:58:28 +00:00
|
|
|
|
|
|
|
|
|
#include "novelparser.h"
|
2024-03-31 05:59:17 +00:00
|
|
|
|
#include "htmlprint.h"
|
2024-03-17 07:58:28 +00:00
|
|
|
|
|
|
|
|
|
using namespace example_novel;
|
|
|
|
|
|
2024-06-05 00:27:34 +00:00
|
|
|
|
/*
|
|
|
|
|
* nsc --help
|
2024-06-22 10:53:51 +00:00
|
|
|
|
* nsc -[pw] --path path-to-dir [--out path-to-dir]
|
2024-06-05 00:27:34 +00:00
|
|
|
|
* opts:
|
2024-06-22 10:53:51 +00:00
|
|
|
|
* p print-struct <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ
|
|
|
|
|
* w print-web <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>webҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
2024-06-05 00:27:34 +00:00
|
|
|
|
*/
|
2024-03-17 07:58:28 +00:00
|
|
|
|
int main(int argc, char* argv[]) {
|
2024-04-05 12:51:20 +00:00
|
|
|
|
QCoreApplication a(argc, argv);
|
2024-03-17 07:58:28 +00:00
|
|
|
|
|
2024-06-22 10:53:51 +00:00
|
|
|
|
args_parse::ArgsParser args_parser;
|
|
|
|
|
QList<std::shared_ptr<args_parse::ArgvPack>> args_mode;
|
|
|
|
|
args_mode << std::make_shared<args_parse::IndexParam>(u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
args_mode << std::make_shared<args_parse::FloatOption>(u8"--help", u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
args_parser.loadMode(0x000Au, args_mode);
|
|
|
|
|
|
|
|
|
|
args_mode.clear();
|
|
|
|
|
args_mode << std::make_shared<args_parse::IndexParam>(u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
args_mode << std::make_shared<args_parse::FloatArgvPack>(u8"--path", u8"Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼");
|
2024-06-23 02:50:38 +00:00
|
|
|
|
args_mode << std::make_shared<args_parse::FloatArgvPack>(u8"--dest", u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼");
|
2024-06-22 10:53:51 +00:00
|
|
|
|
args_mode << std::make_shared<args_parse::FloatOption>(u8"--html", u8"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>html<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>ʽȡ<EFBFBD><EFBFBD>AST", true);
|
|
|
|
|
args_parser.loadMode(0x000Bu, args_mode);
|
2024-06-05 04:12:31 +00:00
|
|
|
|
|
2024-06-22 10:53:51 +00:00
|
|
|
|
|
|
|
|
|
auto parse_result = args_parser.parse(argc, argv);
|
2024-06-23 02:50:38 +00:00
|
|
|
|
switch (std::get<0>(parse_result)) {
|
2024-06-22 10:53:51 +00:00
|
|
|
|
case 0xBu: {
|
|
|
|
|
auto args = std::get<1>(parse_result);
|
|
|
|
|
auto src_dir = std::dynamic_pointer_cast<args_parse::FloatArgvPack>(args_mode[1]);
|
|
|
|
|
auto dst_dir = std::dynamic_pointer_cast<args_parse::FloatArgvPack>(args_mode[2]);
|
2024-06-22 15:19:14 +00:00
|
|
|
|
auto html_opt = std::dynamic_pointer_cast<args_parse::FloatOption>(args_mode[3]);
|
2024-06-22 10:53:51 +00:00
|
|
|
|
|
|
|
|
|
auto source_dir = QDir(src_dir->value());
|
|
|
|
|
if (!source_dir.exists()) {
|
2024-06-23 02:50:38 +00:00
|
|
|
|
std::cout << "%<25><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>" << std::endl;
|
2024-06-22 10:53:51 +00:00
|
|
|
|
exit(0);
|
2024-06-05 04:12:31 +00:00
|
|
|
|
}
|
2024-06-22 10:53:51 +00:00
|
|
|
|
auto destination_dir = QDir::current();
|
|
|
|
|
auto target_output = dst_dir->value();
|
|
|
|
|
if (!target_output.isEmpty() && QDir(target_output).exists()) {
|
|
|
|
|
destination_dir = QDir(target_output);
|
|
|
|
|
}
|
2024-06-22 15:19:14 +00:00
|
|
|
|
else {
|
2024-06-23 02:50:38 +00:00
|
|
|
|
std::cout << "%<25><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>" << destination_dir.absolutePath().toLocal8Bit().data() << std::endl;
|
2024-06-05 04:12:31 +00:00
|
|
|
|
}
|
2024-03-17 07:58:28 +00:00
|
|
|
|
|
2024-06-22 10:53:51 +00:00
|
|
|
|
auto files = source_dir.entryInfoList(QStringList() << "*.story");
|
|
|
|
|
std::shared_ptr<const ast_gen::ElementAccess> access_ptr = nullptr;
|
|
|
|
|
if (files.size()) {
|
|
|
|
|
try {
|
|
|
|
|
auto parser = std::make_shared<NovelParser>();
|
|
|
|
|
access_ptr = parser->parse(files);
|
|
|
|
|
}
|
|
|
|
|
catch (lib_syntax::SyntaxException* e) {
|
|
|
|
|
qDebug().noquote() << e->message();
|
|
|
|
|
delete e;
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
catch (lib_parse::CheckException* e) {
|
|
|
|
|
qDebug().noquote() << e->message();
|
|
|
|
|
delete e;
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-15 01:18:33 +00:00
|
|
|
|
|
2024-06-22 15:19:14 +00:00
|
|
|
|
if (html_opt->value().toInt() == 1 && access_ptr) {
|
2024-06-15 01:18:33 +00:00
|
|
|
|
QTime time_stamp = QTime::currentTime();
|
2024-04-05 12:51:20 +00:00
|
|
|
|
printer::tools_printer tool;
|
2024-06-22 10:53:51 +00:00
|
|
|
|
tool.build_fragments(access_ptr);
|
|
|
|
|
tool.build_refers_network(access_ptr);
|
2024-03-31 05:59:17 +00:00
|
|
|
|
|
2024-06-22 10:53:51 +00:00
|
|
|
|
tool.fragments_anchors_define(tool.fragment_defines.values(), destination_dir);
|
|
|
|
|
tool.storylines_anchors_define(tool.storyline_defines.values(), destination_dir);
|
|
|
|
|
tool.volumes_anchors_define(tool.volume_defines.values(), destination_dir);
|
2024-04-04 05:18:44 +00:00
|
|
|
|
|
2024-04-05 12:51:20 +00:00
|
|
|
|
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);
|
2024-04-04 05:18:44 +00:00
|
|
|
|
|
2024-04-05 12:51:20 +00:00
|
|
|
|
auto body = doc_inst.createElement(u8"body");
|
|
|
|
|
html.appendChild(body);
|
2024-04-04 05:18:44 +00:00
|
|
|
|
|
2024-04-05 12:51:20 +00:00
|
|
|
|
inst->buildPageHTML(body);
|
2024-04-04 05:18:44 +00:00
|
|
|
|
|
2024-04-05 12:51:20 +00:00
|
|
|
|
QTextStream tout(&tfile);
|
|
|
|
|
doc_inst.save(tout, 2);
|
|
|
|
|
tout.flush();
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-04-04 05:18:44 +00:00
|
|
|
|
|
2024-04-05 12:51:20 +00:00
|
|
|
|
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);
|
2024-03-17 07:58:28 +00:00
|
|
|
|
|
2024-06-22 10:53:51 +00:00
|
|
|
|
QDir::setCurrent(destination_dir.canonicalPath());
|
2024-04-16 15:40:13 +00:00
|
|
|
|
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();
|
|
|
|
|
}
|
2024-04-17 17:56:44 +00:00
|
|
|
|
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");
|
2024-04-05 13:39:29 +00:00
|
|
|
|
|
2024-04-05 12:51:20 +00:00
|
|
|
|
|
2024-04-05 13:39:29 +00:00
|
|
|
|
{
|
|
|
|
|
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"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"));
|
|
|
|
|
dom_storyline.appendChild(dom_storyline_title);
|
|
|
|
|
body.appendChild(dom_storyline);
|
|
|
|
|
|
2024-05-26 04:11:45 +00:00
|
|
|
|
auto lines = tool.storyline_defines.values();
|
2024-06-05 04:12:31 +00:00
|
|
|
|
std::sort(lines.begin(), lines.end(), [](std::shared_ptr<printer::StoryLine> a, std::shared_ptr<printer::StoryLine> b)->bool {
|
2024-05-26 04:11:45 +00:00
|
|
|
|
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) {
|
2024-04-05 13:39:29 +00:00
|
|
|
|
auto dom_line = doc_inst.createElement("p");
|
|
|
|
|
dom_storyline.appendChild(dom_line);
|
|
|
|
|
|
|
|
|
|
auto line_href = doc_inst.createElement("a");
|
2024-04-16 15:40:13 +00:00
|
|
|
|
line_href.setAttribute(u8"href", u8"file:///" + inst_line->pageRefers());
|
2024-05-26 04:11:45 +00:00
|
|
|
|
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())));
|
2024-04-05 13:39:29 +00:00
|
|
|
|
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"<EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"));
|
|
|
|
|
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"<EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><EFBFBD><EFBFBD>"));
|
|
|
|
|
dom_fragment.appendChild(dom_fragment_title);
|
|
|
|
|
body.appendChild(dom_fragment);
|
|
|
|
|
|
2024-05-27 11:53:36 +00:00
|
|
|
|
auto table_cube = doc_inst.createElement(u8"table");
|
|
|
|
|
dom_fragment.appendChild(table_cube);
|
|
|
|
|
|
|
|
|
|
int row_ctrl = 0;
|
|
|
|
|
QDomElement elm_row;
|
2024-04-16 15:40:13 +00:00
|
|
|
|
for (auto& inst_frag : tool.fragment_defines) {
|
2024-06-22 10:53:51 +00:00
|
|
|
|
if (row_ctrl++ % 4 == 0) {
|
2024-05-27 11:53:36 +00:00
|
|
|
|
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);
|
2024-04-05 13:39:29 +00:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-16 15:40:13 +00:00
|
|
|
|
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"<EFBFBD><EFBFBD>ϵͼ"));
|
2024-04-16 15:47:58 +00:00
|
|
|
|
dom_relate.appendChild(dom_relate_title);
|
2024-04-16 15:40:13 +00:00
|
|
|
|
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);
|
2024-04-17 17:56:44 +00:00
|
|
|
|
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);
|
2024-04-16 15:40:13 +00:00
|
|
|
|
|
2024-04-05 13:39:29 +00:00
|
|
|
|
QTextStream tout(&tfile);
|
|
|
|
|
doc_inst.save(tout, 2);
|
|
|
|
|
tout.flush();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-15 01:18:33 +00:00
|
|
|
|
auto current_stamp = QTime::currentTime();
|
2024-06-23 02:50:38 +00:00
|
|
|
|
qDebug().noquote() << QString(u8"%html<6D><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䣺%1 ms<6D><73>").arg(time_stamp.msecsTo(current_stamp));
|
|
|
|
|
qDebug().noquote() << u8"%<25><><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>" << destination_dir.absoluteFilePath(u8"index.html");
|
2024-04-05 12:51:20 +00:00
|
|
|
|
}
|
2024-06-22 15:19:14 +00:00
|
|
|
|
else if (access_ptr) {
|
2024-06-23 02:50:38 +00:00
|
|
|
|
QTime time_stamp = QTime::currentTime();
|
2024-06-22 15:19:14 +00:00
|
|
|
|
lib_parse::VisitorControl control;
|
|
|
|
|
auto visitor = std::make_shared<printer::AstGenerate>();
|
|
|
|
|
control.visitWith(access_ptr, visitor);;
|
|
|
|
|
auto dom_result = visitor->content();
|
2024-06-23 02:28:13 +00:00
|
|
|
|
QFile file(destination_dir.absoluteFilePath(u8"storyline.xast"));
|
|
|
|
|
if (file.open(QIODevice::Text | QIODevice::WriteOnly)) {
|
|
|
|
|
QTextStream tout(&file);
|
|
|
|
|
tout.setCodec("UTF-8");
|
|
|
|
|
tout << dom_result;
|
|
|
|
|
tout.flush();
|
|
|
|
|
}
|
2024-06-23 02:50:38 +00:00
|
|
|
|
auto current_stamp = QTime::currentTime();
|
|
|
|
|
qDebug().noquote() << QString(u8"%AST<53><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䣺%1 ms<6D><73>").arg(time_stamp.msecsTo(current_stamp));
|
|
|
|
|
qDebug().noquote() << QString(u8"%<25><><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>%1<><31>").arg(QFileInfo(file).absoluteFilePath());
|
2024-06-22 15:19:14 +00:00
|
|
|
|
}
|
2024-06-22 10:53:51 +00:00
|
|
|
|
}break;
|
2024-06-23 02:50:38 +00:00
|
|
|
|
case 0xAu:
|
|
|
|
|
default: {
|
|
|
|
|
std::cout << "nsc(WsNovelStoryCompiler<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><DFB1><EFBFBD><EFBFBD><EFBFBD>)" << std::endl;
|
|
|
|
|
std::cout << "<EFBFBD>汾<EFBFBD><EFBFBD>V1.0.0" << std::endl;
|
|
|
|
|
std::cout << "nsc --path path-to-dir [--dest path-to-output] [--html]" << std::endl;
|
|
|
|
|
}break;
|
2024-04-05 12:51:20 +00:00
|
|
|
|
}
|
2024-05-26 04:11:45 +00:00
|
|
|
|
//return a.exec();
|
2024-06-23 02:50:38 +00:00
|
|
|
|
return 0;
|
2024-03-17 07:58:28 +00:00
|
|
|
|
}
|