mirror of
https://github.com/go-task/task.git
synced 2026-09-01 19:50:16 +02:00
refactor(site): render the homepage example with shiki
The Taskfile and terminal panels were hand-marked HTML with their own .syntax-* classes, so the sample missed the site's code theme and could drift from what Task actually prints. Move both to files under .vitepress/snippets and highlight the YAML at build time through a VitePress data loader, using the same Shiki themes as fenced code blocks. The terminal transcript is now the verbatim output of running the sample Taskfile: the previous one had the wrong column padding for `task --list`.
This commit is contained in:
@@ -3,6 +3,7 @@ import { computed, ref } from 'vue';
|
||||
import { VPHomeSponsors } from 'vitepress/theme';
|
||||
import { sponsors } from '../sponsors';
|
||||
import AdoptersCarousel from './AdoptersCarousel.vue';
|
||||
import { data as example } from './homeExample.data';
|
||||
|
||||
const installCommand =
|
||||
'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin';
|
||||
@@ -97,29 +98,7 @@ function track(event: string) {
|
||||
<span class="status-dot" aria-hidden="true"></span>
|
||||
Taskfile.yml
|
||||
</div>
|
||||
<pre
|
||||
v-pre
|
||||
><code><span class="syntax-key">version</span>: <span class="syntax-string">'3'</span>
|
||||
|
||||
<span class="syntax-key">vars</span>:
|
||||
<span class="syntax-key">GREETING</span>: <span class="syntax-string">Hello</span>
|
||||
|
||||
<span class="syntax-key">tasks</span>:
|
||||
<span class="syntax-key">test</span>:
|
||||
<span class="syntax-key">desc</span>: <span class="syntax-string">Run the test suite</span>
|
||||
<span class="syntax-key">sources</span>: [<span class="syntax-string">'**/*.go'</span>]
|
||||
<span class="syntax-key">cmds</span>:
|
||||
- go test ./...
|
||||
|
||||
<span class="syntax-key">build</span>:
|
||||
<span class="syntax-key">desc</span>: <span class="syntax-string">Build the application</span>
|
||||
<span class="syntax-key">deps</span>: [test]
|
||||
<span class="syntax-key">sources</span>: [<span class="syntax-string">'**/*.go'</span>]
|
||||
<span class="syntax-key">generates</span>: [bin/app]
|
||||
<span class="syntax-key">cmds</span>:
|
||||
- mkdir -p bin
|
||||
- echo <span class="syntax-string">"{{.GREETING}} from Task"</span>
|
||||
- go build -o bin/app ./cmd/app</code></pre>
|
||||
<div class="code-body" v-html="example.taskfile"></div>
|
||||
</div>
|
||||
|
||||
<div class="code-panel terminal-panel">
|
||||
@@ -127,22 +106,9 @@ function track(event: string) {
|
||||
<span class="status-dot" aria-hidden="true"></span>
|
||||
Terminal
|
||||
</div>
|
||||
<pre><code><span class="terminal-prompt">$</span> task --list
|
||||
task: Available tasks for this project:
|
||||
* build: Build the application
|
||||
* test: Run the test suite
|
||||
|
||||
<span class="terminal-prompt">$</span> task build
|
||||
task: [test] go test ./...
|
||||
ok example/app
|
||||
task: [build] mkdir -p bin
|
||||
task: [build] echo "Hello from Task"
|
||||
Hello from Task
|
||||
task: [build] go build -o bin/app ./cmd/app
|
||||
|
||||
<span class="terminal-prompt">$</span> task build
|
||||
task: Task "test" is up to date
|
||||
task: Task "build" is up to date</code></pre>
|
||||
<div class="code-body">
|
||||
<pre><code v-html="example.terminal"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -286,7 +252,7 @@ task: Task "build" is up to date</code></pre>
|
||||
}
|
||||
|
||||
.install-command .prompt,
|
||||
.terminal-prompt {
|
||||
.example :deep(.terminal-prompt) {
|
||||
color: var(--vp-c-brand-1);
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -354,6 +320,14 @@ task: Task "build" is up to date</code></pre>
|
||||
}
|
||||
|
||||
.code-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.code-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -378,8 +352,9 @@ task: Task "build" is up to date</code></pre>
|
||||
box-shadow: 0 0 0 4px var(--vp-c-brand-soft);
|
||||
}
|
||||
|
||||
.code-panel pre {
|
||||
.code-panel :deep(pre) {
|
||||
min-height: 420px;
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
padding: 1.5rem;
|
||||
@@ -390,15 +365,7 @@ task: Task "build" is up to date</code></pre>
|
||||
line-height: 1.65;
|
||||
}
|
||||
|
||||
.syntax-key {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.syntax-string {
|
||||
color: var(--vp-c-yellow-1);
|
||||
}
|
||||
|
||||
.terminal-panel pre {
|
||||
.terminal-panel :deep(pre) {
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
@@ -502,7 +469,7 @@ task: Task "build" is up to date</code></pre>
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.code-panel pre {
|
||||
.code-panel :deep(pre) {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
@@ -530,7 +497,7 @@ task: Task "build" is up to date</code></pre>
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.code-panel pre {
|
||||
.code-panel :deep(pre) {
|
||||
padding: 1rem;
|
||||
font-size: 0.74rem;
|
||||
}
|
||||
|
||||
67
website/.vitepress/components/homeExample.data.ts
Normal file
67
website/.vitepress/components/homeExample.data.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import fs from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { defineLoader } from 'vitepress';
|
||||
import { codeToHtml } from 'shiki';
|
||||
|
||||
// Same themes VitePress uses for fenced code blocks, so the homepage sample
|
||||
// picks up the site's own light/dark code colours through `.vp-code`.
|
||||
const THEMES = { light: 'github-light', dark: 'github-dark' } as const;
|
||||
|
||||
const taskfilePath = fileURLToPath(
|
||||
new URL('../snippets/homepage-taskfile.yml', import.meta.url)
|
||||
);
|
||||
const terminalPath = fileURLToPath(
|
||||
new URL('../snippets/homepage-terminal.txt', import.meta.url)
|
||||
);
|
||||
|
||||
export interface HomeExample {
|
||||
taskfile: string;
|
||||
terminal: string;
|
||||
}
|
||||
|
||||
declare const data: HomeExample;
|
||||
export { data };
|
||||
|
||||
export default defineLoader({
|
||||
watch: [
|
||||
'../snippets/homepage-taskfile.yml',
|
||||
'../snippets/homepage-terminal.txt'
|
||||
],
|
||||
async load(): Promise<HomeExample> {
|
||||
const taskfile = fs.readFileSync(taskfilePath, 'utf-8').trimEnd();
|
||||
return {
|
||||
taskfile: await codeToHtml(taskfile, {
|
||||
lang: 'yaml',
|
||||
themes: THEMES,
|
||||
defaultColor: false,
|
||||
transformers: [
|
||||
{
|
||||
pre(node) {
|
||||
this.addClassToHast(node, 'vp-code');
|
||||
}
|
||||
}
|
||||
]
|
||||
}),
|
||||
terminal: renderTerminal(fs.readFileSync(terminalPath, 'utf-8'))
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function renderTerminal(source: string): string {
|
||||
return source
|
||||
.trimEnd()
|
||||
.split('\n')
|
||||
.map((line) =>
|
||||
line.startsWith('$ ')
|
||||
? `<span class="terminal-prompt">$</span>${escapeHtml(line.slice(1))}`
|
||||
: escapeHtml(line)
|
||||
)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
function escapeHtml(value: string): string {
|
||||
return value
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
21
website/.vitepress/snippets/homepage-taskfile.yml
Normal file
21
website/.vitepress/snippets/homepage-taskfile.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
GREETING: Hello
|
||||
|
||||
tasks:
|
||||
test:
|
||||
desc: Run the test suite
|
||||
sources: ['**/*.go']
|
||||
cmds:
|
||||
- go test ./...
|
||||
|
||||
build:
|
||||
desc: Build the application
|
||||
deps: [test]
|
||||
sources: ['**/*.go']
|
||||
generates: [bin/app]
|
||||
cmds:
|
||||
- mkdir -p bin
|
||||
- echo "{{.GREETING}} from Task"
|
||||
- go build -o bin/app ./cmd/app
|
||||
16
website/.vitepress/snippets/homepage-terminal.txt
Normal file
16
website/.vitepress/snippets/homepage-terminal.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
$ task --list
|
||||
task: Available tasks for this project:
|
||||
* build: Build the application
|
||||
* test: Run the test suite
|
||||
|
||||
$ task build
|
||||
task: [test] go test ./...
|
||||
ok example/app 0.2s
|
||||
task: [build] mkdir -p bin
|
||||
task: [build] echo "Hello from Task"
|
||||
Hello from Task
|
||||
task: [build] go build -o bin/app ./cmd/app
|
||||
|
||||
$ task build
|
||||
task: Task "test" is up to date
|
||||
task: Task "build" is up to date
|
||||
@@ -18,10 +18,11 @@
|
||||
"gray-matter": "^4.0.3",
|
||||
"netlify-cli": "^27.0.0",
|
||||
"prettier": "^3.6.2",
|
||||
"shiki": "^2.5.0",
|
||||
"vitepress": "^1.6.3",
|
||||
"vitepress-plugin-group-icons": "^1.6.1",
|
||||
"vitepress-plugin-tabs": "^0.9.0",
|
||||
"vitepress-plugin-llms": "^1.9.1",
|
||||
"vitepress-plugin-tabs": "^0.9.0",
|
||||
"vue": "^3.5.18"
|
||||
},
|
||||
"packageManager": "pnpm@11.22.0+sha512.1ff870c4c6133dfd88fb2afc46dd13d47f09c9794b438c6fdb47ca98caf3bc16381ee0be93a091b8e3824cf01f889f46d7d9e20910fb0be1ab0fb5baa80dd621"
|
||||
|
||||
3
website/pnpm-lock.yaml
generated
3
website/pnpm-lock.yaml
generated
@@ -23,6 +23,9 @@ importers:
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.9.6
|
||||
shiki:
|
||||
specifier: ^2.5.0
|
||||
version: 2.5.0
|
||||
vitepress:
|
||||
specifier: ^1.6.3
|
||||
version: 1.6.4(@algolia/client-search@5.35.0)(@types/node@24.13.3)(jwt-decode@4.0.0)(postcss@8.5.26)(search-insights@2.17.3)(typescript@5.9.3)
|
||||
|
||||
Reference in New Issue
Block a user