我正在创建一个用于将latex格式论文转换为docx格式论文的中间格式。该中间格式基于XML。我需要你创建@docs/XThesis.xsd 文件，使用XML Schema格式来描述这个中间格式。此外，你还需要创建@docs/XThesis.md 在该文件中，你需要引导用户访问XThesis.xsd文件，并且将一些不能在XSD中进行表述的内容写在此处。

以下是该中间格式的格式要求，请仔细分析各个元素之间的关系后再编写XSD文件，因为我不一定按层级顺序进行叙述。如果有不懂的地方请问我，而不是进行猜测：

XML文档的根元素为article，表示为一个完整的文档。article元素下只允许4种子元素：preface，document，appendix，reference。四个元素必须按顺序出现，且有且只能有一个。

preface，document，appendix元素表示的意图不同。preface表示如摘要等内容，document表示文章的正文，appendix则表示附录，例如致谢，附录代码等。

reference元素的inner text是指向参考文献bib文件的路径。

有9个层级的章节元素，分别为section1，section2到section9。这些元素只能是document的子元素。章节元素具有一个名为caption的attribute，表示该章节的标题。元素的inner xml表示该章节的内容。章节元素的嵌套有规定，只能相邻向下嵌套，即只能section2在section1内，不能section2在section1内，也不能section3在section2内。section1只能是document的子节点。

有专用于preface和appendix的section元素（不带有任何数字后缀的）。它只能是preface和appendix的子节点，不能是document的子节点。section元素具有一个名为caption的attribute，表示该章节的标题。元素的inner xml表示该章节的内容。论文中的摘要，致谢等会被统一规划为这种section元素，不做区分。

有paragraph元素，表示一个自然段。paragraph只能是9种章节元素的子节点，或section的子节点。paragraph元素的inner xml表示当前自然段的内容。

有span元素，表示纯文本。span元素只能是paragraph的子对象。span元素的inner text是纯文本的内容。

有inlineeq元素，表示内联公式。inlineeq元素只能是paragraph的子对象。inlineeq元素的inner text是公式的内容（不包含两侧的$标记等，以latex原始代码呈现）

有b，i元素，分别表示加粗和斜体文本。他们俩之间不能互相嵌套，也就是一个文本要么是加粗，要么是斜体，不能拥有多个样式。他们只能是paragraph的子元素。他们的inner text是需要进行特殊样式处理的文本。

有equation元素，表示行间公式。equation元素具有一个名为label的attribute，表示该公式的唯一引用名称。equation元素的inner text是公式的内容（以latex原始代码呈现）。equation元素只能是9种章节元素的子节点。

有figure元素，表示图片。figure元素具有一个名为label的attribute，表示该图片的唯一引用名称。figure元素具有一个名为caption的attribute，表示该图片的图题。figure元素的inner text是指向被引图片的路径。figure元素只能是9种章节元素的子节点。

有table元素，表示表格。table元素具有一个名为label的attribute，表示该表格的唯一引用名称。table元素具有一个名为caption的attribute，表示该表格的表题。table元素只能是9种章节元素的子节点。table元素的内部有且只能有一个thead和tbody元素。
thead元素表示表格表头。thead元素的内部可以有多个td元素。
tbody元素表示表格的内容。tbody元素的内部可以有多个tr元素，每个tr元素内有多个td元素。
td元素是表格单元格的内容，其inner text是表格单元格中显示的文本。
这些与HTML中的表格类似，但没有HTML表格中的任何样式设定，例如跨列，边框设置等。只是单纯的表示数据内容。这也就意味着thead中td的元素，和tbody中每个tr内的td元素数量需要完全一致。

有ref元素和cref元素。这两个元素都表示对内容的引用。他们的inner text均为需要引用的对象的名称，且使用逗号分割。这两个元素只能是paragraph的子对象。

有cite元素，表示对文献的引用。元素的inner text均为需要引用的文献的名称，且使用逗号分割。cite元素只能是paragraph的子对象。

有pagebreaker元素，表示在当前位置分页。该元素只能是9种章节元素的子节点，或section的子节点。





我正在编写一个将LaTeX论文，经由一个中间格式xthesis（基于XML），转换为docx论文的程序。我现在正在编写LaTeX到xthesis的部分，该部分被称为latex2xthesis。

# 四种映射模式

xthesis是一个结构化的XML格式，而LaTeX是一个线性文档，除少量environment语法以外，很难将其一对一映射到结构上。因此，在latex2xthesis中，我需要引入一套机制，将线性的latex文档转换到XML结构之上。

以下是我提出的四种映射模式：

- 命令模式（command mode，可简称为cmd mode）
    - 通过LaTeX命令来转化出一个XML元素。
    - 指定命令模式时，需要指定命令的名称name，同时还需要指定body内容。因为命令模式只是一条单独的语句，不像其他模式，有首尾两部分，可以框出来一个具体的范围。
    - 在该模式中，提供的可用变量为：`args`，表示该命令的参数，类型为`list[str]`。
- 守卫模式（guard mode）：通过两个LaTeX命令来框选出XML元素作用范围。头部的LaTeX命令会被消耗掉（consume），尾部的LaTeX命令不会被消耗。该模式适合于section，subsection这种分段式命令。
- 注释模式（comment mode）：通过两个固定文本的注释，框出范围。首尾注释均会被消耗。
- 环境模式（environment mode，可简写为env mode）：利用LaTeX自带的environment语法，天然地框出XML元素作用范围。

# 配置文件

## 配置文件要求

此外，由于不同地方的论文会使用不同的模板和LaTeX语句来构建他们的论文，因此需要为latex2xthesis编写一个配置文件，以拓展latex2xthesis的泛用性，让他不只盯着特定的LaTeX语句来生成xthesis文件。该配置文件为toml格式。

该配置文件中有preface键，用于配置哪些内容会被归类为序言内容。preface键是一个列表，列表中的每一种映射模式均会被视为可被转换为序言。在示例中，以环境模式为例，环境名为abstract，环境的参数0被作为标题

该配置文件中有document键

该配置文件中有appendix键

- 该配置文件中有reference键，用于配置参考文献内容。
    - 下有一个mode子健
        - 描述了如何抽取参考文献。
    - 下有一个inner子健
        - 用于表述reference键所关联的参考文献的路径
        - 该子键是一个python表达式
        - 可用变量为mode中抽取而出的变量
        - 该表达式需要返回一个字符串

## 你要做的工作

创建@docs/latex2xthesis.example.toml 文件，作为一个示例配置文件。你还要在其中使用TOML注释来解释每个字段的作用。

创建@src/config/latex2xthesis.py 文件。在该文件中，你需要利用Python自带的tomllib库，以及pydantic库，来实现对配置文件的读取和验证。封装一个函数，接受配置文件的路径输入（pathlib.Path），将TOML文件读取为一系列Python结构。





# latex2xthesis工作流程

接下来我将向你描述latex2xthesis的工作流程，请阅读以下工作流程，完成@src/latex2xthesis.py 文件的编写。

可使用的依赖：

- 命令行解析功能可以从@src/cli/latex2xthesis.py 中获取
- XThesis格式的组建和写出可以从@src/xthesis.py 中获取
- 配置文件的读取和验证可以从@src/config/latex2xthesis.py 中获取
- 使用pylatexenc库进行latex格式解析（我已经帮你添加好了，不需要再添加了）








# 执行流程

- 使用pylatexenc的节点遍历功能，遍历LaTeX文档。
- 在初始状态下，首先尝试匹配配置文件中preface，document，appendix，reference。一旦匹配成功，可视为进入当前内容的进一步分析。

对于preface和appendix，进入即意味着进入section节点的分析，section节点的标题和内容会被分析。

对于reference，进入即意味着进入section1节点的分析。

对于document，进入则意味着准备

# 注意事项

注意到执行流程具有嵌套性和局部性，一旦进入某一特定元素，就按照该元素内部可能出现的情况进行分析，而不再考虑其他元素。因此我建议，实现时采用状态机，配以状态机上下文

模式，栈顶部的元素为当前操作的元素。完成当前节点就弹出，发现新节点就压入。

例如当前栈顶为paragraph元素，我接受到了一个figure元素，则立即将顶部的paragraph元素弹出，然后处理当前figure元素。因为figure元素不能位于自然段中，要自动断开自然段。

对于command模式和environment模式，其内部节点可在分析过程中立即给出，guard模式和comment模式则必须要继续读取才能获取。你需要仔细评估这两种的区别，采用正确的方式来处理，我这里姑且有两种方式供你参考，我推荐第一种，如果第一种绝对不可行，再使用第二种：

1. command和environment模式立即处理，guard和comment模式压入栈中进行处理，好处是内存用量比较小，坏处是写起来比较复杂
1. 对于guard和comment模式，持续获取节点并暂存到一个list中，把他们转化到command和environment模式，然后一起处理。优点是非常简单，缺点是内存用量会比较大
