mdToVue.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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,callback){
  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. callback({
  140. mdName:mdName,
  141. html:html
  142. })
  143. // resolve({
  144. // mdName:mdName,
  145. // html:html
  146. // })
  147. //创建文件
  148. });
  149. }else{
  150. //reject('nomd')
  151. }
  152. //})
  153. }
  154. //文件监听
  155. function filelisten(){
  156. let fsWatcher = fs.watchFile(filedir, {
  157. persistent: true,
  158. persistent: 1000
  159. }, (err, data) => {
  160. // console.log(err,data,filedir);
  161. fs.readFile(filedir, 'utf-8', (err, data) => {
  162. let html = marked(data);
  163. let filedirarry = filedir.split('/');
  164. let fileNames = filedirarry[filedirarry.length - 2];
  165. createdFile(outPath + fileNames + '.vue', html, nohead)
  166. });
  167. });
  168. }
  169. /**
  170. * 文件转md
  171. * @param {obj}
  172. * @entry {string} 文件读取路径
  173. * @output {string} 文件输出路径
  174. * @needCode {boolen} 是否需要二维码 默认 true
  175. */
  176. function fileDisplay(param) {
  177. // 获取文件
  178. readDirRecur(param.entry, function(filePath) {
  179. //文件列表
  180. fileList.map(item=>{
  181. // ismd(item).then(res=>{
  182. // //res md文件处理结果
  183. // createdFile(param.output + '/' + res.mdName + '.vue', res.html, param.needCode)
  184. // })
  185. ismd(item,res=>{
  186. //res md文件处理结果
  187. createdFile(param.output + res.mdName + '.vue', res.html, param.needCode)
  188. })
  189. })
  190. });
  191. }
  192. //md转 其他格式类型
  193. /**
  194. *
  195. * @outPath {String} 输出的文件目录
  196. */
  197. function ishasOutFile(outPath,callback){
  198. fs.stat(outPath,(err,res)=>{
  199. if(err){
  200. fs.mkdir(outPath,erro=>{
  201. if(erro){
  202. }else{
  203. callback()
  204. }
  205. })
  206. }else{
  207. callback()
  208. }
  209. })
  210. }
  211. /**
  212. *
  213. * @param {entry} 文件读取路径
  214. * @param {output} 文件输出路径
  215. * @param {needCode} 是否需要二维码 默认 true
  216. */
  217. function MdToHtml(commomOption) {
  218. // 默认参数就这么多了,暂时没想到
  219. let params = {
  220. entry:'',
  221. output:'',
  222. needCode:true
  223. }
  224. params = Object.assign(params,commomOption);
  225. //检查输出路径
  226. ishasOutFile(params.output,()=>{
  227. //获取所有的md 转html的结果
  228. fileDisplay(params);
  229. });
  230. }
  231. //用于后期的扩展暂时没想到
  232. MdToHtml.prototype.apply = function (compiler) {
  233. // console.log(compiler,'lls')
  234. };
  235. module.exports = MdToHtml;