diff --git a/DesParser/DesParser.pro b/DesParser/DesParser.pro index e290574..5067c9f 100644 --- a/DesParser/DesParser.pro +++ b/DesParser/DesParser.pro @@ -26,6 +26,7 @@ HEADERS += \ DISTFILES += \ example.storyboard \ example.storychain \ + example.storyconcept \ example.storyunit \ example.storyvolume diff --git a/DesParser/example.storyconcept b/DesParser/example.storyconcept new file mode 100644 index 0000000..d923a4a --- /dev/null +++ b/DesParser/example.storyconcept @@ -0,0 +1,5 @@ +#概念 修炼功法{ +#要点 资质{ +ad浪费看啊;df +} +} diff --git a/DesParser/main.cpp b/DesParser/main.cpp index 080afe5..3aeda15 100644 --- a/DesParser/main.cpp +++ b/DesParser/main.cpp @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) MakeTools::StoryTool tool(&core); // auto path = "D:\\Projects\\Cpp\\QtNovelDesc\\DesParser\\example.storyvolume"; - auto path = "D:\\测试文学项目\\contentfile_851382615.storyboard"; + auto path = "D:\\Projects\\Cpp\\QtNovelDesc\\DesParser\\example.storyconcept"; tool.compile(QFileInfo(path), "后台编译"); auto doc = core.queryDocument(QFileInfo(path)); diff --git a/QtNovelDesc.pro.user b/QtNovelDesc.pro.user index caaea38..873e1c6 100644 --- a/QtNovelDesc.pro.user +++ b/QtNovelDesc.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/WordsIDE/ContentPresent.h b/WordsIDE/ContentPresent.h index 0fa2564..09cf354 100644 --- a/WordsIDE/ContentPresent.h +++ b/WordsIDE/ContentPresent.h @@ -10,7 +10,7 @@ namespace ContentPresent { /** * @brief 允许具有多种显示模式的视图组件 */ - class ModeView : public Core::FileExtension + class ModeView : public Core::Extension { public: virtual ~ModeView() = default; diff --git a/WordsIDE/SourceEditView.cpp b/WordsIDE/SourceEditView.cpp index 822f075..883c960 100644 --- a/WordsIDE/SourceEditView.cpp +++ b/WordsIDE/SourceEditView.cpp @@ -59,7 +59,7 @@ void TextContentEdit::reload(QList configs) default_font.setFamily(font_family); default_font.setPointSize(font_size.toInt()); - this->edit_square->document()->setDefaultFont(default_font); + this->textDocument()->setDefaultFont(default_font); this->rehighlighter(); } @@ -77,6 +77,16 @@ FormattedTextEdit::FormattedTextEdit() }); } +void FormattedTextEdit::resetHighlighter(QSyntaxHighlighter *lighter) +{ + lighter->setDocument(this->edit_square->document()); +} + +QTextDocument *FormattedTextEdit::textDocument() const +{ + return edit_square->document(); +} + QWidget *FormattedTextEdit::textView() const { @@ -135,7 +145,7 @@ TextContentEditFactory::TextContentEditFactory() } -FileExtension *TextContentEditFactory::newInstance(Core::AppCore *core) +Extension *TextContentEditFactory::newInstance(Core::AppCore *core) { return new TextContentEdit(this); } diff --git a/WordsIDE/SourceEditView.h b/WordsIDE/SourceEditView.h index 198d2e5..16aa375 100644 --- a/WordsIDE/SourceEditView.h +++ b/WordsIDE/SourceEditView.h @@ -17,6 +17,8 @@ namespace Components { FormattedTextEdit(); virtual ~FormattedTextEdit() = default; + void resetHighlighter(QSyntaxHighlighter *lighter); + QTextDocument *textDocument() const; // VariedTextView interface public: @@ -26,11 +28,9 @@ namespace Components { protected: - QTextEdit *const edit_square; QList configrations_host; - virtual void rehighlighter() = 0; - + QTextEdit *const edit_square; }; class TextContentEditFactory : public Core::FileExtensionFactory @@ -41,7 +41,7 @@ namespace Components { // PluginFactory interface public: - virtual Core::FileExtension *newInstance(Core::AppCore *core) override; + virtual Core::Extension *newInstance(Core::AppCore *core) override; virtual QList configs() const override; virtual QWidget *getNewPanel(Config::Configration *config) override; virtual QString extensionName() const override; diff --git a/WordsIDE/WordsIDE.pro b/WordsIDE/WordsIDE.pro index b9e27c2..3361c4d 100644 --- a/WordsIDE/WordsIDE.pro +++ b/WordsIDE/WordsIDE.pro @@ -13,12 +13,14 @@ SOURCES += \ SensitiveCore.cpp \ SourceEditView.cpp \ appcore.cpp \ + conceptview.cpp \ keywordshightlighter.cpp \ main.cpp \ mainwindow.cpp \ messagepresent.cpp \ projectview.cpp \ storyboardsourceedit.cpp \ + storyboardspresent.cpp \ storychainsourceeditor.cpp \ storychainspresent.cpp \ storyunitsourceedit.cpp \ @@ -30,11 +32,13 @@ HEADERS += \ SensitiveCore.h \ SourceEditView.h \ appcore.h \ + conceptview.h \ keywordshightlighter.h \ mainwindow.h \ messagepresent.h \ projectview.h \ storyboardsourceedit.h \ + storyboardspresent.h \ storychainsourceeditor.h \ storychainspresent.h \ storyunitsourceedit.h \ diff --git a/WordsIDE/appcore.cpp b/WordsIDE/appcore.cpp index 1342f62..bcfd8e2 100644 --- a/WordsIDE/appcore.cpp +++ b/WordsIDE/appcore.cpp @@ -117,7 +117,7 @@ void AppCore::openTextDocument(const QString &src, const QString &name) tview->setSource(this, QFileInfo(src), name, views); framework->addPerceptionList(tview); - dynamic_cast(tview)->reload(this->getConfigs(QList() << Scale::Global << Scale::Project)); + dynamic_cast(tview)->reload(this->getConfigs(QList() << Scale::Global << Scale::Project)); QFile fin(src); if(!fin.open(QIODevice::ReadOnly | QIODevice::Text)){ diff --git a/WordsIDE/appcore.h b/WordsIDE/appcore.h index e185f26..10cba86 100644 --- a/WordsIDE/appcore.h +++ b/WordsIDE/appcore.h @@ -14,7 +14,7 @@ namespace MakeTools { } namespace Core { - class FileExtensionFactory; + class Extension; class AppCore; enum class Scale @@ -24,36 +24,16 @@ namespace Core { File, }; - class FileExtension - { + class ExtensionFactory{ public: - virtual ~FileExtension() = default; - - /** - * @brief 获取唯一的关联工厂类 - * @return - */ - virtual FileExtensionFactory* factory() const = 0; - - /** - * @brief 载入指定的配置端口实例 - * @param configs - */ - virtual void reload(QList configs) = 0; - - }; - - class FileExtensionFactory - { - public: - virtual ~FileExtensionFactory() = default; + virtual ~ExtensionFactory() = default; /** * @brief 生成新插件内容实例 * @param core * @return */ - virtual FileExtension* newInstance(AppCore *core) = 0; + virtual Extension* newInstance(AppCore *core) = 0; /** * @brief 获取所有指定的配置端口类型 @@ -69,6 +49,32 @@ namespace Core { virtual QWidget* getNewPanel(Config::Configration* config) = 0; virtual QString extensionName() const = 0; + }; + + class Extension + { + public: + virtual ~Extension() = default; + + /** + * @brief 获取唯一的关联工厂类 + * @return + */ + virtual ExtensionFactory* factory() const = 0; + + /** + * @brief 载入指定的配置端口实例 + * @param configs + */ + virtual void reload(QList configs) = 0; + + }; + + class FileExtensionFactory : public ExtensionFactory + { + public: + virtual ~FileExtensionFactory() = default; + /** * @brief 可以处理的文件类型 diff --git a/WordsIDE/conceptview.cpp b/WordsIDE/conceptview.cpp new file mode 100644 index 0000000..627be1e --- /dev/null +++ b/WordsIDE/conceptview.cpp @@ -0,0 +1,103 @@ +#include "conceptview.h" +#include "SensitiveCore.h" + +#include +#include + +using namespace Components; +using namespace Core; +using namespace Parse::Result; + +ConceptView::ConceptView(Core::AppCore *core, QWidget *parent) + : QWidget(parent), core_ins(core), + tree_view(new QTreeView(this)), + model_base(new QStandardItemModel(this)), + details_view(new QTextBrowser(this)) +{ + tree_view->setHeaderHidden(true); + + auto layout = new QVBoxLayout(this); + layout->setMargin(0); + + auto splitter = new QSplitter(Qt::Vertical, this); + layout->addWidget(splitter); + + splitter->addWidget(tree_view); + splitter->addWidget(details_view); + + tree_view->setModel(model_base); + details_view->setReadOnly(true); + + connect(tree_view, &QTreeView::clicked, this, &ConceptView::show_node_description); + connect(tree_view, &QTreeView::doubleClicked, this, &ConceptView::click_to); +} + +void ConceptView::refresh() +{ + model_base->clear(); + auto units = core_ins->parseCore()->allStoryConcept(); + for(auto &unit : units){ + auto unit_node = new QStandardItem(static_cast(unit)->name()[0]); + unit_node->setEditable(false); + model_base->appendRow(unit_node); + + auto children = unit->children(); + for(auto &frag : children){ + if(frag->typeValue() == NODE_STORYSTRONGPOINT){ + auto frag_node = new QStandardItem(static_cast(frag)->name()[0]); + frag_node->setEditable(false); + unit_node->appendRow(frag_node); + } + } + } +} + +void ConceptView::show_node_description(const QModelIndex &curr) +{ + if(!curr.isValid()) + return; + + details_view->clear(); + auto item = model_base->itemFromIndex(curr); + if(item->parent() == nullptr){ + auto node = core_ins->parseCore()->queryStoryConcept(item->text()); + + auto children = node.first()->children(); + for(auto &it : children){ + if(it->typeValue() != NODE_STORYSTRONGPOINT){ + details_view->append(it->toString()); + } + } + } + else{ + auto node = core_ins->parseCore()->queryStoryConcept(item->parent()->text()); + auto point = core_ins->parseCore()->queryStoryStrongPoint(node.first(), item->text()); + + auto children = point.first()->children(); + for(auto &it : children){ + details_view->append(it->toString()); + } + } +} + +void ConceptView::click_to(const QModelIndex &curr) +{ + if(!curr.isValid()) + return; + + auto pnode = this->model_base->itemFromIndex(curr); + QList path; + while (pnode) { + path.insert(0, pnode->text()); + pnode = pnode->parent(); + } + + auto unit_ins = this->core_ins->parseCore()->queryStoryConcept(path[0]).first(); + auto chain_doc = unit_ins->doc(); + this->core_ins->openTextDocument(chain_doc->filePath(), chain_doc->docName()); + auto present = this->core_ins->getFramework()->queryTextComponent(QFileInfo(chain_doc->filePath())); + + if(path.size()){ + present->jumpTo(path); + } +} diff --git a/WordsIDE/conceptview.h b/WordsIDE/conceptview.h new file mode 100644 index 0000000..a77af70 --- /dev/null +++ b/WordsIDE/conceptview.h @@ -0,0 +1,31 @@ +#ifndef CONCEPTVIEW_H +#define CONCEPTVIEW_H + +#include "appcore.h" + +#include +#include +#include +#include + +namespace Components { + class ConceptView : public QWidget + { + public: + ConceptView(Core::AppCore *core, QWidget *parent=nullptr); + + virtual void refresh(); + + private: + Core::AppCore *const core_ins; + QTreeView *const tree_view; + QStandardItemModel *const model_base; + QTextBrowser *const details_view; + + void show_node_description(const QModelIndex &curr); + void click_to(const QModelIndex &curr); + }; +} + + +#endif // CONCEPTVIEW_H diff --git a/WordsIDE/mainwindow.cpp b/WordsIDE/mainwindow.cpp index f3d887a..37003c7 100644 --- a/WordsIDE/mainwindow.cpp +++ b/WordsIDE/mainwindow.cpp @@ -42,7 +42,9 @@ MainWindow::MainWindow(QWidget *parent) project_structure(new ProjectView(app_core, project_manager, this)), chains_view(new StoryChainsPresent(app_core, this)), units_view(new StoryUnitsPresent(app_core, this)), - errors_present(new MessagePresent(app_core->getMake_tool(), this)) + errors_present(new MessagePresent(app_core->getMake_tool(), this)), + boards_view(new StoryBoardsPresent(app_core, this)), + concept_view(new ConceptView(app_core, this)) { QApplication::instance()->installEventFilter(this); this->app_core->setCurrentProject(project_manager); @@ -53,6 +55,8 @@ MainWindow::MainWindow(QWidget *parent) chains_view->setVisible(false); units_view->setVisible(false); errors_present->setVisible(false); + boards_view->setVisible(false); + concept_view->setVisible(false); project_structure->setVisible(false); left_funcs->setVisible(false); right_funcs->setVisible(false); @@ -254,6 +258,24 @@ MainWindow::MainWindow(QWidget *parent) sync_kernel->registerAutoRun([this]()->bool{return right_funcs->indexOf(units_view)!=-1;}, [unit_v](bool v){if(v != unit_v->isChecked()) unit_v->setChecked(v);}); } + // 故事统计 + { + auto board_v = func->addAction("故事统计", [this](bool v){ + toggle_widget_visible(v, right_funcs, boards_view, "故事统计"); + }); + board_v->setCheckable(true); + sync_kernel->registerAutoRun([this]()->bool{return right_funcs->indexOf(boards_view)!=-1;}, + [board_v](bool v){if(v!=board_v->isChecked()) board_v->setChecked(v);}); + } + // 概念统计 + { + auto concept_v = func->addAction("概念统计", [this](bool v){ + toggle_widget_visible(v, right_funcs, concept_view, "概念统计"); + }); + concept_v->setCheckable(true); + sync_kernel->registerAutoRun([this]()->bool{return right_funcs->indexOf(concept_view)!=-1;}, + [concept_v](bool v){if(v != concept_v->isChecked()) concept_v->setChecked(v);}); + } // 工具菜单 auto tool = mbar->addMenu("工具"); @@ -325,6 +347,7 @@ MainWindow::MainWindow(QWidget *parent) this->chains_view->refresh(); this->units_view->refresh(); this->errors_present->refresh(); + this->boards_view->refresh(); }); @@ -381,9 +404,15 @@ void MainWindow::build_internal(bool all_from_disk) for(auto &it : volumes) app_core->getMake_tool()->compile(std::get<0>(it), std::get<1>(it)); + auto concepts = project_manager->filesWithEnds("storyconcept"); + for(auto &it : concepts) + app_core->getMake_tool()->compile(std::get<0>(it), std::get<1>(it)); + errors_present->refresh(); chains_view->refresh(); units_view->refresh(); + boards_view->refresh(); + concept_view->refresh(); } void MainWindow::toggle_widget_visible(bool visible, QTabWidget *con, QWidget *target, const QString &title) diff --git a/WordsIDE/mainwindow.h b/WordsIDE/mainwindow.h index 65607d6..d5e250e 100644 --- a/WordsIDE/mainwindow.h +++ b/WordsIDE/mainwindow.h @@ -14,6 +14,8 @@ #include "storyunitspresent.h" #include "projectview.h" #include "ContentPresent.h" +#include "storyboardspresent.h" +#include "conceptview.h" class Run @@ -77,6 +79,8 @@ private: Components::StoryChainsPresent *const chains_view; Components::StoryUnitsPresent *const units_view; Components::MessagePresent *const errors_present; + Components::StoryBoardsPresent *const boards_view; + Components::ConceptView *const concept_view; // 内部逻辑 =========================================== void build_internal(bool all_from_disk = false); diff --git a/WordsIDE/projectview.cpp b/WordsIDE/projectview.cpp index 8850e31..506a13f 100644 --- a/WordsIDE/projectview.cpp +++ b/WordsIDE/projectview.cpp @@ -71,6 +71,7 @@ void Components::ProjectView::contexMenuPopup(const QPoint &pos) newm->addAction("新建单元", [this, &idx_it](){ alloc_file(idx_it, "单元", "storyunit"); }); newm->addAction("新建故事", [this, &idx_it](){ alloc_file(idx_it, "故事", "storyboard"); }); newm->addAction("新建行文", [this, &idx_it](){ alloc_file(idx_it, "行文", "storyvolume"); }); + newm->addAction("新建概念", [this, &idx_it](){ alloc_file(idx_it, "概念", "storyconcept"); }); popup.addSeparator(); popup.addAction("修改名称", [this, &idx_it](){ if(!idx_it.isValid()) diff --git a/WordsIDE/storyboardsourceedit.cpp b/WordsIDE/storyboardsourceedit.cpp index 0ecf620..b803730 100644 --- a/WordsIDE/storyboardsourceedit.cpp +++ b/WordsIDE/storyboardsourceedit.cpp @@ -14,7 +14,7 @@ using namespace Core; StoryBoardSourceEdit::StoryBoardSourceEdit(FileExtensionFactory *factory) : words_highlighter(new KeywordsHightlighter(this)), factory_ins(factory) { - words_highlighter->setDocument(this->edit_square->document()); + this->resetHighlighter(words_highlighter); edit_square->setContextMenuPolicy(Qt::CustomContextMenu); connect(edit_square, &QTextEdit::customContextMenuRequested, [this](const QPoint &pos){ @@ -94,7 +94,7 @@ void StoryBoardSourceEdit::rehighlighter() this->words_highlighter->rehighlight(); } -FileExtension *StoryBoardSourceEditFactory::newInstance(Core::AppCore *core) +Extension *StoryBoardSourceEditFactory::newInstance(Core::AppCore *core) { return new StoryBoardSourceEdit(this); } diff --git a/WordsIDE/storyboardsourceedit.h b/WordsIDE/storyboardsourceedit.h index 2162b84..94df91c 100644 --- a/WordsIDE/storyboardsourceedit.h +++ b/WordsIDE/storyboardsourceedit.h @@ -11,7 +11,7 @@ namespace Components { // PluginFactory interface public: - virtual Core::FileExtension *newInstance(Core::AppCore *core) override; + virtual Core::Extension *newInstance(Core::AppCore *core) override; virtual QList configs() const override; virtual QWidget *getNewPanel(Config::Configration *config) override; virtual QString extensionName() const override; diff --git a/WordsIDE/storyboardspresent.cpp b/WordsIDE/storyboardspresent.cpp new file mode 100644 index 0000000..4d1e7e1 --- /dev/null +++ b/WordsIDE/storyboardspresent.cpp @@ -0,0 +1,56 @@ +#include "storyboardspresent.h" + +#include +#include + +using namespace Components; +using namespace Parse::Result; + +StoryBoardsPresent::StoryBoardsPresent(Core::AppCore *core, QWidget *parent) + : QWidget(parent), core_ins(core), + tree_view(new QTreeView(this)), details_view(new QTextEdit(this)), + model_base(new QStandardItemModel(this)) +{ + tree_view->setModel(model_base); + auto layout = new QVBoxLayout(this); + layout->setMargin(0); + + auto splitter= new QSplitter(Qt::Vertical, this); + layout->addWidget(splitter); + + splitter->addWidget(tree_view); + splitter->addWidget(details_view); + details_view->setReadOnly(true); + + connect(tree_view, &QTreeView::expanded, [this](){ + tree_view->resizeColumnToContents(0); + tree_view->resizeColumnToContents(1); + }); +} + +void StoryBoardsPresent::refresh() +{ + model_base->clear(); + model_base->setHorizontalHeaderLabels(QStringList() << "名称" << "单元"); + auto storys = core_ins->parseCore()->allStoryBoards(); + + for(auto &b : storys){ + auto item = new QStandardItem(static_cast(b)->name()[0]); + item->setEditable(false); + model_base->appendRow(item); + + auto refers = b->children(); + for(auto &ref : refers){ + if(ref->typeValue() != NODE_FRAGMENTREFERENCE) + continue; + + QList row; + row << new QStandardItem("@"+static_cast(ref)->name()[0]); + row.last()->setEditable(false); + row << new QStandardItem(static_cast(ref)->name()[1]); + row.last()->setEditable(false); + + item->appendRow(row); + } + } +} diff --git a/WordsIDE/storyboardspresent.h b/WordsIDE/storyboardspresent.h new file mode 100644 index 0000000..18361d9 --- /dev/null +++ b/WordsIDE/storyboardspresent.h @@ -0,0 +1,31 @@ +#ifndef STORYBOARDSPRESENT_H +#define STORYBOARDSPRESENT_H + +#include "appcore.h" + +#include +#include +#include + +namespace Components { + + class StoryBoardsPresent : public QWidget + { + public: + StoryBoardsPresent(Core::AppCore *core, QWidget *parent=nullptr); + + void refresh(); + + private: + Core::AppCore *const core_ins; + QTreeView *const tree_view; + QTextEdit *const details_view; + QStandardItemModel *const model_base; + + void show_current_details(const QModelIndex &idx); + void click_to(const QModelIndex &idx); + }; +} + + +#endif // STORYBOARDSPRESENT_H diff --git a/WordsIDE/storychainsourceeditor.cpp b/WordsIDE/storychainsourceeditor.cpp index a932907..758dccd 100644 --- a/WordsIDE/storychainsourceeditor.cpp +++ b/WordsIDE/storychainsourceeditor.cpp @@ -119,7 +119,7 @@ namespace __temp { } StoryChainSourceEditFactory::StoryChainSourceEditFactory(){} -Core::FileExtension *Components::StoryChainSourceEditFactory::newInstance(Core::AppCore *core) +Core::Extension *Components::StoryChainSourceEditFactory::newInstance(Core::AppCore *core) { return new StoryChainSourceEdit(this); } diff --git a/WordsIDE/storychainsourceeditor.h b/WordsIDE/storychainsourceeditor.h index 5cb9e50..c232e36 100644 --- a/WordsIDE/storychainsourceeditor.h +++ b/WordsIDE/storychainsourceeditor.h @@ -18,7 +18,7 @@ namespace Components { // PluginFactory interface public: - virtual Core::FileExtension *newInstance(Core::AppCore *core) override; + virtual Core::Extension *newInstance(Core::AppCore *core) override; virtual QList configs() const override; virtual QWidget *getNewPanel(Config::Configration *config) override; virtual QString extensionName() const override; diff --git a/WordsIDE/storychainspresent.cpp b/WordsIDE/storychainspresent.cpp index 4c30d03..76385bc 100644 --- a/WordsIDE/storychainspresent.cpp +++ b/WordsIDE/storychainspresent.cpp @@ -32,14 +32,14 @@ void StoryChainsPresent::refresh() model_base->clear(); auto list = core_ins->parseCore()->allStoryChains(); for(auto &chain : list){ - auto chain_node = new QStandardItem(static_cast(chain)->name()); + auto chain_node = new QStandardItem(static_cast(chain)->name()[0]); chain_node->setEditable(false); model_base->appendRow(chain_node); auto children = chain->children(); for(auto &point : children){ if(point->typeValue() == NODE_STORYPOINT){ - auto point_node = new QStandardItem(static_cast(point)->name()); + auto point_node = new QStandardItem(static_cast(point)->name()[0]); point_node->setEditable(false); chain_node->appendRow(point_node); } diff --git a/WordsIDE/storyunitsourceedit.cpp b/WordsIDE/storyunitsourceedit.cpp index 2fd30fd..ff47a9b 100644 --- a/WordsIDE/storyunitsourceedit.cpp +++ b/WordsIDE/storyunitsourceedit.cpp @@ -109,7 +109,7 @@ void StoryUnitSourceEdit::jumpTo(const QList &path) edit_square->setFocus(); } -FileExtension *StoryUnitSourceEditFactory::newInstance(Core::AppCore *core) +Extension *StoryUnitSourceEditFactory::newInstance(Core::AppCore *core) { return new StoryUnitSourceEdit(this); } diff --git a/WordsIDE/storyunitsourceedit.h b/WordsIDE/storyunitsourceedit.h index 18412e3..b6ff4f7 100644 --- a/WordsIDE/storyunitsourceedit.h +++ b/WordsIDE/storyunitsourceedit.h @@ -10,7 +10,7 @@ namespace Components { // PluginFactory interface public: - virtual Core::FileExtension *newInstance(Core::AppCore *core) override; + virtual Core::Extension *newInstance(Core::AppCore *core) override; virtual QList configs() const override; virtual QWidget *getNewPanel(Config::Configration *config) override; virtual QString extensionName() const override; diff --git a/WordsIDE/storyunitspresent.cpp b/WordsIDE/storyunitspresent.cpp index 1e57c68..fb0726b 100644 --- a/WordsIDE/storyunitspresent.cpp +++ b/WordsIDE/storyunitspresent.cpp @@ -36,14 +36,14 @@ void StoryUnitsPresent::refresh() model_ins->clear(); auto units = core_ins->parseCore()->allStoryUnits(); for(auto &unit : units){ - auto unit_node = new QStandardItem(static_cast(unit)->name()); + auto unit_node = new QStandardItem(static_cast(unit)->name()[0]); unit_node->setEditable(false); model_ins->appendRow(unit_node); auto children = unit->children(); for(auto &frag : children){ if(frag->typeValue() == NODE_STORYFRAGMENT){ - auto frag_node = new QStandardItem(static_cast(frag)->name()); + auto frag_node = new QStandardItem(static_cast(frag)->name()[0]); frag_node->setEditable(false); unit_node->appendRow(frag_node); } diff --git a/WordsIDE/storyvolumesourceedit.cpp b/WordsIDE/storyvolumesourceedit.cpp index d82cc26..7cc6067 100644 --- a/WordsIDE/storyvolumesourceedit.cpp +++ b/WordsIDE/storyvolumesourceedit.cpp @@ -84,7 +84,7 @@ void StoryVolumeSourceEdit::jumpTo(const QList &path) } -FileExtension *StoryVolumeSourceEditFactory::newInstance(Core::AppCore *core) +Extension *StoryVolumeSourceEditFactory::newInstance(Core::AppCore *core) { return new StoryVolumeSourceEdit(this); } diff --git a/WordsIDE/storyvolumesourceedit.h b/WordsIDE/storyvolumesourceedit.h index f683bb5..07a3212 100644 --- a/WordsIDE/storyvolumesourceedit.h +++ b/WordsIDE/storyvolumesourceedit.h @@ -11,7 +11,7 @@ namespace Components { // PluginFactory interface public: - virtual Core::FileExtension *newInstance(Core::AppCore *core) override; + virtual Core::Extension *newInstance(Core::AppCore *core) override; virtual QList configs() const override; virtual QWidget *getNewPanel(Config::Configration *config) override; virtual QString extensionName() const override; diff --git a/libParse/ComnDef.h b/libParse/ComnDef.h index 4387044..e2da4c8 100644 --- a/libParse/ComnDef.h +++ b/libParse/ComnDef.h @@ -20,9 +20,14 @@ #define NODE_STORYDEPICTION 11 // 卷宗叙述节点 +#define NODE_STORYCONCEPT 20 // 故事概念 +#define NODE_STORYSTRONGPOINT 21 // 故事要点 + + #define DOC_STORYBOARD 0xa0001 // 故事板 #define DOC_STORYUNIT 0xa0002 // 故事单元 #define DOC_STORYCHAIN 0xa0003 // 故事脉络 #define DOC_VOLUMEOUTLINE 0xa0004 // 卷宗大纲 +#define DOC_STORYCONCEPT 0xa0005 // 故事概念 diff --git a/libParse/ParseFrame.cpp b/libParse/ParseFrame.cpp index 9ee33d8..d2df423 100644 --- a/libParse/ParseFrame.cpp +++ b/libParse/ParseFrame.cpp @@ -11,7 +11,8 @@ ParseFrame::ParseFrame() {} QList ParseFrame::analysis(DocCore*doc, const QString & path) { ExStream stream; - if (stream.initSource(path)) + auto val = stream.initSource(path); + if (val) return QList(); LexFoundation token_s(this->token_seqs, this->unknown_token); diff --git a/libParse/StoryBoardDocumentParser.cpp b/libParse/StoryBoardDocumentParser.cpp index b49346f..50e0ee4 100644 --- a/libParse/StoryBoardDocumentParser.cpp +++ b/libParse/StoryBoardDocumentParser.cpp @@ -23,12 +23,12 @@ QString NodeStoryBoard::index() const bool NodeStoryBoard::check(QList &reasons) const { - auto nodes = doc()->core()->queryStoryBoard(name()); + auto nodes = doc()->core()->queryStoryBoard(name()[0]); if(nodes.size() > 1){ ErrorMessage ins; ins.Reason = "重复定义大纲"; - ins.Text = name(); + ins.Text = name()[0]; ins.FilePath = doc()->filePath(); ins.CodeRow = refered().first()->row(); ins.CodeCol = refered().first()->column(); @@ -40,7 +40,7 @@ bool NodeStoryBoard::check(QList &reasons) const QString NodeStoryBoard::toString() const { - QString des = "#故事 "+name() + " " + index() +" {"; + QString des = "#故事 "+name()[0] + " " + index() +" {"; for(auto n : children()) des += "\n" + n->toString(); des += "\n}"; @@ -49,7 +49,7 @@ QString NodeStoryBoard::toString() const } NodeStoryFragmentRefer::NodeStoryFragmentRefer(NodeStoryBoard * const parent_node, const QString &name) - : Result::NamedNode(name, parent_node->doc(), NODE_STORYFRAGMENT, parent_node) { } + : Result::NamedNode(name, parent_node->doc(), NODE_FRAGMENTREFERENCE, parent_node) { fragment_name = name; } void NodeStoryFragmentRefer::setUnit(const QString &name){ this->unit_name_store = name; @@ -73,11 +73,11 @@ bool NodeStoryFragmentRefer::check(QList &reasons) const return false; } - auto fragment = doc()->core()->queryStoryFragment(unitx[0], name()); + auto fragment = doc()->core()->queryStoryFragment(unitx[0], name()[0]); if(!fragment.size()){ ErrorMessage ins; ins.Reason = "指定的情节不存在"; - ins.Text = unit() + ":" + name(); + ins.Text = unit() + ":" + name()[0]; ins.FilePath = doc()->filePath(); ins.CodeRow = refered().first()->row(); ins.CodeCol = refered().first()->column(); @@ -89,13 +89,18 @@ bool NodeStoryFragmentRefer::check(QList &reasons) const QString NodeStoryFragmentRefer::toString() const { - QString des = QString(depth(), ' ') + "@情节 " + name() + " " + unit() + " {"; + QString des = QString(depth(), ' ') + "@情节 " + name()[0] + " " + unit() + " {"; for(auto &c : children()) des += "\n" + QString(depth(), ' ') + c->toString(); return des + "\n"+QString(depth(), ' ') + "}"; } +QList NodeStoryFragmentRefer::name() const +{ + return QList() << fragment_name << unit_name_store; +} + NodeStoryBoardParser::NodeStoryBoardParser(Result::ParseCore *core) :Syntax::XSyntaxBase("情节引用"), project_ins(core) { diff --git a/libParse/StoryBoardDocumentParser.h b/libParse/StoryBoardDocumentParser.h index dd7806a..646ab04 100644 --- a/libParse/StoryBoardDocumentParser.h +++ b/libParse/StoryBoardDocumentParser.h @@ -63,7 +63,10 @@ namespace Parse { virtual bool check(QList &reasons) const override; virtual QString toString() const override; + virtual QList name() const override; + private: + QString fragment_name; QString unit_name_store; }; diff --git a/libParse/StoryChainDocumentParser.cpp b/libParse/StoryChainDocumentParser.cpp index af1ef70..7d27ee1 100644 --- a/libParse/StoryChainDocumentParser.cpp +++ b/libParse/StoryChainDocumentParser.cpp @@ -153,11 +153,11 @@ QString NodeStoryChain::srcPath() const bool NodeStoryChain::check(QList &reasons) const { - auto nodes = doc()->core()->queryStoryChain(name()); + auto nodes = doc()->core()->queryStoryChain(name()[0]); if(nodes.size() > 1){ ErrorMessage ins; ins.Reason = "重复定义脉络"; - ins.Text = name(); + ins.Text = name()[0]; ins.FilePath = doc()->filePath(); ins.CodeRow = refered().first()->row(); ins.CodeCol = refered().first()->column(); @@ -169,7 +169,7 @@ bool NodeStoryChain::check(QList &reasons) const QString NodeStoryChain::toString() const { - auto desc_string = QString(depth(), ' ') + "#脉络 " + name() + " {"; + auto desc_string = QString(depth(), ' ') + "#脉络 " + name()[0] + " {"; for (auto it : children()) desc_string += "\n"+ QString(depth(), ' ') + it->toString(); desc_string +="\n"+ QString(depth(), ' ') + "}"; @@ -178,7 +178,7 @@ QString NodeStoryChain::toString() const } NodeStoryPoint::NodeStoryPoint(NodeStoryChain * chain, const QString & name) - : Result::NamedNode(name, chain->doc(), NODE_STORYPOINT, chain){} + : Result::NamedNode(name, chain->doc(), NODE_STORYPOINT, chain){ store_name = name; } NodeStoryChain * NodeStoryPoint::storyChain() const { @@ -188,11 +188,11 @@ NodeStoryChain * NodeStoryPoint::storyChain() const bool NodeStoryPoint::check(QList &reasons) const { auto chain = parent(); - auto nodes = chain->doc()->core()->queryStoryPoint(chain, name()); + auto nodes = chain->doc()->core()->queryStoryPoint(chain, name()[0]); if(nodes.size() > 1){ ErrorMessage ins; ins.Reason = "重复定义脉络节点"; - ins.Text = static_cast(chain)->name() +":"+ name(); + ins.Text = static_cast(chain)->name()[0] +":"+ name()[0]; ins.FilePath = doc()->filePath(); ins.CodeRow = refered().first()->row(); ins.CodeCol = refered().first()->column(); @@ -205,12 +205,17 @@ bool NodeStoryPoint::check(QList &reasons) const QString NodeStoryPoint::toString() const { QString desc_string = ""; - desc_string += QString(depth(), ' ') + "#节点 " + name() + " {"; + desc_string += QString(depth(), ' ') + "#节点 " + name()[0] + " {"; for (auto it : children()) desc_string += "\n" + QString(depth(), ' ') + it->toString(); desc_string += "\n"+QString(depth(), ' ') + "}"; - return desc_string; + return desc_string; +} + +QList NodeStoryPoint::name() const +{ + return QList() << store_name << static_cast(parent())->name()[0]; } NodeStoryDesGroup::NodeStoryDesGroup(DesNode * parent_refer) @@ -285,7 +290,7 @@ StoryChainDocumentParser::StoryChainDocumentParser(ParseCore * pjt) {"{左界限}","\\{"}, {"{右界限}","\\}"}, {"{换行符}","\\n"}, - {"{引用符}", "@"}, +// {"{引用符}", "@"}, }, "{无法识别}"); auto chain_parser = new NodeStoryChainParser(pjt); diff --git a/libParse/StoryChainDocumentParser.h b/libParse/StoryChainDocumentParser.h index 8e45b61..c712ccf 100644 --- a/libParse/StoryChainDocumentParser.h +++ b/libParse/StoryChainDocumentParser.h @@ -75,6 +75,11 @@ namespace Parse // 通过 NamedNode 继承 virtual bool check(QList& reasons) const override; virtual QString toString() const override; + + virtual QList name() const; + + private: + QString store_name; }; /** diff --git a/libParse/StoryOutlineDocumentParser.cpp b/libParse/StoryOutlineDocumentParser.cpp index 14ad706..635240b 100644 --- a/libParse/StoryOutlineDocumentParser.cpp +++ b/libParse/StoryOutlineDocumentParser.cpp @@ -77,11 +77,11 @@ NodeStoryDepiction::NodeStoryDepiction(Result::DocCore *doc, const QString &name bool NodeStoryDepiction::check(QList &reasons) const { - auto nodes = doc()->core()->queryStoryDepiction(name()); + auto nodes = doc()->core()->queryStoryDepiction(name()[0]); if(nodes.size() > 1){ ErrorMessage ins; ins.Reason = "重复定义叙述"; - ins.Text = name(); + ins.Text = name()[0]; ins.FilePath = doc()->filePath(); ins.CodeRow = refered().first()->row(); ins.CodeCol = refered().first()->column(); @@ -92,7 +92,7 @@ bool NodeStoryDepiction::check(QList &reasons) const QString NodeStoryDepiction::toString() const { - QString des = "#叙述 " + name() + " {"; + QString des = "#叙述 " + name()[0] + " {"; for(auto &c : children()){ des += "\n" + c->toString(); } diff --git a/libParse/StoryTool.cpp b/libParse/StoryTool.cpp index aebabbe..7120e85 100644 --- a/libParse/StoryTool.cpp +++ b/libParse/StoryTool.cpp @@ -2,6 +2,7 @@ #include "StoryChainDocumentParser.h" #include "StoryOutlineDocumentParser.h" #include "StoryTool.h" +#include "storyconceptdocumentparser.h" #include @@ -47,6 +48,12 @@ QList StoryTool::compile(const QFileInfo &file, const QString &doc_name StoryOutlineDocumentParser parser(parse_core); results.append(parser.analysis(doc_core, file.absoluteFilePath())); } + else if(file.suffix() == "storyconcept"){ + if(!doc_core) + doc_core = new DocCore(parse_core, DocType::STORYCONCEPTS, file.absoluteFilePath(), doc_name); + StoryConceptDocumentParser parser(parse_core); + results.append(parser.analysis(doc_core, file.absoluteFilePath())); + } if(doc_core){ parse_core->registerDoc(doc_core); @@ -91,6 +98,12 @@ QList StoryTool::compileSource(const QFileInfo &_file, const QString &s StoryOutlineDocumentParser parser(parse_core); results.append(parser.analysisSource(doc_core, src)); } + else if(_file.suffix() == "storyconcept"){ + if(!doc_core) + doc_core = new DocCore(parse_core, DocType::STORYCONCEPTS, _file.absoluteFilePath(), doc_name); + StoryConceptDocumentParser parser(parse_core); + results.append(parser.analysisSource(doc_core, src)); + } if(doc_core){ parse_core->registerDoc(doc_core); diff --git a/libParse/StoryUnitDocumentParser.cpp b/libParse/StoryUnitDocumentParser.cpp index 366f924..1ecf07b 100644 --- a/libParse/StoryUnitDocumentParser.cpp +++ b/libParse/StoryUnitDocumentParser.cpp @@ -11,12 +11,12 @@ NodeStoryUnit::NodeStoryUnit(DocCore * doc, const QString & name) bool NodeStoryUnit::check(QList &reasons) const { - auto unit_nodes = doc()->core()->queryStoryUnit(name()); + auto unit_nodes = doc()->core()->queryStoryUnit(name()[0]); if(unit_nodes.size() > 1){ ErrorMessage ins; ins.Reason = "重复定义单元"; - ins.Text = name(); + ins.Text = name()[0]; ins.FilePath = doc()->filePath(); ins.CodeRow = refered().first()->row(); ins.CodeCol = refered().first()->column(); @@ -27,7 +27,7 @@ bool NodeStoryUnit::check(QList &reasons) const QString NodeStoryUnit::toString() const { - QString rets = "#单元 " + name() + "{"; + QString rets = "#单元 " + name()[0] + "{"; for (auto &it : children()) rets += "\n" + it->toString(); rets += "\n}"; @@ -36,15 +36,15 @@ QString NodeStoryUnit::toString() const NodeStoryFragment::NodeStoryFragment(NodeStoryUnit * unit, const QString & name) - : Result::NamedNode(name, unit->doc(), NODE_STORYFRAGMENT, unit){} + : Result::NamedNode(name, unit->doc(), NODE_STORYFRAGMENT, unit){ store_name = name; } bool NodeStoryFragment::check(QList &reasons) const { - auto nodes = doc()->core()->queryStoryFragment(parent(), name()); + auto nodes = doc()->core()->queryStoryFragment(parent(), name()[0]); if(nodes.size() > 1){ ErrorMessage ins; ins.Reason = "重复定义情节"; - ins.Text = name(); + ins.Text = name()[0]; ins.FilePath = doc()->filePath(); ins.CodeRow = refered().first()->row(); ins.CodeCol = refered().first()->column(); @@ -56,12 +56,19 @@ bool NodeStoryFragment::check(QList &reasons) const QString NodeStoryFragment::toString() const { - QString rets = QString(depth(), ' ') + "#情节 " + name() + "{"; + QString rets = QString(depth(), ' ') + "#情节 " + name()[0] + "{"; for (auto cin : children()) rets += "\n" + QString(depth(), ' ') + cin->toString(); return rets + "\n"+QString(depth(), ' ') + "}"; } +QList NodeStoryFragment::name() const +{ + return QList() + << store_name + << static_cast(parent())->name()[0]; +} + NodeStoryPointRefer::NodeStoryPointRefer(DesNode * parent, const QString & chain, const QString & point) : Result::DesNode(parent->doc(), NODE_POINTREFERENCE, parent), diff --git a/libParse/StoryUnitDocumentParser.h b/libParse/StoryUnitDocumentParser.h index c3c0421..12d3003 100644 --- a/libParse/StoryUnitDocumentParser.h +++ b/libParse/StoryUnitDocumentParser.h @@ -43,6 +43,11 @@ namespace Parse { // 通过 NamedNode 继承 virtual bool check(QList& reasons) const override; virtual QString toString() const override; + + virtual QList name() const override; + + private: + QString store_name; }; /** diff --git a/libParse/libParse.cpp b/libParse/libParse.cpp index cfcebf6..9d4ad53 100644 --- a/libParse/libParse.cpp +++ b/libParse/libParse.cpp @@ -32,9 +32,9 @@ namespace Parse { NamedNode::NamedNode(const QString &name, DocCore *core, int type, DesNode *pnode) : Result::DesNode(core, type, pnode), name_store(name){} -QString NamedNode::name() const +QList NamedNode::name() const { - return name_store; + return QList() << name_store; } DesNode::DesNode(DocCore *core, int type_value, DesNode *pnode) @@ -178,7 +178,7 @@ QList ParseCore::queryStoryChain(const QString &name) const QList retlist; for(auto &xnode : allStoryChains()) - if(static_cast(xnode)->name() == name) + if(static_cast(xnode)->name()[0] == name) retlist << xnode; return retlist; @@ -189,7 +189,7 @@ QList ParseCore::queryStoryPoint(DesNode *chain, const QString QList retlist; for(auto &n : chain->children()) if(n->typeValue() == NODE_STORYPOINT && - static_cast(n)->name() == name) + static_cast(n)->name()[0] == name) retlist << n; return retlist; @@ -214,7 +214,7 @@ QList ParseCore::queryStoryUnit(const QString &name) const QList retlist; for(auto &k : allStoryUnits()) - if(static_cast(k)->name() == name) + if(static_cast(k)->name()[0] == name) retlist << k; return retlist; @@ -225,12 +225,12 @@ QList ParseCore::queryStoryFragment(DesNode *unit, const QStri QList retlist; for(auto &n : unit->children()) if(n->typeValue() == NODE_STORYFRAGMENT && - static_cast(n)->name() == name) + static_cast(n)->name()[0] == name) retlist << n; return retlist; } -QList ParseCore::queryStoryBoard(const QString &name) const +QList ParseCore::allStoryBoards() const { QList retlist; @@ -238,14 +238,71 @@ QList ParseCore::queryStoryBoard(const QString &name) const for(auto &k : keys) if(k->docType() == DocType::STORYBOARD) for(auto &n : *nodes_map[k]){ - if(n->typeValue() == NODE_STORYBOARD && - static_cast(n)->name() == name) + if(n->typeValue() == NODE_STORYBOARD) retlist << n; } return retlist; } +QList ParseCore::queryStoryBoard(const QString &name) const +{ + QList retlist; + + for(auto &it : allStoryBoards()) + if(static_cast(it)->name()[0] == name) + retlist << it; + + return retlist; +} + +QList ParseCore::queryStoryFragmentRefer(DesNode *unit, const QString &name) const +{ + QList retlist; + for(auto &it : unit->children()){ + if(it->typeValue() == NODE_FRAGMENTREFERENCE && static_cast(it)->name()[0] == name) + retlist << it; + } + + return retlist; +} + +QList ParseCore::allStoryConcept() const +{ + QList rets; + for(auto &it : nodes_map.keys()){ + if(it->docType() == DocType::STORYCONCEPTS) + for(auto n : *nodes_map[it]) + if(n->typeValue() == NODE_STORYCONCEPT) + rets << n; + } + + return rets; +} + +QList ParseCore::queryStoryConcept(const QString &name) const +{ + QList rets; + for(auto &it : allStoryConcept()){ + if(static_cast(it)->name()[0] == name) + rets << it; + } + + return rets; +} + +QList ParseCore::queryStoryStrongPoint(DesNode *concept, const QString &name) const +{ + QList rets; + for(auto &it : concept->children()){ + if(it->typeValue() == NODE_STORYSTRONGPOINT && + static_cast(it)->name()[0] == name) + rets << it; + } + + return rets; +} + QList ParseCore::queryStoryDepiction(const QString &name) const { QList retlist; @@ -253,7 +310,7 @@ QList ParseCore::queryStoryDepiction(const QString &name) const if(it->docType() == DocType::STORYOUTLINES) for(auto &n : *nodes_map[it]) if(n->typeValue() == NODE_STORYDEPICTION && - static_cast(n)->name() == name) + static_cast(n)->name()[0] == name) retlist << n; } diff --git a/libParse/libParse.h b/libParse/libParse.h index d2c0a4a..5daf54c 100644 --- a/libParse/libParse.h +++ b/libParse/libParse.h @@ -30,7 +30,8 @@ namespace Parse STORYBOARD = DOC_STORYBOARD, STORYUNIT = DOC_STORYUNIT, STORYCHAIN = DOC_STORYCHAIN, - STORYOUTLINES = DOC_VOLUMEOUTLINE + STORYOUTLINES = DOC_VOLUMEOUTLINE, + STORYCONCEPTS = DOC_STORYCONCEPT }; /** @@ -194,7 +195,7 @@ namespace Parse * * \return 名称字符串 */ - QString name() const; + virtual QList name() const; private: QString name_store; @@ -314,7 +315,13 @@ namespace Parse virtual QList queryStoryUnit(const QString &name) const; virtual QList queryStoryFragment(Result::DesNode *unit, const QString &name) const; + virtual QList allStoryBoards() const; virtual QList queryStoryBoard(const QString &name) const; + virtual QList queryStoryFragmentRefer(Result::DesNode *unit, const QString &name) const; + + virtual QList allStoryConcept() const; + virtual QList queryStoryConcept(const QString &name) const; + virtual QList queryStoryStrongPoint(Result::DesNode *concept, const QString &name) const; /** * @brief 获取卷宗大纲叙述节点 diff --git a/libParse/libParse.pro b/libParse/libParse.pro index 5e66ce3..2c3e169 100644 --- a/libParse/libParse.pro +++ b/libParse/libParse.pro @@ -19,7 +19,8 @@ SOURCES += \ StoryUnitDocumentParser.cpp \ WordsPeak.cpp \ XSyntaxBase.cpp \ - libParse.cpp + libParse.cpp \ + storyconceptdocumentparser.cpp HEADERS += \ ComnDef.h \ @@ -34,7 +35,8 @@ HEADERS += \ WordsPeak.h \ XSyntaxBase.h \ libParse.h \ - libParse_global.h + libParse_global.h \ + storyconceptdocumentparser.h TRANSLATIONS += \ libParse_zh_CN.ts diff --git a/libParse/storyconceptdocumentparser.cpp b/libParse/storyconceptdocumentparser.cpp new file mode 100644 index 0000000..b46e2b0 --- /dev/null +++ b/libParse/storyconceptdocumentparser.cpp @@ -0,0 +1,193 @@ +#include "StoryChainDocumentParser.h" +#include "storyconceptdocumentparser.h" + +using namespace Parse; +using namespace Parse::Result; +using namespace Syntax; +using namespace Syntax::Defines; +using namespace Lex; + +StoryConceptDocumentParser::StoryConceptDocumentParser(ParseCore *core) +{ + appendTokensDefine({ + {"{概念定义}","#概念"}, + {"{要点定义}", "#要点"}, + {"{描述文本}", "[^#@\\{\\}\\n]+"}, + {"{左界限}","\\{"}, + {"{右界限}","\\}"}, + {"{换行符}","\\n"} + }, "{无法识别}"); + + auto chain_parser = new NodeStoryConceptParser(core); + appendParser(chain_parser); +} + +Parse::NodeStoryConcept::NodeStoryConcept(const QString &name, DocCore *doc) + : Result::NamedNode(name, doc, NODE_STORYCONCEPT, nullptr) +{ + +} + +bool NodeStoryConcept::check(QList &reasons) const +{ +return true; +} + +QString NodeStoryConcept::toString() const +{ + QString string = ""; + string += "#概念 "+name()[0] + " {"; + for(auto &c : children()) + string += "\n" + QString(depth(), ' ') + c->toString(); + string +="\n" + QString(depth(),' ') + "}"; + + return string; +} + +NodeStoryStrongPoint::NodeStoryStrongPoint(NodeStoryConcept *parent, const QString &name) + : Result::NamedNode(name, parent->doc(), NODE_STORYSTRONGPOINT, parent), + concept_point(parent) +{ + +} + +bool NodeStoryStrongPoint::check(QList &reasons) const +{ + return true; +} + +QString NodeStoryStrongPoint::toString() const +{ + QString string = "#要点 " + name()[0] + " {"; + for(auto &c : children()) + string += "\n" + QString(depth(), ' ') + c->toString(); + string += "\n" + QString(depth(),' ') + "}"; + return string; +} + +QList NodeStoryStrongPoint::name() const +{ + QList rets; + rets << NamedNode::name()[0] << concept_point->name()[0]; + return rets; +} + +NodeStoryConceptParser::NodeStoryConceptParser(Result::ParseCore *core) + : Syntax::XSyntaxBase("概念解析"), core(core) +{ + set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)}); + + auto rule = addRule("进入概念解析", 0, [this](const QList &seqs, int cnt)->ParseResult + { + auto nmunit = seqs[cnt-1]; + auto defunit = seqs[cnt-2]; + auto node = new NodeStoryConcept(nmunit.Text, docRef()); + refocusNode(node); + + auto word1 = new Words(node, docRef(), defunit.Text, defunit.StartRow, defunit.StartCol); + auto word0 = new Words(node, docRef(), nmunit.Text, nmunit.StartRow, nmunit.StartCol); + docRef()->append(word1); + docRef()->append(word0); + + return ParseResult::SelfManipulate; + }); + rule->addExpression("基础概念定义", {Elm("{概念定义}"), Elm("{描述文本}", true)}); + rule->addExpression("拓展概念定义", {Exp("::换行前缀"), Exp("基础概念定义", true)}); + + rule = addRule("进入成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult { + auto node = currNode(); + + auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); + docRef()->append(word); + + return ParseResult::EnterNext; + }); + rule->addExpression("基础成分解析", { Elm("{左界限}", true) }); + rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) }); + + rule = addRule("跳出成分解析", 2, [this](const QList &seqs, int cnt)->ParseResult { + auto node = currNode(); + + auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); + docRef()->append(word); + + return ParseResult::Completed; + }); + rule->addExpression("基础跳出解析", { Elm("{右界限}", true) }); + rule->addExpression("拓展跳出解析", { Exp("::换行前缀"), Exp("基础跳出解析", true) }); + + addChild(QList() << new NodeStoryPureTextDesGroupParser(this) + << new NodeStoryStrongPointParser(this)); +} + + + + +NodeStoryStrongPointParser::NodeStoryStrongPointParser(NodeStoryConceptParser *pparser) + : Syntax::XSyntaxBase("要点解析") +{ + set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)}); + + auto rule = addRule("进入要点解析", 0, [this, pparser](const QList &seqs, int cnt)->ParseResult + { + auto nmunit = seqs[cnt-1]; + auto defunit = seqs[cnt-2]; + auto node = new NodeStoryStrongPoint(static_cast(pparser->currNode()), nmunit.Text); + refocusNode(node); + pparser->currNode()->appendChild(node); + + auto word1 = new Words(node, docRef(), defunit.Text, defunit.StartRow, defunit.StartCol); + auto word0 = new Words(node, docRef(), nmunit.Text, nmunit.StartRow, nmunit.StartCol); + docRef()->append(word1); + docRef()->append(word0); + + return ParseResult::SelfManipulate; + }); + rule->addExpression("基础要点定义", {Elm("{要点定义}"), Elm("{描述文本}", true)}); + rule->addExpression("拓展要点定义", {Exp("::换行前缀"), Exp("基础要点定义", true)}); + + rule = addRule("进入成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult { + auto node = currNode(); + + auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); + docRef()->append(word); + + return ParseResult::EnterNext; + }); + rule->addExpression("基础成分解析", { Elm("{左界限}", true) }); + rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) }); + + rule = addRule("跳出成分解析", 2, [this](const QList &seqs, int cnt)->ParseResult { + auto node = currNode(); + + auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); + docRef()->append(word); + + return ParseResult::Completed; + }); + rule->addExpression("基础跳出解析", { Elm("{右界限}", true) }); + rule->addExpression("拓展跳出解析", { Exp("::换行前缀"), Exp("基础跳出解析", true) }); + + addChild(QList() << new NodeStoryPureTextDesGroupParser(this)); +} + + + + + + + + + + + + + + + + + + + + + diff --git a/libParse/storyconceptdocumentparser.h b/libParse/storyconceptdocumentparser.h new file mode 100644 index 0000000..2f71678 --- /dev/null +++ b/libParse/storyconceptdocumentparser.h @@ -0,0 +1,81 @@ +#ifndef STORYCONCEPTDOCUMENTPARSER_H +#define STORYCONCEPTDOCUMENTPARSER_H + +#include "ParseFrame.h" +#include "SyntaxBase.h" +#include "XSyntaxBase.h" + +namespace Parse { + + class NodeStoryConcept : public Result::NamedNode + { + public: + NodeStoryConcept(const QString &name, Result::DocCore *doc); + + // DesNode interface + public: + virtual bool check(QList &reasons) const override; + virtual QString toString() const override; + }; + + class NodeStoryConceptParser : public Syntax::XSyntaxBase + { + public: + NodeStoryConceptParser(Result::ParseCore *core); + + private: + Result::ParseCore *const core; + }; + + + class NodeStoryStrongPoint : public Result::NamedNode + { + public: + NodeStoryStrongPoint(NodeStoryConcept *parent, const QString &name); + + // DesNode interface + public: + virtual bool check(QList &reasons) const override; + virtual QString toString() const override; + + // NamedNode interface + public: + virtual QList name() const override; + + private: + NodeStoryConcept *const concept_point; + }; + + + class NodeStoryStrongPointParser : public Syntax::XSyntaxBase + { + public: + NodeStoryStrongPointParser(NodeStoryConceptParser *pparser); + + }; + + + + class StoryConceptDocumentParser : public Syntax::ParseFrame + { + public: + StoryConceptDocumentParser(Result::ParseCore *core); + }; + +} + + + + + + + + + + + + + + + +#endif // STORYCONCEPTDOCUMENTPARSER_H