Skip to content

Commit e83bfcb

Browse files
sy-recordsjamesgeorge007
andauthoredJan 22, 2021
feat: auto generate sidebar (#130)
* feat: auto generate sidebar * test: generate _sidebar.md * Apply suggestions from code review Co-authored-by: James George <[email protected]> * test: Add the sidebar file already exists test Co-authored-by: James George <[email protected]>
1 parent f7e6b37 commit e83bfcb

File tree

10 files changed

+168
-16
lines changed

10 files changed

+168
-16
lines changed
 

Diff for: ‎README.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Use `init` to generate your docs.
5252
```shell
5353
docsify init <path> [--local false] [--theme vue]
5454

55-
# docsify i <path> [--local false] [--theme vue]
55+
# docsify i <path> [-l false] [-t vue]
5656
```
5757

5858
`<path>` defaults to the current directory. Use relative paths like `./docs` (or `docs`).
@@ -75,7 +75,7 @@ Run a server on `localhost` with livereload.
7575
```shell
7676
docsify serve <path> [--open false] [--port 3000]
7777

78-
# docsify s <path> [--open false] [--port 3000]
78+
# docsify s <path> [-o false] [-p 3000]
7979
```
8080

8181
- `--open` option:
@@ -89,6 +89,22 @@ docsify serve <path> [--open false] [--port 3000]
8989
- Default: `3000`
9090
- Description: Choose a listen port, defaults to `3000`.
9191

92+
### `generate` command
93+
94+
Docsify's generators.
95+
96+
```shell
97+
docsify generate <path> [--sidebar _sidebar.md]
98+
99+
# docsify g <path> [-s _sidebar.md]
100+
```
101+
102+
- `--sidebar` option:
103+
- Shorthand: `-s`
104+
- Type: string
105+
- Default: `_sidebar.md`
106+
- Description: Generate sidebar file, defaults to `_sidebar.md`.
107+
92108
## Contributing
93109

94110
Please see the [Contributing Guidelines](./CONTRIBUTING.md)

Diff for: ‎e2e/cli.test.js.md

+16-12
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ Generated by [AVA](https://avajs.dev).
1111
`Usage: docsify <init|serve> <path>␊
1212
1313
Commands:␊
14-
docsify init [path] Creates new docs [aliases: i]␊
15-
docsify serve [path] Run local server to preview site. [aliases: s]␊
16-
docsify start <path> Server for SSR␊
14+
docsify init [path] Creates new docs [aliases: i]␊
15+
docsify serve [path] Run local server to preview site. [aliases: s]␊
16+
docsify start <path> Server for SSR␊
17+
docsify generate <path> Docsify's generators [aliases: g]␊
1718
1819
Global Options␊
1920
--help, -h Show help [boolean]␊
@@ -35,9 +36,10 @@ Generated by [AVA](https://avajs.dev).
3536
`Usage: docsify <init|serve> <path>␊
3637
3738
Commands:␊
38-
docsify init [path] Creates new docs [aliases: i]␊
39-
docsify serve [path] Run local server to preview site. [aliases: s]␊
40-
docsify start <path> Server for SSR␊
39+
docsify init [path] Creates new docs [aliases: i]␊
40+
docsify serve [path] Run local server to preview site. [aliases: s]␊
41+
docsify start <path> Server for SSR␊
42+
docsify generate <path> Docsify's generators [aliases: g]␊
4143
4244
Global Options␊
4345
--help, -h Show help [boolean]␊
@@ -57,9 +59,10 @@ Generated by [AVA](https://avajs.dev).
5759
`Usage: docsify <init|serve> <path>␊
5860
5961
Commands:␊
60-
docsify init [path] Creates new docs [aliases: i]␊
61-
docsify serve [path] Run local server to preview site. [aliases: s]␊
62-
docsify start <path> Server for SSR␊
62+
docsify init [path] Creates new docs [aliases: i]␊
63+
docsify serve [path] Run local server to preview site. [aliases: s]␊
64+
docsify start <path> Server for SSR␊
65+
docsify generate <path> Docsify's generators [aliases: g]␊
6366
6467
Global Options␊
6568
--help, -h Show help [boolean]␊
@@ -79,9 +82,10 @@ Generated by [AVA](https://avajs.dev).
7982
`Usage: docsify <init|serve> <path>␊
8083
8184
Commands:␊
82-
docsify init [path] Creates new docs [aliases: i]␊
83-
docsify serve [path] Run local server to preview site. [aliases: s]␊
84-
docsify start <path> Server for SSR␊
85+
docsify init [path] Creates new docs [aliases: i]␊
86+
docsify serve [path] Run local server to preview site. [aliases: s]␊
87+
docsify start <path> Server for SSR␊
88+
docsify generate <path> Docsify's generators [aliases: g]␊
8589
8690
Global Options␊
8791
--help, -h Show help [boolean]␊

Diff for: ‎e2e/cli.test.js.snap

31 Bytes
Binary file not shown.

Diff for: ‎e2e/commands/generate.test.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const test = require('ava')
2+
const fs = require('fs')
3+
const path = require('path')
4+
5+
const {run} = require('../helpers/test-utils.js')
6+
7+
const genPath = path.join(__dirname, 'generate-cmd')
8+
const docsPath = path.join(genPath, 'docs')
9+
10+
test.before('create temp directory', () => {
11+
// Cleanup if the directory already exists
12+
if (fs.existsSync(genPath)) {
13+
fs.rmdirSync(genPath, {recursive: true})
14+
}
15+
16+
fs.mkdirSync(genPath)
17+
})
18+
19+
test.after('cleanup', () => {
20+
fs.rmdirSync(genPath, {recursive: true})
21+
})
22+
23+
test('generate _sidebar.md', t => {
24+
run(['init', 'docs'], {cwd: genPath})
25+
run(['generate', 'docs'], {cwd: genPath})
26+
// Check for existence
27+
t.true(fs.existsSync(path.join(docsPath, '_sidebar.md')))
28+
29+
const {stderr} = run(['generate', 'docs'], {cwd: genPath})
30+
t.is(stderr, 'The sidebar file \'_sidebar.md\' already exists.')
31+
})

Diff for: ‎lib/cli.js

+17
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,23 @@ require('yargs')
109109
}),
110110
handler: argv => run.start(argv.path, argv.config, argv.port)
111111
})
112+
.command({
113+
command: 'generate <path>',
114+
aliases: 'g',
115+
desc: chalk.gray(y18n.__('generate')),
116+
builder: yargs =>
117+
yargs.options({
118+
sidebar: {
119+
alias: 's',
120+
default: '_sidebar.md',
121+
desc: chalk.gray(y18n.__('gen.sidebar')),
122+
nargs: 1,
123+
requiresArg: true,
124+
type: 'string'
125+
}
126+
}),
127+
handler: argv => run.generate(argv.path, argv.sidebar)
128+
})
112129
.help()
113130
.option('help', {
114131
alias: 'h',

Diff for: ‎lib/commands/generate.js

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
'use strict'
2+
3+
const fs = require('fs')
4+
const os = require('os')
5+
const {cwd, exists} = require('../util')
6+
const chalk = require('chalk')
7+
const path = require('path')
8+
const ignoreFiles = ['_navbar', '_coverpage', '_sidebar']
9+
10+
// eslint-disable-next-line
11+
module.exports = function (path = '', sidebar) {
12+
const cwdPath = cwd(path || '.')
13+
14+
if (exists(cwdPath)) {
15+
if (sidebar) {
16+
const sidebarPath = cwdPath + '/' + sidebar || '_sidebar.md'
17+
18+
if (!exists(sidebarPath)) {
19+
genSidebar(cwdPath, sidebarPath)
20+
console.log(chalk.green(`Successfully generated the sidebar file '${sidebar}'.`))
21+
return true
22+
}
23+
24+
console.error(chalk.red(`The sidebar file '${sidebar}' already exists.`))
25+
return false
26+
}
27+
}
28+
29+
console.error(chalk.red(`${cwdPath}`) + ' directory does not exist.')
30+
}
31+
32+
function genSidebar(cwdPath, sidebarPath) {
33+
let tree = ''
34+
let lastPath = ''
35+
let nodeName = ''
36+
getDirFiles(cwdPath, function (pathname) {
37+
path.relative(pathname, cwdPath)
38+
pathname = pathname.replace(cwdPath + '/', '')
39+
let filename = path.basename(pathname, '.md')
40+
let splitPath = pathname.split(path.sep)
41+
42+
if (ignoreFiles.indexOf(filename) === -1) {
43+
nodeName = '- [' + filename + '](' + pathname + ')' + os.EOL
44+
}
45+
46+
if (splitPath.length > 1) {
47+
if (splitPath[0] !== lastPath) {
48+
lastPath = splitPath[0]
49+
tree += os.EOL + '- ' + splitPath[0] + os.EOL
50+
}
51+
52+
tree += ' ' + nodeName
53+
} else {
54+
if (lastPath !== '') {
55+
lastPath = ''
56+
tree += os.EOL
57+
}
58+
59+
tree += nodeName
60+
}
61+
})
62+
fs.writeFile(sidebarPath, tree, 'utf8', err => {
63+
if (err) {
64+
console.error(chalk.red(`Couldn't generate the sidebar file, error: ${err.message}`))
65+
}
66+
})
67+
}
68+
69+
function getDirFiles(dir, callback) {
70+
fs.readdirSync(dir).forEach(function (file) {
71+
let pathname = path.join(dir, file)
72+
73+
if (fs.statSync(pathname).isDirectory()) {
74+
getDirFiles(pathname, callback)
75+
} else if (path.extname(file) === '.md') {
76+
callback(pathname)
77+
}
78+
})
79+
}

Diff for: ‎lib/commands/init.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module.exports = function (path = '', local, theme) {
2222
const cwdPath = cwd(path || '.')
2323

2424
if (exists(cwdPath)) {
25-
console.log(chalk.red(`${path || '.'}`) + ' already exists.')
25+
console.log(chalk.red(`${path || '.'} already exists.`))
2626

2727
prompt({
2828
type: 'confirm',

Diff for: ‎lib/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
init: require('./commands/init'),
33
serve: require('./commands/serve'),
4-
start: require('./commands/start')
4+
start: require('./commands/start'),
5+
generate: require('./commands/generate')
56
}

Diff for: ‎tools/locales/en.json

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"serve.open": "Open docs in default browser. To explicitly set --open to false you may use --no-open.",
1111
"serve.port": "Listen port.",
1212
"serve.indexname": "Custom filename instead of index.html to serve by default",
13+
"generate": "Docsify's generators",
14+
"generate.sidebar": "Generate sidebar file",
1315
"livereload.port": "livereload Listen port.",
1416
"usage": "Usage",
1517
"version": "Show version number"

Diff for: ‎tools/locales/zh.json

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"serve.open": "自动打开浏览器",
1111
"serve.port": "设置端口",
1212
"serve.indexname": "Custom filename instead of index.html to serve by default",
13+
"generate": "Docsify的生成器",
14+
"generate.sidebar": "生成侧边栏文件",
1315
"livereload.port": "设置livereload端口",
1416
"usage": "例子",
1517
"version": "当前版本号"

0 commit comments

Comments
 (0)
Please sign in to comment.