Node自動生成markdown目錄(萌新版)

看到各位大佬在掘金上發文章,看到一些大佬的倉庫的目錄,想本身也搞一個,然而懶癌發做,得找個理由讓本身不作這件事,程序員不就得偷懶麼(認真):前端

手動處理目錄的缺點:

  1. 添加文章、修改文章標題、刪除文章,須要找到對應的標題操做,其中包括內容和 markdown 語法,多了很繁瑣git

  2. 添加文章、修改文章時,我但願能記錄文章的更新時間,這個手動拿到時間再填進去,多了也很繁瑣程序員

成功地說服了本身,而後開始動手

思路

  1. 遍歷全部的文件 遞歸實現github

  2. 遇到文件和文件夾時,按照 markdown 語法寫入到 README.md 中數組

遇到的問題:

  1. 文件所屬文件夾出錯,好比說不是 CSS 的出如今 CSS 目錄下,這裏須要使用同步方式讀取來處理這個問題markdown

  2. 完成的文章和未完成的合併在一塊兒,沒有按照未完成(n)文件夾來分開,這部分是由於 fs 的 fs.readdirSync 這個 API 讀取文件列表後,它的順序不是咱們在資源管理看到的,而是按照某種排序,咱們須要手動控制在讀取子目錄根目錄時,把未完成(n)文件名移到文件列表的最後app

// 檢測文件夾下屬文件名是否有n(未完成)這個文件夾,有的話,將這個n移動到數組末端
let nIndex = files.findIndex(f => f === 'n')
~nIndex && (files.splice(nIndex, 1), files.push('n'))
複製代碼

文件結構

目前只考慮到支持子目錄以及n(未完成),擴展這方面嘛,暫時沒考慮那麼多ui

示例:

let fpath = '前端'
const repPath = 'https://github.com/869288142/blog/tree/master'
const outputFile = 'README.md'

let g = require('./generateDir')

new g(repPath, outputFile, fpath).run()
複製代碼

完整代碼

let fs = require('fs') //讀寫文件就須要引入fs--文件系統模塊
let path = require('path')
let { sep } = path
class generateDir {
  constructor(repPath, outputFile, path) {
    this.repPath = repPath
    this.outputFile = outputFile
    this.path = path
  }
  run() {
    this.unLinkOutput(this.outputFile)
    this.readDir(this.path)
  }
  readDir(path) {
    let exists = fs.existsSync(path), //以同步的方法檢測目錄是否存在
      stat = fs.statSync(path) //文件信息

    if (exists && stat) {
      //若是目錄存在
      if (stat.isFile()) {
        //若是是文件
        let fpath = path.split(sep) //以路徑分割符將路徑分割成數組
        // 獲取文件名
        let fileName = fpath[fpath.length - 1]
        // 文件更新時間
        let updateTime = this.formatDate(stat.mtime)
        // 將內容追加到README.md
        let fileNameWithoutSuffix = fileName.replace(/(.*)\.md/, '$1')
        // 文件輸出內容
        let content =
          // 文件名
          `* [${fileNameWithoutSuffix}]` +
          // URL
          `(${this.repPath}/${fpath.join('/')}) ` +
          // 更新時間
          `更新於${updateTime}` +
          // 空行
          `\r\n \r\n`
        fs.appendFileSync(this.outputFile, content)
      } else if (stat.isDirectory()) {
        //若是是文件夾
        let fpath = path.split(sep) //以路徑分割符將路徑分割成數組
        // 獲取文件名
        let fileName = fpath[fpath.length - 1]
        let files = fs.readdirSync(path) //返回 指定目錄下全部文件名稱
        // 過濾掉只有n下屬文件夾和空n文件夾
        let normalContent = `**${fileName}**`
        let nContent = ' \r\n \r\n**撰寫中**'
        let totalContent = `${ fileName === 'n' ? nContent : normalContent } \r\n \r\n`

        if (files.length !== 1 && files.length !== 0) {
          // n 文件夾名替換成撰寫中
          fs.appendFileSync(this.outputFile, totalContent)
          // 遍歷文件夾下屬文件
          if (files && files.length > 0) {
            // 確保n文件夾的下屬文件在第一級文件夾後面輸出
            let nIndex = files.findIndex(f => f === 'n')
            ~nIndex && (files.splice(nIndex, 1), files.push('n'))
            // 對每一個文件進行遞歸操做
            files.forEach(file => {
              this.readDir(path + sep + file)
            })
          }
        }
      }
    } else {
      console.info('根目錄不存在.')
    }
  }
  formatDate(date) {
    return `${date.getFullYear()}.${date.getMonth() + 1}.${date.getDate()}`
  }
  unLinkOutput(outputFile) {
    let unlinkPath = `${path.resolve('.')}/${outputFile}`
    if (fs.existsSync(unlinkPath)) {
      fs.unlinkSync(unlinkPath)
    }
  }
}

module.exports = exports = generateDir
複製代碼

小結:

其實呢,這個應該挺多人想到的吧,嘻嘻,不過做爲萌新,仍是挺開心能用技術來簡化本身的平常操做,以前也嘗試過寫腳原本實現自動刪庫而後填充數據,代碼邏輯和質量方面也說不上好,若是大佬們以爲過得去的話,但願能獲得人生中的第一顆小星星,新人還在練習寫做中。this

相關文章
相關標籤/搜索