mirror of https://github.com/vuejs/vitepress
close #728 close #1242 Co-authored-by: "Jinjing.Zhou" <allenzhou@tensorchord.ai> Co-authored-by: Kia King Ishii <kia.king.08@gmail.com>pull/1700/head
parent
2343bd17c2
commit
a684b67ec0
@ -0,0 +1,84 @@
|
|||||||
|
# Code Groups
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```txt-vue{1}
|
||||||
|
{{ 1 + 1 }}
|
||||||
|
```
|
||||||
|
|
||||||
|
```js [app.vue]
|
||||||
|
<template>
|
||||||
|
<NuxtLayout>
|
||||||
|
<NuxtPage />
|
||||||
|
</NuxtLayout>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- kkk -->
|
||||||
|
|
||||||
|
```vue-html{3,4} [layouts/custom.vue]
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Some *custom* layout
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur imperdiet mi in nunc faucibus consequat.
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js{1-3,5} [layouts/default.vue]
|
||||||
|
export default {
|
||||||
|
name: 'MyComponent'
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Some *custom* layout
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
- in list
|
||||||
|
|
||||||
|
- ::: code-group
|
||||||
|
|
||||||
|
```js
|
||||||
|
printf('111')
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
import torch as th
|
||||||
|
print("Hello world")
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
import torch as th
|
||||||
|
print("Hello world")
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├─ index.md
|
||||||
|
├─ foo
|
||||||
|
│ ├─ index.md
|
||||||
|
│ ├─ one.md
|
||||||
|
│ └─ two.md
|
||||||
|
└─ bar
|
||||||
|
├─ index.md
|
||||||
|
├─ three.md
|
||||||
|
└─ four.md
|
||||||
|
```
|
||||||
|
|
||||||
|
- ```md{1-3,5}
|
||||||
|
[Home](/) <!-- sends the user to the root index.md -->
|
||||||
|
[foo](/foo/) <!-- sends the user to index.html of directory foo -->
|
||||||
|
[foo heading](./#heading) <!-- anchors user to a heading in the foo index file -->
|
||||||
|
[bar - three](../bar/three) <!-- you can omit extention -->
|
||||||
|
[bar - three](../bar/three.md) <!-- you can append .md -->
|
||||||
|
[bar - four](../bar/four.html) <!-- or you can append .html -->
|
||||||
|
```
|
@ -0,0 +1,23 @@
|
|||||||
|
import { inBrowser } from 'vitepress'
|
||||||
|
|
||||||
|
export function useCodeGroups() {
|
||||||
|
if (inBrowser) {
|
||||||
|
window.addEventListener('click', (e) => {
|
||||||
|
const el = e.target as HTMLInputElement
|
||||||
|
|
||||||
|
if (el.matches('.vp-code-group input')) {
|
||||||
|
// input <- .tabs <- .vp-code-group
|
||||||
|
const group = el.parentElement?.parentElement
|
||||||
|
const i = Array.from(group?.querySelectorAll('input') || []).indexOf(el)
|
||||||
|
|
||||||
|
const current = group?.querySelector('div[class*="language-"].active')
|
||||||
|
const next = group?.querySelectorAll('div[class*="language-"]')?.[i]
|
||||||
|
|
||||||
|
if (current && next && current !== next) {
|
||||||
|
current.classList.remove('active')
|
||||||
|
next.classList.add('active')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
.vp-code-group {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group .tabs {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
margin-right: -24px;
|
||||||
|
margin-left: -24px;
|
||||||
|
padding: 0 12px;
|
||||||
|
background-color: var(--vp-code-tab-bg);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group .tabs::after {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--vp-code-tab-divider);
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
.vp-code-group .tabs {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group .tabs input {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group .tabs label {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
padding: 0 12px;
|
||||||
|
line-height: 48px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--vp-code-tab-text-color);
|
||||||
|
background-color: var(--vp-code-tab-bg);
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group .tabs label::after {
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
bottom: -1px;
|
||||||
|
left: 8px;
|
||||||
|
z-index: 10;
|
||||||
|
height: 1px;
|
||||||
|
content: '';
|
||||||
|
background-color: transparent;
|
||||||
|
transition: background-color 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group label:hover {
|
||||||
|
color: var(--vp-code-tab-hover-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group input:checked + label {
|
||||||
|
color: var(--vp-code-tab-active-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group input:checked + label::after {
|
||||||
|
background-color: var(--vp-code-tab-active-bar-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group div[class*='language-'] {
|
||||||
|
display: none;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-code-group div[class*='language-'].active {
|
||||||
|
display: block;
|
||||||
|
}
|
@ -1,22 +1,24 @@
|
|||||||
// markdown-it plugin for wrapping <pre> ... </pre>.
|
|
||||||
//
|
|
||||||
// If your plugin was chained before preWrapper, you can add additional element directly.
|
|
||||||
// If your plugin was chained after preWrapper, you can use these slots:
|
|
||||||
// 1. <!--beforebegin-->
|
|
||||||
// 2. <!--afterbegin-->
|
|
||||||
// 3. <!--beforeend-->
|
|
||||||
// 4. <!--afterend-->
|
|
||||||
|
|
||||||
import MarkdownIt from 'markdown-it'
|
import MarkdownIt from 'markdown-it'
|
||||||
|
|
||||||
export const preWrapperPlugin = (md: MarkdownIt) => {
|
export function preWrapperPlugin(md: MarkdownIt) {
|
||||||
const fence = md.renderer.rules.fence!
|
const fence = md.renderer.rules.fence!
|
||||||
md.renderer.rules.fence = (...args) => {
|
md.renderer.rules.fence = (...args) => {
|
||||||
const [tokens, idx] = args
|
const { info } = args[0][args[1]]
|
||||||
const lang = tokens[idx].info.trim().replace(/-vue$/, '')
|
const lang = extractLang(info)
|
||||||
const rawCode = fence(...args)
|
const rawCode = fence(...args)
|
||||||
return `<div class="language-${lang}"><button title="Copy Code" class="copy"></button><span class="lang">${
|
return `<div class="language-${lang}${
|
||||||
lang === 'vue-html' ? 'template' : lang
|
/ active( |$)/.test(info) ? ' active' : ''
|
||||||
}</span>${rawCode}</div>`
|
}"><button title="Copy Code" class="copy"></button><span class="lang">${lang}</span>${rawCode}</div>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function extractTitle(info: string) {
|
||||||
|
return info.match(/\[(.*)\]/)?.[1] || extractLang(info) || 'txt'
|
||||||
|
}
|
||||||
|
|
||||||
|
const extractLang = (info: string) => {
|
||||||
|
return info
|
||||||
|
.trim()
|
||||||
|
.replace(/(-vue|{| ).*$/, '')
|
||||||
|
.replace(/^vue-html$/, 'template')
|
||||||
|
}
|
||||||
|
Loading…
Reference in new issue