mirror of
https://github.com/wahyd4/docsify.git
synced 2026-08-10 05:48:18 +10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db7db5af8b | ||
|
|
a418096a29 | ||
|
|
90b490c9c1 | ||
|
|
7915027418 | ||
|
|
87b373b841 | ||
|
|
510ae37a04 | ||
|
|
ef53a07f49 | ||
|
|
9defe1bf7d | ||
|
|
b87f6ae5e8 | ||
|
|
b8b9dbc872 | ||
|
|
f7779b01d9 | ||
|
|
1c935b2fd7 | ||
|
|
114955558e | ||
|
|
847cf3b656 | ||
|
|
356b937d44 | ||
|
|
8df57f0bc2 | ||
|
|
73dfbf5be3 | ||
|
|
ecba3f1b05 | ||
|
|
e5452243b1 | ||
|
|
8b1000a4a5 | ||
|
|
897283418a | ||
|
|
7be6baae7a | ||
|
|
24ab3d4d10 | ||
|
|
424a243c5c | ||
|
|
9ce47c48af | ||
|
|
4e7485aa1f |
@@ -1,3 +1,30 @@
|
||||
## 1.6.1
|
||||
### Bug fixes
|
||||
- Fixed sidebar bug when the coverpage exist
|
||||
|
||||
## 1.6.0
|
||||
### Features
|
||||
- Improve sidebar performance. The active item is automatically scrolled in the visible view.
|
||||
- New doc helper: `! `. e.g. `! content` will be rendered as `<p class="tip">content</p>`
|
||||
|
||||
## 1.5.2
|
||||
### Bug fixes
|
||||
- Fixed number at the beginning of the slug
|
||||
|
||||
## 1.5.1
|
||||
### Bug fixes
|
||||
- Remove HTML tag when handling slug
|
||||
|
||||
## 1.5.0
|
||||
|
||||
### Bug fixes
|
||||
- Fix slugify.
|
||||
- Fix nav highlight.
|
||||
|
||||
### Features
|
||||
- Initialize the configuration by `window.$docsify`.
|
||||
- Markdown parser is configurable.
|
||||
|
||||
## 1.4.3
|
||||
### Bug fixes
|
||||
- Tweak style.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
- [CLI](https://github.com/QingWei-Li/docsify-cli)
|
||||
|
||||
## Features
|
||||
- Simple and lightweight (~12kb gzipped)
|
||||
- Simple and lightweight (~13kB gzipped)
|
||||
- Multiple themes
|
||||
- Not build static html files
|
||||
|
||||
@@ -51,6 +51,7 @@ These open-source projects are using docsify to generate their sites. Pull reque
|
||||
|
||||
- [docsify](https://docsify.js.org) - A magical documentation site generator.
|
||||
- [Snipaste](https://docs.snipaste.com/) - A new way to boost your productivity.
|
||||
- [puck](https://puck.zz173.com/) - A small & magical php framework.
|
||||
|
||||
## Similar projects
|
||||
- [docute](https://github.com/egoist/docute) - 📜 Effortlessly documentation done right
|
||||
@@ -67,11 +68,20 @@ These open-source projects are using docsify to generate their sites. Pull reque
|
||||
|
||||
## Development
|
||||
|
||||
### prepare
|
||||
```shell
|
||||
npm i && npm run dev
|
||||
open http://localhost:3000
|
||||
```
|
||||
|
||||
### More Language Highlight
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-php.js"></script>
|
||||
```
|
||||
|
||||
## License
|
||||
MIT
|
||||
|
||||
|
||||
+152
-27
@@ -33,7 +33,7 @@ Create `README.md` as the main page
|
||||
```
|
||||
|
||||
### Deploy!
|
||||
Push and open the **GitHub Pages** feature
|
||||
Push code and activate **GitHub Pages** via your repo's settings
|
||||

|
||||
|
||||
## CLI
|
||||
@@ -60,7 +60,11 @@ docsify serve docs
|
||||
|
||||
Read more [docsify-cli](https://github.com/QingWei-Li/docsify-cli)
|
||||
|
||||
## Themes
|
||||
|
||||
|
||||
## More
|
||||
|
||||
### Themes
|
||||
Currently available `vue.css` and `buble.css`
|
||||
```html
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
@@ -74,8 +78,6 @@ Minified files
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css">
|
||||
```
|
||||
|
||||
## More
|
||||
|
||||
### Multiple pages
|
||||
If you need other pages, directly create the markdown file, such as `guide.md` is `/#/guide`.
|
||||
|
||||
@@ -96,7 +98,7 @@ Code in `index.html`
|
||||
|
||||
### Cover Page
|
||||
|
||||
Generate a cover page through with markdown. Create a `_coverpage.md` and set `data-coverpage` in script tag.
|
||||
Generate a cover page with markdown. Create a `_coverpage.md` and set `data-coverpage` in the script tag.
|
||||
|
||||
```markdown
|
||||

|
||||
@@ -115,7 +117,7 @@ Generate a cover page through with markdown. Create a `_coverpage.md` and set `d
|
||||
```
|
||||
|
||||
#### Custom background
|
||||
Currently the background of cover page is generated randomly. We can customize the background, just using the syntax to add image.
|
||||
Currently the background of the cover page is generated randomly. We can customize the background color, or add a background image.
|
||||
|
||||
```markdown
|
||||
# docsify <small>1.2.0</small>
|
||||
@@ -131,31 +133,95 @@ Currently the background of cover page is generated randomly. We can customize t
|
||||

|
||||
```
|
||||
|
||||
### Markdown parser
|
||||
|
||||
### Options
|
||||
Docsify uses [marked](https://github.com/chjj/marked) to parse markdown. We can configure it
|
||||
|
||||
#### repo
|
||||
```js
|
||||
window.$docsify = {
|
||||
markdown: {
|
||||
smartypants: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And it can even be customized
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
markdown: function(marked) {
|
||||
// ...
|
||||
|
||||
return marked
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Doc Helpers
|
||||
#### p.tip
|
||||
|
||||
'! ' add your content will rendered as `<p class="tip">content</p>`
|
||||
|
||||
```markdown
|
||||
! Important **information**
|
||||
```
|
||||
|
||||
It will be rendered
|
||||
|
||||
```html
|
||||
<p class="tip">Important <strong>information</strong></p>
|
||||
```
|
||||
|
||||
e.g.
|
||||
|
||||
! Important **information**
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
You can add configurations in the script tag attributes or with `window.$docsify`.
|
||||
|
||||
### repo
|
||||
Display the [GitHub Corner](http://tholman.com/github-corners/) widget.
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-repo="your/repo"></script>
|
||||
```
|
||||
|
||||
#### max-level
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
repo: 'your/repo'
|
||||
}
|
||||
```
|
||||
|
||||
### max-level
|
||||
TOC level.
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-max-level="6"></script>
|
||||
```
|
||||
|
||||
#### el
|
||||
```js
|
||||
window.$docsify = {
|
||||
maxLevel: 6
|
||||
}
|
||||
```
|
||||
|
||||
### el
|
||||
Root element.
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
||||
```
|
||||
|
||||
#### sidebar-toggle
|
||||
```js
|
||||
window.$docsify = {
|
||||
el: '#app'
|
||||
}
|
||||
```
|
||||
|
||||
### sidebar-toggle
|
||||
|
||||
Sidebar with toggle
|
||||
|
||||
@@ -163,7 +229,13 @@ Sidebar with toggle
|
||||
<script src="//unpkg.com/docsify" data-sidebar-toggle></script>
|
||||
```
|
||||
|
||||
#### sidebar
|
||||
```js
|
||||
window.$docsify = {
|
||||
sidebarToggle: true
|
||||
}
|
||||
```
|
||||
|
||||
### sidebar
|
||||
|
||||
Custom sidebar. If it's set, the TOC will be disabled. Bind global variables on the `data-sidebar`.
|
||||
|
||||
@@ -187,9 +259,15 @@ Custom sidebar. If it's set, the TOC will be disabled. Bind global variables on
|
||||
```
|
||||
|
||||
|
||||
#### load-sidebar
|
||||
```js
|
||||
window.$docsify = {
|
||||
sidebar: 'sidebar'
|
||||
}
|
||||
```
|
||||
|
||||
Load sidebar markdown file. If it is configured, load the current directory `_sidebar.md` by default. If the file isn't exist, sidebar will appear as a TOC.
|
||||
### load-sidebar
|
||||
|
||||
Load sidebar markdown file. If it is configured, load the current directory `_sidebar.md` by default. If the file doesn't exist, the sidebar will appear as a TOC.
|
||||
** you should add `.nojekyll` into docs folder to prevent GitHub Pages from ignoring the `_sidebar.md`**
|
||||
|
||||
```html
|
||||
@@ -202,6 +280,12 @@ You can specify a file:
|
||||
<script src="/lib/docsify.js" data-load-sidebar="_sidebar.md"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
loadSidebar: '_sidebar.md'
|
||||
}
|
||||
```
|
||||
|
||||
The contents of the file can be:
|
||||
|
||||
```markdown
|
||||
@@ -211,14 +295,9 @@ The contents of the file can be:
|
||||
- [Getting Started](/getting-started)
|
||||
- [Dynamic Route Matching](/dynamic-matching)
|
||||
- [Nested Routes](/nested-routes)
|
||||
- [Programmatic Navigation](/navigation)
|
||||
- [Named Routes](/named-routes)
|
||||
- [Named Views](/named-views)
|
||||
- [Redirect and Alias](/redirect-and-alias)
|
||||
- [HTML5 History Mode](/history-mode)
|
||||
```
|
||||
|
||||
#### sub-max-level
|
||||
### sub-max-level
|
||||
|
||||
Display TOC in the custom sidebar. The default value is 0.
|
||||
|
||||
@@ -227,10 +306,14 @@ Display TOC in the custom sidebar. The default value is 0.
|
||||
<script src="/lib/docsify.js" data-load-sidebar data-max-sub-level="4"></script>
|
||||
```
|
||||
|
||||

|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
maxSubLevel: 4
|
||||
}
|
||||
```
|
||||
|
||||
#### load-navbar
|
||||
### load-navbar
|
||||
|
||||
Load navbar markdown file. If it is configured, load the current directory `_navbar.md` by default.
|
||||
|
||||
@@ -244,6 +327,12 @@ You can specify a file:
|
||||
<script src="/lib/docsify.js" data-load-navbar="_navbar.md"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
loadNavbar: '_navbar.md'
|
||||
}
|
||||
```
|
||||
|
||||
The contents of the file can be:
|
||||
|
||||
```markdown
|
||||
@@ -260,7 +349,7 @@ If you write a sub level list, it will generate a dropdown list.
|
||||
- [chinese](/zh-cn)
|
||||
```
|
||||
|
||||
#### router
|
||||
### router
|
||||
|
||||
Hash router.
|
||||
|
||||
@@ -268,16 +357,32 @@ Hash router.
|
||||
<script src="/lib/docsify.js" data-router></script>
|
||||
```
|
||||
|
||||
#### auto2top
|
||||
```js
|
||||
window.$docsify = {
|
||||
router: true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### auto2top
|
||||
|
||||
Scroll to the top on changing hash.
|
||||
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-auto2top></script>
|
||||
<!-- Set offset top -->
|
||||
<script src="/lib/docsify.js" data-auto2top="50"></script>
|
||||
```
|
||||
|
||||
#### homepage
|
||||
```js
|
||||
window.$docsify = {
|
||||
auto2top: true,
|
||||
// auto2top: 50
|
||||
}
|
||||
```
|
||||
|
||||
### homepage
|
||||
|
||||
`README.md` will be rendered as a homepage for your website in the docs folder, but sometimes we want to specify another file as a homepage, or even use the `README.md` in your repo. We can use (need `data-router`):
|
||||
|
||||
@@ -288,7 +393,14 @@ Scroll to the top on changing hash.
|
||||
```
|
||||
|
||||
|
||||
#### basePath
|
||||
```js
|
||||
window.$docsify = {
|
||||
homepage: true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### basePath
|
||||
|
||||
If your HTML entry file and the markdown files are in different directories, we can use:
|
||||
|
||||
@@ -300,7 +412,14 @@ If your HTML entry file and the markdown files are in different directories, we
|
||||
```
|
||||
|
||||
|
||||
#### coverpage
|
||||
```js
|
||||
window.$docsify = {
|
||||
basePath: '/base/'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### coverpage
|
||||
|
||||
Generate cover page.
|
||||
|
||||
@@ -308,4 +427,10 @@ Generate cover page.
|
||||
<script src="/lib/docsify.js" data-coverpage></script>
|
||||
<!-- or -->
|
||||
<script src="/lib/docsify.js" data-coverpage="other.md"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
coverpage: true
|
||||
}
|
||||
```
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||

|
||||
|
||||
# docsify <small>1.4.2</small>
|
||||
# docsify <small>1.6.0</small>
|
||||
|
||||
> A magical documentation site generator.
|
||||
|
||||
- Simple and lightweight (~12kb gzipped)
|
||||
- Simple and lightweight (~13kB gzipped)
|
||||
- Multiple themes
|
||||
- Not build static html files
|
||||
|
||||
|
||||
+147
-24
@@ -65,7 +65,10 @@ docsify serve docs
|
||||
|
||||
更多选项参考 [docsify-cli](https://github.com/QingWei-Li/docsify-cli)
|
||||
|
||||
## 主题
|
||||
|
||||
## 更多功能
|
||||
|
||||
### 主题
|
||||
目前提供 vue.css 和 buble.css,直接修改 `index.html` 里的 cdn 地址即可
|
||||
```html
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
@@ -79,8 +82,6 @@ docsify serve docs
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css">
|
||||
```
|
||||
|
||||
## 更多功能
|
||||
|
||||
### 多页面
|
||||
`README.md` 作为主页面,如果需要其他页面,直接在文档目录下创建对应的 `*.md` 文件,例如创建一个 `guide.md` 那么对应的路由就是 `/#/guide`。
|
||||
|
||||
@@ -138,30 +139,95 @@ docsify serve docs
|
||||

|
||||
```
|
||||
|
||||
### 自定义 Markdown parser
|
||||
|
||||
### 配置参数
|
||||
默认使用 [marked](https://github.com/chjj/marked) 处理 markdown 部分,你可以修改默认配置
|
||||
|
||||
#### repo
|
||||
```js
|
||||
window.$docsify = {
|
||||
markdown: {
|
||||
smartypants: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
甚至可以完全定制化
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
markdown: function(marked) {
|
||||
// ...
|
||||
|
||||
return marked
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 文档助手
|
||||
#### 内置「提示」语法
|
||||
|
||||
感叹号加空格,后面接内容,会渲染成带 tip 类名的段落。
|
||||
|
||||
```markdown
|
||||
! 提示信息,**支持其他 markdown 语法**
|
||||
```
|
||||
|
||||
将被渲染成
|
||||
|
||||
```html
|
||||
<p class="tip">提示信息<strong>支持其他 markdown 语法</strong></p>
|
||||
```
|
||||
|
||||
效果
|
||||
|
||||
! 适合显示醒目的内容
|
||||
|
||||
## 配置参数
|
||||
|
||||
你可以通过在标签上添加属性的方式,或者给 `window.$docsify` 传配置信息。
|
||||
|
||||
### repo
|
||||
参考本文档的右上角的 GitHub 图标,如果要开启的话,将 `index.html` 里的 script 改成
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-repo="your/repo"></script>
|
||||
```
|
||||
|
||||
#### max-level
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
repo: 'your/repo'
|
||||
}
|
||||
```
|
||||
|
||||
### max-level
|
||||
目录最大展开层级,默认值为 6
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-max-level="6"></script>
|
||||
```
|
||||
|
||||
#### el
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
maxLevel: 6
|
||||
}
|
||||
```
|
||||
|
||||
### el
|
||||
替换节点元素,默认为 `#app`
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
||||
```
|
||||
|
||||
#### sidebar-toggle
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
el: '#app'
|
||||
}
|
||||
```
|
||||
|
||||
### sidebar-toggle
|
||||
|
||||
Sidebar 开关按钮
|
||||
|
||||
@@ -169,7 +235,14 @@ Sidebar 开关按钮
|
||||
<script src="//unpkg.com/docsify" data-sidebar-toggle></script>
|
||||
```
|
||||
|
||||
#### sidebar
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
sidebarToggle: true
|
||||
}
|
||||
```
|
||||
|
||||
### sidebar
|
||||
|
||||
设置后 TOC 功能将不可用,适合导航较多的文档,`data-sidebar` 传入全局变量名。
|
||||
|
||||
@@ -192,7 +265,14 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-sidebar="sidebar"></script>
|
||||
```
|
||||
|
||||
#### load-sidebar
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
sidebar: 'sidebar'
|
||||
}
|
||||
```
|
||||
|
||||
### load-sidebar
|
||||
|
||||
读取侧边栏配置文件,如果配置,默认加载当前目录下的 `_sidebar.md`。如果文件不存在,会显示 TOC 作为侧边栏内容。如果你有二级目录,也应该放置一份配置文件。
|
||||
**如果用 `_` 开头作为文件名,你应该在文档目录下添加 `.nojekyll`,阻止 GitHub Pages 忽略下划线开头的文件。**
|
||||
@@ -201,12 +281,19 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-load-sidebar></script>
|
||||
```
|
||||
|
||||
|
||||
你可以指定侧边栏文件名
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-sidebar="_sidebar.md"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
loadSidebar: '_sidebar.md'
|
||||
}
|
||||
```
|
||||
|
||||
`_sidebar.md` 的内容可以是这样的
|
||||
|
||||
```markdown
|
||||
@@ -216,14 +303,9 @@ Sidebar 开关按钮
|
||||
- [Getting Started](/getting-started)
|
||||
- [Dynamic Route Matching](/dynamic-matching)
|
||||
- [Nested Routes](/nested-routes)
|
||||
- [Programmatic Navigation](/navigation)
|
||||
- [Named Routes](/named-routes)
|
||||
- [Named Views](/named-views)
|
||||
- [Redirect and Alias](/redirect-and-alias)
|
||||
- [HTML5 History Mode](/history-mode)
|
||||
```
|
||||
|
||||
#### sub-max-level
|
||||
### sub-max-level
|
||||
|
||||
显示 TOC 在自定义的侧边栏里,默认最大显示 0 层。
|
||||
|
||||
@@ -232,10 +314,13 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-load-sidebar data-max-sub-level="4"></script>
|
||||
```
|
||||
|
||||

|
||||
```js
|
||||
window.$docsify = {
|
||||
maxSubLevel: 4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### load-navbar
|
||||
### load-navbar
|
||||
|
||||
读取导航配置文件,如果配置,默认加载当前目录下的 `_navbar.md`。如果文件不存在,会显示 html 里定义的导航栏。
|
||||
|
||||
@@ -249,6 +334,12 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-load-navbar="_navbar.md"></script>
|
||||
```
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
loadNavbar: '_navbar.md'
|
||||
}
|
||||
```
|
||||
|
||||
`_navbar.md` 的内容可以是这样
|
||||
|
||||
```markdown
|
||||
@@ -265,7 +356,7 @@ Sidebar 开关按钮
|
||||
```
|
||||
|
||||
|
||||
#### router
|
||||
### router
|
||||
|
||||
开启 hash router 功能,同时多页面切换不会重新加载资源。资源路径会被替换成 `/#/` 的形式。
|
||||
|
||||
@@ -273,7 +364,13 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-router></script>
|
||||
```
|
||||
|
||||
#### auto2top
|
||||
```js
|
||||
window.$docsify = {
|
||||
router: true
|
||||
}
|
||||
```
|
||||
|
||||
### auto2top
|
||||
|
||||
切换路由时自动跳转到页面顶部
|
||||
|
||||
@@ -282,7 +379,13 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-auto2top></script>
|
||||
```
|
||||
|
||||
#### homepage
|
||||
```js
|
||||
window.$docsify = {
|
||||
auto2top: true
|
||||
}
|
||||
```
|
||||
|
||||
### homepage
|
||||
|
||||
默认情况下网站会将根目录下 `README.md` 作为首页渲染,但是有些时候我们想指定其他文件,甚至想直接将 repo 下的 README 作为首页。你可以这样做(需要设置 `data-router`):
|
||||
|
||||
@@ -293,7 +396,13 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-homepage="Welcome.md"></script>
|
||||
```
|
||||
|
||||
#### basePath
|
||||
```js
|
||||
window.$docsify = {
|
||||
homepage: true
|
||||
}
|
||||
```
|
||||
|
||||
### basePath
|
||||
|
||||
指定加载文档的路径,如果你的 HTML 入口文件和文档是放在不同地方,你可以设置:
|
||||
|
||||
@@ -304,7 +413,14 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-base-path="https://docsify.js.org/"></script>
|
||||
```
|
||||
|
||||
#### coverpage
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
basePath: '/base/'
|
||||
}
|
||||
```
|
||||
|
||||
### coverpage
|
||||
|
||||
生成封面,参考 [#封面](/zh-cn#封面).
|
||||
|
||||
@@ -314,3 +430,10 @@ Sidebar 开关按钮
|
||||
<script src="/lib/docsify.js" data-coverpage="other.md"></script>
|
||||
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
coverpage: true
|
||||
}
|
||||
```
|
||||
|
||||
+132
-73
@@ -118,14 +118,18 @@ function slugify (string) {
|
||||
var re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,.\/:;<=>?@\[\]^`{|}~]/g;
|
||||
var maintainCase = false;
|
||||
var replacement = '-';
|
||||
|
||||
slugify.occurrences = slugify.occurrences || {};
|
||||
|
||||
if (typeof string !== 'string') { return '' }
|
||||
if (!maintainCase) { string = string.toLowerCase(); }
|
||||
|
||||
var slug = string.trim()
|
||||
.replace(/<[^>\d]+>/g, '')
|
||||
.replace(re, '')
|
||||
.replace(/\s/g, replacement);
|
||||
.replace(/\s/g, replacement)
|
||||
.replace(/-+/g, replacement)
|
||||
.replace(/^(\d)/, '_$1');
|
||||
var occurrences = slugify.occurrences[slug];
|
||||
|
||||
if (slugify.occurrences.hasOwnProperty(slug)) {
|
||||
@@ -143,6 +147,27 @@ function slugify (string) {
|
||||
return slug
|
||||
}
|
||||
|
||||
slugify.clear = function () {
|
||||
slugify.occurrences = {};
|
||||
};
|
||||
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var merge = Object.assign || function (to) {
|
||||
var arguments$1 = arguments;
|
||||
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var from = Object(arguments$1[i]);
|
||||
|
||||
for (var key in from) {
|
||||
if (hasOwnProperty.call(from, key)) {
|
||||
to[key] = from[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to
|
||||
};
|
||||
|
||||
/**
|
||||
* Active sidebar when scroll
|
||||
* @link https://buble.surge.sh/
|
||||
@@ -150,10 +175,12 @@ function slugify (string) {
|
||||
function scrollActiveSidebar () {
|
||||
if (isMobile()) { return }
|
||||
|
||||
var hoveredOverSidebar = false;
|
||||
var anchors = document.querySelectorAll('.anchor');
|
||||
var sidebar = document.querySelector('aside.sidebar');
|
||||
var nav = {};
|
||||
var lis = document.querySelectorAll('.sidebar li');
|
||||
var active = null;
|
||||
var lis = sidebar.querySelectorAll('li');
|
||||
var active = sidebar.querySelector('li.active');
|
||||
|
||||
for (var i = 0, len = lis.length; i < len; i += 1) {
|
||||
var li = lis[i];
|
||||
@@ -168,27 +195,34 @@ function scrollActiveSidebar () {
|
||||
}
|
||||
|
||||
function highlight () {
|
||||
var top = document.body.scrollTop;
|
||||
var last;
|
||||
|
||||
for (var i = 0, len = anchors.length; i < len; i += 1) {
|
||||
var node = anchors[i];
|
||||
var bcr = node.getBoundingClientRect();
|
||||
|
||||
if (bcr.top < 10 && bcr.bottom > 10) {
|
||||
var li = nav[node.getAttribute('data-id')];
|
||||
|
||||
if (!li || li === active) { return }
|
||||
if (active) { active.setAttribute('class', ''); }
|
||||
|
||||
li.setAttribute('class', 'active');
|
||||
active = li;
|
||||
|
||||
return
|
||||
if (node.offsetTop > top) {
|
||||
if (!last) { last = node; }
|
||||
break
|
||||
} else {
|
||||
last = node;
|
||||
}
|
||||
}
|
||||
if (!last) { return }
|
||||
var li = nav[last.getAttribute('data-id')];
|
||||
|
||||
if (!li || li === active) { return }
|
||||
if (active) { active.classList.remove('active'); }
|
||||
|
||||
li.classList.add('active');
|
||||
active = li;
|
||||
!hoveredOverSidebar && sticky.isSticky && active.scrollIntoView();
|
||||
}
|
||||
|
||||
window.removeEventListener('scroll', highlight);
|
||||
window.addEventListener('scroll', highlight);
|
||||
highlight();
|
||||
sidebar.addEventListener('mouseover', function () { hoveredOverSidebar = true; });
|
||||
sidebar.addEventListener('mouseleave', function () { hoveredOverSidebar = false; });
|
||||
}
|
||||
|
||||
function scrollIntoView () {
|
||||
@@ -196,7 +230,9 @@ function scrollIntoView () {
|
||||
if (!id || !id.length) { return }
|
||||
var section = document.querySelector(decodeURIComponent(id[0]));
|
||||
|
||||
if (section) { section.scrollIntoView(); }
|
||||
if (section) { setTimeout(function () { return section.scrollIntoView(); }, 0); }
|
||||
|
||||
return section
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,13 +248,13 @@ function activeLink (dom, activeParent) {
|
||||
.forEach(function (node) {
|
||||
if (host.indexOf(node.href) === 0 && !target) {
|
||||
activeParent
|
||||
? node.parentNode.setAttribute('class', 'active')
|
||||
: node.setAttribute('class', 'active');
|
||||
? node.parentNode.classList.add('active')
|
||||
: node.classList.add('active');
|
||||
target = node;
|
||||
} else {
|
||||
activeParent
|
||||
? node.parentNode.removeAttribute('class')
|
||||
: node.removeAttribute('class');
|
||||
? node.parentNode.classList.remove('active')
|
||||
: node.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -236,13 +272,18 @@ function bindToggle (dom) {
|
||||
dom.addEventListener('click', function () { return body.classList.toggle('close'); });
|
||||
|
||||
if (isMobile()) {
|
||||
document.querySelector('aside')
|
||||
.addEventListener('click', function (_) { return body.classList.toggle('close'); });
|
||||
var sidebar = document.querySelector('aside.sidebar');
|
||||
document.body.addEventListener('click', function (e) {
|
||||
if (e.target !== dom && !dom.contains(e.target)) { body.classList.toggle('close'); }
|
||||
if (sidebar.contains(e.target)) { setTimeout(function () { return activeLink(sidebar, true); }, 0); }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function scroll2Top () {
|
||||
document.body.scrollTop = 0;
|
||||
function scroll2Top (offset) {
|
||||
if ( offset === void 0 ) offset = 0;
|
||||
|
||||
document.body.scrollTop = offset === true ? 0 : Number(offset);
|
||||
}
|
||||
|
||||
function sticky () {
|
||||
@@ -252,8 +293,10 @@ function sticky () {
|
||||
return (function () {
|
||||
if (window.pageYOffset >= coverHeight || dom.classList.contains('hidden')) {
|
||||
document.body.classList.add('sticky');
|
||||
sticky.isSticky = true;
|
||||
} else {
|
||||
document.body.classList.remove('sticky');
|
||||
sticky.isSticky = false;
|
||||
}
|
||||
})()
|
||||
}
|
||||
@@ -2411,50 +2454,71 @@ function tree (toc, tpl) {
|
||||
}
|
||||
|
||||
var OPTIONS$1 = {};
|
||||
var markdown = marked;
|
||||
var toc = [];
|
||||
var CACHE = {};
|
||||
var TIP_RE = /^!\s/;
|
||||
|
||||
var renderTo = function (dom, content) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
dom.innerHTML = content;
|
||||
slugify.clear();
|
||||
|
||||
return dom
|
||||
};
|
||||
var toc = [];
|
||||
var renderer = new marked.Renderer();
|
||||
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
* init render
|
||||
* @param {Object} options
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
var slug = slugify(text);
|
||||
var route = '';
|
||||
function init (options) {
|
||||
OPTIONS$1 = options;
|
||||
|
||||
if (OPTIONS$1.router) {
|
||||
route = "#/" + (getRoute());
|
||||
var renderer = new marked.Renderer();
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
var slug = slugify(text);
|
||||
var route = '';
|
||||
|
||||
if (OPTIONS$1.router) {
|
||||
route = "#/" + (getRoute());
|
||||
}
|
||||
|
||||
toc.push({ level: level, slug: (route + "#" + (encodeURIComponent(slug))), title: text });
|
||||
|
||||
return ("<h" + level + " id=\"" + slug + "\"><a href=\"" + route + "#" + slug + "\" data-id=\"" + slug + "\" class=\"anchor\"><span>" + text + "</span></a></h" + level + ">")
|
||||
};
|
||||
// highlight code
|
||||
renderer.code = function (code, lang) {
|
||||
if ( lang === void 0 ) lang = '';
|
||||
|
||||
var hl = prism.highlight(code, prism.languages[lang] || prism.languages.markup)
|
||||
.replace(/{{/g, '<span>{{</span>');
|
||||
|
||||
return ("<pre data-lang=\"" + lang + "\"><code class=\"lang-" + lang + "\">" + hl + "</code></pre>")
|
||||
};
|
||||
renderer.link = function (href, title, text) {
|
||||
if (OPTIONS$1.router && !/:/.test(href)) {
|
||||
href = ("#/" + href).replace(/\/\//g, '/');
|
||||
}
|
||||
|
||||
return ("<a href=\"" + href + "\" title=\"" + (title || '') + "\">" + text + "</a>")
|
||||
};
|
||||
renderer.paragraph = function (text) {
|
||||
var isTip = TIP_RE.test(text);
|
||||
return isTip ? ("<p class=\"tip\">" + (text.replace(TIP_RE, '')) + "</p>") : ("<p>" + text + "</p>")
|
||||
};
|
||||
|
||||
if (typeof OPTIONS$1.markdown === 'function') {
|
||||
markdown.setOptions({ renderer: renderer });
|
||||
markdown = OPTIONS$1.markdown.call(this, markdown);
|
||||
} else {
|
||||
markdown.setOptions(merge({ renderer: renderer }, OPTIONS$1.markdown));
|
||||
}
|
||||
|
||||
toc.push({ level: level, slug: (route + "#" + (encodeURIComponent(slug))), title: text });
|
||||
|
||||
return ("<h" + level + " id=\"" + slug + "\"><a href=\"" + route + "#" + slug + "\" data-id=\"" + slug + "\" class=\"anchor\"><span>" + text + "</span></a></h" + level + ">")
|
||||
};
|
||||
// highlight code
|
||||
renderer.code = function (code, lang) {
|
||||
if ( lang === void 0 ) lang = '';
|
||||
|
||||
var hl = prism.highlight(code, prism.languages[lang] || prism.languages.markup)
|
||||
.replace(/{{/g, '<span>{{</span>');
|
||||
|
||||
return ("<pre data-lang=\"" + lang + "\"><code class=\"lang-" + lang + "\">" + hl + "</code></pre>")
|
||||
};
|
||||
renderer.link = function (href, title, text) {
|
||||
if (OPTIONS$1.router && !/:/.test(href)) {
|
||||
href = ("#/" + href).replace(/\/\//g, '/');
|
||||
}
|
||||
|
||||
return ("<a href=\"" + href + "\" title=\"" + (title || '') + "\">" + text + "</a>")
|
||||
};
|
||||
marked.setOptions({ renderer: renderer });
|
||||
}
|
||||
|
||||
/**
|
||||
* App
|
||||
@@ -2483,14 +2547,14 @@ function renderApp (dom, replace) {
|
||||
* article
|
||||
*/
|
||||
function renderArticle (content) {
|
||||
renderTo('article', content ? marked(content) : 'not found');
|
||||
renderTo('article', content ? markdown(content) : 'not found');
|
||||
if (!OPTIONS$1.sidebar && !OPTIONS$1.loadSidebar) { renderSidebar(); }
|
||||
|
||||
if (content && typeof Vue !== 'undefined' && typeof Vuep !== 'undefined') {
|
||||
var vm = new Vue({ el: 'main' }); // eslint-disable-line
|
||||
vm.$nextTick(function (_) { return scrollActiveSidebar(); });
|
||||
}
|
||||
if (OPTIONS$1.auto2top) { scroll2Top(); }
|
||||
if (OPTIONS$1.auto2top) { setTimeout(function () { return scroll2Top(OPTIONS$1.auto2top); }, 0); }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2500,7 +2564,7 @@ function renderNavbar (content) {
|
||||
if (CACHE.navbar && CACHE.navbar === content) { return }
|
||||
CACHE.navbar = content;
|
||||
|
||||
if (content) { renderTo('nav', marked(content)); }
|
||||
if (content) { renderTo('nav', markdown(content)); }
|
||||
activeLink('nav');
|
||||
}
|
||||
|
||||
@@ -2511,7 +2575,7 @@ function renderSidebar (content) {
|
||||
var html;
|
||||
|
||||
if (content) {
|
||||
html = marked(content);
|
||||
html = markdown(content);
|
||||
} else if (OPTIONS$1.sidebar) {
|
||||
html = tree(OPTIONS$1.sidebar, '<ul>');
|
||||
} else {
|
||||
@@ -2520,7 +2584,7 @@ function renderSidebar (content) {
|
||||
|
||||
renderTo('aside.sidebar', html);
|
||||
var target = activeLink('aside.sidebar', true);
|
||||
if (content) { renderSubSidebar(target); }
|
||||
if (target) { renderSubSidebar(target); }
|
||||
toc = [];
|
||||
|
||||
scrollActiveSidebar();
|
||||
@@ -2544,7 +2608,7 @@ function renderCover (content) {
|
||||
if (renderCover.rendered) { return }
|
||||
|
||||
// render cover
|
||||
var html = marked(content);
|
||||
var html = markdown(content);
|
||||
var match = html.trim().match('<p><img[^s]+src="(.*?)"[^a]+alt="(.*?)"></p>$');
|
||||
|
||||
// render background
|
||||
@@ -2603,15 +2667,7 @@ function renderLoading (ref) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Config
|
||||
* @param {Object} options
|
||||
*/
|
||||
function config (options) {
|
||||
OPTIONS$1 = options;
|
||||
}
|
||||
|
||||
var OPTIONS = {
|
||||
var OPTIONS = merge({
|
||||
el: '#app',
|
||||
repo: '',
|
||||
maxLevel: 6,
|
||||
@@ -2625,7 +2681,7 @@ var OPTIONS = {
|
||||
coverpage: '',
|
||||
basePath: '',
|
||||
auto2top: false
|
||||
};
|
||||
}, window.$docsify);
|
||||
var script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop();
|
||||
|
||||
// load configuration for script attribute
|
||||
@@ -2641,7 +2697,7 @@ if (script) {
|
||||
}
|
||||
|
||||
// load options
|
||||
config(OPTIONS);
|
||||
init(OPTIONS);
|
||||
|
||||
var cacheRoute = null;
|
||||
var cacheXhr = null;
|
||||
@@ -2701,7 +2757,10 @@ var Docsify = function () {
|
||||
var dom = document.querySelector(OPTIONS.el) || document.body;
|
||||
var replace = dom !== document.body;
|
||||
var main = function () {
|
||||
mainRender(function (_) { return scrollIntoView(); });
|
||||
mainRender(function (_) {
|
||||
scrollIntoView();
|
||||
activeLink('nav');
|
||||
});
|
||||
};
|
||||
|
||||
// Render app
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docsify",
|
||||
"version": "1.4.3",
|
||||
"version": "1.6.1",
|
||||
"description": "A magical documentation generator.",
|
||||
"main": "lib/docsify.js",
|
||||
"files": [
|
||||
|
||||
+39
-23
@@ -7,10 +7,12 @@ import { isMobile } from './util'
|
||||
export function scrollActiveSidebar () {
|
||||
if (isMobile()) return
|
||||
|
||||
let hoveredOverSidebar = false
|
||||
const anchors = document.querySelectorAll('.anchor')
|
||||
const sidebar = document.querySelector('aside.sidebar')
|
||||
const nav = {}
|
||||
const lis = document.querySelectorAll('.sidebar li')
|
||||
let active = null
|
||||
const lis = sidebar.querySelectorAll('li')
|
||||
let active = sidebar.querySelector('li.active')
|
||||
|
||||
for (let i = 0, len = lis.length; i < len; i += 1) {
|
||||
const li = lis[i]
|
||||
@@ -25,27 +27,34 @@ export function scrollActiveSidebar () {
|
||||
}
|
||||
|
||||
function highlight () {
|
||||
const top = document.body.scrollTop
|
||||
let last
|
||||
|
||||
for (let i = 0, len = anchors.length; i < len; i += 1) {
|
||||
const node = anchors[i]
|
||||
const bcr = node.getBoundingClientRect()
|
||||
|
||||
if (bcr.top < 10 && bcr.bottom > 10) {
|
||||
const li = nav[node.getAttribute('data-id')]
|
||||
|
||||
if (!li || li === active) return
|
||||
if (active) active.setAttribute('class', '')
|
||||
|
||||
li.setAttribute('class', 'active')
|
||||
active = li
|
||||
|
||||
return
|
||||
if (node.offsetTop > top) {
|
||||
if (!last) last = node
|
||||
break
|
||||
} else {
|
||||
last = node
|
||||
}
|
||||
}
|
||||
if (!last) return
|
||||
const li = nav[last.getAttribute('data-id')]
|
||||
|
||||
if (!li || li === active) return
|
||||
if (active) active.classList.remove('active')
|
||||
|
||||
li.classList.add('active')
|
||||
active = li
|
||||
!hoveredOverSidebar && sticky.isSticky && active.scrollIntoView()
|
||||
}
|
||||
|
||||
window.removeEventListener('scroll', highlight)
|
||||
window.addEventListener('scroll', highlight)
|
||||
highlight()
|
||||
sidebar.addEventListener('mouseover', () => { hoveredOverSidebar = true })
|
||||
sidebar.addEventListener('mouseleave', () => { hoveredOverSidebar = false })
|
||||
}
|
||||
|
||||
export function scrollIntoView () {
|
||||
@@ -53,7 +62,9 @@ export function scrollIntoView () {
|
||||
if (!id || !id.length) return
|
||||
const section = document.querySelector(decodeURIComponent(id[0]))
|
||||
|
||||
if (section) section.scrollIntoView()
|
||||
if (section) setTimeout(() => section.scrollIntoView(), 0)
|
||||
|
||||
return section
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,13 +82,13 @@ export function activeLink (dom, activeParent) {
|
||||
.forEach(node => {
|
||||
if (host.indexOf(node.href) === 0 && !target) {
|
||||
activeParent
|
||||
? node.parentNode.setAttribute('class', 'active')
|
||||
: node.setAttribute('class', 'active')
|
||||
? node.parentNode.classList.add('active')
|
||||
: node.classList.add('active')
|
||||
target = node
|
||||
} else {
|
||||
activeParent
|
||||
? node.parentNode.removeAttribute('class')
|
||||
: node.removeAttribute('class')
|
||||
? node.parentNode.classList.remove('active')
|
||||
: node.classList.remove('active')
|
||||
}
|
||||
})
|
||||
|
||||
@@ -95,13 +106,16 @@ export function bindToggle (dom) {
|
||||
dom.addEventListener('click', () => body.classList.toggle('close'))
|
||||
|
||||
if (isMobile()) {
|
||||
document.querySelector('aside')
|
||||
.addEventListener('click', _ => body.classList.toggle('close'))
|
||||
const sidebar = document.querySelector('aside.sidebar')
|
||||
document.body.addEventListener('click', e => {
|
||||
if (e.target !== dom && !dom.contains(e.target)) body.classList.toggle('close')
|
||||
if (sidebar.contains(e.target)) setTimeout(() => activeLink(sidebar, true), 0)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function scroll2Top () {
|
||||
document.body.scrollTop = 0
|
||||
export function scroll2Top (offset = 0) {
|
||||
document.body.scrollTop = offset === true ? 0 : Number(offset)
|
||||
}
|
||||
|
||||
export function sticky () {
|
||||
@@ -111,8 +125,10 @@ export function sticky () {
|
||||
return (function () {
|
||||
if (window.pageYOffset >= coverHeight || dom.classList.contains('hidden')) {
|
||||
document.body.classList.add('sticky')
|
||||
sticky.isSticky = true
|
||||
} else {
|
||||
document.body.classList.remove('sticky')
|
||||
sticky.isSticky = false
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
+9
-6
@@ -1,8 +1,8 @@
|
||||
import { load, camel2kebab, isNil, getRoute } from './util'
|
||||
import { scrollIntoView } from './event'
|
||||
import { load, camel2kebab, isNil, getRoute, merge } from './util'
|
||||
import { scrollIntoView, activeLink } from './event'
|
||||
import * as render from './render'
|
||||
|
||||
const OPTIONS = {
|
||||
const OPTIONS = merge({
|
||||
el: '#app',
|
||||
repo: '',
|
||||
maxLevel: 6,
|
||||
@@ -16,7 +16,7 @@ const OPTIONS = {
|
||||
coverpage: '',
|
||||
basePath: '',
|
||||
auto2top: false
|
||||
}
|
||||
}, window.$docsify)
|
||||
const script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop()
|
||||
|
||||
// load configuration for script attribute
|
||||
@@ -32,7 +32,7 @@ if (script) {
|
||||
}
|
||||
|
||||
// load options
|
||||
render.config(OPTIONS)
|
||||
render.init(OPTIONS)
|
||||
|
||||
let cacheRoute = null
|
||||
let cacheXhr = null
|
||||
@@ -92,7 +92,10 @@ const Docsify = function () {
|
||||
const dom = document.querySelector(OPTIONS.el) || document.body
|
||||
const replace = dom !== document.body
|
||||
const main = function () {
|
||||
mainRender(_ => scrollIntoView())
|
||||
mainRender(_ => {
|
||||
scrollIntoView()
|
||||
activeLink('nav')
|
||||
})
|
||||
}
|
||||
|
||||
// Render app
|
||||
|
||||
+62
-50
@@ -1,52 +1,73 @@
|
||||
import marked from 'marked'
|
||||
import Prism from 'prismjs'
|
||||
import * as tpl from './tpl'
|
||||
import { activeLink, scrollActiveSidebar, bindToggle, scroll2Top, sticky } from './event'
|
||||
import { genTree, getRoute, isMobile, slugify } from './util'
|
||||
import * as event from './event'
|
||||
import { genTree, getRoute, isMobile, slugify, merge } from './util'
|
||||
|
||||
let OPTIONS = {}
|
||||
let markdown = marked
|
||||
let toc = []
|
||||
const CACHE = {}
|
||||
const TIP_RE = /^!\s/
|
||||
|
||||
const renderTo = function (dom, content) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom)
|
||||
dom.innerHTML = content
|
||||
slugify.clear()
|
||||
|
||||
return dom
|
||||
}
|
||||
let toc = []
|
||||
const renderer = new marked.Renderer()
|
||||
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
* init render
|
||||
* @param {Object} options
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
const slug = slugify(text)
|
||||
let route = ''
|
||||
export function init (options) {
|
||||
OPTIONS = options
|
||||
|
||||
if (OPTIONS.router) {
|
||||
route = `#/${getRoute()}`
|
||||
const renderer = new marked.Renderer()
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
const slug = slugify(text)
|
||||
let route = ''
|
||||
|
||||
if (OPTIONS.router) {
|
||||
route = `#/${getRoute()}`
|
||||
}
|
||||
|
||||
toc.push({ level, slug: `${route}#${encodeURIComponent(slug)}`, title: text })
|
||||
|
||||
return `<h${level} id="${slug}"><a href="${route}#${slug}" data-id="${slug}" class="anchor"><span>${text}</span></a></h${level}>`
|
||||
}
|
||||
// highlight code
|
||||
renderer.code = function (code, lang = '') {
|
||||
const hl = Prism.highlight(code, Prism.languages[lang] || Prism.languages.markup)
|
||||
.replace(/{{/g, '<span>{{</span>')
|
||||
|
||||
return `<pre data-lang="${lang}"><code class="lang-${lang}">${hl}</code></pre>`
|
||||
}
|
||||
renderer.link = function (href, title, text) {
|
||||
if (OPTIONS.router && !/:/.test(href)) {
|
||||
href = `#/${href}`.replace(/\/\//g, '/')
|
||||
}
|
||||
|
||||
return `<a href="${href}" title="${title || ''}">${text}</a>`
|
||||
}
|
||||
renderer.paragraph = function (text) {
|
||||
const isTip = TIP_RE.test(text)
|
||||
return isTip ? `<p class="tip">${text.replace(TIP_RE, '')}</p>` : `<p>${text}</p>`
|
||||
}
|
||||
|
||||
toc.push({ level, slug: `${route}#${encodeURIComponent(slug)}`, title: text })
|
||||
|
||||
return `<h${level} id="${slug}"><a href="${route}#${slug}" data-id="${slug}" class="anchor"><span>${text}</span></a></h${level}>`
|
||||
}
|
||||
// highlight code
|
||||
renderer.code = function (code, lang = '') {
|
||||
const hl = Prism.highlight(code, Prism.languages[lang] || Prism.languages.markup)
|
||||
.replace(/{{/g, '<span>{{</span>')
|
||||
|
||||
return `<pre data-lang="${lang}"><code class="lang-${lang}">${hl}</code></pre>`
|
||||
}
|
||||
renderer.link = function (href, title, text) {
|
||||
if (OPTIONS.router && !/:/.test(href)) {
|
||||
href = `#/${href}`.replace(/\/\//g, '/')
|
||||
if (typeof OPTIONS.markdown === 'function') {
|
||||
markdown.setOptions({ renderer })
|
||||
markdown = OPTIONS.markdown.call(this, markdown)
|
||||
} else {
|
||||
markdown.setOptions(merge({ renderer }, OPTIONS.markdown))
|
||||
}
|
||||
|
||||
return `<a href="${href}" title="${title || ''}">${text}</a>`
|
||||
}
|
||||
marked.setOptions({ renderer })
|
||||
|
||||
/**
|
||||
* App
|
||||
@@ -62,10 +83,10 @@ export function renderApp (dom, replace) {
|
||||
document.body.insertBefore(nav, document.body.children[0])
|
||||
|
||||
// bind toggle
|
||||
bindToggle('button.sidebar-toggle')
|
||||
event.bindToggle('button.sidebar-toggle')
|
||||
// bind sticky effect
|
||||
if (OPTIONS.coverpage) {
|
||||
!isMobile() && window.addEventListener('scroll', sticky)
|
||||
!isMobile() && window.addEventListener('scroll', event.sticky)
|
||||
} else {
|
||||
document.body.classList.add('sticky')
|
||||
}
|
||||
@@ -75,14 +96,14 @@ export function renderApp (dom, replace) {
|
||||
* article
|
||||
*/
|
||||
export function renderArticle (content) {
|
||||
renderTo('article', content ? marked(content) : 'not found')
|
||||
renderTo('article', content ? markdown(content) : 'not found')
|
||||
if (!OPTIONS.sidebar && !OPTIONS.loadSidebar) renderSidebar()
|
||||
|
||||
if (content && typeof Vue !== 'undefined' && typeof Vuep !== 'undefined') {
|
||||
const vm = new Vue({ el: 'main' }) // eslint-disable-line
|
||||
vm.$nextTick(_ => scrollActiveSidebar())
|
||||
vm.$nextTick(_ => event.scrollActiveSidebar())
|
||||
}
|
||||
if (OPTIONS.auto2top) scroll2Top()
|
||||
if (OPTIONS.auto2top) setTimeout(() => event.scroll2Top(OPTIONS.auto2top), 0)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,8 +113,8 @@ export function renderNavbar (content) {
|
||||
if (CACHE.navbar && CACHE.navbar === content) return
|
||||
CACHE.navbar = content
|
||||
|
||||
if (content) renderTo('nav', marked(content))
|
||||
activeLink('nav')
|
||||
if (content) renderTo('nav', markdown(content))
|
||||
event.activeLink('nav')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +124,7 @@ export function renderSidebar (content) {
|
||||
let html
|
||||
|
||||
if (content) {
|
||||
html = marked(content)
|
||||
html = markdown(content)
|
||||
} else if (OPTIONS.sidebar) {
|
||||
html = tpl.tree(OPTIONS.sidebar, '<ul>')
|
||||
} else {
|
||||
@@ -111,11 +132,11 @@ export function renderSidebar (content) {
|
||||
}
|
||||
|
||||
renderTo('aside.sidebar', html)
|
||||
const target = activeLink('aside.sidebar', true)
|
||||
if (content) renderSubSidebar(target)
|
||||
const target = event.activeLink('aside.sidebar', true)
|
||||
if (target) renderSubSidebar(target)
|
||||
toc = []
|
||||
|
||||
scrollActiveSidebar()
|
||||
event.scrollActiveSidebar()
|
||||
}
|
||||
|
||||
export function renderSubSidebar (target) {
|
||||
@@ -136,7 +157,7 @@ export function renderCover (content) {
|
||||
if (renderCover.rendered) return
|
||||
|
||||
// render cover
|
||||
let html = marked(content)
|
||||
let html = markdown(content)
|
||||
const match = html.trim().match('<p><img[^s]+src="(.*?)"[^a]+alt="(.*?)"></p>$')
|
||||
|
||||
// render background
|
||||
@@ -155,7 +176,7 @@ export function renderCover (content) {
|
||||
renderTo('.cover-main', html)
|
||||
renderCover.rendered = true
|
||||
|
||||
sticky()
|
||||
event.sticky()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,12 +211,3 @@ export function renderLoading ({ loaded, total, step }) {
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Config
|
||||
* @param {Object} options
|
||||
*/
|
||||
export function config (options) {
|
||||
OPTIONS = options
|
||||
}
|
||||
|
||||
|
||||
@@ -291,6 +291,40 @@ body.sticky {
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-section p.tip {
|
||||
padding: 12px 24px 12px 30px;
|
||||
margin: 2em 0;
|
||||
border-left: 4px solid #f66;
|
||||
background-color: #f8f8f8;
|
||||
position: relative;
|
||||
border-bottom-right-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: -12px;
|
||||
background-color: #f66;
|
||||
color: $color-bg;
|
||||
content: "!";
|
||||
size: 20px;
|
||||
border-radius: 100%;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
font-weight: bold;
|
||||
font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
em {
|
||||
color: $color-text;
|
||||
}
|
||||
}
|
||||
|
||||
body.close {
|
||||
.sidebar {
|
||||
transform: translateX(-$sidebar-width);
|
||||
|
||||
@@ -238,15 +238,3 @@ code .token {
|
||||
-webkit-font-smoothing: initial;
|
||||
-moz-osx-font-smoothing: initial;
|
||||
}
|
||||
|
||||
.content span.light {
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.content span.info {
|
||||
display: inline-block;
|
||||
font-size: 0.85em;
|
||||
margin-left: 20px;
|
||||
vertical-align: middle;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
@@ -285,15 +285,3 @@ pre::after {
|
||||
text-align: right;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.content span.light {
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.content span.info {
|
||||
display: inline-block;
|
||||
font-size: 0.85em;
|
||||
margin-left: 20px;
|
||||
vertical-align: middle;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
+23
@@ -110,14 +110,18 @@ export function slugify (string) {
|
||||
const re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,.\/:;<=>?@\[\]^`{|}~]/g
|
||||
const maintainCase = false
|
||||
const replacement = '-'
|
||||
|
||||
slugify.occurrences = slugify.occurrences || {}
|
||||
|
||||
if (typeof string !== 'string') return ''
|
||||
if (!maintainCase) string = string.toLowerCase()
|
||||
|
||||
let slug = string.trim()
|
||||
.replace(/<[^>\d]+>/g, '')
|
||||
.replace(re, '')
|
||||
.replace(/\s/g, replacement)
|
||||
.replace(/-+/g, replacement)
|
||||
.replace(/^(\d)/, '_$1')
|
||||
let occurrences = slugify.occurrences[slug]
|
||||
|
||||
if (slugify.occurrences.hasOwnProperty(slug)) {
|
||||
@@ -134,3 +138,22 @@ export function slugify (string) {
|
||||
|
||||
return slug
|
||||
}
|
||||
|
||||
slugify.clear = function () {
|
||||
slugify.occurrences = {}
|
||||
}
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||
export const merge = Object.assign || function (to) {
|
||||
for (let i = 1; i < arguments.length; i++) {
|
||||
const from = Object(arguments[i])
|
||||
|
||||
for (const key in from) {
|
||||
if (hasOwnProperty.call(from, key)) {
|
||||
to[key] = from[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user