1.设计内容
使用 C++ 语言编写文档转换工具,其可以将 Markdown 格式转换为 Html 格式。转换中不使用第三方 Markdown 格式解析库。
2.设计思想和实现方法
设计思想:
采用树形结构,定义自定义数据结构 Node ,用向量 vector 的自定义数据结构类型存储所有读入数据的标签类型和数据,从左到右存储,通过深度优先遍历读取数据。
struct Node {
int _type;//语法类型
vector<Node*> _child;//孩子节点
string elem[2];//elem[0]:保存需要显示的内容//elem[1]:保存网址/路径
Node(int type){
_type = type;//赋值
}};
标签类型采用枚举结构存储,将之等价为数字;
定义 Html 文件的前置标签数组 frontTag[] 和后置标签数组 backTag[] ,分别与枚举类型中的标签类型一一对应,深度优先遍历时通过节点的标签类型访问。
在解析markdown文件时,主要采用逐行解析的逻辑
对于每一行的文本,通过预处理,词法分析,语法树构建三个过程,我markdown文件中的内容全部放入一棵语法树中,最后通过展开语法树,把解析之后的文档用html的形式展示。
1、解析行首语法
2、根据语法创建结点(N叉树结点),把对应的语法结点插入到此N叉树中。结点层次对应html的标签层次。存在嵌套。结点结构:语法类型,孩子结点指针数组,内容(显示内容+链接、地址)
3、插入结点
4、N叉树展开:结点内容转换为HTML文档(深度优先,每一层从左向右)
语法树展开
采用深度优先遍历展开语法树,可以生成标签嵌套的html文档。展开的主要过程如下:
1、遍历当前节点:加入节点的前置标签, 如果是链接或者图片,标签比较复杂,单独处理;再加入节点内容。
2、遍历当前节点的孩子节点。
3、孩子节点遍历完之后,加入当前节点的后置标签。
实现方法:
class markdownPaerser {
public:
markdownPaerser(const string &filename);
~markdownPaerser() ;
void transferm();
void dfs(Node* root);
const char* processStr(const char* str);
void insert(Node* curNode, const char* str);
pair<int, const char*> parseType(const char* str);
bool isCutLine(const char* str);
void html();
void destory(Node* root);
private:
Node* _root;
string _filename;
string _content;
};
3.程序说明
方法 | 说明 |
---|---|
markdownPaerser(const string &filename) | 初始化 _filename (文件名)和 _root (语法树根节点)。 |
~markdownPaerser() | 调用 destory(Node* root) 方法。删除所有节点。 |
void transferm() | 主程序调用执行。打开文件读取数据,调用 processStr(const char* str) 方法、 parseType(const char* str) 方法、 isCutLine(const char* str) 方法、 insert(Node* curNode, const char* str) 方法、dfs(Node* root) 方法。 |
const char* processStr(const char* str) | 被 transferm() 方法调用。去除行首空格。 |
pair<int, const char*>parseType(const char* str) | 被 transferm() 方法调用。str存储transferm()传来的需要处理的数据。解析行首语法类型,返回子:语法类型 + 对应内容起始位置 |
void isCutLine(const char* str) | 被 transferm() 方法调用。str存储transferm()传来的需要处理的数据。判断是否是水平分割线 “—”,并处理。 |
void insert(Node* curNode, const char* str) | 被 transferm() 方法调用。curNode和str分别存储transferm()传来的需要处理的节点和数据。读取每个字符内容,插入对应类型。 |
void dfs(Node* root) | 被 transferm() 方法调用。自调用直至读完。root 存储传来的根节点。嵌套递归,深度优先遍历 DFS 将语法树转换成HTML源代码。 |
void html() | 主程序调用,生成 html 文件。 |
void destory(Node* root) | 被 ~markdownPaerser() 方法调用。删除所有节点。 |
私有变量 | 说明 |
---|---|
Node* _root | 语法树根节点 |
string _filename | 文件名 |
string _content | 存放HTML文档内容 |
4.总结分析
本次课程设计,实现了对Markdown 格式中,分段、超链接、无序集、有续集、列表项目、斜体、加粗、标题、图片、块引用、标题、代码、分割线等格式的识别和转换成Html文件中的对应格式。文件转换成功。
程序设计过程中,图片的处理与其他格式不同,单独处理。分割线处只存在分割线,故单独判断可以提高程序性效率。
本次设计涉及的技术要点:文件的读写、词法分析技术、语法树、DFS 深度优先遍历。
由于对Markdown文件格式不熟悉,只完成了上述几种格式的转换,若有其他格式再扩展。
源码压缩包 https://download.csdn.net/download/qq_46457493/20368583?spm=1001.2014.3001.5503
自己复制粘贴 https://blog.csdn.net/qq_46457493/article/details/124361688