a.png
保存完之后,会有⼀个htm⽂件和⼀个⽂件夹。打开⽹页,我们发现⾃动⽣成的⽬录是这样的:
b.png
⼀级⼆级三级菜单都是扁平结构的,⽽我们⼀般开发的⽬录菜单,都是带层级的嵌套ul li结构。
所以难点就在于:
形容冬天的成语
如何将word⽣成的⽬录,与我们开发的左侧导航联系起来?
以下是我的解决⽅案。主要是利⽤node的cheerio包,将扁平结构的⽬录,转成带层级的数据结构,然后再⽣成树结构。⽬录处理完后,将word⽣成的⽬录部分去掉即可。
const fs = require('fs');
const cheerio = require('cheerio');
//=================================⽣成内容================================================//
async function handleContent(path,destPath) { //需清除word的⽬录
服装剪裁
工作顺利let newHtml = await fsRead(path);
let $ = cheerio.load(newHtml);
let bodyPart = $('body').html();
let $d = cheerio.load(bodyPart);
$d('.MsoToc1').parent().replaceWith('');
$d('.MsoTocHeading').replaceWith('');
$d('.MsoTitle').replaceWith('');
$d('body').append(`<script src="../layout/jquery.min.js"></script>
<script>
$('img').parents('p').removeAttr('style').css('text-align','left');
</script>`);
let res = await fsWrite(destPath, $d.html());//⽣成处理过的html
if (res === 'ok') {
console.log('内容处理完毕');
} else {
console.log('内容处理出错了');
}
}
//=================================⽣成⽬录================================================// async function handlecatalogue(path, destPath) {
let content = await fsRead(path);
let listHtml = getHtml();//读取⽬录⽂件
let arr: any[] = [];
let count = 0;
let count1 = 0;
let count2 = 0;
let $ = cheerio.load(content);
let $list = cheerio.load(listHtml);
$('.MsoTocHeading').eq(0).siblings('p').each((key, element) => {
let className = $(element).attr('class');
if (className === 'MsoToc1') { // ⼀级⽬录
$(element).find('a').each((k, v) => {
count++;
let url = $(v).attr('href');
let title = $(v).text().replace(/\.{1,}\s+\d+/ig, '');
let obj = { id: count, title: title, url: url, parent: 0 };
arr.push(obj);
count1 = count;
});
}
if (className === 'MsoToc2') { // ⼀级⽬录
$(element).find('a').each((k, v) => {
count++;
let url = $(v).attr('href');
let title = $(v).text().trim().replace(/\.{1,}\s+\d+/ig, '');
let obj = { id: count, title: title, url: url, parent: count1 };
arr.push(obj);
count2 = count;
});
}
if (className === 'MsoToc3') { // ⼀级⽬录
$(element).find('a').each((k, v) => {
count++;
let url = $(v).attr('href');
let title = $(v).text().trim().replace(/\.{1,}\s+\d+/ig, '');
let obj = { id: count, title: title, url: url, parent: count2 };
arr.push(obj);
});
}
});
let newarr = convertData(arr);
let nodes = createTree(newarr, true);
$list('.left-part').html(nodes);
$list('.left-part').html(nodes);
let res = await fsWrite(destPath, $list.html());//⽣成处理过的html
if (res === 'ok') {
console.log('⽬录处理完毕');
} else {
console.log('⽬录处理出错了');
}
}
//==================================⽣成html=======================================================// function createTree(list, flag = false) {
if (Array.isArray(list)) {
let str = '';
if (flag) {
str = `<ul class="lp-cont">`;//最外层ul
} else {
str = `<ul class="lp-cont-child">`;
}
list.forEach(item => {
str += `<li onclick="toPage('./pages/book.html${item.url}')">${item.title}`;
if (item.children && item.children.length > 0) {
str += createTree(item.children);
}
str += `</li>`;
});
str += `</ul>`;
return str;
}
}
//======================================⽣成tree data============================================// function convertData(jsonData) {
var result: any[] = [], temp = {}, i = 0, j = 0, len = jsonData.length;
for (; i < len; i++) {
temp[jsonData[i]['id']] = jsonData[i] // 以id作为索引存储元素,可以⽆需遍历直接定位元素
}
for (; j < len; j++) {
var currentElement = jsonData[j]
var tempCurrentElementParent = temp[currentElement['parent']] // 临时变量⾥⾯的当前元素的⽗元素 parentId ⽗级ID
if (tempCurrentElementParent) { // 如果存在⽗元素
if (!tempCurrentElementParent['children']) { // 如果⽗元素没有chindren键
tempCurrentElementParent['children'] = [] // 设上⽗元素的children键
}
tempCurrentElementParent['children'].push(currentElement) // 给⽗元素加上当前元素作为⼦元素
} else { // 不存在⽗元素,意味着当前元素是⼀级元素
result.push(currentElement);
}
}七月你好心语说说
return result;
}
//======================================读⽂件====================================================// function fsRead(filename) {
return new Promise((resolve, reject) => {
if (err) {
reject(err);
} else {
resolve(data);
}
})
})
}
//===================================写⽂件===================================================//
//===================================写⽂件===================================================// function fsWrite(path, content) {
return new Promise((resolve, reject) => {
fs.writeFile(path, content, { flag: 'w', encoding: 'utf-8' }, (err) => {
if (err) {
reject(err);
} else {
resolve('ok');
}
})
})
}
//====================================⽬录⽂件=====================================================// function getHtml() {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>⽤户⼿册</title>
<style>
body{
margin:0;
padding:0;
}
ul{
margin:0;
padding:0;
list-style:none;
/* margin-bottom:15px; */
}
ul li{
position: relative;
line-height:40px;
}
.container{
width:100%;
height:100%;
display:flex;
flex-direction: column;
野狼disco是哪一期align-items: center;
justify-content: center;
}
.header{
width:inherit;
height:50px;
百里弘毅怎么爱上柳然的
display:flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
color:#fff;
background:#000;
}
.h-back{
width:20px;
height:20px;
margin-left:15px;
margin-right:20px;
}
.content{
width:inherit;
height:calc(100vh - 50px);
display:flex;
flex-direction: row;
justify-content: center;
}