提交 ce86da7e 编写于 作者: E Evan You

theme tweaks

上级 f97e6766
# Asset Handling
## Relative URLs
Since your markdown files are compiled into Vue components via webpack, you can safely reference any asset using relative paths on your file system:
``` markdown
![logo][./logo.png]
```
This would work the same way as if you are referencing it inside a `*.vue` file template. The image will be processed with `url-loader` and `file-loader`, and copied to appropriate locations in the generated static build.
## Public Files
Sometimes you may need to provide some static assets that are not directly referenced in any of your markdown or theme components - for example, favicons and PWA icons. In that case you can put them inside `.vuepress/public` and they will be copied to the root of the generated static build.
## Referencing Base URL Dynamically
If your site is deployed to a non-root URL, you will need to set the `base` option in `.vuepress/config.js`. The value of this option will be available anywhere in markdown or your components as `$site.base`. In order to use it though, you will have to use direct HTML along with Vue bindings:
``` html
<img :src="$site.base + 'foo.png'" alt="foo">
```
......@@ -13,6 +13,31 @@
Headers automatically get anchor links applied.
## YAML Front Matter
[YAML front matter](https://jekyllrb.com/docs/frontmatter/) is supported out of the box:
```
---
title: Blogging Like a Hacker
lang: en-US
---
```
The data will be available to the rest of the page, plus all custom and theming components as `$page`.
`title` and `lang` will be automatically set on the current page. In addition you can specify extra meta tags to be injected:
```
---
meta:
- name: description
content: hello
- name: keywords
content: super duper SEO
---
```
## Table of Contents
**Input**
......@@ -97,4 +122,21 @@ export default {
:tada: :100:
## Custom Configuration
## Advanced Configuration
VuePress uses [markdown-it]() as the markdown renderer. A lot of the extensions above are implemented via custom plugins. You can further customize the `markdown-it` instance using the `markdown` option in `.vuepress/config.js`:
``` js
module.exports = {
markdown: {
// options for markdown-it-anchor
anchor: { permalink: false },
// options for markdown-it-toc
toc: { includeLevel: [1, 2] },
config: md => {
// use more markdown-it plugins!
md.use(require('markdown-it-xxx'))
}
}
}
```
......@@ -9,16 +9,68 @@ VuePress uses Vue single file components for custom themes. To use a custom layo
      └── Layout.vue
```
From there it's the same as developing a normal Vue application. There are only a few special things to note:
From there it's the same as developing a normal Vue application. It is entirely up to you how to organize your theme.
## Using Theme from a Dependency
Themes can be published on npm as `vuepress-theme-xxx`.
To use a theme from an npm dependency, provide a `theme` option in `.vuepress/config.js`:
``` js
module.exports = {
theme: 'awesome'
}
```
VuePress will attempt to locate and use `node_modules/vuepress-theme-awesome/Layout.vue`.
## Content Outlet
The compiled content of the current `.md` file being rendered will be available as a special `<Content/>` global component. You will need to render it somewhere in your layout in order to display the content of the page. The simplest theme can be just a single `Layout.vue` component with the following content:
``` html
<template>
<div class="theme-container">
<Content/>
</div>
</template>
```
In addition to rendering the markdown content, the `<Content/>` component is also responsible for setting the title and other metadata of a specific page.
## Site and Page Metadata
The `Layout` component will be invoked once for every `.md` file in `docs`, and the metadata for the entire site and that specific page will be exposed respectively in `$site` and `$page` properties which are injected into every component in the app.
// TODO details about $site & $page
This is the value of `$site` of this very website:
## Content Outlet
``` json
{
"title": "VuePress",
"description": "Minimalistic docs generator with Vue component based layout system",
"base": "/vuepress/",
"pages": [
{
"path": "/",
"title": "VuePress",
"frontmatter": {}
},
...
]
}
```
`title`, `description` and `base` are copied from respective fields in `.vuepress/config.js`. `pages` contains an array of metadata objects for each page, including its path, page title (explicitly specified in YAML frontmatter or inferred from the first header on the page), and any YAML frontmatter data in that file.
The compiled content of the current `.md` file being rendered will be available as a special `<Content/>` global component. You will need to render it somewhere in your layout in order to display the content of the page.
This is the `$page` object for this page you are looking at:
``` json
{
"path": "/theming.html",
"title": "Custom Theme",
"frontmatter": {}
}
```
// TODO give an example
If the user provided `themeConfig` in `.vuepress/config.js`, it will also be available as `$site.themeConfig`. You can use this to allow users to customize behavior of your theme - for example, specifying categories and page order. You can then use these data together with `$site.pages` to dynamically construct navigation links.
......@@ -34,5 +34,6 @@ export default {
}
</script>
<style src="./nprogress.css"></style>
<style src="prismjs/themes/prism-tomorrow.css"></style>
<style src="./styles.css"></style>
<style src="./theme.stylus" lang="stylus"></style>
.theme-container {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
}
pre, pre[class*="language-"] {
background-color: #2d2d2d;
color: white;
line-height: 1.4;
border-radius: 5px;
padding: 1.3rem 1.575rem;
white-space: pre-wrap;
word-break: break-word;
overflow: auto;
}
pre code, pre[class*="language-"] code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
font-size: 14px;
-webkit-font-smoothing: antialiased;
}
.highlighted-line {
background-color: #14161a;
display: block;
margin: 0 -1.575rem;
padding: 0.2rem 1.575rem 0;
}
div.tip {
color: white;
background-color: green;
}
div.warning {
background-color: yellow;
}
div.danger {
color: white;
background-color: red;
}
p.demo {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 4px;
}
/*
Copied from nprogress since it doens't
allow programmatic configuration of color
*/
/* Make clicks pass-through */
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: #41b883;
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
/* Fancy blur effect */
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #41b883, 0 0 5px #41b883;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
/* Remove these to get rid of the spinner */
#nprogress .spinner {
display: block;
position: fixed;
z-index: 1031;
top: 15px;
right: 15px;
}
#nprogress .spinner-icon {
width: 18px;
height: 18px;
box-sizing: border-box;
border: solid 2px transparent;
border-top-color: #41b883;
border-left-color: #41b883;
border-radius: 50%;
-webkit-animation: nprogress-spinner 400ms linear infinite;
animation: nprogress-spinner 400ms linear infinite;
}
.nprogress-custom-parent {
overflow: hidden;
position: relative;
}
.nprogress-custom-parent #nprogress .spinner,
.nprogress-custom-parent #nprogress .bar {
position: absolute;
}
@-webkit-keyframes nprogress-spinner {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes nprogress-spinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.theme-container
font-family -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif
padding 0 30px
a
color #41b883
text-decoration none
h1, h2, h3, h4, h5, h6
&:hover .header-anchor
opacity: 1
a.header-anchor
font-size 0.8em
float left
padding-right 4px
margin-left -20px
margin-top 3px
opacity 0
pre, pre[class*="language-"]
background-color #2d2d2d
color white
line-height 1.4
border-radius 5px
padding 1.3rem 1.575rem
white-space pre-wrap
word-break break-word
overflow auto
code
font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace
font-size 14px
-webkit-font-smoothing antialiased
.highlighted-line
background-color #14161a
display block
margin 0 -1.575rem
padding 0.2rem 1.575rem 0
div
&.tip
color white
background-color green
&.warning
background-color yellow
&.danger
color white
background-color red
p
&.demo
padding 1rem
border 1px solid #ddd
border-radius 4px
......@@ -25,8 +25,13 @@ module.exports = ({ markdown = {}}) => {
.use(hoistScriptStyle)
// 3rd party plugins
.use(emoji)
.use(anchor, Object.assign({ permalink: true, permalinkBefore: true }, markdown.anchor))
.use(toc, Object.assign({ includeLevel: [2, 3] }, markdown.toc))
.use(anchor, Object.assign({
permalink: true,
permalinkBefore: true // TODO use an svg?
}, markdown.anchor))
.use(toc, Object.assign({
includeLevel: [2, 3]
}, markdown.toc))
.use(container, 'tip')
.use(container, 'warning')
.use(container, 'danger')
......
......@@ -80,7 +80,7 @@ async function resolveOptions (sourceDir) {
if (fs.existsSync(notFoundPath)) {
options.notFoundPath = notFoundPath
} else {
throw new Error('[vuepress] Custom theme must have a NotFound.vue file.')
options.notFoundPath = path.resolve(__dirname, 'default-theme/NotFound.vue')
}
}
......
......@@ -136,6 +136,10 @@ alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
ansi-align@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
......@@ -1117,6 +1121,10 @@ css-loader@^0.28.11:
postcss-value-parser "^3.3.0"
source-list-map "^2.0.0"
css-parse@1.7.x:
version "1.7.0"
resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.7.0.tgz#321f6cf73782a6ff751111390fc05e2c657d8c9b"
css-select@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
......@@ -2084,6 +2092,17 @@ glob-to-regexp@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
glob@7.0.x:
version "7.0.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.2"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
......@@ -3291,6 +3310,10 @@ lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
......@@ -3607,7 +3630,7 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
"mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
......@@ -4939,6 +4962,10 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
sax@0.5.x:
version "0.5.8"
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
sax@^1.2.4, sax@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
......@@ -5106,6 +5133,12 @@ source-map-url@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
source-map@0.1.x:
version "0.1.43"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
dependencies:
amdefine ">=0.0.4"
source-map@0.5.6:
version "0.5.6"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
......@@ -5316,6 +5349,25 @@ strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
stylus-loader@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-3.0.2.tgz#27a706420b05a38e038e7cacb153578d450513c6"
dependencies:
loader-utils "^1.0.2"
lodash.clonedeep "^4.5.0"
when "~3.6.x"
stylus@^0.54.5:
version "0.54.5"
resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79"
dependencies:
css-parse "1.7.x"
debug "*"
glob "7.0.x"
mkdirp "0.5.x"
sax "0.5.x"
source-map "0.1.x"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
......@@ -5962,6 +6014,10 @@ whatwg-url@^6.4.0:
tr46 "^1.0.0"
webidl-conversions "^4.0.1"
when@~3.6.x:
version "3.6.4"
resolved "https://registry.yarnpkg.com/when/-/when-3.6.4.tgz#473b517ec159e2b85005497a13983f095412e34e"
whet.extend@~0.9.9:
version "0.9.9"
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册