WsParser_VS/StoryPresent/xast_parse.h

257 lines
7.4 KiB
C++

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