#pragma once #include #include #include #include #include #include #include #include namespace xast_parse { enum class SliceType { StoryDefines, // 故事线定义 TextPragraph, // 文字段落 FragmentDefines, // 情节定义 PointRefers, // 情节引用 VolumeDefines, // 卷宗定义 ArticleDefines, // 章节定义 }; /// /// 故事节点切片 /// class IElementSlice { public: virtual SliceType type() const = 0; virtual std::weak_ptr parentSlice() const = 0; virtual QList nameSet() const = 0; virtual void setPrev(std::shared_ptr inst) = 0; virtual std::weak_ptr prevSlice() const = 0; virtual void setNext(std::shared_ptr next) = 0; virtual std::shared_ptr nextSlice() const = 0; virtual uint index() const = 0; }; /// /// 可以包含子节点的故事节点 /// class ICollection { public: virtual std::shared_ptr firstChild() const = 0; virtual void setFirstChild(std::shared_ptr inst) = 0; }; class __SiblingImpl : public IElementSlice, public std::enable_shared_from_this<__SiblingImpl> { private: SliceType t_store; std::weak_ptr parent_store; std::weak_ptr prev_store; std::shared_ptr next_store; public: __SiblingImpl(SliceType t, std::shared_ptr pnode); virtual SliceType type() const; virtual std::weak_ptr parentSlice() const; virtual void setPrev(std::shared_ptr inst); virtual std::weak_ptr prevSlice() const; virtual void setNext(std::shared_ptr next); virtual std::shared_ptr nextSlice() const; virtual uint index() const; }; class __CollectionElement : public __SiblingImpl, public ICollection { private: std::shared_ptr first_head; public: __CollectionElement(SliceType t, std::shared_ptr pnode); // 通过 ICollection 继承 std::shared_ptr firstChild() const override; void setFirstChild(std::shared_ptr inst) override; }; /// /// 连续文本段落 /// class TextParagraph : public __SiblingImpl { private: QStringList lines; public: TextParagraph(std::shared_ptr parent); virtual ~TextParagraph() = default; virtual void setLines(const QString& contents); virtual QString getLines() const; virtual void addLine(const QString& line); // IElementSlice virtual QList nameSet() const override; }; class __DesElement : public __SiblingImpl { private: std::shared_ptr text_store; public: __DesElement(SliceType t, std::shared_ptr pnode); virtual std::shared_ptr getTextNode() const; }; /// /// 故事定义节点 /// class StoryDefine : public __CollectionElement { private: QString name_store, file_path; uint sort_store; public: StoryDefine(const QString& name, uint sort, const QString &path); virtual ~StoryDefine() = default; virtual QString name() const; virtual QString bindPath() const; virtual uint index() const; virtual std::shared_ptr getFragment(const QString& name); // IElementSlice virtual QList nameSet() const override; }; /// /// 情节定义节点 /// class PointDefines : public __DesElement { private: QString name_store; QList> refs_list; public: PointDefines(const QString& name, std::shared_ptr pnode); virtual ~PointDefines() = default; virtual QString name() const; virtual QList> referSlices() const; virtual void appendRefer(std::shared_ptr slice); // IElementSlice virtual QList nameSet() const override; }; /// /// 情节引用节点 /// class FragmentRefer : public __DesElement { private: QString story_refers, fragment_refers; std::weak_ptr refer_targets; public: FragmentRefer(const QString& story, const QString& fragm, std::shared_ptr pnode); virtual ~FragmentRefer() = default; virtual QString storyRefer() const; virtual QString fragmentRefer() const; virtual std::weak_ptr referTarget() const; virtual void setReferTowards(std::shared_ptr target); // IElementSlice virtual QList nameSet() const override; }; /// /// 章节定义节点 /// class ArticleDefine : public __CollectionElement { private: QString name_store; public: ArticleDefine(const QString& name, std::shared_ptr pnode); virtual ~ArticleDefine() = default; virtual QString name() const; // IElementSlice virtual QList nameSet() const override; }; /// /// 卷宗定义节点 /// class VolumeDefine : public __CollectionElement { private: QString name_store, file_path; public: VolumeDefine(const QString &name, const QString &path); virtual ~VolumeDefine() = default; virtual QString name() const; virtual QString bindPath() const; virtual QList getArticleNames() const; virtual std::shared_ptr getArticleWith(const QString& name) const; // IElementSlice virtual QList nameSet() const override; }; class RankDecs { private: QString fpath, rank_v; public: RankDecs(const QString &path, const QString &rank); QString bindPath() const; QString rank() const; }; class XAST_Parser { private: QDomDocument dom_tree; QList> rank_coll; QHash> story_dict; QHash> volume_dict; public: XAST_Parser(const QString& ast_path); QList> rankList() const; QHash> storyGraph() const; QHash> volumeGraph() const; void output(const QDir &dir); private: std::shared_ptr init_story_define(const QDomElement& story_e); uint text_sections_count(const QList& elms); std::shared_ptr text_paragraph_build(std::shared_ptr<__CollectionElement> pnode, QList& elms, uint count); std::shared_ptr fragment_define_build(std::shared_ptr pnode, const QDomElement& e); std::shared_ptr fragment_refer_build(std::shared_ptr<__CollectionElement> pnode, const QDomElement& e); void fragments_plait(QHash> story_map, std::shared_ptr reflist); std::shared_ptr init_volume_define(const QDomElement& volume_e); std::shared_ptr init_article_define(std::shared_ptr pnode, const QDomElement& article_e); void write_rank(std::shared_ptr inst, const QDir &odir); void write_story(std::shared_ptr inst, const QDir &odir); void write_text(int dep, std::shared_ptr inst, QTextStream &out); void write_fragmdef(int dep, std::shared_ptr inst, QTextStream& out); void write_fragmref(int dep, std::shared_ptr inst, QTextStream& out); void write_volume(std::shared_ptr inst, const QDir &odir); void write_article(int dep, std::shared_ptr inst, QTextStream &out); }; }