node.js 使用 elementtree 生成思维导图 Freemind 文件

请参阅: java : pdfbox 读取 PDF文件内书签

请注意:书的目录.txt 编码:UTF-8,推荐用 Notepad++ 转换编码。

npm install elementtree --save

编写 txt_etree_mm.js 如下

javascript 复制代码
// 读目录.txt文件,使用 elementtree 生成思维导图 Freemind(.mm)文件
let fs = require('fs');
let process = require('process');
let path = require('path');
let readline = require('readline');
let et = require('elementtree');
let XML = et.XML;
let ElementTree = et.ElementTree;
//  element = et.Element;
let subElement = et.SubElement;

if (process.argv.length <3){
    console.error("usage: node txt_etree.mm.js file1.txt");
    return 1;
}
let file1 = process.argv[2];
if (! fs.statSync(file1).isFile()) {
    console.error("it is not File.");
    return 2;
}
let ext = path.extname(file1);
if (ext.toLowerCase() != '.txt'){
    console.error(ext +" is not .txt");
    return 3;
}
let file2 = file1.replace('.txt', '.mm');
console.log(file2);
let fRead = fs.createReadStream(file1);
let fWrite = fs.createWriteStream(file2);
// 创建readline接口实例
let rline = readline.createInterface({
    input: fRead,
//  output: fWrite,
    terminal: true
});
var txt, map1, root, edge, p_node, node1, node2, node3, node4, node5;
// 创建 map节点
map1 = et.Element('map');
map1.set('version', '1.0.1');

// 用缩排表现层级关系,假设最多5个层级
const indent1 ="  ";
const indent2 ="    ";
const indent3 ="      ";
const indent4 ="        ";

// line 事件
let n =1;
rline.on('line', function(line){
    txt = line.trim();
    if (n ==1){
        // 读取第一行:书名
        // 创建主题节点
        root = subElement(map1, "node");
        root.set('ID', '1');
        root.set('STYLE', 'bubble'); // 泡框
        root.set('TEXT', txt);
        // 定义连线的颜色:红色
        edge = subElement(root, "edge")
        edge.set('COLOR', "#ff0000")
    }
    txt = txt.slice(0,-3); // 去掉行尾的页数
    if (txt.length ==0 || n==1){ ;}
    else if (txt.length >0 && line.slice(0,1) !=' '){
        // 创建主题的子节点(1级节点)
        node1 = subElement(root, "node");
        node1.set('ID', String(n));
        node1.set('POSITION', "right");
        node1.set('TEXT', txt);
        p_node = node1; // 寄存父节点
    }
    else if (line.startsWith(indent1) && line.slice(2,3) !=' '){
        // 创建node1的子节点(2级节点)
        if (node1) node2 = subElement(node1, "node");
        else node2 = subElement(root, "node");
        node2.set('ID', String(n));
        node2.set('TEXT', txt);
        p_node = node2;
    }
    else if (line.startsWith(indent2) && line.slice(4,5) !=' '){    
        // 创建node2的子节点(3级节点)
        if (node2) node3 = subElement(node2, "node");
        else if(node1) node3 = subElement(node1, "node");
        else node3 = subElement(root, "node");
        node3.set('FOLDED', "true");
        node3.set('ID', String(n));
        node3.set('TEXT', txt);
        p_node = node3;
    }
    else if (line.startsWith(indent3) && line.slice(6,7) !=' '){
        // 创建node3的子节点(4级节点)
        if (node3) node4 = subElement(node3, "node");
        else if (node2) node4 = subElement(node2, "node");
        else if (node1) node4 = subElement(node1, "node");
        else node4 = subElement(root, "node");
        node4.set('ID', String(n));
        node4.set('TEXT', txt);
        p_node = node4;
    }
    else if (line.startsWith(indent4) && line.slice(8,9) !=' '){
        // 创建node4的子节点(5级节点)
        if (node4) node5 = subElement(node4, "node");
        else if (p_node) node5 = subElement(p_node, "node");
        else node5 = subElement(root, "node");
        node5.set('ID', String(n));
        node5.set('TEXT', txt);
    }
    else {
        console.log(txt);
    }
    n++;
});
var etree, xml;
rline.on('close', function(){
    etree = new ElementTree(map1);
    xml = etree.write({'xml_declaration': false});
    //console.log(xml);
    fWrite.write(xml);
    console.log("line number: "+n);
});

运行 node txt_etree.mm.js your_pdf_dir.txt

相关推荐
晓杰'14 小时前
从0到1实现Balatro游戏后端(4):玩家手牌操作(出牌 / 弃牌 / 补牌)与状态流转设计
后端·websocket·typescript·node.js·状态模式·项目实战·nestjs
LinDaiDai_霖呆呆16 小时前
呆老师亲授前端转全栈+AI 开发的学习图谱
前端·javascript·node.js
m0_5358175517 小时前
Claude Code在Linux/WSL2环境完整部署指南:API中转+避坑配置一篇搞定
linux·服务器·node.js·claude·wsl2·claudecode·88api
神所夸赞的夏天18 小时前
安装 HTTP 客户端 npm install axios报错:“code EPERM“解决方法
前端·npm·node.js
ZTStory1 天前
Volta 新一代 node 版本管理工具
前端·javascript·node.js
wyc是xxs2 天前
npm包推荐
前端·npm·node.js
muddjsv3 天前
Node.js 概览:是什么、能做什么、从业价值与前景分析
node.js
Rain5093 天前
mini-cc 技术栈:跟着 Claude Code 先选 TypeScript + React + Ink
前端·javascript·react.js·typescript·node.js·ai编程
Rain5093 天前
架构解密:mini-cc 的核心设计思路
前端·架构·开源·node.js·ai编程
yantuguiguziPGJ3 天前
WeMed:一个医疗垂直领域大模型 问答系统的 Taro 小程序
typescript·node.js