mdToVue.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. const fs = require('fs');
  2. var path = require('path');
  3. //marked转换工具
  4. let marked = require('marked');
  5. if (!marked) {
  6. console.log('you need npm i marked -D!');
  7. }
  8. // 基本配置文件信息
  9. let {version} = require("../package.json");
  10. //vue js脚本
  11. let jsroot = require('./mdtoVueroot');
  12. //获取所有文件列表
  13. let fileList = [];
  14. // maked文件配置
  15. var rendererMd = new marked.Renderer();
  16. //maked文件规则
  17. rendererMd.code = function (code, infostring, escaped) {
  18. var lang = (infostring || '').match(/\S*/)[0];
  19. if (this.options.highlight) {
  20. var out = this.options.highlight(code, lang);
  21. if (out != null && out !== code) {
  22. escaped = true;
  23. code = out;
  24. }
  25. }
  26. if (!lang) {
  27. return '<pre><code>'
  28. + (escaped ? code : escape(code, true))
  29. + '</code></pre>';
  30. }
  31. if (lang === 'html') {
  32. code = code.replace(/@latest/g, '@' + version)
  33. }
  34. return '<pre class="prettyprint"><span class="lang">' + lang + '</span><code class="'
  35. + this.options.langPrefix
  36. + escape(lang, true)
  37. + '">'
  38. + (escaped ? code : escape(code, true))
  39. + '</code><i class="copy" copy="copy" data-clipboard-action="copy" data-clipboard-target="code" title="复制代码"></i><i toast="toast" title="全屏"></i></pre>\n';
  40. };
  41. marked.setOptions({
  42. renderer: rendererMd,
  43. highlight: function (code) {
  44. return require('highlight.js').highlightAuto(code).value;
  45. },
  46. tables: true
  47. }, res => {
  48. })
  49. /**
  50. * 是否需要单独处理头部信息
  51. * @param {text} sorce 替换 头部信息
  52. */
  53. function insert(sorce) {
  54. var insert = sorce.indexOf('</h1>');
  55. if (insert > -1) {
  56. return sorce.substring(0, insert) + '<i class="qrcode"><a :href="demourl"><span>请使用手机扫码体验</span><img :src="codeurl" alt=""></a></i>' + sorce.substring(insert, sorce.length);
  57. } else {
  58. return sorce
  59. }
  60. }
  61. ///创建一个空文件
  62. /**
  63. * 修复中
  64. * @param {string} output 输出路径
  65. * @param {string} sorce 文件源
  66. * @param {boole} ishasCode 是否需要二维码
  67. */
  68. function createdFile(output, sorce, ishasCode) {
  69. var pathSrc = output;
  70. if (!ishasCode) {
  71. var res = insert(sorce);
  72. } else {
  73. var res = sorce;
  74. }
  75. fs.open(pathSrc, "w+", (err, fd) => {
  76. var bufs = `<template><div @click="dsCode">
  77. <div v-if="content" class="layer">
  78. <pre><span class="close-box" @click="closelayer"></span><div v-html="content"></div></pre>
  79. </div>`+ res + '</div></template>' + jsroot;
  80. var buf = new Buffer(bufs);
  81. if (typeof fd == 'number') {
  82. fs.writeSync(fd, buf, 0, buf.length, 0);
  83. } else {
  84. console.log(pathSrc, ' typeof fd != number 请改正文件')
  85. }
  86. })
  87. }
  88. /**
  89. * 目录读取,找到跟文件
  90. * @fileSrc {string} 打开文件路径
  91. * @callback {fn} 结束后回调函数
  92. */
  93. function readDirRecur(fileSrc, callback) {
  94. fs.readdir(fileSrc, function(err, files) {
  95. var count = 0
  96. var checkEnd = function() {
  97. ++count == files.length && callback()
  98. }
  99. files.forEach(function(file) {
  100. var fullPath = fileSrc + '/' + file;
  101. fs.stat(fullPath, function(err, stats) {
  102. if (stats.isDirectory()) {
  103. return readDirRecur(fullPath, checkEnd);
  104. } else {
  105. /*not use ignore files*/
  106. if(file[0] == '.') {
  107. } else {
  108. fileList.push(fullPath)
  109. }
  110. checkEnd()
  111. }
  112. })
  113. })
  114. //为空时直接回调
  115. files.length === 0 && callback()
  116. })
  117. }
  118. /**
  119. * 判断是否位md文件 并进行操作
  120. * @src {string} 打开的文件目录
  121. */
  122. function ismd(src){
  123. //判断文件类型是否是md文件
  124. let filedir = src;
  125. return new Promise((resolve,reject)=>{
  126. if (/.md$/.test(filedir)) {
  127. //文件读取
  128. fs.readFile(filedir, 'utf-8', (err, data) => {
  129. let html = marked(data);
  130. let mdName = "";
  131. let opensName = filedir.replace(/(^.*\/|.md)/g,"");
  132. //如果是doc文件以前缀 为
  133. if (opensName === 'doc') {
  134. mdName = filedir.replace(/(^.*packages\/|\/doc\.md)/g,'');
  135. } else {
  136. //如果不是doc命名的文件
  137. mdName = opensName;
  138. }
  139. resolve({
  140. mdName:mdName,
  141. html:html
  142. })
  143. //创建文件
  144. });
  145. }else{
  146. reject('nomd')
  147. }
  148. })
  149. }
  150. //文件监听
  151. function filelisten(){
  152. let fsWatcher = fs.watchFile(filedir, {
  153. persistent: true,
  154. persistent: 1000
  155. }, (err, data) => {
  156. // console.log(err,data,filedir);
  157. fs.readFile(filedir, 'utf-8', (err, data) => {
  158. let html = marked(data);
  159. let filedirarry = filedir.split('/');
  160. let fileNames = filedirarry[filedirarry.length - 2];
  161. createdFile(outPath + fileNames + '.vue', html, nohead)
  162. });
  163. });
  164. }
  165. /**
  166. * 文件转md
  167. * @param {obj}
  168. * @entry {string} 文件读取路径
  169. * @output {string} 文件输出路径
  170. * @needCode {boolen} 是否需要二维码 默认 true
  171. */
  172. function fileDisplay(param) {
  173. // 获取文件
  174. readDirRecur(param.entry, function(filePath) {
  175. //文件列表
  176. fileList.map(item=>{
  177. ismd(item).then(res=>{
  178. //res md文件处理结果
  179. createdFile(param.output + '/' + res.mdName + '.vue', res.html, param.needCode)
  180. })
  181. })
  182. });
  183. }
  184. //md转 其他格式类型
  185. /**
  186. *
  187. * @param {entry} 文件读取路径
  188. * @param {output} 文件输出路径
  189. * @param {needCode} 是否需要二维码 默认 true
  190. */
  191. function MdToHtml(commomOption) {
  192. // 默认参数就这么多了,暂时没想到
  193. let params = {
  194. entry:'',
  195. output:'',
  196. needCode:true
  197. }
  198. params = Object.assign(params,commomOption);
  199. //获取所有的md 转html的结果
  200. fileDisplay(params);
  201. }
  202. //用于后期的扩展暂时没想到
  203. MdToHtml.prototype.apply = function (compiler) {
  204. // console.log(compiler,'lls')
  205. };
  206. module.exports = MdToHtml;