粥里有勺糖

vuePress-theme-reco 粥里有勺糖    2018 - 2023
粥里有勺糖 粥里有勺糖

Choose mode

  • dark
  • auto
  • light
关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
author-avatar

粥里有勺糖

285

文章

40

标签

关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
  • wheel

    • 个人作品
    • 时间管理CLI工具
      • 做一个CLI版的时间管理工具(一)
      • 做一个CLI版的时间管理工具(十)
      • 做一个CLI版的时间管理工具(11)
      • 做一个CLI版的时间管理工具(12)
      • 做一个CLI版的时间管理工具(13)
      • 做一个CLI版的时间管理工具(14)
      • 做一个CLI版的时间管理工具(15)
      • 做一个CLI版的时间管理工具(二)
      • 做一个CLI版的时间管理工具(三)
      • 做一个CLI版的时间管理工具(四)
      • 做一个CLI版的时间管理工具(五)
      • 做一个CLI版的时间管理工具(六)
      • 做一个CLI版的时间管理工具(七)
      • 做一个CLI版的时间管理工具(八)
      • 做一个CLI版的时间管理工具(九)
    • 组装个支持记笔记的CodePen
    • ESCheck工具原理解析及增强实现
    • 一款检测代码中TODO的eslint插件
    • 实现一个Web UI检测(视觉走查)工具ing
    • 从0-1实现文件下载CLI工具
    • 内联JS处理(ES语法降级&内容压缩)
    • Node CLI工具原理解析
    • 我打造的在线简历生成应用
    • 助你轻松编写与分享snippet的VsCode插件
    • SourceMap解析CLI工具实现
    • 一个通过NPM包共(分)享代码块的解决方案
    • 实践:给女朋友个性化定制应用-体重记录(一)
    • 实践:给女朋友个性化定制应用-体重记录(二)
    • 实践:给女朋友个性化定制应用-体重记录(三)

做一个CL版的时间管理工具(二)

vuePress-theme-reco 粥里有勺糖    2018 - 2023

做一个CL版的时间管理工具(二)

粥里有勺糖 2021-08-03 技术笔记个人作品CLI工具

# 做一个CLI版的时间管理工具(二)

# 前言

上一篇文章已经介绍了项目的背景与期望通过这个项目的达到的目的

搭建了项目的初始工程

本文就继续进行功能的拓展

# 功能开发

# MD转JSON

最简单的markdown格式如下

# 2021-08-03
## TaskName
* 摸鱼 0.6
1
2
3

其对应的JSON结构如下

[
  {
    "title": "2021-08-03",
    "tasks": [
      {
        "title": "TaskName",
        "things": [
          {
            "time": "0.6",
            "content": "摸鱼"
          }
        ]
      }
    ]
  }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  • 最外层是数组
    • 一个md中会存在多个1级标题,所以最外层数据结构使用数组
  • 第二层
    • title对应一级标题
    • tasks存放由二级标题及其子内容构成的任务列表,用数组存放
  • 第三层
    • title对应二级标题的内容
    • things由其子列表的每一行内容构成
      • 每一行内容对应一个基本事件单元
      • 基本事件单元包含事件内容和事件耗时两部分

转换过程如下:

将md内容读入,按行解析

const lines = fileContent.split('\n')
1

判断是否以# 一级标题开头,如果是则为新的一天

为其添加title,tasks属性

const resData = []
let item = null
for (const line of lines) {
       // 判断是否新的一天
       if (line.startsWith('# ')) {
           // 存储旧的
           if (item) {
               resData.push(item)
           }
       const title = line.replace(/#|\s/g, '')
        item = {
            title,
            tasks: []
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

紧接着判断是否以## 二级标题开头,如果是则将其作为task加入tasks列表

// 判断是否是任务
if (line.startsWith('## ')) {
    const title = line.replace(/#|\s/g, '')
    let task = {
        title,
        things: []
    }
    item.tasks.push(task)
}
1
2
3
4
5
6
7
8
9

判断是否以*开头,如果是则将其作为一件thing加入things列表

if (line.startsWith('* ')) {
    const task = item.tasks.pop()
    const { things } = task
    const rTime = /((0.\d*)|(\d*))?$/
    const time = line.match(rTime)[0] || '0'
    let step = -1, text = ''
    const content = (step = (text = line.replace(/\*|\s/g, '')).lastIndexOf(time)) === -1 ? text : text.slice(0, step)
    const thing = {
        time,
        content
    }
    things.push(thing)
    item.tasks.push(task)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

这样如此循环直到 遇到下一个 # 一级标题

完整代码链接 (opens new window)

# 添加指令

编辑bin/index.js文件

添加两个optionsoutput,json

当同时键入了 --output,--json两个参数时才执行导出json的操作

#!/usr/bin/env node
const json = require('../package.json');
const commander = require('commander');
const { getFilesContent, getFilePath, createFile } = require('../src/utils');
const { outputJson } = require('../src/output');

// 命令执行目录
const cwd = process.cwd()

// 设置版号
commander.version(json.version)

// 导出
commander.arguments('<filenames...>') // 多个文件/目录
    .option('-o, --output', 'Export analysis results')
    .option('-j, --json', 'Export result as json description file')
    .action((filenames, cmdObj) => {
        const { output, json } = cmdObj

        // 导出
        if (output) {
            let outFileName = 'res'
            // 后续逻辑

            // 获取所有文件的内容
            const content = getFilesContent(filenames.map(filename => {
                return getFilePath(cwd, filename)
            }))
            if (json) {
                createFile(getFilePath(cwd, `${outFileName}.json`), outputJson(content), false)
            }
        }
    })

commander.parse(process.argv)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

添加完成后执行timec --help查看添加的指令如下

图片

对应执行指令为

timec -oj filepath1 filepath2 ....
1
  • 其中process.cwd()能够获取到执行指令的目录
  • filenames参数获取到的内容是除开options部分的参数
  • cmdObj包含的是options参数的内容,值类型为布尔类型
    • --output对应output参数
    • --json对应json参数的内容
    • 以此类推

# 其它

由于每天空闲时间有限,本文就先到这

如果读者还感觉意犹未尽,敬请期待后续更新,或先关注一下仓库 (opens new window)

欢迎评论区提需求,交流探讨

本系列会不断的更新迭代,直至产品初代完成

  • 仓库地址 (opens new window)
Edit this page (opens new window)
Last Updated: 2022/5/15 12:46:34