257 lines
7.4 KiB
C++
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 FragmentDefine : public __DesElement {
|
|
private:
|
|
QString name_store;
|
|
QList<std::shared_ptr<IElementSlice>> refs_list;
|
|
|
|
public:
|
|
FragmentDefine(const QString& name, std::shared_ptr<StoryDefine> pnode);
|
|
virtual ~FragmentDefine() = 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<FragmentDefine> 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<FragmentDefine> referTarget() const;
|
|
virtual void setReferTowards(std::shared_ptr<FragmentDefine> 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<FragmentDefine> 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<FragmentDefine> 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);
|
|
};
|
|
}
|