UNPKG

i5ting_toc_v2

Version:

tocmd.npm:a npm wrapper of i5ting_ztree_toc with automatic image processing

219 lines (175 loc) 6.26 kB
'use strict' require('shelljs/global') var assign = require('object-assign') var fs = require('fs') var path = require('path') var BufferHelper = require('bufferhelper') var Handlebars = require('handlebars') var open = require("open") // 新增:处理Markdown中的图片 function processImages(markdownContent, sourceDir, previewPath) { var imagesDir = path.join(previewPath, 'toc', 'images') // 创建images文件夹(如果不存在) if (!test('-d', imagesDir)) { mkdir('-p', imagesDir) console.log('已创建images文件夹:', imagesDir) } // 正则表达式匹配Markdown图片语法:![alt](path) var imageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g var processedContent = markdownContent var match // 查找所有图片 while ((match = imageRegex.exec(markdownContent)) !== null) { var altText = match[1] var imagePath = match[2] // 跳过网络图片 if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) { continue } // 构建完整的图片源路径 var fullImagePath if (path.isAbsolute(imagePath)) { fullImagePath = imagePath } else { fullImagePath = path.join(sourceDir, imagePath) } // 检查图片文件是否存在 if (test('-f', fullImagePath)) { // 获取图片文件名 var imageFileName = path.basename(imagePath) // 构建目标路径 var destImagePath = path.join(imagesDir, imageFileName) // 复制图片到images文件夹 try { cp(fullImagePath, destImagePath) console.log('已复制图片:', imageFileName) // 更新Markdown中的图片路径 var newImagePath = 'toc/images/' + imageFileName processedContent = processedContent.replace( '![' + altText + '](' + imagePath + ')', '![' + altText + '](' + newImagePath + ')' ) } catch (err) { console.error('复制图片失败:', fullImagePath, err.message) } } else { console.warn('图片文件不存在:', fullImagePath) } } return processedContent } function generator(pwd, source_file_name, dest_file_path, is_open, options) { var file_name = source_file_name.split('/').pop() var _file_name = file_name.split('.')[0] var is_debug = options.debug function log(str) { if (is_debug == true) console.log(str) } // 点号表示当前文件所在路径 var str = fs.realpathSync('.') log(str) //函数可以返回当前正在执行的项目路径 //:属性返回的是 nodejs 的安装路径 // processor.execPath var preview_path = pwd + '/preview' var source_file_path = source_file_name var dest_file_path = dest_file_path if (!test('-d', preview_path)) { mkdir('-p', preview_path) } cp_template_dir(__dirname, preview_path) function cp_template_dir(_cur_dir, _dest_dir) { var i = _cur_dir log(i) cp('-R', _cur_dir + '/vendor/toc', _dest_dir + '/') } var template_path = __dirname + '/vendor/template.html' log('template_path = ' + template_path) fs.readFile(source_file_path, function (err, data) { if (err) throw err log(data) // var rs = fs.createReadStream(template_path, {encoding: 'utf-8', bufferSize: 11}) var rs = fs.createReadStream(template_path, { bufferSize: 11 }) var bufferHelper = new BufferHelper() rs.on("data", function (trunk) { bufferHelper.concat(trunk) }) rs.on("end", function () { var source = bufferHelper.toBuffer().toString('utf8') var template = Handlebars.compile(source) log(template) var marked = require('marked') // marked = require('gulp-markdown-livereload') // 新增:处理Markdown中的图片 var markdownContent = data.toString() var sourceDir = path.dirname(source_file_path) markdownContent = processImages(markdownContent, sourceDir, preview_path) function detectLanguage(code){ var text = code || '' if (/^\s*#include\s+<.+?>/m.test(text) || /\bstd::/m.test(text)) return 'cpp' if (/\bpublic\s+class\b/.test(text) || /\bSystem\.out\.println\b/.test(text)) return 'java' if (/^\s*#include\s+".+?\.h"/m.test(text) || /\bprintf\s*\(/.test(text)) return 'c' if (/^\s*def\s+\w+\s*\(/m.test(text) || /:\s*$/m.test(text) && /\bimport\s+\w+/.test(text)) return 'python' if (/\bfunction\b/.test(text) || /=>/.test(text) || /console\.log\b/.test(text)) return 'javascript' if (/\b\{[\s\S]*\}\s*$/.test(text) && /"[^"]+"\s*:/.test(text)) return 'json' if (/^\s*<\/?[a-zA-Z]/m.test(text)) return 'markup' if (/\bint\s+main\s*\(/.test(text)) return 'cpp' if (/^\s*#!/.test(text)) return 'bash' if (/\bSELECT\b|\bFROM\b|\bWHERE\b/i.test(text)) return 'sql' return '' } function escapeHtml(html){ return String(html) .replace(/&/g,'&amp;') .replace(/</g,'&lt;') .replace(/>/g,'&gt;') .replace(/\"/g,'&quot;') } var renderer = new marked.Renderer() renderer.code = function (code, infostring) { var lang = (infostring || '').trim() if (!lang) { lang = detectLanguage(code) } var cls = lang ? ' class="language-' + lang + '"' : '' return '<pre><code' + cls + '>' + escapeHtml(code) + '\n</code></pre>' } var markedOptions = assign({ langPrefix: 'language-', renderer: renderer }, options || {}) // 使用处理后的Markdown内容 marked(markdownContent, markedOptions, function (err, data) { if (err) { log('err ' + err) return } log(data) // 生成唯一的版本号,用于破坏缓存 var version = Date.now().toString(36) + Math.random().toString(36).substr(2) var data1 = { "title": "i5ting_ztree_toc:" + _file_name, "parse_markdown": data, "theme_css": markedOptions.theme_css || 'toc/style/code-theme/prism-tomorrow.css', "version": version // 新增版本号 } var final_html_content = Buffer.from(template(data1), 'utf8') log(dest_file_path) if (markedOptions.index === true) { dest_file_path = dest_file_path.replace('README', 'index') } log(dest_file_path) fs.writeFile(dest_file_path, final_html_content, function (err) { if (err) throw err log('It\'s saved!') if (is_open == true) { open(dest_file_path) } }) }) }) }) } // generator('sample.md') module.exports = generator