Compare commits

..

37 commits

Author SHA1 Message Date
James Hegedus
1d3246a26f
Fix typo in docs #869
Fix typo
2019-06-18 09:02:10 +10:00
Parkjunwoo
8ea4865c84 Fix typo 2019-06-18 00:30:43 +09:00
Anton Wilhelm
676f84cffa chore: add changelog 4.9.4 2019-05-05 18:41:18 +02:00
Anton Wilhelm
7bdcadc7d7 [build] 4.9.4 next 2019-05-05 18:41:17 +02:00
Anton Wilhelm
5bd24fb83c Do not commit any files in lib during release 2019-05-05 18:35:34 +02:00
Anton Wilhelm
76cc0f672b Cleanup gitignore 2019-05-05 18:12:20 +02:00
Anton Wilhelm
3f50381090 Add matomo plugin to build script 2019-05-05 18:12:13 +02:00
Anton Wilhelm
b847c20cab Remove lib files from version control 2019-05-05 13:29:56 +02:00
James Hegedus
ce829b24d6
Merge pull request #827 from rodrigobdz/link-showcase
Fix #826: Link directly to showcase in readme and website
2019-04-26 17:01:22 +10:00
Rodrigo Bermudez Schettino
1ce53cf9ec
Readme: Improve outdated links to showcase
Link to Showcase in awesome-docsify.
2019-04-26 11:25:17 +08:00
Gorgi Kosev
bc1d8e4bda add scoring and sort to search plugin 2019-04-23 16:29:30 +02:00
Alexandru Cambose
78f5564a30 Updated to remove all headers under it 2019-04-23 07:08:29 +02:00
Alexandru Cambose
6cc069cb9f Added filtering in sidebar for ignoreSubHeading 2019-04-23 07:08:29 +02:00
Anton Wilhelm
d355272461 chore: add changelog 4.9.2 2019-04-21 12:06:17 +02:00
Anton Wilhelm
af161cd3b4 [build] 4.9.2 next 2019-04-21 12:06:16 +02:00
Anton Wilhelm
5bcb016bee Keep themes directory which is required for npm run dev 2019-04-21 12:05:41 +02:00
Anton Wilhelm
b38c2065e0 add execute access to release.sh 2019-04-21 12:01:04 +02:00
Anton Wilhelm
e5bab8d967 Add link to develop branch preview on netlify 2019-04-21 11:58:07 +02:00
Anton Wilhelm
da3e2d7b18 Remove lib directory from version control 2019-04-21 11:53:30 +02:00
Anton Wilhelm
b93a667f24 provide plugin for matomo 2019-04-21 11:17:14 +02:00
Anton Wilhelm
e8d850c9ba align dev index.html to production 2019-04-14 21:03:34 +02:00
Anton Wilhelm
514a027991
Minor update of bug template 2019-04-14 21:01:24 +02:00
Anton Wilhelm
314e2d9d39
Align IE support from root README.md 2019-04-14 11:27:03 +02:00
Anton Wilhelm
a86de3d81a Remove IE10 from supported browsers 2019-04-13 23:37:11 +02:00
Persevere Von
5f960102e7 Create .gitkeep
Fix #812
2019-04-13 17:38:57 +02:00
Anton Wilhelm
0bd5c8b020 fix #812 add empty themes directory for local watch setup 2019-04-13 15:42:22 +02:00
Anton Wilhelm
044a5ec2b8 add OS to GitHub template 2019-04-13 15:41:35 +02:00
Anton Wilhelm
b15eccfac0 add npm and nodejs version to template 2019-04-13 15:33:49 +02:00
Anton Wilhelm
4e0298088b
Merge pull request #817 from docsifyjs/update-github-templates
Update GitHub templates
2019-04-13 15:29:11 +02:00
Anton Wilhelm
09616dec06 Update GitHub templates 2019-04-13 15:28:12 +02:00
Anton Wilhelm
f74b53f53e
Merge pull request #733 from jthegedus/master
document customising page title with sidebar
2019-04-08 08:26:36 +02:00
Anton Wilhelm
bba44fb536
Merge pull request #714 from ENOVACOM/relative-path
feat: allows relative path, fixed #590
2019-04-07 22:23:18 +02:00
Anton Wilhelm
270fa6cb41
Merge pull request #807 from cyrilf/patch-1
Fix typo in edit button example
2019-04-05 19:58:06 +02:00
cyrilf
24e61f5e2f
Fix typo in Edit Button example
Missing trailing slash in the Edit button url
2019-04-06 00:11:54 +10:00
Sylvain Brocard
ca8ae50717 IE compatibility and add unit tests 2019-03-25 17:20:09 +01:00
Sylvain Brocard
31654f12ec feat: allows relative path, fixed #590 2019-03-25 16:33:03 +01:00
jthegedus
99dbaa3050 document customising page title with sidebar 2019-01-05 19:19:54 +11:00
40 changed files with 590 additions and 479 deletions

View file

@ -1,2 +0,0 @@
<!-- Love docsify? Please consider supporting our collective:
👉 https://opencollective.com/docsify/donate -->

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
---
<!-- Please don't delete this template or we'll close your issue -->
<!-- Please use English language -->
<!-- Before creating an issue please make sure you are using the latest version of Docsify. -->
<!-- Please ask questions on StackOverflow: https://stackoverflow.com/questions/ask?tags=docsify -->
## Bug Report
#### Steps to reproduce
#### What is current behaviour
#### What is the expected behaviour
#### Other relevant information
<!-- (Update "[ ]" to "[x]" to check a box) -->
- [ ] Bug does still occur when all/other plugins are disabled?
- Your OS:
- Node.js version:
- npm/yarn version:
- Browser version:
- Docsify version:
- Docsify plugins:
<!-- Love docsify? Please consider supporting our collective:
👉 https://opencollective.com/docsify/donate -->

View file

@ -0,0 +1,25 @@
---
name: Feature request
about: Suggest an idea for this project
---
<!-- Please don't delete this template or we'll close your issue -->
<!-- Please use English language -->
<!-- Before creating an issue please make sure you are using the latest version of Docsify. -->
<!-- Please ask questions on StackOverflow 👉 https://stackoverflow.com/questions/ask?tags=docsify -->
## Feature request
#### What problem does this feature solve?
#### What does the proposed API look like?
#### How should this be implemented in your opinion?
#### Are you willing to work on this yourself?

View file

@ -1,5 +1,54 @@
Please makes sure these boxes are checked before submitting your PR, thank you!
<!-- Please use English language -->
<!-- Please don't delete this template -->
<!-- PULL REQUEST TEMPLATE -->
<!-- (Update "[ ]" to "[x]" to check a box) -->
**Summary**
**What kind of change does this PR introduce?** (check at least one)
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update
- [ ] Refactor
- [ ] Docs
- [ ] Build-related changes
- [ ] Other, please describe:
If changing the UI of default theme, please provide the **before/after** screenshot:
**Does this PR introduce a breaking change?** (check one)
- [ ] Yes
- [ ] No
If yes, please describe the impact and migration path for existing applications:
**The PR fulfills these requirements:**
- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
You have tested in the following browsers: (Providing a detailed version will be better.)
- [ ] Chrome
- [ ] Firefox
- [ ] Safari
- [ ] Edge
- [ ] IE
If adding a **new feature**, the PR's description includes:
- [ ] A convincing reason for adding this feature
- [ ] Related documents have been updated
- [ ] Related tests have been updated
To avoid wasting your time, it's best to open a **feature request issue** first and wait for approval before working on it.
**Other information:**
---
* [ ] Make sure you are merging your commits to `master` branch.
* [ ] Add some descriptions and refer relative issues for you PR.
* [ ] DO NOT include files inside `lib` directory.

9
.gitignore vendored
View file

@ -1,8 +1,9 @@
*.log
.DS_Store
/themes/*
!.gitkeep
node_modules
lib
.idea
node_modules
themes/
lib/
# exceptions
!.gitkeep

View file

@ -1,3 +1,23 @@
<a name="4.9.4"></a>
## [4.9.4](https://github.com/docsifyjs/docsify/compare/v4.9.2...v4.9.4) (2019-05-05)
<a name="4.9.2"></a>
## [4.9.2](https://github.com/docsifyjs/docsify/compare/v4.9.1...v4.9.2) (2019-04-21)
### Bug Fixes
* re-render gitalk when router changed ([11ea1f8](https://github.com/docsifyjs/docsify/commit/11ea1f8))
### Features
* allows relative path, fixed [#590](https://github.com/docsifyjs/docsify/issues/590) ([31654f1](https://github.com/docsifyjs/docsify/commit/31654f1))
<a name="4.9.1"></a>
## [4.9.1](https://github.com/docsifyjs/docsify/compare/v4.9.0...v4.9.1) (2019-02-21)

View file

@ -27,6 +27,7 @@
## Links
- [`develop` branch preview](https://docsifyjs.netlify.com/)
- [Documentation](https://docsify.js.org)
- [CLI](https://github.com/docsifyjs/docsify-cli)
- CDN: [UNPKG](https://unpkg.com/docsify/) | [jsDelivr](https://cdn.jsdelivr.net/npm/docsify/) | [cdnjs](https://cdnjs.com/libraries/docsify)
@ -40,7 +41,7 @@
- Smart full-text search plugin
- Multiple themes
- Useful plugin API
- Compatible with IE10+
- Compatible with IE11
- Support SSR ([example](https://github.com/docsifyjs/docsify-ssr-demo))
- Support embedded files
@ -54,7 +55,7 @@ Look at [this tutorial](https://docsify.js.org/#/quickstart)
These projects are using docsify to generate their sites. Pull requests welcome :blush:
Move to [awesome-docsify](https://github.com/docsifyjs/awesome-docsify)
Move to [awesome-docsify](https://github.com/docsifyjs/awesome-docsify#showcase)
## Similar projects

View file

@ -55,6 +55,7 @@ const buildAllPlugin = function () {
var plugins = [
{name: 'search', input: 'search/index.js'},
{name: 'ga', input: 'ga.js'},
{name: 'matomo', input: 'matomo.js'},
{name: 'emoji', input: 'emoji.js'},
{name: 'external-script', input: 'external-script.js'},
{name: 'front-matter', input: 'front-matter/index.js'},

1
build/release.sh Normal file → Executable file
View file

@ -29,7 +29,6 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then
# commit
git add -A
git add -f lib/ -A
git commit -m "[build] $VERSION $RELEASE_TAG"
npm --no-git-tag-version version $VERSION --message "[release] $VERSION $RELEASE_TAG"

View file

@ -16,12 +16,12 @@ See the [Quick start](quickstart.md) guide for more details.
- Multiple themes
- Useful plugin API
- Emoji support
- Compatible with IE10+
- Compatible with IE11
- Support server-side rendering ([example](https://github.com/docsifyjs/docsify-ssr-demo))
## Examples
Check out the [Showcase](https://github.com/docsifyjs/docsify/#showcase) to see docsify in use.
Check out the [Showcase](https://github.com/docsifyjs/awesome-docsify#showcase) to see docsify in use.
## Donate

View file

@ -1,6 +1,6 @@
![logo](_media/icon.svg)
# docsify <small>4.9.1</small>
# docsify <small>4.9.4</small>
> A magical documentation site generator.

View file

@ -23,7 +23,6 @@
- [Offline Mode(PWA)](pwa.md)
- [Server-Side Rendering(SSR)](ssr.md)
- [Embed Files](embed-files.md)
- [Generate static html](static.md)
- [Awesome docsify](awesome.md)
- [Changelog](changelog.md)

View file

@ -150,6 +150,46 @@ window.$docsify = {
};
```
## relativePath
- Type: `Boolean`
- Default: `false`
If **true** links are relative to the current context.
For example, the directory structure is as follows:
```text
.
└── docs
├── README.md
├── guide.md
└── zh-cn
├── README.md
├── guide.md
└── config
└── example.md
```
With relative path **enabled** and current URL `http://domain.com/zh-cn/README`, given links will resolve to:
```text
guide.md => http://domain.com/zh-cn/guide
config/example.md => http://domain.com/zh-cn/config/example
../README.md => http://domain.com/README
/README.md => http://domain.com/README
```
```js
window.$docsify = {
// Relative path enabled
relativePath: true,
// Relative path disabled (default value)
relativePath: false
};
```
## coverpage
- Type: `Boolean|String|String[]|Object`

View file

@ -15,7 +15,7 @@ It is recommended that you save your files to the `./docs` subfolder of the `mas
![github pages](_images/deploy-github-pages.png)
!> You can also save files in the root directory and select `master branch`.
You'll need to place a `.nojekyll` file in the deploy location (such as `/docs` or the gh-pages branch
You'll need to place a `.nojekyll` file in the deploy location (such as `/docs` or the gh-pages branch)
## GitLab Pages

View file

@ -7,72 +7,24 @@ docsify extends Markdown syntax to make your documents more readable.
Important content like:
```markdown
> [!] **Time** is money, my friend!
!> **Time** is money, my friend!
```
is rendered as:
> [!] **Time** is money, my friend!
!> **Time** is money, my friend!
## General tips
General tips like:
```markdown
> [?] _TODO_ unit test
?> _TODO_ unit test
```
are rendered as:
> [?] _TODO_ unit test
## More tips
```markdown
> [x] bad
> [v] good
```
> [x] bad
> [v] good
## Details
````markdown
> [details] Sample code
>
> js code
>
> ```javascript
> console.log("foo");
> ```
> [details:open] Sample code open
>
> js code
>
> ```javascript
> console.log("foo");
> ```
````
> [details] Sample code
>
> js code
>
> ```javascript
> console.log("foo");
> ```
> [details:open] Sample code open
>
> js code
>
> ```javascript
> console.log("foo");
> ```
?> _TODO_ unit test
## Ignore to compile link
@ -87,13 +39,13 @@ It will be compiled to `<a href="/#/demo/">link</a>` and will be loaded `/demo/R
Now you can do that
```md
[link](/demo/ ":ignore")
[link](/demo/ ':ignore')
```
You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set title for link.
```md
[link](/demo/ ":ignore title")
[link](/demo/ ':ignore title')
<a href="/demo/" title="title">link</a>
```
@ -101,14 +53,14 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set ti
## Set target attribute for link
```md
[link](/demo ":target=_blank")
[link](/demo2 ":target=_self")
[link](/demo ':target=_blank')
[link](/demo2 ':target=_self')
```
## Disable link
```md
[link](/demo ":disabled")
[link](/demo ':disabled')
```
## Github Task Lists
@ -132,17 +84,17 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set ti
## Image resizing
```md
![logo](https://docsify.js.org/_media/icon.svg ":size=50x100")
![logo](https://docsify.js.org/_media/icon.svg ":size=100")
![logo](https://docsify.js.org/_media/icon.svg ':size=50x100')
![logo](https://docsify.js.org/_media/icon.svg ':size=100')
<!-- Support percentage -->
![logo](https://docsify.js.org/_media/icon.svg ":size=10%")
![logo](https://docsify.js.org/_media/icon.svg ':size=10%')
```
![logo](https://docsify.js.org/_media/icon.svg ":size=50x100")
![logo](https://docsify.js.org/_media/icon.svg ":size=100")
![logo](https://docsify.js.org/_media/icon.svg ":size=10%")
![logo](https://docsify.js.org/_media/icon.svg ':size=50x100')
![logo](https://docsify.js.org/_media/icon.svg ':size=100')
![logo](https://docsify.js.org/_media/icon.svg ':size=10%')
## Customise ID for headings

View file

@ -1,46 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta charset="UTF-8">
<title>docsify</title>
<link rel="icon" href="_media/favicon.ico" />
<meta
name="google-site-verification"
content="6t0LoIeFksrjF4c9sqUEsVXiQNxLp2hgoqo0KryT-sE"
/>
<link rel="icon" href="_media/favicon.ico">
<meta name="google-site-verification" content="6t0LoIeFksrjF4c9sqUEsVXiQNxLp2hgoqo0KryT-sE" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta
name="keywords"
content="doc,docs,documentation,gitbook,creator,generator,github,jekyll,github-pages"
/>
<meta name="description" content="A magical documentation generator." />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<link
rel="stylesheet"
href="//unpkg.com/docsify/lib/themes/vue.css"
title="vue"
/>
<link
rel="stylesheet"
href="//unpkg.com/docsify/lib/themes/dark.css"
title="dark"
disabled
/>
<link
rel="stylesheet"
href="//unpkg.com/docsify/lib/themes/buble.css"
title="buble"
disabled
/>
<link
rel="stylesheet"
href="//unpkg.com/docsify/lib/themes/pure.css"
title="pure"
disabled
/>
<meta name="keywords" content="doc,docs,documentation,gitbook,creator,generator,github,jekyll,github-pages">
<meta name="description" content="A magical documentation generator.">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css" title="vue">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/dark.css" title="dark" disabled>
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css" title="buble" disabled>
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/pure.css" title="pure" disabled>
<script src="//unpkg.com/docsify-plugin-codefund/index.js"></script>
<style>
nav.app-nav li ul {
@ -54,19 +27,13 @@
<script>
window.$docsify = {
alias: {
".*?/awesome":
"https://raw.githubusercontent.com/docsifyjs/awesome-docsify/master/README.md",
".*?/changelog":
"https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG.md",
"/.*/_navbar.md": "/_navbar.md",
"/zh-cn/(.*)":
"https://raw.githubusercontent.com/docsifyjs/docs-zh/master/$1",
"/de-de/(.*)":
"https://raw.githubusercontent.com/docsifyjs/docs-de/master/$1",
"/ru/(.*)":
"https://raw.githubusercontent.com/docsifyjs/docs-ru/master/$1",
"/es/(.*)":
"https://raw.githubusercontent.com/docsifyjs/docs-es/master/$1"
'.*?/awesome': 'https://raw.githubusercontent.com/docsifyjs/awesome-docsify/master/README.md',
'.*?/changelog': 'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG.md',
'/.*/_navbar.md': '/_navbar.md',
'/zh-cn/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-zh/master/$1',
'/de-de/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-de/master/$1',
'/ru/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-ru/master/$1',
'/es/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-es/master/$1'
},
auto2top: true,
coverpage: true,
@ -76,62 +43,62 @@
mergeNavbar: true,
maxLevel: 4,
subMaxLevel: 2,
ga: "UA-106147152-1",
name: "docsify",
ga: 'UA-106147152-1',
matomo: {
host: '//matomo.thunderwave.de',
id: 6
},
name: 'docsify',
search: {
noData: {
"/de-de/": "Keine Ergebnisse!",
"/zh-cn/": "没有结果!",
"/": "No results!"
'/de-de/': 'Keine Ergebnisse!',
'/zh-cn/': '没有结果!',
'/': 'No results!'
},
paths: "auto",
paths: 'auto',
placeholder: {
"/de-de/": "Suche",
"/zh-cn/": "搜索",
"/": "Search"
'/de-de/': 'Suche',
'/zh-cn/': '搜索',
'/': 'Search'
}
},
formatUpdated: "{MM}/{DD} {HH}:{mm}",
formatUpdated: '{MM}/{DD} {HH}:{mm}',
plugins: [
function (hook, vm) {
hook.beforeEach(function (html) {
if (/githubusercontent\.com/.test(vm.route.file)) {
url = vm.route.file
.replace("raw.githubusercontent.com", "github.com")
.replace(/\/master/, "/blob/master");
.replace('raw.githubusercontent.com', 'github.com')
.replace(/\/master/, '/blob/master')
} else {
url =
"https://github.com/docsifyjs/docsify/blob/master/docs/" +
vm.route.file;
url = 'https://github.com/docsifyjs/docsify/blob/master/docs/' + vm.route.file
}
var editHtml = "[:memo: Edit Document](" + url + ")\n";
return (
editHtml +
html +
"\n\n----\n\n" +
'<a href="https://docsify.js.org" target="_blank" style="color: inherit; font-weight: normal; text-decoration: none;">Powered by docsify</a>'
);
});
var editHtml = '[:memo: Edit Document](' + url + ')\n'
return editHtml
+ html
+ '\n\n----\n\n'
+ '<a href="https://docsify.js.org" target="_blank" style="color: inherit; font-weight: normal; text-decoration: none;">Powered by docsify</a>'
})
},
DocsifyCodefund.create("fae1f9a4-870c-4c25-b8e0-c80464f7a95c")
DocsifyCodefund.create('fae1f9a4-870c-4c25-b8e0-c80464f7a95c')
]
};
}
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/ga.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/matomo.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-nginx.min.js"></script>
<script>
((window.gitter = {}).chat = {}).options = {
room: "docsifyjs/Lobby"
room: 'docsifyjs/Lobby'
};
</script>
<script
src="https://sidecar.gitter.im/dist/sidecar.v1.js"
async
defer
></script>
<script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
</body>
</html>

View file

@ -72,6 +72,16 @@ You can specify `alias` to avoid unnecessary fallback.
!> You can create a `README.md` file in a subdirectory to use it as the landing page for the route.
## Set Page Titles from Sidebar Selection
A page's `title` tag is generated from the _selected_ sidebar item name. For better SEO, you can customize the title by specifying a string after the filename.
```markdown
<!-- docs/_sidebar.md -->
* [Home](/)
* [Guide](guide.md "The greatest guide in the world")
```
## Table of Contents
Once you've created `_sidebar.md`, the sidebar content is automatically generated based on the headers in the markdown files.

View file

@ -1,50 +0,0 @@
# Generate static html
> _Experimental feature_
Generating static html files is good for SEO and speeds up the first rendering.
But this is not an advantage of docsify. If you only need powerful static documentation, choose another documentation tool like Gitbook or Vuepress.
## Configuration
You can configure it in a special config file.
_config.js_
```js
module.exports = {
template: `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Doc</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css" title="vue">
</head>
<body>
<!--inject-app-->
<!--inject-config-->
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
</body>
</html>`, // or html file path
config: {
// docsify config
coverpage: true
}
};
```
## Generate
Please use docsify-cli 5.0+ and run this command.
```sh
docsify static docs -c config.js
```
## Simple Demo
This is an example showing the docsify official documentation generating static files. [docsify-static-demo](https://github.com/docsifyjs/docsify-static-demo)

View file

@ -79,7 +79,7 @@ window.$docsify = {
function(hook, vm) {
hook.beforeEach(function(html) {
var url =
'https://github.com/docsifyjs/docsify/blob/master/docs' +
'https://github.com/docsifyjs/docsify/blob/master/docs/' +
vm.route.file;
var editHtml = '[📝 EDIT DOCUMENT](' + url + ')\n';

View file

@ -21,48 +21,64 @@
<script>
window.$docsify = {
alias: {
'.*?/changelog': 'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG',
'.*?/awesome': 'https://raw.githubusercontent.com/docsifyjs/awesome-docsify/master/README.md',
'.*?/changelog': 'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG.md',
'/.*/_navbar.md': '/_navbar.md',
'/zh-cn/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-zh/master/$1',
'/de-de/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-de/master/$1',
'/ru/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-ru/master/$1',
'/es/(.*)': 'https://raw.githubusercontent.com/docsifyjs/docs-es/master/$1'
},
notFoundPage: '_404.html',
auto2top: true,
basePath: '/docs/',
executeScript: true,
loadNavbar: true,
loadSidebar: true,
coverpage: true,
name: 'docsify',
subMaxLevel: 2,
executeScript: true,
loadSidebar: true,
loadNavbar: true,
mergeNavbar: true,
maxLevel: 4,
subMaxLevel: 2,
name: 'docsify',
search: {
noData: {
'/de-de/': 'Keine Ergebnisse!',
'/zh-cn/': '没有结果!',
'/': 'No results!'
},
paths: 'auto',
placeholder: {
'/de-de/': 'Suche',
'/zh-cn/': '搜索',
'/': 'Search'
}
},
formatUpdated: '{MM}/{DD} {HH}:{mm}',
plugins: [
function (hook, vm) {
hook.beforeEach(function (html) {
var url
if (/githubusercontent\.com/.test(vm.route.file)) {
url = vm.route.file
.replace('raw.githubusercontent.com', 'github.com')
.replace(/\/master/, '/blob/master')
} else {
url = 'https://github.com/docsifyjs/docsify/blob/master/' + vm.route.file
url = 'https://github.com/docsifyjs/docsify/blob/master/docs/' + vm.route.file
}
var editHtml = '[:memo: Edit Document](' + url + ')\n'
return editHtml
+ html
+ '\n\n----\n\n'
+ 'Last modified {docsify-updated} '
+ editHtml
+ '<a href="https://docsify.js.org" target="_blank" style="color: inherit; font-weight: normal; text-decoration: none;">Powered by docsify</a>'
})
}
},
]
}
</script>
<script src="/lib/docsify.js"></script>
<script src="/lib/plugins/search.js"></script>
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
<script src="//unpkg.com/prismjs/components/prism-nginx.min.js"></script>
</body>
</html>

2
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "docsify",
"version": "4.9.1",
"version": "4.9.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "docsify",
"version": "4.9.1",
"version": "4.9.4",
"description": "A magical documentation generator.",
"author": {
"name": "qingwei-li",
@ -32,11 +32,11 @@
"watch:css": "run-p 'css -- -o themes -w'",
"watch:js": "node build/build.js",
"build:css:min": "mkdir lib/themes && run-p 'css -- -o lib/themes' && node build/mincss.js",
"build:css": "mkdir themes && run-p 'css -- -o themes'",
"build:css": "mkdir -p themes && run-p 'css -- -o themes'",
"build:js": "cross-env NODE_ENV=production node build/build.js",
"build:ssr": "node build/ssr.js",
"build:cover": "node build/cover.js",
"build": "rimraf lib themes && run-s build:js build:css build:css:min build:ssr build:cover",
"build": "rimraf lib themes/* && run-s build:js build:css build:css:min build:ssr build:cover",
"pub:next": "cross-env RELEASE_TAG=next sh build/release.sh",
"pub": "sh build/release.sh",
"postinstall": "opencollective postinstall"

View file

@ -22,7 +22,7 @@ function mainTpl(config) {
html += tpl.corner(config.repo)
}
if (config.coverpage) {
html += '<!--cover-->'
html += tpl.cover()
}
html += tpl.main(config)
@ -31,13 +31,12 @@ function mainTpl(config) {
}
export default class Renderer {
constructor({template, config, cache, path}) {
constructor({template, config, cache}) {
this.html = template
this.config = config = Object.assign({}, config, {
routerMode: 'history'
})
this.cache = cache
this.path = path
this.router = new AbstractHistory(config)
this.compiler = new Compiler(config, this.router)
@ -53,19 +52,9 @@ export default class Renderer {
}
_getPath(url) {
const path = resolve(this.path, url)
const file = this.router.getFile(path)
return file
}
const file = this.router.getFile(url)
async render(url) {
const content = await this.renderToString(url)
return {
content,
url: this.router.parse(url).path,
path: this._getPath(url)
}
return isAbsolutePath(file) ? file : cwd(`./${file}`)
}
async renderToString(url) {
@ -77,35 +66,32 @@ export default class Renderer {
if (loadSidebar) {
const name = loadSidebar === true ? '_sidebar.md' : loadSidebar
const sidebarFile = this._getPath(resolvePathname(name, url))
const sidebarFile = this._getPath(resolve(url, `./${name}`))
this._renderHtml('sidebar', await this._render(sidebarFile, 'sidebar'))
}
if (loadNavbar) {
const name = loadNavbar === true ? '_navbar.md' : loadNavbar
const navbarFile = this._getPath(resolvePathname(name, url))
const navbarFile = this._getPath(resolve(url, `./${name}`))
this._renderHtml('navbar', await this._render(navbarFile, 'navbar'))
}
if (coverpage) {
let name = null
if (typeof coverpage === 'string' || coverpage === true) {
if (url === 'README.md') {
name = coverpage === true ? '_coverpage.md' : coverpage
let path = null
if (typeof coverpage === 'string') {
if (url === '/') {
path = coverpage
}
} else if (Array.isArray(coverpage)) {
name = coverpage.indexOf(url) > -1 && '_coverpage.md'
path = coverpage.indexOf(url) > -1 && '_coverpage.md'
} else {
const cover = coverpage[url]
name = cover === true ? '_coverpage.md' : cover
path = cover === true ? '_coverpage.md' : cover
}
if (name) {
const coverFile = this._getPath(resolvePathname(name, url))
const coverFile = this._getPath(resolve(url, `./${path}`))
this._renderHtml('cover', await this._render(coverFile, 'cover'))
}
this._renderHtml('cover', await this._render(coverFile), 'cover')
}
const html = this.html
@ -122,7 +108,6 @@ export default class Renderer {
async _render(path, type) {
let html = await this._loadFile(path)
const {subMaxLevel, maxLevel} = this.config
let tokens
@ -141,8 +126,7 @@ export default class Renderer {
tokens = await new Promise(r => {
prerenderEmbed(
{
// Url is absolute path
fetch: url => this._loadFile(this._getPath('.' + url)),
fetch: url => this._loadFile(this._getPath(url)),
compiler: this.compiler,
raw: html
},
@ -179,7 +163,7 @@ export default class Renderer {
return content
} catch (e) {
this.lock = this.lock || 0
if (++this.lock > 4) {
if (++this.lock > 10) {
this.lock = 0
return
}

View file

@ -37,5 +37,5 @@
"integrity": "sha1-6DWIAbhrg7F1YNTjw4LXrvIQCUQ="
}
},
"version": "4.9.1"
"version": "4.9.4"
}

View file

@ -1,6 +1,6 @@
{
"name": "docsify-server-renderer",
"version": "4.9.1",
"version": "4.9.4",
"description": "docsify server renderer",
"author": {
"name": "qingwei-li",

View file

@ -25,7 +25,8 @@ export default function () {
formatUpdated: '',
externalLinkTarget: '_blank',
routerMode: 'hash',
noCompileLinks: []
noCompileLinks: [],
relativePath: false
},
window.$docsify
)

View file

@ -1,12 +1,6 @@
import marked from 'marked'
import Prism from 'prismjs'
import {
helper as helperTpl,
newHelper as newHelperTpl,
tree as treeTpl,
cover as coverTpl,
details as detailsTpl
} from './tpl'
import {helper as helperTpl, tree as treeTpl} from './tpl'
import {genTree} from './gen-tree'
import {slugify} from './slugify'
import {emojify} from './emojify'
@ -197,7 +191,7 @@ export class Compiler {
/**
* Render anchor tag
* @link https://marked.js.org/#/USING_PRO.md#renderer
* @link https://github.com/markedjs/marked#overriding-renderer-methods
*/
origin.heading = renderer.heading = function (text, level) {
let {str, config} = getAndRemoveConfig(text)
@ -309,68 +303,22 @@ export class Compiler {
return `<img src="${url}"data-origin="${href}" alt="${text}"${attrs}>`
}
origin.list = renderer.list = function (body, ordered, start) {
const isTaskList = /<li class="task-list-item">/.test(
body.split('class="task-list"')[0]
)
const isTaskList = /<li class="task-list-item">/.test(body.split('class="task-list"')[0])
const isStartReq = start && start > 1
const tag = ordered ? 'ol' : 'ul'
const tagAttrs = [
isTaskList ? 'class="task-list"' : '',
isStartReq ? `start="${start}"` : ''
]
.join(' ')
.trim()
(isTaskList ? 'class="task-list"' : ''),
(isStartReq ? `start="${start}"` : '')
].join(' ').trim()
return `<${tag} ${tagAttrs}>${body}</${tag}>`
}
origin.listitem = renderer.listitem = function (text) {
const isTaskItem = /^(<input.*type="checkbox"[^>]*>)/.test(text)
const html = isTaskItem ?
`<li class="task-list-item"><label>${text}</label></li>` :
`<li>${text}</li>`
const html = isTaskItem ? `<li class="task-list-item"><label>${text}</label></li>` : `<li>${text}</li>`
return html
}
origin.blockquote = renderer.blockquote = function (quote) {
const m = quote.match(/^\<p\>(\[\S+\])/)
if (m) {
const text = quote.replace(m[1], '')
switch (m[1]) {
case '[!]':
result = newHelperTpl('docsify-tip', text)
break
case '[?]':
result = newHelperTpl('docsify-warn', text)
break
case '[x]':
result = newHelperTpl('docsify-error', text)
break
case '[v]':
result = newHelperTpl('docsify-success', text)
break
case '[details]':
case '[details:open]':
let summary = false
const html = text.replace(
/^\<p\>([^<]+)<\/p>([\s\S]+)/,
(m, m1, m2) => {
summary = m1
return m2
}
)
const open = Boolean(/:open/.test(m[1]))
result = detailsTpl({open, summary, html})
break
default:
return quote
}
return result
}
return quote
}
renderer.origin = origin
@ -381,13 +329,25 @@ export class Compiler {
* Compile sidebar
*/
sidebar(text, level) {
const {toc} = this
const currentPath = this.router.getCurrentPath()
let html = ''
if (text) {
html = this.compile(text)
} else {
const tree = this.cacheTree[currentPath] || genTree(this.toc, level)
for (let i = 0; i < toc.length; i++) {
if (toc[i].ignoreSubHeading) {
const deletedHeaderLevel = toc[i].level
toc.splice(i, 1)
// Remove headers who are under current header
for (let j = i; deletedHeaderLevel < toc[j].level && j < toc.length; j++) {
toc.splice(j, 1) && j-- && i++
}
i--
}
}
const tree = this.cacheTree[currentPath] || genTree(toc, level)
html = treeTpl(tree, '<ul>{inner}</ul>')
this.cacheTree[currentPath] = tree
}
@ -412,7 +372,6 @@ export class Compiler {
for (let i = 0; i < toc.length; i++) {
toc[i].ignoreSubHeading && toc.splice(i, 1) && i--
}
const tree = cacheTree[currentPath] || genTree(toc, level)
cacheTree[currentPath] = tree
@ -427,37 +386,12 @@ export class Compiler {
/**
* Compile cover page
*/
cover(text, isHTML = false) {
let html = text
if (!isHTML) {
cover(text) {
const cacheToc = this.toc.slice()
html = this.compile(text) || ''
const html = this.compile(text)
this.toc = cacheToc.slice()
}
const m = html
.trim()
.match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$')
let style = ''
let hasMask = false
if (m) {
if (m[2] === 'color') {
style = `background: ${m[1] + (m[3] || '')}`
} else {
let path = m[1]
hasMask = true
if (!isAbsolutePath(m[1])) {
path = getPath(this.router.getBasePath(), m[1])
}
style = `background-image: url(${path}); background-size: cover; background-position: center center;`
}
html = html.replace(m[0], '')
}
return coverTpl({
style,
hasMask,
text: html
})
return html
}
}

View file

@ -22,10 +22,8 @@ function walkFetchEmbed({embedTokens, compile, fetch}, cb) {
} else if (token.embed.type === 'code') {
if (token.embed.fragment) {
const fragment = token.embed.fragment
const pattern = new RegExp(
`(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]`
)
text = ((text.match(pattern) || [])[1] || '').trim()
const pattern = new RegExp(`(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]`)
text = ((text.match(pattern) || [])[1] || '').trim()
}
embedToken = compile.lexer(
'```' +

View file

@ -175,10 +175,30 @@ export function renderMixin(proto) {
}
dom.toggleClass(el, 'add', 'show')
let html = this.compiler.cover(text, this.coverIsHTML)
let html = this.coverIsHTML ? text : this.compiler.cover(text)
this._renderTo('.cover-placeholder', html, true)
const m = html
.trim()
.match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$')
if (m) {
if (m[2] === 'color') {
el.style.background = m[1] + (m[3] || '')
} else {
let path = m[1]
dom.toggleClass(el, 'add', 'has-mask')
if (!isAbsolutePath(m[1])) {
path = getPath(this.router.getBasePath(), m[1])
}
el.style.backgroundImage = `url(${path})`
el.style.backgroundSize = 'cover'
el.style.backgroundPosition = 'center center'
}
html = html.replace(m[0], '')
}
this._renderTo('.cover-main', html)
sticky()
}
@ -208,9 +228,8 @@ export function initRender(vm) {
if (config.repo) {
html += tpl.corner(config.repo)
}
if (config.coverpage) {
html += '<div class=cover-placeholder></div>'
html += tpl.cover()
}
if (config.logo) {

View file

@ -57,19 +57,16 @@ export function main(config) {
/**
* Cover Page
*/
export function cover({style, text, hasMask}) {
export function cover() {
const SL = ', 100%, 85%'
style =
style ||
'background: linear-gradient(to left bottom, ' +
const bgc =
'linear-gradient(to left bottom, ' +
`hsl(${Math.floor(Math.random() * 255) + SL}) 0%,` +
`hsl(${Math.floor(Math.random() * 255) + SL}) 100%)`
return (
`<section class="cover show ${
hasMask ? ' has-mask' : ''
}" style="${style}">` +
`<div class="cover-main">${text}</div>` +
`<section class="cover show" style="background: ${bgc}">` +
'<div class="cover-main"><!--cover--></div>' +
'<div class="mask"></div>' +
'</section>'
)
@ -87,9 +84,7 @@ export function tree(toc, tpl = '<ul class="app-sub-sidebar">{inner}</ul>') {
}
let innerHTML = ''
toc.forEach(node => {
innerHTML += `<li><a class="section-link" href="${node.slug}">${
node.title
}</a></li>`
innerHTML += `<li><a class="section-link" href="${node.slug}">${node.title}</a></li>`
if (node.children) {
innerHTML += tree(node.children, tpl)
}
@ -101,17 +96,6 @@ export function helper(className, content) {
return `<p class="${className}">${content.slice(5).trim()}</p>`
}
export function newHelper(className, content) {
return `<div class="${className}">${content}</div>`
}
export function theme(color) {
return `<style>:root{--theme-color: ${color};}</style>`
}
export function details({open, summary, html}) {
return `<details ${open ? 'open=open' : ''}>${
summary ? `<summary>${summary}</summary>` : ''
}
${html}</details>`
}

View file

@ -7,7 +7,7 @@ export class AbstractHistory extends History {
this.mode = 'abstract'
}
parse(path = '') {
parse(path) {
let query = ''
const queryIndex = path.indexOf('?')

View file

@ -3,7 +3,8 @@ import {
isAbsolutePath,
stringifyQuery,
cleanPath,
replaceSlug
replaceSlug,
resolvePath
} from '../util'
import {noop, merge} from '../../util/core'
@ -21,11 +22,9 @@ function getAlias(path, alias, last) {
}
function getFileName(path, ext) {
return /\.\w+$/.test(path) ?
return new RegExp(`\\.(${ext.replace(/^\./, '')}|html)$`, 'g').test(path) ?
path :
/\/$/g.test(path) ?
`${path}README${ext}` :
`${path}${ext}`
/\/$/g.test(path) ? `${path}README${ext}` : `${path}${ext}`
}
export class History {
@ -75,9 +74,13 @@ export class History {
if (local) {
const idIndex = currentRoute.indexOf('?')
path =
(idIndex > 0 ? currentRoute.substr(0, idIndex) : currentRoute) + path
(idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + path
}
if (this.config.relativePath && path.indexOf('/') !== 0) {
const currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1)
return cleanPath(resolvePath(currentDir + path))
}
return cleanPath('/' + path)
}
}

View file

@ -46,15 +46,27 @@ export const isAbsolutePath = cached(path => {
export const getParentPath = cached(path => {
return /\/$/g.test(path) ?
path :
(path = path.match(/(\S*\/)[^/]+$/)) ?
path[1] :
''
(path = path.match(/(\S*\/)[^/]+$/)) ? path[1] : ''
})
export const cleanPath = cached(path => {
return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/')
})
export const resolvePath = cached(path => {
const segments = path.replace(/^\//, '').split('/')
let resolved = []
for (let i = 0, len = segments.length; i < len; i++) {
const segment = segments[i]
if (segment === '..') {
resolved.pop()
} else if (segment !== '.') {
resolved.push(segment)
}
}
return '/' + resolved.join('/')
})
export function getPath(...args) {
return cleanPath(args.join('/'))
}

37
src/plugins/matomo.js Normal file
View file

@ -0,0 +1,37 @@
function appendScript(options) {
const script = document.createElement('script')
script.async = true
script.src = options.host + '/matomo.js'
document.body.appendChild(script)
}
function init(options) {
window._paq = window._paq || []
window._paq.push(['trackPageView'])
window._paq.push(['enableLinkTracking'])
setTimeout(function() {
appendScript(options)
window._paq.push(['setTrackerUrl', options.host + '/matomo.php'])
window._paq.push(['setSiteId', options.id + ''])
}, 0)
}
function collect() {
if (!window._paq) {
init($docsify.matomo)
}
window._paq.push(['setCustomUrl', window.location.hash.substr(1)])
window._paq.push(['setDocumentTitle', document.title])
window._paq.push(['trackPageView'])
}
const install = function (hook) {
if (!$docsify.matomo) {
console.error('[Docsify] matomo is required.')
return
}
hook.beforeEach(collect)
}
$docsify.plugins = [].concat(install, $docsify.plugins)

View file

@ -96,29 +96,27 @@ export function search(query) {
for (let i = 0; i < data.length; i++) {
const post = data[i]
let isMatch = false
let matchesScore = 0
let resultStr = ''
const postTitle = post.title && post.title.trim()
const postContent = post.body && post.body.trim()
const postUrl = post.slug || ''
if (postTitle && postContent) {
if (postTitle) {
keywords.forEach( keyword => {
// From https://github.com/sindresorhus/escape-string-regexp
const regEx = new RegExp(
keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'),
'gi'
)
);
let indexTitle = -1
let indexContent = -1
indexTitle = postTitle && postTitle.search(regEx)
indexContent = postContent && postContent.search(regEx)
indexTitle = postTitle ? postTitle.search(regEx) : -1
indexContent = postContent ? postContent.search(regEx) : -1
if (indexTitle < 0 && indexContent < 0) {
isMatch = false
} else {
isMatch = true
if (indexTitle >= 0 || indexContent >= 0) {
matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0;
if (indexContent < 0) {
indexContent = 0
}
@ -144,11 +142,12 @@ export function search(query) {
}
})
if (isMatch) {
if (matchesScore > 0) {
const matchingPost = {
title: escapeHtml(postTitle),
content: resultStr,
url: postUrl
content: postContent ? resultStr : '',
url: postUrl,
score: matchesScore
}
matchingResults.push(matchingPost)
@ -156,7 +155,7 @@ export function search(query) {
}
}
return matchingResults
return matchingResults.sort((r1, r2) => r2.score - r1.score);
}
export function init(config, vm) {

View file

@ -321,9 +321,6 @@ body.sticky
border-bottom 1px solid #eee
margin 2em 0
.markdown-section summary
cursor pointer
.markdown-section iframe
border 1px solid #eee
/* fix horizontal overflow on iOS Safari */
@ -354,7 +351,6 @@ body.sticky
background-color #f8f8f8
.markdown-section p.tip
.markdown-section .docsify-tip
background-color #f8f8f8
border-bottom-right-radius 2px
border-left 4px solid #f66
@ -386,23 +382,9 @@ body.sticky
color $color-text
.markdown-section p.warn
.markdown-section .docsify-warn
background rgba($color-primary, 0.1)
border-radius 2px
padding 1rem
margin: 2em 0
.markdown-section .docsify-success
background rgba(#42b983, 0.1)
border-radius 2px
padding 1rem
margin: 2em 0
.markdown-section .docsify-error
background rgba(#f66, 0.1)
border-radius 2px
margin: 2em 0
padding 1rem
.markdown-section ul.task-list > li
list-style-type none

View file

@ -216,7 +216,6 @@ pre::after
top 0
.markdown-section p.tip
.markdown-section .docsify-tip
background-color #282828
color #657b83

62
test/unit/base.js Normal file
View file

@ -0,0 +1,62 @@
/* eslint-env node, chai, mocha */
require = require('esm')(module/*, options*/)
const {expect} = require('chai')
const {History} = require('../../src/core/router/history/base')
class MockHistory extends History {
parse(path) {
return {path}
}
}
describe('router/history/base', function () {
describe('relativePath true', function () {
var history
beforeEach(function () {
history = new MockHistory({relativePath: true})
})
it('toURL', function () {
// WHEN
const url = history.toURL('guide.md', {}, '/zh-ch/')
// THEN
expect(url).equal('/zh-ch/guide')
})
it('toURL with double dot', function () {
// WHEN
const url = history.toURL('../README.md', {}, '/zh-ch/')
// THEN
expect(url).equal('/README')
})
it('toURL child path', function () {
// WHEN
const url = history.toURL('config/example.md', {}, '/zh-ch/')
// THEN
expect(url).equal('/zh-ch/config/example')
})
it('toURL absolute path', function () {
// WHEN
const url = history.toURL('/README', {}, '/zh-ch/')
// THEN
expect(url).equal('/README')
})
})
it('toURL without relative path', function () {
const history = new MockHistory({relativePath: false})
// WHEN
const url = history.toURL('README', {}, '/zh-ch/')
// THEN
expect(url).equal('/README')
})
})

30
test/unit/util.js Normal file
View file

@ -0,0 +1,30 @@
/* eslint-env node, chai, mocha */
require = require('esm')(module/*, options*/)
const {expect} = require('chai')
const {resolvePath} = require('../../src/core/router/util')
describe('router/util', function () {
it('resolvePath', async function () {
// WHEN
const result = resolvePath('hello.md')
// THEN
expect(result).equal('/hello.md')
})
it('resolvePath with dot', async function () {
// WHEN
const result = resolvePath('./hello.md')
// THEN
expect(result).equal('/hello.md')
})
it('resolvePath with two dots', async function () {
// WHEN
const result = resolvePath('test/../hello.md')
// THEN
expect(result).equal('/hello.md')
})
})

1
themes/.gitkeep Normal file
View file

@ -0,0 +1 @@