JavaScript笔记 #05# 用Regex辅助生成文章目录
PS. 用来生成个人笔记的目录
1、输入:html文本
<h2>Notes</h2> <p>1、小标题1。正文正文正文</p> <div class="cnblogs_code"> <pre><span style="color: #000000;">ddjlasjdlas </span><span style="color: #0000ff;">as</span><span style="color: #000000;"> dasdasjda</span></pre> </div> <p>2、小标题2</p> <p>正文正文正文正文正文</p> <p>3、小标题3</p> <p>正文正文正文</p> <p>4、小标题4</p> <p>正文正文正文</p> <p> </p> <h2>Excercises</h2> <p>① xxxxxx1</p> <p>正文正文正文</p> <p>② xxx2</p> <p>正文正文</p> <p>③ xx3</p> <p>正文正文正文</p>
2、输出:含目录的html文本
<div id="diy_right_menu"> <h2>索引</h2> <ul> <li> <p>Notes</p> <ol> <li><a href="#a1">标题1</a></li> <li><a href="#a2">标题2</a></li> <li><a href="#a4">标题3</a></li> <li><a href="#a5">标题4</a></li> </ol></li> <li> <p>Excercise</p> <ol> <li><a href="#b1">练习1</a></li> <li><a href="#b2">练习2</a></li> <li><a href="#b3">练习3</a></li> </ol></li> </ul> </div> <h2>Notes</h2> <p><a name="a1"></a>1、小标题1。正文正文正文</p> <div class="cnblogs_code"> <pre><span style="color: #000000;">ddjlasjdlas </span><span style="color: #0000ff;">as</span><span style="color: #000000;"> dasdasjda</span></pre> </div> <p><a name="a2"></a>2、小标题2</p> <p>正文正文正文正文正文</p> <p><a name="a3"></a>3、小标题3</p> <p>正文正文正文</p> <p><a name="a4"></a>4、小标题4</p> <p>正文正文正文</p> <p> </p> <h2>Excercises</h2> <p><a name="b1"></a>① xxxxxx1</p> <p>正文正文正文</p> <p><a name="b2"></a>② xxx2</p> <p>正文正文</p> <p><a name="b3"></a>③ xx3</p> <p>正文正文正文</p> <p> </p>
3、自定义的规则
- “类似1、xx 2、xx”会被转化为目录中的第一类二级标题Notes
- “类似① xxx ② xx”会被转化为目录中的第二类二级标题Excercises
- 第二类二级标题必须全部为英文字符,且1或者①前面都不能有空格,①后面只能是英文空格
- Copy来的标题要先清除格式
4、Javascript代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <textarea id="big-textarea" placeholder="paste your origin html text here..." rows="30" cols="150"><h2>Notes</h2> <h2>Exercises</h2></textarea> <button id="big-button">Generate</button> <script type="text/javascript"> const button = document.querySelector('#big-button'); button.addEventListener('click', handleClick); function handleClick(event) { const textarea = document.querySelector('#big-textarea'); let inputHtml = textarea.value; textarea.value = generateDiy_right_menu(inputHtml); }; function replaceAndRecordSmallTitles(str ,arr) { const regex = /<p>(\d{1,2})\u3001([\d\w\s\u4e00-\u9fa5]+)/g; const replaceAndRecordHelper = (_, index, smallTitle) => { arr.push(smallTitle); return `<p><a name="a${index}"></a>${index}、${smallTitle}`; } return str.replace(regex, replaceAndRecordHelper); } function replaceAndRecordExercises(str, arr) { const regex = /<p>([\u2460-\u2469])\s([\w\s]+)/g; let exerciseCount = 1; const replaceAndRecordHelper = (_, unicodeIndex, exerciseName) => { arr.push(exerciseName); return `<p><a name="b${exerciseCount++}"></a>${unicodeIndex} ${exerciseName}`; } return str.replace(regex, replaceAndRecordHelper); } function htmlMenu(small_titles, exercise_names) { const htmlMenuHead = '<div id="diy_right_menu">\n' + '<h2>索引</h2>\n' + '<ul>\n<li>\n' + '<p>Notes</p>\n<ol>\n'; let htmlTitles = ""; for (let i = 0; i != small_titles.length; ++i) { htmlTitles += `<li><a href="#a${i+1}">${small_titles[i]}</a></li>\n`; } let htmlExercise = "</ol></li>\n<li>\n<p>Exercises</p>\n<ol>\n"; for (let i = 0; i != exercise_names.length; ++i) { htmlExercise += `<li><a href="#b${i+1}">${exercise_names[i]}</a></li>\n`; } const htmlMenuTail = '</ol></li>\n</ul>\n</div>\n'; const result = htmlMenuHead + htmlTitles + htmlExercise + htmlMenuTail; return result; } function generateDiy_right_menu(inputHtml) { let result = inputHtml.slice(); // 用replace替换掉原文,顺便记录标题内容 const small_titles = []; const exercise_names = []; result = replaceAndRecordSmallTitles(result, small_titles); result = replaceAndRecordExercises(result, exercise_names); // 自动生成目录 if (result.slice(0, '<div id="diy'.length) != '<div id="diy') { // 避免重复生成目录 result = htmlMenu(small_titles, exercise_names) + result; } return result; } </script> </body> </html>