概况
本文介绍的是将百度脑图编辑器kityminder-editor导出的km文件转为markdown格式的文件。
当前支持情况:
- 支持节点转为markdown标题
- 支持备注转为markdown内容
- 支持导出图片
- 支持链接
基本环境
nodejs 18+
vscode
基本逻辑
KityMinder-Editor节点结构
kityminder-editor编辑器中节点的大致结构如下
{
"data": {
"id": "",
"created": 0,
"text": "B",
"image": "base64字符串",
"imageTitle": "图片标题",
"note": "备注",
"hyperlink": "超链接",
"hyperlinkTitle": "标题",
"progress": "进度"
},
"children": [
{
"data":{},
"children":[]
}
]
}
知道文件结构后,只需要写程序将km的结构映射到markdown对应的格式上即可
生成Markdown核心代码
const { randomUUID } = require('crypto');
const fs = require('fs');
const path = require('path')
/**
* 生成markdown
* @param {文件句柄} fd
* @param {markdown文件名称} name
* @param {节点} node
* @param {等级} level
*/
function generateMarkdown(fd, name, node, level) {
// let markdown = ""
if (!level) {
level = 0
}
//处理节点文本
if (node.data.text) {
let prefix = ''
for (let i = 0; i < level; i++) {
prefix += '#'
}
let markdown = `${prefix} ${node.data.text}\n\n`
myWriteFile(fd, markdown)
}
//处理tag
if (node.data.resource) {
let resources = node.data.resource
let tags = ""
for (let r of resources) {
tags += `- [ ] ${r}\n\n`
}
myWriteFile(fd, tags)
}
//处理进度图标
if (node.data.progress) {
let content = `> 当前进度: ${name.data.progress}/8 \n\n`
if (node.data.progress == 0) {
content = `> 当前进度: 未开始 \n\n`
}
myWriteFile(fd, content);
}
//处理备注
if (node.data.note) {
let markdown = node.data.note + "\n\n"
myWriteFile(fd, markdown)
}
//处理图片
if (node.data.image) {
let originalString = node.data.image;
let result = originalString.match(/^data:image\/\w+/)
//提取图片类型
let suffix = result[0].replace("data:image/", "")
//提取图片base64字符串
let baseString = originalString.replace(/^data:image\/\w+;base64,/, '')
const bufferData = Buffer.from(baseString, 'base64');
let attachDir = `${name}.attachments`
if (!fs.existsSync(attachDir)) {
fs.mkdirSync(attachDir);
}
let uuid = node.data.imageTitle || randomUUID()
let imagePath = `${attachDir}/${uuid}.${suffix}`
//保存图片
fs.writeFile(imagePath, bufferData, (err) => {
if (err) {
console.error(err);
return
}
})
//将图片写入到markdown
let title = node.data.imageTitle || "defaultTitle"
let imageContent = `![${title}](${imagePath})\n\n`;
myWriteFile(fd, imageContent)
}
//处理超链接
if (node.data.hyperlink) {
let hyperlinkTitle = node.data.hyperlinkTitle || "linkTitle"
let hyperlinkContent = `[${hyperlinkTitle}](${node.data.hyperlink})\n\n`
myWriteFile(fd, hyperlinkContent)
}
//处理子节点
if (node.children && node.children.length > 0) {
node.children.forEach(element => {
generateMarkdown(fd, name, element, level + 1);
});
}
}
/**
* 向文件中写入内容
* @param {markdown文件} fd
* @param {要写入的内容} content
*/
function myWriteFile(fd, content) {
fs.writeFileSync(fd, content);
}
函数调用
let name="hello"
fd = fs.openSync(`${name}.md`, 'w+');
//node 为km节点数据
generateMarkdown(fd, name, node, 1);