mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 11:51:02 +00:00
Add syntax highlighting for pipeline config (#1082)
This commit is contained in:
parent
66be4923d2
commit
2e8f9e17e6
6 changed files with 926 additions and 294 deletions
|
@ -29,6 +29,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"node-emoji": "^1.11.0",
|
||||
"pinia": "^2.0.17",
|
||||
"prismjs": "^1.28.0",
|
||||
"vue": "^3.2.37",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "^4.1.3"
|
||||
|
@ -40,6 +41,7 @@
|
|||
"@types/lodash": "^4.14.182",
|
||||
"@types/node": "^16.11.6",
|
||||
"@types/node-emoji": "^1.8.1",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"@vitejs/plugin-vue": "^3.0.1",
|
||||
|
@ -59,6 +61,7 @@
|
|||
"unplugin-icons": "^0.14.8",
|
||||
"unplugin-vue-components": "^0.22.3",
|
||||
"vite": "^3.0.4",
|
||||
"vite-plugin-prismjs": "^0.0.8",
|
||||
"vite-plugin-windicss": "^1.8.7",
|
||||
"vite-svg-loader": "^3.4.0",
|
||||
"vue-tsc": "^0.39.5",
|
||||
|
|
37
web/src/components/atomic/SyntaxHighlight.ts
Normal file
37
web/src/components/atomic/SyntaxHighlight.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import '~/style/prism.css';
|
||||
|
||||
import Prism from 'prismjs';
|
||||
import { computed, defineComponent, h, toRef, VNode } from 'vue';
|
||||
|
||||
declare type Data = Record<string, unknown>;
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SyntaxHighlight',
|
||||
|
||||
props: {
|
||||
code: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
|
||||
language: {
|
||||
type: String,
|
||||
default: 'yaml',
|
||||
},
|
||||
},
|
||||
|
||||
setup(props, { attrs }: { attrs: Data }) {
|
||||
const code = toRef(props, 'code');
|
||||
const language = toRef(props, 'language');
|
||||
const prismLanguage = computed(() => Prism.languages[language.value]);
|
||||
const className = computed(() => `language-${language.value}`);
|
||||
|
||||
return (): VNode =>
|
||||
h('pre', { ...attrs, class: [attrs.class, className] }, [
|
||||
h('code', {
|
||||
class: className,
|
||||
innerHTML: Prism.highlight(code.value, prismLanguage.value, language.value),
|
||||
}),
|
||||
]);
|
||||
},
|
||||
});
|
291
web/src/style/prism.css
Normal file
291
web/src/style/prism.css
Normal file
|
@ -0,0 +1,291 @@
|
|||
.token.atrule {
|
||||
color: #7c4dff;
|
||||
}
|
||||
|
||||
.token.attr-name {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.attr-value {
|
||||
color: #f6a434;
|
||||
}
|
||||
|
||||
.token.attribute {
|
||||
color: #f6a434;
|
||||
}
|
||||
|
||||
.token.boolean {
|
||||
color: #7c4dff;
|
||||
}
|
||||
|
||||
.token.builtin {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.cdata {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.char {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.class {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.class-name {
|
||||
color: #6182b8;
|
||||
}
|
||||
|
||||
.token.comment {
|
||||
color: #aabfc9;
|
||||
}
|
||||
|
||||
.token.constant {
|
||||
color: #7c4dff;
|
||||
}
|
||||
|
||||
.token.deleted {
|
||||
color: #e53935;
|
||||
}
|
||||
|
||||
.token.doctype {
|
||||
color: #aabfc9;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
color: #e53935;
|
||||
}
|
||||
|
||||
.token.function {
|
||||
color: #7c4dff;
|
||||
}
|
||||
|
||||
.token.hexcode {
|
||||
color: #f76d47;
|
||||
}
|
||||
|
||||
.token.id {
|
||||
color: #7c4dff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.important {
|
||||
color: #7c4dff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.inserted {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: #7c4dff;
|
||||
}
|
||||
|
||||
.token.number {
|
||||
color: #f76d47;
|
||||
}
|
||||
|
||||
.token.operator {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.prolog {
|
||||
color: #aabfc9;
|
||||
}
|
||||
|
||||
.token.property {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.pseudo-class {
|
||||
color: #f6a434;
|
||||
}
|
||||
|
||||
.token.pseudo-element {
|
||||
color: #f6a434;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #39adb5;
|
||||
}
|
||||
|
||||
.token.regex {
|
||||
color: #6182b8;
|
||||
}
|
||||
|
||||
.token.selector {
|
||||
color: #e53935;
|
||||
}
|
||||
|
||||
.token.string {
|
||||
color: #f6a434;
|
||||
}
|
||||
|
||||
.token.symbol {
|
||||
color: #7c4dff;
|
||||
}
|
||||
|
||||
.token.tag {
|
||||
color: #e53935;
|
||||
}
|
||||
|
||||
.token.unit {
|
||||
color: #f76d47;
|
||||
}
|
||||
|
||||
.token.url {
|
||||
color: #e53935;
|
||||
}
|
||||
|
||||
.token.variable {
|
||||
color: #e53935;
|
||||
}
|
||||
|
||||
.dark .token.atrule {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.dark .token.attr-name {
|
||||
color: #ffcb6b;
|
||||
}
|
||||
|
||||
.dark .token.attr-value {
|
||||
color: #a5e844;
|
||||
}
|
||||
|
||||
.dark .token.attribute {
|
||||
color: #a5e844;
|
||||
}
|
||||
|
||||
.dark .token.boolean {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.dark .token.builtin {
|
||||
color: #ffcb6b;
|
||||
}
|
||||
|
||||
.dark .token.cdata {
|
||||
color: #80cbc4;
|
||||
}
|
||||
|
||||
.dark .token.char {
|
||||
color: #80cbc4;
|
||||
}
|
||||
|
||||
.dark .token.class {
|
||||
color: #ffcb6b;
|
||||
}
|
||||
|
||||
.dark .token.class-name {
|
||||
color: #f2ff00;
|
||||
}
|
||||
|
||||
.dark .token.comment {
|
||||
color: #616161;
|
||||
}
|
||||
|
||||
.dark .token.constant {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.dark .token.deleted {
|
||||
color: #ff6666;
|
||||
}
|
||||
|
||||
.dark .token.doctype {
|
||||
color: #616161;
|
||||
}
|
||||
|
||||
.dark .token.entity {
|
||||
color: #ff6666;
|
||||
}
|
||||
|
||||
.dark .token.function {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.dark .token.hexcode {
|
||||
color: #f2ff00;
|
||||
}
|
||||
|
||||
.dark .token.id {
|
||||
color: #c792ea;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dark .token.important {
|
||||
color: #c792ea;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dark .token.inserted {
|
||||
color: #80cbc4;
|
||||
}
|
||||
|
||||
.dark .token.keyword {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.dark .token.number {
|
||||
color: #fd9170;
|
||||
}
|
||||
|
||||
.dark .token.operator {
|
||||
color: #89ddff;
|
||||
}
|
||||
|
||||
.dark .token.prolog {
|
||||
color: #616161;
|
||||
}
|
||||
|
||||
.dark .token.property {
|
||||
color: #80cbc4;
|
||||
}
|
||||
|
||||
.dark .token.pseudo-class {
|
||||
color: #a5e844;
|
||||
}
|
||||
|
||||
.dark .token.pseudo-element {
|
||||
color: #a5e844;
|
||||
}
|
||||
|
||||
.dark .token.punctuation {
|
||||
color: #89ddff;
|
||||
}
|
||||
|
||||
.dark .token.regex {
|
||||
color: #f2ff00;
|
||||
}
|
||||
|
||||
.dark .token.selector {
|
||||
color: #ff6666;
|
||||
}
|
||||
|
||||
.dark .token.string {
|
||||
color: #a5e844;
|
||||
}
|
||||
|
||||
.dark .token.symbol {
|
||||
color: #c792ea;
|
||||
}
|
||||
|
||||
.dark .token.tag {
|
||||
color: #ff6666;
|
||||
}
|
||||
|
||||
.dark .token.unit {
|
||||
color: #fd9170;
|
||||
}
|
||||
|
||||
.dark .token.url {
|
||||
color: #ff6666;
|
||||
}
|
||||
|
||||
.dark .token.variable {
|
||||
color: #ff6666;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<FluidContainer v-if="buildConfigs" class="flex flex-col gap-y-6 text-color justify-between !pt-0">
|
||||
<Panel v-for="buildConfig in buildConfigs" :key="buildConfig.hash" :title="buildConfig.name">
|
||||
<span class="font-mono whitespace-pre">{{ buildConfig.data }}</span>
|
||||
<SyntaxHighlight class="font-mono whitespace-pre overflow-auto" language="yaml" :code="buildConfig.data" />
|
||||
</Panel>
|
||||
</FluidContainer>
|
||||
</template>
|
||||
|
@ -9,6 +9,7 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent, inject, onMounted, Ref, ref, watch } from 'vue';
|
||||
|
||||
import SyntaxHighlight from '~/components/atomic/SyntaxHighlight';
|
||||
import FluidContainer from '~/components/layout/FluidContainer.vue';
|
||||
import Panel from '~/components/layout/Panel.vue';
|
||||
import useApiClient from '~/compositions/useApiClient';
|
||||
|
@ -20,6 +21,7 @@ export default defineComponent({
|
|||
components: {
|
||||
FluidContainer,
|
||||
Panel,
|
||||
SyntaxHighlight,
|
||||
},
|
||||
|
||||
setup() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import IconsResolver from 'unplugin-icons/resolver';
|
|||
import Icons from 'unplugin-icons/vite';
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
import prismjs from 'vite-plugin-prismjs';
|
||||
import WindiCSS from 'vite-plugin-windicss';
|
||||
import svgLoader from 'vite-svg-loader';
|
||||
|
||||
|
@ -36,6 +37,9 @@ export default defineConfig({
|
|||
resolvers: IconsResolver(),
|
||||
}),
|
||||
woodpeckerInfoPlugin(),
|
||||
prismjs({
|
||||
languages: ['yaml'],
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
|
|
881
web/yarn.lock
881
web/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue